|
| 1 | +package com.zulipmobile.notifications |
| 2 | + |
| 3 | +import com.google.firebase.iid.FirebaseInstanceId |
| 4 | +import com.google.firebase.iid.InstanceIdResult |
| 5 | +import android.os.Bundle |
| 6 | +import android.util.Log |
| 7 | +import androidx.core.app.NotificationManagerCompat |
| 8 | +import com.facebook.react.bridge.* |
| 9 | +import com.google.android.gms.common.ConnectionResult |
| 10 | +import com.google.android.gms.common.GoogleApiAvailability |
| 11 | +import java.lang.Exception |
| 12 | + |
| 13 | +internal class NotificationsModule(reactContext: ReactApplicationContext?) : |
| 14 | + ReactContextBaseJavaModule(reactContext) { |
| 15 | + override fun getName(): String { |
| 16 | + return "Notifications" |
| 17 | + } |
| 18 | + |
| 19 | + /** |
| 20 | + * Grab the token and return it to the JavaScript caller. |
| 21 | + */ |
| 22 | + @ReactMethod |
| 23 | + fun getToken(promise: Promise) { |
| 24 | + FirebaseInstanceId.getInstance().instanceId |
| 25 | + .addOnSuccessListener { instanceId: InstanceIdResult -> promise.resolve(instanceId.token) } |
| 26 | + .addOnFailureListener { e: Exception? -> promise.reject(e) } |
| 27 | + } |
| 28 | + |
| 29 | + @ReactMethod |
| 30 | + fun readInitialNotification(promise: Promise) { |
| 31 | + if (null == initialNotification) { |
| 32 | + promise.resolve(null) |
| 33 | + } else { |
| 34 | + promise.resolve(Arguments.fromBundle(initialNotification)) |
| 35 | + initialNotification = null |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + /** |
| 40 | + * Tell the JavaScript caller about the availability of Google Play Services. |
| 41 | + */ |
| 42 | + // Ideally we wouldn't depend on Google Play Services for notifications; |
| 43 | + // that's #3838. |
| 44 | + @ReactMethod |
| 45 | + fun googlePlayServicesAvailability(promise: Promise) { |
| 46 | + val result = Arguments.createMap() |
| 47 | + val googleApiAvailability = GoogleApiAvailability.getInstance() |
| 48 | + |
| 49 | + // https://developers.google.com/android/reference/com/google/android/gms/common/GoogleApiAvailability#isGooglePlayServicesAvailable(android.content.Context) |
| 50 | + val connectionResult = ConnectionResult( |
| 51 | + googleApiAvailability.isGooglePlayServicesAvailable(reactApplicationContext)) |
| 52 | + result.putInt("errorCode", connectionResult.errorCode) |
| 53 | + result.putString("errorMessage", connectionResult.errorMessage) |
| 54 | + result.putBoolean("hasResolution", connectionResult.hasResolution()) |
| 55 | + result.putBoolean("isSuccess", connectionResult.isSuccess) |
| 56 | + |
| 57 | + // Keep return value in sync with the Flow type on the JS side. |
| 58 | + promise.resolve(result) |
| 59 | + } |
| 60 | + |
| 61 | + /** |
| 62 | + * Tell the JavaScript caller whether notifications are not blocked. |
| 63 | + */ |
| 64 | + // Ideally we could subscribe to changes in this value, but there |
| 65 | + // doesn't seem to be an API for that. The caller can poll, e.g., by |
| 66 | + // re-checking when the user has returned to the app, which they might |
| 67 | + // do after changing the notification settings. |
| 68 | + @ReactMethod |
| 69 | + fun areNotificationsEnabled(promise: Promise) { |
| 70 | + val notificationManagerCompat = NotificationManagerCompat |
| 71 | + .from(reactApplicationContext) |
| 72 | + |
| 73 | + // https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#areNotificationsEnabled() |
| 74 | + promise.resolve(notificationManagerCompat.areNotificationsEnabled()) |
| 75 | + } |
| 76 | + |
| 77 | + companion object { |
| 78 | + var initialNotification: Bundle? = null |
| 79 | + fun emitToken(reactContext: ReactContext?, token: String?) { |
| 80 | + if (reactContext == null) { |
| 81 | + // Perhaps this is possible if InstanceIDListenerService gets invoked? |
| 82 | + return |
| 83 | + } |
| 84 | + Log.i(TAG, "Got token; emitting event") |
| 85 | + emit(reactContext, "remoteNotificationsRegistered", token) |
| 86 | + } |
| 87 | + } |
| 88 | +} |
0 commit comments