Merge "MediaRouteButton: Show output switcher dialog when available" into androidx-master-dev
diff --git a/jetifier/jetifier/migration.config b/jetifier/jetifier/migration.config
index 0533d73..c7c0b32 100644
--- a/jetifier/jetifier/migration.config
+++ b/jetifier/jetifier/migration.config
@@ -581,6 +581,10 @@
       "to": "ignore"
     },
     {
+      "from": "androidx/mediarouter/app/OutputSwitcherConstants(.*)",
+      "to": "ignore"
+    },
+    {
       "from": "androidx/mediarouter/app/OverlayListView(.*)",
       "to": "ignore"
     },
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 195b7bc..ea4c9ea 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
@@ -22,6 +22,10 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -88,6 +92,8 @@
 public class MediaRouteButton extends View {
     private static final String TAG = "MediaRouteButton";
 
+    private static final boolean USE_OUTPUT_SWITCHER_IF_AVAILABLE = true;
+
     private static final String CHOOSER_FRAGMENT_TAG =
             "android.support.v7.mediarouter:MediaRouteChooserDialogFragment";
     private static final String CONTROLLER_FRAGMENT_TAG =
@@ -305,6 +311,32 @@
             return false;
         }
 
+        if (USE_OUTPUT_SWITCHER_IF_AVAILABLE && MediaRouter.isTransferEnabled()) {
+            Context context = getContext();
+
+            Intent intent = new Intent()
+                    .setAction(OutputSwitcherConstants.ACTION_MEDIA_OUTPUT)
+                    .putExtra(OutputSwitcherConstants.EXTRA_PACKAGE_NAME, context.getPackageName())
+                    .putExtra(OutputSwitcherConstants.KEY_MEDIA_SESSION_TOKEN,
+                            mRouter.getMediaSessionToken());
+
+            PackageManager packageManager = context.getPackageManager();
+            List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
+            for (ResolveInfo resolveInfo : resolveInfos) {
+                ActivityInfo activityInfo = resolveInfo.activityInfo;
+                if (activityInfo == null || activityInfo.applicationInfo == null) {
+                    continue;
+                }
+                ApplicationInfo appInfo = activityInfo.applicationInfo;
+                if (((ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
+                        & appInfo.flags) != 0) {
+                    context.startActivity(intent);
+                    return true;
+                }
+            }
+            // If there is no output switcher, fall back to the normal dialog.
+        }
+
         final FragmentManager fm = getFragmentManager();
         if (fm == null) {
             throw new IllegalStateException("The activity must be a subclass of FragmentActivity");
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/OutputSwitcherConstants.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/OutputSwitcherConstants.java
new file mode 100644
index 0000000..ad28ebb
--- /dev/null
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/OutputSwitcherConstants.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.mediarouter.app;
+
+/**
+ * Constants for opening Output Switcher activity.
+ */
+class OutputSwitcherConstants {
+    /**
+     * Copied from MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT.
+     */
+    static final String ACTION_MEDIA_OUTPUT = "com.android.settings.panel.action.MEDIA_OUTPUT";
+
+    /**
+     * Copied from MediaOutputSliceConstants.EXTRA_PACKAGE_NAME.
+     */
+    static final String EXTRA_PACKAGE_NAME = "com.android.settings.panel.extra.PACKAGE_NAME";
+
+    /**
+     * Copied from MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN.
+     */
+    static final String KEY_MEDIA_SESSION_TOKEN = "key_media_session_token";
+
+    private OutputSwitcherConstants() {}
+}
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java
index 8049777..1e043a4 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java
@@ -885,8 +885,10 @@
      * Returns whether the seamless transfer feature is enabled.
      *
      * @see MediaRouter
+     * @hide
      */
-    static boolean isTransferEnabled() {
+    @RestrictTo(LIBRARY)
+    public static boolean isTransferEnabled() {
         if (sGlobal == null) {
             return false;
         }
@@ -2264,7 +2266,7 @@
             }
         };
 
-        @SuppressLint("SyntheticAccessor")
+        @SuppressLint({"SyntheticAccessor", "NewApi"})
         GlobalMediaRouter(Context applicationContext) {
             mApplicationContext = applicationContext;
             mDisplayManager = DisplayManagerCompat.getInstance(applicationContext);
@@ -2284,7 +2286,7 @@
 
             if (TextUtils.equals(feature, METADATA_FEATURE_SEAMLESS_TRANSFER)) {
                 mDynamicGroupEnabled = true;
-                mTransferEnabled = true;
+                mTransferEnabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
             } else if (TextUtils.equals(feature, METADATA_FEATURE_DYNAMIC_GROUP)) {
                 mDynamicGroupEnabled = true;
                 mTransferEnabled = false;
@@ -2294,7 +2296,7 @@
                 mTransferEnabled = false;
             }
 
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && mTransferEnabled) {
+            if (mTransferEnabled) {
                 mMr2Provider = new MediaRoute2Provider(
                         mApplicationContext, new Mr2ProviderCallback());
             } else {