Differential D7873 Diff 27226 native/android/app/src/main/java/app/comm/android/notifications/CommNotificationsHandler.java
Changeset View
Changeset View
Standalone View
Standalone View
native/android/app/src/main/java/app/comm/android/notifications/CommNotificationsHandler.java
package app.comm.android.notifications; | package app.comm.android.notifications; | ||||
import android.app.Notification; | import android.app.Notification; | ||||
import android.app.NotificationManager; | import android.app.NotificationManager; | ||||
import android.app.PendingIntent; | import android.app.PendingIntent; | ||||
import android.content.Context; | import android.content.Context; | ||||
import android.content.Intent; | import android.content.Intent; | ||||
import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
import android.graphics.BitmapFactory; | import android.graphics.BitmapFactory; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.service.notification.StatusBarNotification; | import android.service.notification.StatusBarNotification; | ||||
import android.util.JsonReader; | |||||
import android.util.Log; | import android.util.Log; | ||||
import androidx.core.app.NotificationCompat; | import androidx.core.app.NotificationCompat; | ||||
import androidx.lifecycle.Lifecycle; | import androidx.lifecycle.Lifecycle; | ||||
import androidx.lifecycle.ProcessLifecycleOwner; | import androidx.lifecycle.ProcessLifecycleOwner; | ||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager; | import androidx.localbroadcastmanager.content.LocalBroadcastManager; | ||||
import app.comm.android.ExpoUtils; | import app.comm.android.ExpoUtils; | ||||
import app.comm.android.MainActivity; | import app.comm.android.MainActivity; | ||||
import app.comm.android.R; | import app.comm.android.R; | ||||
import app.comm.android.fbjni.CommSecureStore; | import app.comm.android.fbjni.CommSecureStore; | ||||
import app.comm.android.fbjni.GlobalDBSingleton; | import app.comm.android.fbjni.GlobalDBSingleton; | ||||
import app.comm.android.fbjni.MessageOperationsUtilities; | import app.comm.android.fbjni.MessageOperationsUtilities; | ||||
import app.comm.android.fbjni.NetworkModule; | import app.comm.android.fbjni.NetworkModule; | ||||
import app.comm.android.fbjni.NotificationsCryptoModule; | |||||
import app.comm.android.fbjni.ThreadOperations; | import app.comm.android.fbjni.ThreadOperations; | ||||
import com.google.firebase.messaging.FirebaseMessagingService; | import com.google.firebase.messaging.FirebaseMessagingService; | ||||
import com.google.firebase.messaging.RemoteMessage; | import com.google.firebase.messaging.RemoteMessage; | ||||
import java.io.File; | import java.io.File; | ||||
import me.leolin.shortcutbadger.ShortcutBadger; | import me.leolin.shortcutbadger.ShortcutBadger; | ||||
import org.json.JSONException; | |||||
import org.json.JSONObject; | |||||
public class CommNotificationsHandler extends FirebaseMessagingService { | public class CommNotificationsHandler extends FirebaseMessagingService { | ||||
private static final String BADGE_KEY = "badge"; | private static final String BADGE_KEY = "badge"; | ||||
private static final String BADGE_ONLY_KEY = "badgeOnly"; | private static final String BADGE_ONLY_KEY = "badgeOnly"; | ||||
private static final String BACKGROUND_NOTIF_TYPE_KEY = "backgroundNotifType"; | private static final String BACKGROUND_NOTIF_TYPE_KEY = "backgroundNotifType"; | ||||
private static final String SET_UNREAD_STATUS_KEY = "setUnreadStatus"; | private static final String SET_UNREAD_STATUS_KEY = "setUnreadStatus"; | ||||
private static final String NOTIF_ID_KEY = "id"; | private static final String NOTIF_ID_KEY = "id"; | ||||
private static final String ENCRYPTED_PAYLOAD_KEY = "encryptedPayload"; | |||||
private static final String ENCRYPTION_FAILED_KEY = "encryptionFailed"; | |||||
private static final String CHANNEL_ID = "default"; | private static final String CHANNEL_ID = "default"; | ||||
private static final long[] VIBRATION_SPEC = {500, 500}; | private static final long[] VIBRATION_SPEC = {500, 500}; | ||||
private Bitmap displayableNotificationLargeIcon; | private Bitmap displayableNotificationLargeIcon; | ||||
private NotificationManager notificationManager; | private NotificationManager notificationManager; | ||||
private LocalBroadcastManager localBroadcastManager; | private LocalBroadcastManager localBroadcastManager; | ||||
public static final String RESCIND_KEY = "rescind"; | public static final String RESCIND_KEY = "rescind"; | ||||
Show All 29 Lines | public class CommNotificationsHandler extends FirebaseMessagingService { | ||||
@Override | @Override | ||||
public void onMessageReceived(RemoteMessage message) { | public void onMessageReceived(RemoteMessage message) { | ||||
String rescind = message.getData().get(RESCIND_KEY); | String rescind = message.getData().get(RESCIND_KEY); | ||||
if ("true".equals(rescind) && | if ("true".equals(rescind) && | ||||
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { | android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { | ||||
handleNotificationRescind(message); | handleNotificationRescind(message); | ||||
} | } | ||||
if (message.getData().get(ENCRYPTED_PAYLOAD_KEY) != null) { | |||||
try { | |||||
message = this.decryptRemoteMessage(message); | |||||
} catch (JSONException e) { | |||||
Log.w("COMM", "Malformed notification JSON payload.", e); | |||||
return; | |||||
} catch (IllegalStateException e) { | |||||
Log.w("COMM", "Android notification type violation.", e); | |||||
return; | |||||
} catch (Exception e) { | |||||
Log.w("COMM", "Notification decryption failure.", e); | |||||
return; | |||||
} | |||||
} else if ("1".equals(message.getData().get(ENCRYPTION_FAILED_KEY))) { | |||||
Log.w( | |||||
"COMM", | |||||
"Received unencrypted notification for client with existing olm session for notifications"); | |||||
} | |||||
String badge = message.getData().get(BADGE_KEY); | String badge = message.getData().get(BADGE_KEY); | ||||
if (badge != null) { | if (badge != null) { | ||||
try { | try { | ||||
int badgeCount = Integer.parseInt(badge); | int badgeCount = Integer.parseInt(badge); | ||||
if (badgeCount > 0) { | if (badgeCount > 0) { | ||||
ShortcutBadger.applyCount(this, badgeCount); | ShortcutBadger.applyCount(this, badgeCount); | ||||
} else { | } else { | ||||
ShortcutBadger.removeCount(this); | ShortcutBadger.removeCount(this); | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | private PendingIntent createStartMainActivityAction(RemoteMessage message) { | ||||
intent.putExtra("message", message); | intent.putExtra("message", message); | ||||
return PendingIntent.getActivity( | return PendingIntent.getActivity( | ||||
this.getApplicationContext(), | this.getApplicationContext(), | ||||
message.getData().get(NOTIF_ID_KEY).hashCode(), | message.getData().get(NOTIF_ID_KEY).hashCode(), | ||||
intent, | intent, | ||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); | PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); | ||||
} | } | ||||
private RemoteMessage decryptRemoteMessage(RemoteMessage message) | |||||
throws JSONException, IllegalStateException { | |||||
String encryptedSerializedPayload = | |||||
message.getData().get(ENCRYPTED_PAYLOAD_KEY); | |||||
String decryptedSerializedPayload = NotificationsCryptoModule.decrypt( | |||||
encryptedSerializedPayload, | |||||
NotificationsCryptoModule.olmEncryptedTypeMessage(), | |||||
"CommNotificationsHandler"); | |||||
JSONObject decryptedPayload = new JSONObject(decryptedSerializedPayload); | |||||
((Iterable<String>)() -> decryptedPayload.keys()) | |||||
.forEach(payloadFieldName -> { | |||||
if (decryptedPayload.optJSONArray(payloadFieldName) != null || | |||||
decryptedPayload.optJSONObject(payloadFieldName) != null) { | |||||
throw new IllegalStateException( | |||||
"Notification payload JSON is not {[string]: string} type."); | |||||
} | |||||
String payloadFieldValue = | |||||
decryptedPayload.optString(payloadFieldName); | |||||
message.getData().put(payloadFieldName, payloadFieldValue); | |||||
}); | |||||
return message; | |||||
} | |||||
} | } |