Add broadcast receiver export flags

Bug: 197817693
Test: Ran module unit tests
Change-Id: I52fe95584b732a1104dd83e616da42985344620c
diff --git a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2DrmTestBase.java b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2DrmTestBase.java
index b2cd2e7..2663a7e 100644
--- a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2DrmTestBase.java
+++ b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2DrmTestBase.java
@@ -32,6 +32,7 @@
 import android.content.res.Resources;
 import android.media.MediaDrm;
 import android.net.Uri;
+import android.os.Build;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.Base64;
@@ -935,7 +936,11 @@
             try {
                 IntentFilter intentFilter =
                         new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-                mContext.registerReceiver(receiver, intentFilter);
+                if (Build.VERSION.SDK_INT < 33) {
+                    mContext.registerReceiver(receiver, intentFilter);
+                } else {
+                    mContext.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED);
+                }
 
                 Request request = new Request(uri);
                 request.setDestinationUri(file);
diff --git a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayerDrmTest.java b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayerDrmTest.java
index d7bba40..e6a44a6 100644
--- a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayerDrmTest.java
+++ b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayerDrmTest.java
@@ -34,6 +34,7 @@
 import android.content.res.Resources;
 import android.media.MediaDrm;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Environment;
 import android.os.PowerManager;
 import android.os.SystemClock;
@@ -1016,7 +1017,11 @@
             try {
                 IntentFilter intentFilter =
                         new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-                mContext.registerReceiver(receiver, intentFilter);
+                if (Build.VERSION.SDK_INT < 33) {
+                    mContext.registerReceiver(receiver, intentFilter);
+                } else {
+                    mContext.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED);
+                }
 
                 Request request = new Request(uri);
                 request.setDestinationUri(file);
diff --git a/media2/media2-player/src/main/java/androidx/media2/player/AudioFocusHandler.java b/media2/media2-player/src/main/java/androidx/media2/player/AudioFocusHandler.java
index c33b952..b7f0e3c 100644
--- a/media2/media2-player/src/main/java/androidx/media2/player/AudioFocusHandler.java
+++ b/media2/media2-player/src/main/java/androidx/media2/player/AudioFocusHandler.java
@@ -24,9 +24,13 @@
 import android.content.IntentFilter;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.os.Build;
 import android.util.Log;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 import androidx.media.AudioAttributesCompat;
 
 /**
@@ -246,7 +250,12 @@
             }
             // Registering the receiver multiple-times may not be allowed for newer platform.
             // Register only when it's not registered.
-            mContext.registerReceiver(mBecomingNoisyReceiver, mIntentFilter);
+            if (Build.VERSION.SDK_INT < 33) {
+                mContext.registerReceiver(mBecomingNoisyReceiver, mIntentFilter);
+            } else {
+                Api33.registerReceiver(mContext, mBecomingNoisyReceiver, mIntentFilter,
+                        Context.RECEIVER_NOT_EXPORTED);
+            }
             mBecomingNoisyReceiverRegistered = true;
         }
 
@@ -450,6 +459,15 @@
                         break;
                 }
             }
-        };
+        }
+    }
+
+    @RequiresApi(33)
+    private static class Api33 {
+        @DoNotInline
+        static void registerReceiver(@NonNull Context context, @NonNull BroadcastReceiver receiver,
+                @NonNull IntentFilter filter, int flags) {
+            context.registerReceiver(receiver, filter, flags);
+        }
     }
 }
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
index 27ec402..c4e41b3 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
@@ -203,6 +203,7 @@
             mBroadcastReceiver = new MediaButtonReceiver();
             IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
             filter.addDataScheme(mSessionUri.getScheme());
+            // TODO(b/197817693): Explicitly indicate whether the receiver should be exported.
             context.registerReceiver(mBroadcastReceiver, filter);
         } else {
             // Has MediaSessionService to revive playback after it's dead.
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
index b935fec..149ee4e 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
@@ -40,8 +40,10 @@
 import android.view.SoundEffectConstants;
 import android.view.View;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
 import androidx.appcompat.content.res.AppCompatResources;
 import androidx.appcompat.widget.TooltipCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
@@ -915,7 +917,12 @@
             if (mButtons.size() == 0) {
                 IntentFilter intentFilter = new IntentFilter();
                 intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-                mContext.registerReceiver(this, intentFilter);
+                if (Build.VERSION.SDK_INT < 33) {
+                    mContext.registerReceiver(this, intentFilter);
+                } else {
+                    Api33.registerReceiver(mContext, this, intentFilter,
+                            Context.RECEIVER_NOT_EXPORTED);
+                }
             }
             mButtons.add(button);
         }
@@ -940,11 +947,20 @@
                         ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                 if (mIsConnected != isConnected) {
                     mIsConnected = isConnected;
-                    for (MediaRouteButton button: mButtons) {
+                    for (MediaRouteButton button : mButtons) {
                         button.refreshVisibility();
                     }
                 }
             }
         }
     }
+
+    @RequiresApi(33)
+    private static class Api33 {
+        @DoNotInline
+        static void registerReceiver(@NonNull Context context, @NonNull BroadcastReceiver receiver,
+                @NonNull IntentFilter filter, int flags) {
+            context.registerReceiver(receiver, filter, flags);
+        }
+    }
 }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RegisteredMediaRouteProviderWatcher.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RegisteredMediaRouteProviderWatcher.java
index 2918139..883276c 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RegisteredMediaRouteProviderWatcher.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RegisteredMediaRouteProviderWatcher.java
@@ -28,6 +28,7 @@
 import android.os.Build;
 import android.os.Handler;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
@@ -68,7 +69,12 @@
             filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
             filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
             filter.addDataScheme("package");
-            mContext.registerReceiver(mScanPackagesReceiver, filter, null, mHandler);
+            if (Build.VERSION.SDK_INT < 33) {
+                mContext.registerReceiver(mScanPackagesReceiver, filter, null, mHandler);
+            } else {
+                Api33.registerReceiver(mContext, mScanPackagesReceiver, filter, mHandler,
+                        Context.RECEIVER_NOT_EXPORTED);
+            }
 
             // Scan packages.
             // Also has the side-effect of restarting providers if needed.
@@ -200,8 +206,20 @@
 
     public interface Callback {
         void addProvider(@NonNull MediaRouteProvider provider);
+
         void removeProvider(@NonNull MediaRouteProvider provider);
+
         void releaseProviderController(@NonNull RegisteredMediaRouteProvider provider,
                 @NonNull MediaRouteProvider.RouteController controller);
     }
+
+    @RequiresApi(33)
+    private static class Api33 {
+        @DoNotInline
+        static void registerReceiver(@NonNull Context context, @NonNull BroadcastReceiver receiver,
+                @NonNull IntentFilter filter, Handler scheduler, int flags) {
+            context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, scheduler,
+                    flags);
+        }
+    }
 }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RemotePlaybackClient.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RemotePlaybackClient.java
index 6cb2428..f59b93d 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RemotePlaybackClient.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RemotePlaybackClient.java
@@ -77,6 +77,7 @@
         actionFilter.addAction(ActionReceiver.ACTION_SESSION_STATUS_CHANGED);
         actionFilter.addAction(ActionReceiver.ACTION_MESSAGE_RECEIVED);
         mActionReceiver = new ActionReceiver();
+        // TODO(b/197817693): Add flag to indicate whether the receiver should be exported.
         context.registerReceiver(mActionReceiver, actionFilter);
 
         Intent itemStatusIntent = new Intent(ActionReceiver.ACTION_ITEM_STATUS_CHANGED);
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java
index ccc0588..2648406 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java
@@ -128,6 +128,8 @@
             mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
             mVolumeChangeReceiver = new VolumeChangeReceiver();
 
+            // There's no need to specify RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED here, since
+            // LegacyImpl is not used on versions of Android new enough to allow this.
             context.registerReceiver(mVolumeChangeReceiver,
                     new IntentFilter(VolumeChangeReceiver.VOLUME_CHANGED_ACTION));
             publishRoutes();