package ai.sirrus.reactnativesdk import android.app.ActivityManager import android.content.Context import android.os.Process import android.util.Log import com.google.firebase.messaging.RemoteMessage import org.json.JSONObject object SirrusPushMessagingHandler { private const val LOG_TAG = "SirrusSDK" @JvmStatic fun isSirrusPayload(data: Map): Boolean { return SirrusNotificationDataParser.isSirrusPayload(data) } @JvmStatic fun handleRemoteMessage(context: Context, remoteMessage: RemoteMessage): Boolean { val data = remoteMessage.data if (!isSirrusPayload(data)) { return false } if (remoteMessage.notification != null) { Log.w( LOG_TAG, "Sirrus Android push included an FCM notification block. Use data-only Android pushes so the SDK native renderer can attach media and action buttons." ) } val payload = SirrusNotificationDataParser.fromRemoteMessage( data = data, fallbackMessageId = remoteMessage.messageId, fallbackTitle = remoteMessage.notification?.title, fallbackBody = remoteMessage.notification?.body, fallbackImageUrl = remoteMessage.notification?.imageUrl?.toString() ) Log.i(LOG_TAG, "Sirrus notification received payload: ${payload.toEventJson()}") emitReceivedEvent(context.applicationContext, payload) if (payload.title.isNotBlank() || payload.body.isNotBlank()) { SirrusNotificationRenderer.show(context.applicationContext, payload) val appState = if (isAppInForeground(context.applicationContext)) { "foreground" } else { "background" } Log.i(LOG_TAG, "Sirrus $appState push rendered by SDK native service.") } return true } @JvmStatic @JvmOverloads fun handleNewToken(context: Context, token: String, provider: String = "fcm") { SirrusNotificationEventDispatcher.storeLatestPushToken( context.applicationContext, token, provider ) } private fun emitReceivedEvent(context: Context, payload: SirrusNotificationPayload) { val event = JSONObject().apply { put("type", "received") put("actionId", "") put("deeplinkUrl", payload.deeplinkUrl ?: "") put("payload", payload.toEventJson()) } SirrusNotificationEventDispatcher.emitOrStore(context, event) } private fun isAppInForeground(context: Context): Boolean { val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager ?: return false val appProcesses = activityManager.runningAppProcesses ?: return false val currentPid = Process.myPid() return appProcesses.any { process -> process.pid == currentPid && ( process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND || process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE ) } } }