Switch from GCM to FCM.

This commit is contained in:
Greyson Parrelli 2019-01-24 03:04:28 -08:00
parent ebe8d38a91
commit d482c60a98
15 changed files with 216 additions and 111 deletions

View File

@ -87,10 +87,6 @@
<uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<permission android:name="org.thoughtcrime.securesms.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="org.thoughtcrime.securesms.permission.C2D_MESSAGE" />
<application android:name=".ApplicationContext"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@ -110,6 +106,11 @@
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
<meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
<meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
<meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" />
<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
<activity android:name="org.thoughtcrime.securesms.WebRtcCallActivity"
android:excludeFromRecents="true"
android:screenOrientation="portrait"
@ -472,12 +473,11 @@
<service android:name=".service.GenericForegroundService"/>
<receiver android:name=".gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<service android:name=".gcm.FcmService">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="org.thoughtcrime.securesms" />
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</receiver>
</service>
<receiver android:name=".service.SmsListener"
android:permission="android.permission.BROADCAST_SMS"

View File

@ -15,6 +15,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.google.gms:google-services:4.0.2'
classpath files('libs/gradle-witness.jar')
}
}
@ -79,7 +80,8 @@ dependencies {
compile 'android.arch.lifecycle:common-java8:1.1.1'
compile 'android.arch.work:work-runtime:1.0.0-beta03'
compile 'com.google.android.gms:play-services-gcm:16.0.0'
compile 'com.google.firebase:firebase-messaging:17.3.4'
compile 'com.google.firebase:firebase-core:16.0.6'
compile 'com.google.android.gms:play-services-maps:16.0.0'
compile 'com.google.android.gms:play-services-places:16.0.0'
compile 'com.google.android.gms:play-services-auth:16.0.1'
@ -178,7 +180,8 @@ dependencyVerification {
'android.arch.work:work-runtime:f428464342adeb412fd350a0c268134e92a13cf3d71c5d38180386c2b23fa694',
'android.arch.lifecycle:extensions:429426b2feec2245ffc5e75b3b5309bedb36159cf06dc71843ae43526ac289b6',
'android.arch.lifecycle:common-java8:7078b5c8ccb94203df9cc2a463c69cf0021596e6cf966d78fbfd697aaafe0630',
'com.google.android.gms:play-services-gcm:921b4651a2f4d108753f8b4c5d3844b5f8c1f3c31b740c80f69765082713d004',
'com.google.firebase:firebase-messaging:e42288e7950d7d3b033d3395a5ac9365d230da3e439a2794ec13e2ef0fbaf078',
'com.google.firebase:firebase-core:07d1544aeed9690843858982ea5a69506038f94e93b5d031b741ba9164f6258a',
'com.google.android.gms:play-services-places:2d5c4e4ac3ee5be21b4ec544411bc51d11457b5ae2fa2a5d4539019f87c233c6',
'com.google.android.gms:play-services-maps:07f59c5955b759ce7b80ceaeb8261643c5b79acc9f180df2b7c3987658eed2e8',
'com.google.android.gms:play-services-auth:aec9e1c584d442cb9f59481a50b2c66dc191872607c04d97ecb82dd0eb5149ec',
@ -208,13 +211,22 @@ dependencyVerification {
'com.github.dmytrodanylyk.circular-progress-button:library:8dc6a29a5a8db7b2ad5a9a7fda1dc9ae0893f4c8f0545732b2c63854ea693e8e',
'org.signal:android-database-sqlcipher:33d4063336893af00b9d68b418e7b290cace74c20ce8aacffddc0911010d3d73',
'com.googlecode.ez-vcard:ez-vcard:7e24ad50b222d2f70ac91bdccfa3c0f6200b078d797cb784837f75e77bb4210f',
'com.google.android.gms:play-services-iid:62aa9d8fbfb66ab68d5afdfe78db3d5da1f6adcc19abac142cee25fb23d3391f',
'com.google.firebase:firebase-measurement-connector-impl:eacaa68ed2c5c390b517267d7dae34268084d43b006db12682db88d17bbdc0ee',
'com.google.firebase:firebase-analytics:91a6b814b556779c223c80f52d0ca8ed48edbd4645b0d9104ac7b22639d5acf1',
'com.google.android.gms:play-services-measurement-api:a026fc70e777bcda3f7e51e68e331a03ed7a1143a7b3e3f67b99c21177a5b4d5',
'com.google.firebase:firebase-analytics-impl:dff7c79fe2dc3bef441057ae36678b51e27301f9b03377657170820bbe3c7441',
'com.google.firebase:firebase-iid:bb42774e309d5eac1aa493d19711032bee4f677a409639b6a5cfa93089af93eb',
'com.google.firebase:firebase-common:3db6bfd4c6f758551e5f9acdeada2050577277e6da1aefb2412de23829759bcf',
'com.google.android.gms:play-services-auth-api-phone:19365818b9ceb048ef48db12b5ffadd5eb86dbeb2c7c7b823bfdd89c665f42e5',
'com.google.android.gms:play-services-auth-base:51dc02ad2f8d1d9dff7b5b52c4df2c6c12ef7df55d752e919d5cb4dd6002ecd0',
'com.google.firebase:firebase-iid-interop:2a86322b9346fd4836219206d249e85803311655e96036a8e4b714ce7e79693b',
'com.google.android.gms:play-services-base:aca10c780c3219bc50f3db06734f4ab88badd3113c564c0a3156ff8ff674655b',
'com.google.android.gms:play-services-stats:5b2d8281adbfd6e74d2295c94bab9ea80fc9a84dfbb397995673f5af4d4c6368',
'com.google.android.gms:play-services-places-placereport:04f8baeb1f8f8a734c7d4b1701a3974281b45591affa7e963b59dd019b8abc6e',
'com.google.android.gms:play-services-tasks:b31c18d8d1cc8d9814f295ee7435471333f370ba5bd904ca14f8f2bec4f35c35',
'com.google.firebase:firebase-measurement-connector:bc318110486ed738e1cc84d4b280e156b35a9a3964d678ee64930d846150d0c3',
'com.google.android.gms:play-services-places-placereport:04f8baeb1f8f8a734c7d4b1701a3974281b45591affa7e963b59dd019b8abc6e',
'com.google.android.gms:play-services-stats:5b2d8281adbfd6e74d2295c94bab9ea80fc9a84dfbb397995673f5af4d4c6368',
'com.google.android.gms:play-services-measurement-base:887ddc8b384108a35ff7a41c8bc5c653dcedb44d9d6e46110569f586898d3c1d',
'com.google.android.gms:play-services-ads-identifier:380b09bfc5389fff93b5719c04e57c99678c9c3af0402a91e26d89734babcc49',
'com.google.android.gms:play-services-basement:e08bfd1e87c4e50ef76161d7ac76b873aeb975367eeb3afa4abe62ea1887c7c6',
'com.android.support:support-v4:8b9031381c678d628c9e47b566ae1d161e1c9710f7855c759beeac7596cecf30',
'com.android.support:support-fragment:3772fc738ada86824ba1a4b3f197c3dbd67b7ddcfe2c9db1de95ef2e3487a915',
@ -494,4 +506,4 @@ def getLastCommitTimestamp() {
return os.toString() + "000"
}
}
apply plugin: 'com.google.gms.google-services'

42
google-services.json Normal file
View File

@ -0,0 +1,42 @@
{
"project_info": {
"project_number": "312334754206",
"firebase_url": "https://api-project-312334754206.firebaseio.com",
"project_id": "api-project-312334754206",
"storage_bucket": "api-project-312334754206.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:312334754206:android:a9297b152879f266",
"android_client_info": {
"package_name": "org.thoughtcrime.securesms"
}
},
"oauth_client": [
{
"client_id": "312334754206-dg1p1mtekis8ivja3ica50vonmrlunh4.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDrfzNAPBPzX6key51hqo3p5LZXF5Y-yxU"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

View File

@ -39,7 +39,7 @@ import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.dependencies.DependencyInjector;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob;
@ -204,10 +204,10 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
private void initializeGcmCheck() {
if (TextSecurePreferences.isPushRegistered(this)) {
long nextSetTime = TextSecurePreferences.getGcmRegistrationIdLastSetTime(this) + TimeUnit.HOURS.toMillis(6);
long nextSetTime = TextSecurePreferences.getFcmTokenLastSetTime(this) + TimeUnit.HOURS.toMillis(6);
if (TextSecurePreferences.getGcmRegistrationId(this) == null || nextSetTime <= System.currentTimeMillis()) {
this.jobManager.add(new GcmRefreshJob(this));
if (TextSecurePreferences.getFcmToken(this) == null || nextSetTime <= System.currentTimeMillis()) {
this.jobManager.add(new FcmRefreshJob(this));
}
}
}

View File

@ -25,14 +25,15 @@ import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesUtil;
public class PlayServicesProblemFragment extends DialogFragment {
@Override
public @NonNull Dialog onCreateDialog(@NonNull Bundle bundle) {
int code = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(code, getActivity(), 9111);
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getActivity());
Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), code, 9111);
if (dialog == null) {
return new AlertDialog.Builder(getActivity())

View File

@ -45,7 +45,6 @@ import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.tasks.Task;
import com.google.i18n.phonenumbers.AsYouTypeFormatter;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
@ -71,8 +70,8 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.IdentityDatabase;
import org.thoughtcrime.securesms.database.NoExternalStorageException;
import org.thoughtcrime.securesms.gcm.FcmUtil;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.RotateCertificateJob;
import org.thoughtcrime.securesms.lock.RegistrationLockReminders;
import org.thoughtcrime.securesms.logging.Log;
@ -507,18 +506,18 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
String password = Util.getSecret(18);
Optional<String> gcmToken;
Optional<String> fcmToken;
if (gcmSupported) {
gcmToken = Optional.of(GoogleCloudMessaging.getInstance(RegistrationActivity.this).register(GcmRefreshJob.REGISTRATION_ID));
fcmToken = FcmUtil.getToken();
} else {
gcmToken = Optional.absent();
fcmToken = Optional.absent();
}
accountManager = AccountManagerFactory.createManager(RegistrationActivity.this, e164number, password);
accountManager.requestSmsVerificationCode(smsRetrieverSupported);
return new Pair<>(password, gcmToken);
return new Pair<>(password, fcmToken);
} catch (IOException e) {
Log.w(TAG, "Error during account registration", e);
return null;
@ -726,8 +725,8 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
accountManager.setGcmId(registrationState.gcmToken);
}
TextSecurePreferences.setGcmRegistrationId(RegistrationActivity.this, registrationState.gcmToken.orNull());
TextSecurePreferences.setGcmDisabled(RegistrationActivity.this, !registrationState.gcmToken.isPresent());
TextSecurePreferences.setFcmToken(RegistrationActivity.this, registrationState.gcmToken.orNull());
TextSecurePreferences.setFcmDisabled(RegistrationActivity.this, !registrationState.gcmToken.isPresent());
TextSecurePreferences.setWebsocketRegistered(RegistrationActivity.this, true);
DatabaseFactory.getIdentityDatabase(RegistrationActivity.this)

View File

@ -39,7 +39,7 @@ public class DozeReminder extends Reminder {
}
public static boolean isEligible(Context context) {
return TextSecurePreferences.isGcmDisabled(context) &&
return TextSecurePreferences.isFcmDisabled(context) &&
!TextSecurePreferences.hasPromptedOptimizeDoze(context) &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
!((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isIgnoringBatteryOptimizations(context.getPackageName());

View File

@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.dependencies;
import android.content.Context;
import org.thoughtcrime.securesms.gcm.GcmBroadcastReceiver;
import org.thoughtcrime.securesms.gcm.FcmService;
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob;
import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob;
@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
import org.thoughtcrime.securesms.jobs.AvatarDownloadJob;
import org.thoughtcrime.securesms.jobs.CleanPreKeysJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob;
@ -76,7 +76,7 @@ import dagger.Provides;
MultiDeviceBlockedUpdateJob.class,
DeviceListFragment.class,
RefreshAttributesJob.class,
GcmRefreshJob.class,
FcmRefreshJob.class,
RequestGroupInfoJob.class,
PushGroupUpdateJob.class,
AvatarDownloadJob.class,
@ -90,7 +90,7 @@ import dagger.Provides;
SendReadReceiptJob.class,
MultiDeviceReadReceiptUpdateJob.class,
AppProtectionPreferenceFragment.class,
GcmBroadcastReceiver.class,
FcmService.class,
RotateCertificateJob.class,
SendDeliveryReceiptJob.class,
RotateProfileKeyJob.class,
@ -147,7 +147,7 @@ public class SignalCommunicationModule {
@Provides
synchronized SignalServiceMessageReceiver provideSignalMessageReceiver() {
if (this.messageReceiver == null) {
SleepTimer sleepTimer = TextSecurePreferences.isGcmDisabled(context) ? new RealtimeSleepTimer(context) : new UptimeSleepTimer();
SleepTimer sleepTimer = TextSecurePreferences.isFcmDisabled(context) ? new RealtimeSleepTimer(context) : new UptimeSleepTimer();
this.messageReceiver = new SignalServiceMessageReceiver(networkAccess.getConfiguration(context),
new DynamicCredentialsProvider(context),

View File

@ -1,92 +1,88 @@
package org.thoughtcrime.securesms.gcm;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.text.TextUtils;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.logging.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.jobs.PushContentReceiveJob;
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.concurrent.SignalExecutors;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
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 GcmBroadcastReceiver extends WakefulBroadcastReceiver implements InjectableType {
public class FcmService extends FirebaseMessagingService implements InjectableType {
private static final String TAG = GcmBroadcastReceiver.class.getSimpleName();
private static final String TAG = FcmService.class.getSimpleName();
private static final Executor MESSAGE_EXECUTOR = SignalExecutors.newCachedSingleThreadExecutor("GcmMessageProcessing");
private static int activeCount = 0;
private static final Executor MESSAGE_EXECUTOR = SignalExecutors.newCachedSingleThreadExecutor("FcmMessageProcessing");
@Inject SignalServiceMessageReceiver messageReceiver;
private static int activeCount;
@Override
public void onReceive(Context context, Intent intent) {
ApplicationContext.getInstance(context).injectDependencies(this);
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.i(TAG, "FCM message... Original Priority: " + remoteMessage.getOriginalPriority() + ", Actual Priority: " + remoteMessage.getPriority());
ApplicationContext.getInstance(getApplicationContext()).injectDependencies(this);
handleReceivedNotification(getApplicationContext());
}
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
Log.i(TAG, "GCM message...");
if (!TextSecurePreferences.isPushRegistered(context)) {
Log.w(TAG, "Not push registered!");
return;
}
if (intent.hasExtra("notification")) {
handleReceivedNotification(context);
} else {
Log.w(TAG, "Received an unexpected intent.");
}
@Override
public void onNewToken(String token) {
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(getApplicationContext()));
}
private void handleReceivedNotification(Context context) {
if (!incrementActiveGcmCount()) {
Log.i(TAG, "Skipping GCM processing -- there's already one enqueued.");
Log.i(TAG, "Skipping FCM processing -- there's already one enqueued.");
return;
}
TextSecurePreferences.setNeedsMessagePull(context, true);
long startTime = System.currentTimeMillis();
PendingResult callback = goAsync();
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
boolean doze = PowerManagerCompat.isDeviceIdleMode(powerManager);
boolean network = new NetworkRequirement(context).isPresent();
long startTime = System.currentTimeMillis();
PowerManager powerManager = ServiceUtil.getPowerManager(getApplicationContext());
boolean doze = PowerManagerCompat.isDeviceIdleMode(powerManager);
boolean network = new NetworkRequirement(context).isPresent();
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);
callback.finish();
latch.countDown();
}
MESSAGE_EXECUTOR.execute(() -> {
@ -102,7 +98,7 @@ public class GcmBroadcastReceiver extends WakefulBroadcastReceiver implements In
if (foregroundRunning.getAndSet(false)) {
GenericForegroundService.stopForegroundTask(context);
} else {
callback.finish();
latch.countDown();
}
taskCompleted.set(true);
}
@ -113,20 +109,26 @@ public class GcmBroadcastReceiver extends WakefulBroadcastReceiver implements In
});
if (!foregroundRunning.get()) {
new Thread("GcmForegroundServiceTimer") {
new Thread("FcmForegroundServiceTimer") {
@Override
public void run() {
Util.sleep(4500);
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);
callback.finish();
latch.countDown();
}
}
}
}.start();
}
try {
latch.await();
} catch (InterruptedException e) {
Log.w(TAG, "Latch was interrupted.", e);
}
}
private void showForegroundNotification(@NonNull Context context) {
@ -147,4 +149,4 @@ public class GcmBroadcastReceiver extends WakefulBroadcastReceiver implements In
private static synchronized void decrementActiveGcmCount() {
activeCount--;
}
}
}

View File

@ -0,0 +1,43 @@
package org.thoughtcrime.securesms.gcm;
import android.support.annotation.WorkerThread;
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) {
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());
}
}

View File

@ -24,43 +24,44 @@ 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.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import org.thoughtcrime.securesms.PlayServicesProblemActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
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 javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class GcmRefreshJob extends ContextJob implements InjectableType {
public class FcmRefreshJob extends ContextJob implements InjectableType {
private static final String TAG = GcmRefreshJob.class.getSimpleName();
public static final String REGISTRATION_ID = "312334754206";
private static final String TAG = FcmRefreshJob.class.getSimpleName();
@Inject transient SignalServiceAccountManager textSecureAccountManager;
public GcmRefreshJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
public FcmRefreshJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public GcmRefreshJob(Context context) {
public FcmRefreshJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(GcmRefreshJob.class.getSimpleName())
.withGroupId(FcmRefreshJob.class.getSimpleName())
.withDuplicatesIgnored(true)
.withNetworkRequirement()
.withRetryCount(1)
@ -78,20 +79,25 @@ public class GcmRefreshJob extends ContextJob implements InjectableType {
@Override
public void onRun() throws Exception {
if (TextSecurePreferences.isGcmDisabled(context)) return;
if (TextSecurePreferences.isFcmDisabled(context)) return;
Log.i(TAG, "Reregistering GCM...");
int result = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
Log.i(TAG, "Reregistering FCM...");
int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
if (result != ConnectionResult.SUCCESS) {
notifyGcmFailure();
notifyFcmFailure();
} else {
String gcmId = GoogleCloudMessaging.getInstance(context).register(REGISTRATION_ID);
textSecureAccountManager.setGcmId(Optional.of(gcmId));
Optional<String> token = FcmUtil.getToken();
TextSecurePreferences.setGcmRegistrationId(context, gcmId);
TextSecurePreferences.setGcmRegistrationIdLastSetTime(context, System.currentTimeMillis());
TextSecurePreferences.setWebsocketRegistered(context, true);
if (token.isPresent()) {
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."));
}
}
}
@ -106,7 +112,7 @@ public class GcmRefreshJob extends ContextJob implements InjectableType {
return true;
}
private void notifyGcmFailure() {
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);

View File

@ -53,7 +53,7 @@ public class RefreshAttributesJob extends ContextJob implements InjectableType {
@Override
public void onRun() throws IOException {
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
boolean fetchesMessages = TextSecurePreferences.isGcmDisabled(context);
boolean fetchesMessages = TextSecurePreferences.isFcmDisabled(context);
String pin = TextSecurePreferences.getRegistrationLockPin(context);
byte[] unidentifiedAccessKey = UnidentifiedAccessUtil.getSelfUnidentifiedAccessKey(context);
boolean universalUnidentifiedAccess = TextSecurePreferences.isUniversalUnidentifiedAccess(context);

View File

@ -17,7 +17,7 @@ import android.support.v7.preference.Preference;
import org.thoughtcrime.securesms.logging.Log;
import android.widget.Toast;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.firebase.iid.FirebaseInstanceId;
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
import org.thoughtcrime.securesms.LogSubmitActivity;
@ -192,8 +192,8 @@ public class AdvancedPreferenceFragment extends CorrectedPreferenceFragment {
Log.w(TAG, e);
}
if (!TextSecurePreferences.isGcmDisabled(context)) {
GoogleCloudMessaging.getInstance(context).unregister();
if (!TextSecurePreferences.isFcmDisabled(context)) {
FirebaseInstanceId.getInstance().deleteInstanceId();
}
return SUCCESS;

View File

@ -60,7 +60,7 @@ public class IncomingMessageObserver implements InjectableType, RequirementListe
new NetworkRequirementProvider(context).setListener(this);
new MessageRetrievalThread().start();
if (TextSecurePreferences.isGcmDisabled(context)) {
if (TextSecurePreferences.isFcmDisabled(context)) {
ContextCompat.startForegroundService(context, new Intent(context, ForegroundService.class));
}
@ -95,7 +95,7 @@ public class IncomingMessageObserver implements InjectableType, RequirementListe
}
private synchronized boolean isConnectionNecessary() {
boolean isGcmDisabled = TextSecurePreferences.isGcmDisabled(context);
boolean isGcmDisabled = TextSecurePreferences.isFcmDisabled(context);
Log.d(TAG, String.format("Network requirement: %s, app visible: %s, gcm disabled: %b",
networkRequirement.isPresent(), appVisible, isGcmDisabled));

View File

@ -388,11 +388,11 @@ public class TextSecurePreferences {
return getBooleanPreference(context, ALWAYS_RELAY_CALLS_PREF, false);
}
public static boolean isGcmDisabled(Context context) {
public static boolean isFcmDisabled(Context context) {
return getBooleanPreference(context, GCM_DISABLED_PREF, false);
}
public static void setGcmDisabled(Context context, boolean disabled) {
public static void setFcmDisabled(Context context, boolean disabled) {
setBooleanPreference(context, GCM_DISABLED_PREF, disabled);
}
@ -486,12 +486,12 @@ public class TextSecurePreferences {
setBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, value);
}
public static void setGcmRegistrationId(Context context, String registrationId) {
public static void setFcmToken(Context context, String registrationId) {
setStringPreference(context, GCM_REGISTRATION_ID_PREF, registrationId);
setIntegerPrefrence(context, GCM_REGISTRATION_ID_VERSION_PREF, Util.getCurrentApkReleaseVersion(context));
}
public static String getGcmRegistrationId(Context context) {
public static String getFcmToken(Context context) {
int storedRegistrationIdVersion = getIntegerPreference(context, GCM_REGISTRATION_ID_VERSION_PREF, 0);
if (storedRegistrationIdVersion != Util.getCurrentApkReleaseVersion(context)) {
@ -501,11 +501,11 @@ public class TextSecurePreferences {
}
}
public static long getGcmRegistrationIdLastSetTime(Context context) {
public static long getFcmTokenLastSetTime(Context context) {
return getLongPreference(context, GCM_REGISTRATION_ID_TIME_PREF, 0);
}
public static void setGcmRegistrationIdLastSetTime(Context context, long timestamp) {
public static void setFcmTokenLastSetTime(Context context, long timestamp) {
setLongPreference(context, GCM_REGISTRATION_ID_TIME_PREF, timestamp);
}