Remove un-used permissions.
parent
7c89f5ce1a
commit
a57bf0cd98
@ -1,49 +0,0 @@
|
||||
package org.thoughtcrime.securesms.contacts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.content.SyncResult;
|
||||
import android.os.Bundle;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
private static final String TAG = ContactsSyncAdapter.class.getSimpleName();
|
||||
|
||||
public ContactsSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority,
|
||||
ContentProviderClient provider, SyncResult syncResult)
|
||||
{
|
||||
Log.i(TAG, "onPerformSync(" + authority +")");
|
||||
|
||||
if (TextSecurePreferences.isPushRegistered(getContext())) {
|
||||
try {
|
||||
DirectoryHelper.refreshDirectory(getContext(), true);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncCanceled() {
|
||||
Log.w(TAG, "onSyncCanceled()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncCanceled(Thread thread) {
|
||||
Log.w(TAG, "onSyncCanceled(" + thread + ")");
|
||||
}
|
||||
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
package org.thoughtcrime.securesms.gcm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||
import com.google.firebase.messaging.RemoteMessage;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
||||
import org.thoughtcrime.securesms.util.PowerManagerCompat;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.WakeLockUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class FcmService extends FirebaseMessagingService implements InjectableType {
|
||||
|
||||
private static final String TAG = FcmService.class.getSimpleName();
|
||||
|
||||
private static final Executor MESSAGE_EXECUTOR = SignalExecutors.newCachedSingleThreadExecutor("FcmMessageProcessing");
|
||||
private static final String WAKE_LOCK_TAG = "FcmMessageProcessing";
|
||||
|
||||
@Inject SignalServiceMessageReceiver messageReceiver;
|
||||
|
||||
private static int activeCount;
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage remoteMessage) {
|
||||
Log.i(TAG, "FCM message... Original Priority: " + remoteMessage.getOriginalPriority() + ", Actual Priority: " + remoteMessage.getPriority());
|
||||
ApplicationContext.getInstance(getApplicationContext()).injectDependencies(this);
|
||||
|
||||
WakeLockUtil.runWithLock(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK, 60000, WAKE_LOCK_TAG, () -> {
|
||||
handleReceivedNotification(getApplicationContext());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewToken(String token) {
|
||||
Log.i(TAG, "onNewToken()");
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(getApplicationContext())) {
|
||||
Log.i(TAG, "Got a new FCM token, but the user isn't registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationContext.getInstance(getApplicationContext())
|
||||
.getJobManager()
|
||||
.add(new FcmRefreshJob());
|
||||
}
|
||||
|
||||
private void handleReceivedNotification(Context context) {
|
||||
if (!incrementActiveGcmCount()) {
|
||||
Log.i(TAG, "Skipping FCM processing -- there's already one enqueued.");
|
||||
return;
|
||||
}
|
||||
|
||||
TextSecurePreferences.setNeedsMessagePull(context, true);
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
PowerManager powerManager = ServiceUtil.getPowerManager(getApplicationContext());
|
||||
boolean doze = PowerManagerCompat.isDeviceIdleMode(powerManager);
|
||||
boolean network = new NetworkConstraint.Factory(ApplicationContext.getInstance(context)).create().isMet();
|
||||
|
||||
final Object foregroundLock = new Object();
|
||||
final AtomicBoolean foregroundRunning = new AtomicBoolean(false);
|
||||
final AtomicBoolean taskCompleted = new AtomicBoolean(false);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
if (doze || !network) {
|
||||
Log.i(TAG, "Starting a foreground task because we may be operating in a constrained environment. Doze: " + doze + " Network: " + network);
|
||||
showForegroundNotification(context);
|
||||
foregroundRunning.set(true);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
MESSAGE_EXECUTOR.execute(() -> {
|
||||
try {
|
||||
new PushNotificationReceiveJob(context).pullAndProcessMessages(messageReceiver, TAG, startTime);
|
||||
} catch (IOException e) {
|
||||
Log.i(TAG, "Failed to retrieve the envelope. Scheduling on JobManager.", e);
|
||||
ApplicationContext.getInstance(context)
|
||||
.getJobManager()
|
||||
.add(new PushNotificationReceiveJob(context));
|
||||
} finally {
|
||||
synchronized (foregroundLock) {
|
||||
if (foregroundRunning.getAndSet(false)) {
|
||||
GenericForegroundService.stopForegroundTask(context);
|
||||
} else {
|
||||
latch.countDown();
|
||||
}
|
||||
taskCompleted.set(true);
|
||||
}
|
||||
|
||||
decrementActiveGcmCount();
|
||||
Log.i(TAG, "Processing complete.");
|
||||
}
|
||||
});
|
||||
|
||||
if (!foregroundRunning.get()) {
|
||||
new Thread("FcmForegroundServiceTimer") {
|
||||
@Override
|
||||
public void run() {
|
||||
Util.sleep(7000);
|
||||
synchronized (foregroundLock) {
|
||||
if (!taskCompleted.get() && !foregroundRunning.getAndSet(true)) {
|
||||
Log.i(TAG, "Starting a foreground task because the job is running long.");
|
||||
showForegroundNotification(context);
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
Log.w(TAG, "Latch was interrupted.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void showForegroundNotification(@NonNull Context context) {
|
||||
GenericForegroundService.startForegroundTask(context,
|
||||
context.getString(R.string.GcmBroadcastReceiver_retrieving_a_message),
|
||||
NotificationChannels.OTHER,
|
||||
R.drawable.ic_signal_downloading);
|
||||
}
|
||||
|
||||
private static synchronized boolean incrementActiveGcmCount() {
|
||||
if (activeCount < 2) {
|
||||
activeCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static synchronized void decrementActiveGcmCount() {
|
||||
activeCount--;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package org.thoughtcrime.securesms.gcm;
|
||||
|
||||
import android.support.annotation.WorkerThread;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.firebase.iid.FirebaseInstanceId;
|
||||
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public final class FcmUtil {
|
||||
|
||||
private static final String TAG = FcmUtil.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Retrieves the current FCM token. If one isn't available, it'll be generated.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static Optional<String> getToken() {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AtomicReference<String> token = new AtomicReference<>(null);
|
||||
|
||||
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful() && task.getResult() != null && !TextUtils.isEmpty(task.getResult().getToken())) {
|
||||
token.set(task.getResult().getToken());
|
||||
} else {
|
||||
Log.w(TAG, "Failed to get the token.", task.getException());
|
||||
}
|
||||
|
||||
latch.countDown();
|
||||
});
|
||||
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
Log.w(TAG, "Was interrupted while waiting for the token.");
|
||||
}
|
||||
|
||||
return Optional.fromNullable(token.get());
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
|
||||
import org.thoughtcrime.securesms.gcm.FcmUtil;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.PlayServicesProblemActivity;
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class FcmRefreshJob extends BaseJob implements InjectableType {
|
||||
|
||||
public static final String KEY = "FcmRefreshJob";
|
||||
|
||||
private static final String TAG = FcmRefreshJob.class.getSimpleName();
|
||||
|
||||
@Inject SignalServiceAccountManager textSecureAccountManager;
|
||||
|
||||
public FcmRefreshJob() {
|
||||
this(new Job.Parameters.Builder()
|
||||
.setQueue("FcmRefreshJob")
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setMaxAttempts(1)
|
||||
.setLifespan(TimeUnit.MINUTES.toMillis(5))
|
||||
.setMaxInstances(1)
|
||||
.build());
|
||||
}
|
||||
|
||||
private FcmRefreshJob(@NonNull Job.Parameters parameters) {
|
||||
super(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Data serialize() {
|
||||
return Data.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getFactoryKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun() throws Exception {
|
||||
if (TextSecurePreferences.isFcmDisabled(context)) return;
|
||||
|
||||
Log.i(TAG, "Reregistering FCM...");
|
||||
|
||||
int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
|
||||
|
||||
if (result != ConnectionResult.SUCCESS) {
|
||||
notifyFcmFailure();
|
||||
} else {
|
||||
Optional<String> token = FcmUtil.getToken();
|
||||
|
||||
if (token.isPresent()) {
|
||||
String oldToken = TextSecurePreferences.getFcmToken(context);
|
||||
|
||||
if (!token.get().equals(oldToken)) {
|
||||
int oldLength = oldToken != null ? oldToken.length() : -1;
|
||||
Log.i(TAG, "Token changed. oldLength: " + oldLength + " newLength: " + token.get().length());
|
||||
} else {
|
||||
Log.i(TAG, "Token didn't change.");
|
||||
}
|
||||
|
||||
textSecureAccountManager.setGcmId(token);
|
||||
TextSecurePreferences.setFcmToken(context, token.get());
|
||||
TextSecurePreferences.setFcmTokenLastSetTime(context, System.currentTimeMillis());
|
||||
TextSecurePreferences.setWebsocketRegistered(context, true);
|
||||
} else {
|
||||
throw new RetryLaterException(new IOException("Failed to retrieve a token."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled() {
|
||||
Log.w(TAG, "GCM reregistration failed after retry attempt exhaustion!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetry(@NonNull Exception throwable) {
|
||||
if (throwable instanceof NonSuccessfulResponseCodeException) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void notifyFcmFailure() {
|
||||
Intent intent = new Intent(context, PlayServicesProblemActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1122, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationChannels.FAILURES);
|
||||
|
||||
builder.setSmallIcon(R.drawable.ic_notification);
|
||||
builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
|
||||
R.drawable.ic_action_warning_red));
|
||||
builder.setContentTitle(context.getString(R.string.GcmRefreshJob_Permanent_Signal_communication_failure));
|
||||
builder.setContentText(context.getString(R.string.GcmRefreshJob_Signal_was_unable_to_register_with_Google_Play_Services));
|
||||
builder.setTicker(context.getString(R.string.GcmRefreshJob_Permanent_Signal_communication_failure));
|
||||
builder.setVibrate(new long[] {0, 1000});
|
||||
builder.setContentIntent(pendingIntent);
|
||||
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.notify(12, builder.build());
|
||||
}
|
||||
|
||||
public static final class Factory implements Job.Factory<FcmRefreshJob> {
|
||||
@Override
|
||||
public @NonNull FcmRefreshJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
return new FcmRefreshJob(parameters);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.ContactsSyncAdapter;
|
||||
|
||||
public class ContactsSyncAdapterService extends Service {
|
||||
|
||||
private static ContactsSyncAdapter syncAdapter;
|
||||
|
||||
@Override
|
||||
public synchronized void onCreate() {
|
||||
if (syncAdapter == null) {
|
||||
syncAdapter = new ContactsSyncAdapter(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return syncAdapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue