From 1e32ebde41e5dc944c07f23d122cef2d411e3243 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 18 Jul 2024 16:59:05 +0200 Subject: [PATCH] Use ContextCompat.registerReceiver with explicit RECEIVER_EXPORTED to fix crash on API 34. java.lang.SecurityException: im.vector.app.debug: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts --- .../network/NetworkCallbackStrategy.kt | 8 +++++++- .../app/receivers/VectorDebugReceiver.kt | 8 +++++++- .../java/im/vector/app/VectorApplication.kt | 18 +++++++++++------- .../core/services/BluetoothHeadsetReceiver.kt | 8 +++++++- .../core/services/WiredHeadsetStateReceiver.kt | 8 +++++++- .../app/features/mdm/DefaultMdmService.kt | 8 +++++++- .../app/features/widgets/WidgetActivity.kt | 12 +++++++----- 7 files changed, 53 insertions(+), 17 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkCallbackStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkCallbackStrategy.kt index 90d2719e25..540fc845c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkCallbackStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkCallbackStrategy.kt @@ -22,6 +22,7 @@ import android.content.IntentFilter import android.net.ConnectivityManager import android.net.Network import android.os.Build +import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import timber.log.Timber import javax.inject.Inject @@ -43,7 +44,12 @@ internal class FallbackNetworkCallbackStrategy @Inject constructor( networkInfoReceiver.isConnectedCallback = { hasChanged() } - context.registerReceiver(networkInfoReceiver, filter) + ContextCompat.registerReceiver( + context, + networkInfoReceiver, + filter, + ContextCompat.RECEIVER_NOT_EXPORTED, + ) } override fun unregister() { diff --git a/vector-app/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt b/vector-app/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt index 4edbdd0591..8c317fc935 100644 --- a/vector-app/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt +++ b/vector-app/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.SharedPreferences +import androidx.core.content.ContextCompat import androidx.core.content.edit import im.vector.app.core.debug.DebugReceiver import im.vector.app.core.di.DefaultPreferences @@ -37,7 +38,12 @@ class VectorDebugReceiver @Inject constructor( ) : BroadcastReceiver(), DebugReceiver { override fun register(context: Context) { - context.registerReceiver(this, getIntentFilter(context)) + ContextCompat.registerReceiver( + context, + this, + getIntentFilter(context), + ContextCompat.RECEIVER_NOT_EXPORTED, + ) } override fun unregister(context: Context) { diff --git a/vector-app/src/main/java/im/vector/app/VectorApplication.kt b/vector-app/src/main/java/im/vector/app/VectorApplication.kt index df1c584b3a..18ea1b91bb 100644 --- a/vector-app/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector-app/src/main/java/im/vector/app/VectorApplication.kt @@ -27,6 +27,7 @@ import android.os.HandlerThread import android.os.StrictMode import android.util.Log import android.view.Gravity +import androidx.core.content.ContextCompat import androidx.core.provider.FontRequest import androidx.core.provider.FontsContractCompat import androidx.lifecycle.DefaultLifecycleObserver @@ -217,13 +218,16 @@ class VectorApplication : ProcessLifecycleOwner.get().lifecycle.addObserver(callManager) // This should be done as early as possible // initKnownEmojiHashSet(appContext) - - applicationContext.registerReceiver(powerKeyReceiver, IntentFilter().apply { - // Looks like i cannot receive OFF, if i don't have both ON and OFF - addAction(Intent.ACTION_SCREEN_OFF) - addAction(Intent.ACTION_SCREEN_ON) - }) - + ContextCompat.registerReceiver( + applicationContext, + powerKeyReceiver, + IntentFilter().apply { + // Looks like i cannot receive OFF, if i don't have both ON and OFF + addAction(Intent.ACTION_SCREEN_OFF) + addAction(Intent.ACTION_SCREEN_ON) + }, + ContextCompat.RECEIVER_NOT_EXPORTED, + ) EmojiManager.install(GoogleEmojiProvider()) // Initialize Mapbox before inflating mapViews diff --git a/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt b/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt index 4925adf69d..be32bc4c66 100644 --- a/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt @@ -23,6 +23,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import androidx.core.content.ContextCompat import im.vector.lib.core.utils.compat.getParcelableExtraCompat import java.lang.ref.WeakReference @@ -83,7 +84,12 @@ class BluetoothHeadsetReceiver : BroadcastReceiver() { fun createAndRegister(context: Context, listener: EventListener): BluetoothHeadsetReceiver { val receiver = BluetoothHeadsetReceiver() receiver.delegate = WeakReference(listener) - context.registerReceiver(receiver, IntentFilter(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) + ContextCompat.registerReceiver( + context, + receiver, + IntentFilter(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED, + ) return receiver } diff --git a/vector/src/main/java/im/vector/app/core/services/WiredHeadsetStateReceiver.kt b/vector/src/main/java/im/vector/app/core/services/WiredHeadsetStateReceiver.kt index a223352095..416cb43be6 100644 --- a/vector/src/main/java/im/vector/app/core/services/WiredHeadsetStateReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/services/WiredHeadsetStateReceiver.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.media.AudioManager +import androidx.core.content.ContextCompat import timber.log.Timber import java.lang.ref.WeakReference @@ -69,7 +70,12 @@ class WiredHeadsetStateReceiver : BroadcastReceiver() { val receiver = WiredHeadsetStateReceiver() receiver.delegate = WeakReference(listener) val action = AudioManager.ACTION_HEADSET_PLUG - context.registerReceiver(receiver, IntentFilter(action)) + ContextCompat.registerReceiver( + context, + receiver, + IntentFilter(action), + ContextCompat.RECEIVER_NOT_EXPORTED, + ) return receiver } diff --git a/vector/src/main/java/im/vector/app/features/mdm/DefaultMdmService.kt b/vector/src/main/java/im/vector/app/features/mdm/DefaultMdmService.kt index 6633f3ce06..4786341a05 100644 --- a/vector/src/main/java/im/vector/app/features/mdm/DefaultMdmService.kt +++ b/vector/src/main/java/im/vector/app/features/mdm/DefaultMdmService.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.RestrictionsManager +import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import dagger.hilt.android.qualifiers.ApplicationContext import timber.log.Timber @@ -44,7 +45,12 @@ class DefaultMdmService @Inject constructor( override fun registerListener(context: Context, onChangedListener: () -> Unit) { val restrictionsFilter = IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED) this.onChangedListener = onChangedListener - context.registerReceiver(restrictionsReceiver, restrictionsFilter) + ContextCompat.registerReceiver( + context, + restrictionsReceiver, + restrictionsFilter, + ContextCompat.RECEIVER_NOT_EXPORTED + ) } override fun unregisterListener(context: Context) { diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt index 8eb2b66453..32bf92881b 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt @@ -31,6 +31,7 @@ import android.os.Build import android.util.Rational import androidx.annotation.RequiresApi import androidx.core.app.PictureInPictureModeChangedInfo +import androidx.core.content.ContextCompat import androidx.core.util.Consumer import androidx.core.view.isVisible import com.airbnb.mvrx.Mavericks @@ -201,11 +202,12 @@ class WidgetActivity : VectorBaseActivity() { } } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - registerReceiver(hangupBroadcastReceiver, IntentFilter(ACTION_MEDIA_CONTROL), RECEIVER_NOT_EXPORTED) - } else { - registerReceiver(hangupBroadcastReceiver, IntentFilter(ACTION_MEDIA_CONTROL)) - } + ContextCompat.registerReceiver( + this, + hangupBroadcastReceiver, + IntentFilter(ACTION_MEDIA_CONTROL), + ContextCompat.RECEIVER_NOT_EXPORTED, + ) } else { unregisterReceiver(hangupBroadcastReceiver) }