diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/receivers/RegisterBroadcastReceiver.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/receivers/RegisterBroadcastReceiver.kt index afb153d..1bd39ef 100644 --- a/app/src/main/java/org/unifiedpush/distributor/nextpush/receivers/RegisterBroadcastReceiver.kt +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/receivers/RegisterBroadcastReceiver.kt @@ -1,11 +1,14 @@ package org.unifiedpush.distributor.nextpush.receivers +import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.os.Build import android.os.PowerManager import android.util.Log import android.widget.Toast +import androidx.annotation.RequiresApi import org.unifiedpush.distributor.nextpush.AppCompanion import org.unifiedpush.distributor.nextpush.Database.Companion.getDb import org.unifiedpush.distributor.nextpush.account.Account.isConnected @@ -19,6 +22,7 @@ import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteApp import org.unifiedpush.distributor.nextpush.distributor.Distributor.sendEndpoint import org.unifiedpush.distributor.nextpush.distributor.Distributor.sendRegistrationFailed import org.unifiedpush.distributor.nextpush.utils.TAG +import org.unifiedpush.distributor.nextpush.utils.appInfoForMetadata import org.unifiedpush.distributor.nextpush.utils.containsTokenElseAdd import org.unifiedpush.distributor.nextpush.utils.getApplicationName import org.unifiedpush.distributor.nextpush.utils.removeToken @@ -32,6 +36,67 @@ private const val WAKE_LOCK_TAG = "NextPush:RegisterBroadcastReceiver:lock" class RegisterBroadcastReceiver : BroadcastReceiver() { + /** + * Get application package name + */ + private fun getApplication(context: Context, intent: Intent): String? { + return getApplicationAnd3(context, intent) + ?: getApplicationAnd2(intent) + } + + /** + * Get application package name following AND_3 specifications. + */ + private fun getApplicationAnd3(context: Context, intent: Intent): String? { + return if (Build.VERSION.SDK_INT >= 34) getApplicationAnd3SharedId(context, intent) + else getApplicationAnd3PendingIntent(intent) + } + + /** + * Try get application package name following AND_3 specifications for SDK>=34, with the shared + * identity. + * + * It fallback to [getApplicationAnd3PendingIntent] if the other application targets SDK<34. + */ + @RequiresApi(34) + private fun getApplicationAnd3SharedId(context: Context, intent: Intent): String? { + return sentFromPackage?.also { + // We got the package name with the shared identity + Log.d(TAG, "Registering $it. Package name retrieved with shared identity") + } ?: getApplicationAnd3PendingIntent(intent)?.let { + // We got the package name with the pending intent, checking if that app targets SDK<34 + if (context.appInfoForMetadata(it).targetSdkVersion >= 34) { + Log.d(TAG, "App targeting Sdk >= 34 without shared identity, ignoring.") + null + } else { + it + } + } + } + + /** + * Try get application package name following AND_3 specifications when running on + * a device with SDK<34 or receiving message from an application targeting SDK<34, with a pending + * intent. + * + * Always prefer [getApplicationAnd3SharedId] if possible. + */ + private fun getApplicationAnd3PendingIntent(intent: Intent): String? { + return intent.getParcelableExtra(EXTRA_PI)?.creatorPackage?.also { + Log.d(TAG, "Registering $it. Package name retrieved with PendingIntent") + } + } + + /** + * Try get the application package name using AND_2 specifications + */ + @Deprecated("This follows AND_2 specifications. Will be removed.") + private fun getApplicationAnd2(intent: Intent): String? { + return intent.getStringExtra(EXTRA_APPLICATION)?.also { + Log.d(TAG, "Registering $it. Package name retrieved with legacy String extra") + } + } + override fun onReceive(rContext: Context, intent: Intent?) { val context = rContext.applicationContext val wakeLock = (context.getSystemService(Context.POWER_SERVICE) as PowerManager).run { @@ -45,7 +110,7 @@ class RegisterBroadcastReceiver : BroadcastReceiver() { Log.w(TAG, "Trying to register an app without connector token") return } - val application = intent.getStringExtra(EXTRA_APPLICATION) ?: run { + val application = getApplication(context, intent) ?: run { Log.w(TAG, "Trying to register an app without packageName") return }