From 54f72e733f0ddc3b51dd7227d4ee02c21bfc701c Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 15 Jun 2022 15:00:47 +0000 Subject: [PATCH] Don't export broadcast receivers that don't require it Issue: google/ExoPlayer#10287 PiperOrigin-RevId: 455131138 (cherry picked from commit 9267ba3f9e14da4436bfbfe76045f7d09af80feb) --- .../exoplayer2/util/NetworkTypeObserver.java | 2 +- .../google/android/exoplayer2/util/Util.java | 48 +++++++++++++++++++ .../exoplayer2/AudioBecomingNoisyManager.java | 5 +- .../exoplayer2/StreamVolumeManager.java | 2 +- .../exoplayer2/audio/AudioCapabilities.java | 4 +- .../audio/AudioCapabilitiesReceiver.java | 6 +-- .../exoplayer2/scheduler/Requirements.java | 8 ++-- .../scheduler/RequirementsWatcher.java | 2 +- 8 files changed, 62 insertions(+), 15 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/NetworkTypeObserver.java b/library/common/src/main/java/com/google/android/exoplayer2/util/NetworkTypeObserver.java index 9d24d0d93e..4112e6bb6b 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/NetworkTypeObserver.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/NetworkTypeObserver.java @@ -93,7 +93,7 @@ public final class NetworkTypeObserver { networkType = C.NETWORK_TYPE_UNKNOWN; IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - context.registerReceiver(/* receiver= */ new Receiver(), filter); + Util.registerReceiverNotExported(context, new Receiver(), filter); } /** diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java index 947e0351fb..5d9b5b2e82 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -34,9 +34,11 @@ import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.app.UiModeManager; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -186,6 +188,52 @@ public final class Util { return outputStream.toByteArray(); } + /** + * Registers a {@link BroadcastReceiver} that's not intended to receive broadcasts from other + * apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link + * #SDK_INT} is 33 or above. + * + * @param context The context on which {@link Context#registerReceiver} will be called. + * @param receiver The {@link BroadcastReceiver} to register. This value may be null. + * @param filter Selects the Intent broadcasts to be received. + * @return The first sticky intent found that matches {@code filter}, or null if there are none. + */ + @Nullable + public static Intent registerReceiverNotExported( + Context context, @Nullable BroadcastReceiver receiver, IntentFilter filter) { + if (SDK_INT < 33) { + return context.registerReceiver(receiver, filter); + } else { + return context.registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED); + } + } + + /** + * Registers a {@link BroadcastReceiver} that's not intended to receive broadcasts from other + * apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link + * #SDK_INT} is 33 or above. + * + * @param context The context on which {@link Context#registerReceiver} will be called. + * @param receiver The {@link BroadcastReceiver} to register. This value may be null. + * @param filter Selects the Intent broadcasts to be received. + * @param handler Handler identifying the thread that will receive the Intent. + * @return The first sticky intent found that matches {@code filter}, or null if there are none. + */ + @Nullable + public static Intent registerReceiverNotExported( + Context context, BroadcastReceiver receiver, IntentFilter filter, Handler handler) { + if (SDK_INT < 33) { + return context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, handler); + } else { + return context.registerReceiver( + receiver, + filter, + /* broadcastPermission= */ null, + handler, + Context.RECEIVER_NOT_EXPORTED); + } + } + /** * Calls {@link Context#startForegroundService(Intent)} if {@link #SDK_INT} is 26 or higher, or * {@link Context#startService(Intent)} otherwise. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/AudioBecomingNoisyManager.java b/library/core/src/main/java/com/google/android/exoplayer2/AudioBecomingNoisyManager.java index 2a52a039d6..f8be0198c8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/AudioBecomingNoisyManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/AudioBecomingNoisyManager.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; import android.os.Handler; +import com.google.android.exoplayer2.util.Util; /* package */ final class AudioBecomingNoisyManager { @@ -46,8 +47,8 @@ import android.os.Handler; */ public void setEnabled(boolean enabled) { if (enabled && !receiverRegistered) { - context.registerReceiver( - receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); + Util.registerReceiverNotExported( + context, receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); receiverRegistered = true; } else if (!enabled && receiverRegistered) { context.unregisterReceiver(receiver); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/StreamVolumeManager.java b/library/core/src/main/java/com/google/android/exoplayer2/StreamVolumeManager.java index 19b9f5c666..41e1c0f6ca 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/StreamVolumeManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/StreamVolumeManager.java @@ -74,7 +74,7 @@ import com.google.android.exoplayer2.util.Util; VolumeChangeReceiver receiver = new VolumeChangeReceiver(); IntentFilter filter = new IntentFilter(VOLUME_CHANGED_ACTION); try { - applicationContext.registerReceiver(receiver, filter); + Util.registerReceiverNotExported(applicationContext, receiver, filter); this.receiver = receiver; } catch (RuntimeException e) { Log.w(TAG, "Error registering stream volume receiver", e); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilities.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilities.java index db14515ba9..066786bd60 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilities.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilities.java @@ -86,8 +86,8 @@ public final class AudioCapabilities { @SuppressWarnings("InlinedApi") public static AudioCapabilities getCapabilities(Context context) { Intent intent = - context.registerReceiver( - /* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG)); + Util.registerReceiverNotExported( + context, /* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG)); return getCapabilities(context, intent); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilitiesReceiver.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilitiesReceiver.java index caed07b6ad..0707824296 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilitiesReceiver.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioCapabilitiesReceiver.java @@ -88,12 +88,10 @@ public final class AudioCapabilitiesReceiver { if (externalSurroundSoundSettingObserver != null) { externalSurroundSoundSettingObserver.register(); } - Intent stickyIntent = null; + @Nullable Intent stickyIntent = null; if (receiver != null) { IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG); - stickyIntent = - context.registerReceiver( - receiver, intentFilter, /* broadcastPermission= */ null, handler); + stickyIntent = Util.registerReceiverNotExported(context, receiver, intentFilter, handler); } audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent); return audioCapabilities; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java index dedb5c6bb5..030ac1cbcb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java @@ -182,8 +182,8 @@ public final class Requirements implements Parcelable { private boolean isDeviceCharging(Context context) { @Nullable Intent batteryStatus = - context.registerReceiver( - /* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + Util.registerReceiverNotExported( + context, /* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); if (batteryStatus == null) { return false; } @@ -201,8 +201,8 @@ public final class Requirements implements Parcelable { } private boolean isStorageNotLow(Context context) { - return context.registerReceiver( - /* receiver= */ null, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW)) + return Util.registerReceiverNotExported( + context, /* receiver= */ null, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW)) == null; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java index 5e4630c31c..c8e48c826f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java @@ -109,7 +109,7 @@ public final class RequirementsWatcher { filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); } receiver = new DeviceStatusChangeReceiver(); - context.registerReceiver(receiver, filter, null, handler); + Util.registerReceiverNotExported(context, receiver, filter, handler); return notMetRequirements; }