File size: 3,595 Bytes
0b2a88d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | package org.thoughtcrime.securesms.notifications;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.service.FetchForegroundService;
import org.thoughtcrime.securesms.util.Util;
public class FcmReceiveService extends FirebaseMessagingService {
private static final String TAG = FcmReceiveService.class.getSimpleName();
private static final Object INIT_LOCK = new Object();
private static boolean initialized;
private static volatile boolean triedRegistering;
private static volatile String prefixedToken;
public static void register(Context context) {
if (FcmReceiveService.prefixedToken != null) {
Log.i(TAG, "FCM already registered");
triedRegistering = true;
return;
}
Util.runOnAnyBackgroundThread(() -> {
final String rawToken;
try {
synchronized (INIT_LOCK) {
if (!initialized) {
// manual init: read tokens from `./google-services.json`;
// automatic init disabled in AndroidManifest.xml to skip FCM code completely.
FirebaseApp.initializeApp(context);
}
initialized = true;
}
rawToken = Tasks.await(FirebaseMessaging.getInstance().getToken());
} catch (Exception e) {
// we're here usually when FCM is not available and initializeApp() or getToken() failed.
Log.w(TAG, "cannot get FCM token for " + BuildConfig.APPLICATION_ID + ": " + e);
triedRegistering = true;
return;
}
if (TextUtils.isEmpty(rawToken)) {
Log.w(TAG, "got empty FCM token for " + BuildConfig.APPLICATION_ID);
triedRegistering = true;
return;
}
prefixedToken = addPrefix(rawToken);
Log.i(TAG, "FCM token: " + prefixedToken);
ApplicationContext.dcAccounts.setPushDeviceToken(prefixedToken);
triedRegistering = true;
});
}
// wait a until FCM registration got a token or not.
// we're calling register() pretty soon and getToken() pretty late on init,
// so usually, this should not block anything.
// still, waitForRegisterFinished() needs to be called from a background thread.
@WorkerThread
public static void waitForRegisterFinished() {
while (!triedRegistering) {
Util.sleep(100);
}
}
private static String addPrefix(String rawToken) {
return "fcm-" + BuildConfig.APPLICATION_ID + ":" + rawToken;
}
@Nullable
public static String getToken() {
return prefixedToken;
}
@WorkerThread
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
Log.i(TAG, "FCM push notification received");
FetchForegroundService.start(this);
}
@Override
public void onDeletedMessages() {
Log.i(TAG, "FCM push notifications dropped");
FetchForegroundService.start(this);
}
@Override
public void onNewToken(@NonNull String rawToken) {
prefixedToken = addPrefix(rawToken);
Log.i(TAG, "new FCM token: " + prefixedToken);
ApplicationContext.dcAccounts.setPushDeviceToken(prefixedToken);
}
}
|