diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index b7265b951387c..51211a0c0d2a5 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -85,6 +85,36 @@
android:overScrollMode="never"/>
+
+
+
+
+
+
16dp
16dp
12.5dp
+ 20dp
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3b7e9d46c9537..d4cc718b9cc8d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2205,6 +2205,11 @@
Can\'t switch. Tap to try again.
Pair new device
+
+ To cast this session, please open the app.
+
+ Unknown app
+
Build number
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index e55b25ffa29d1..7bb5454112c42 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -21,10 +21,15 @@ import static android.view.WindowInsets.Type.statusBars;
import android.app.WallpaperColors;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -76,8 +81,10 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
private ImageView mAppResourceIcon;
private RecyclerView mDevicesRecyclerView;
private LinearLayout mDeviceListLayout;
+ private LinearLayout mCastAppLayout;
private Button mDoneButton;
private Button mStopButton;
+ private Button mAppButton;
private int mListMaxHeight;
private WallpaperColors mWallpaperColors;
@@ -129,7 +136,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
mDoneButton = mDialogView.requireViewById(R.id.done);
mStopButton = mDialogView.requireViewById(R.id.stop);
+ mAppButton = mDialogView.requireViewById(R.id.launch_app_button);
mAppResourceIcon = mDialogView.requireViewById(R.id.app_source_icon);
+ mCastAppLayout = mDialogView.requireViewById(R.id.cast_app_section);
mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
mDeviceListLayoutListener);
@@ -144,6 +153,13 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
mMediaOutputController.releaseSession();
dismiss();
});
+ mAppButton.setOnClickListener(v -> {
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ if (mMediaOutputController.getAppLaunchIntent() != null) {
+ mContext.startActivity(mMediaOutputController.getAppLaunchIntent());
+ }
+ dismiss();
+ });
}
@Override
@@ -169,8 +185,16 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
final IconCompat iconCompat = getHeaderIcon();
final Drawable appSourceDrawable = getAppSourceIcon();
boolean colorSetUpdated = false;
+ mCastAppLayout.setVisibility(
+ mMediaOutputController.shouldShowLaunchSection()
+ ? View.VISIBLE : View.GONE);
if (appSourceDrawable != null) {
mAppResourceIcon.setImageDrawable(appSourceDrawable);
+ mAppButton.setCompoundDrawablesWithIntrinsicBounds(resizeDrawable(appSourceDrawable,
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.media_output_dialog_app_tier_icon_size
+ )),
+ null, null, null);
} else {
mAppResourceIcon.setVisibility(View.GONE);
}
@@ -205,6 +229,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
R.dimen.media_output_dialog_header_icon_padding);
mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size + padding, size));
}
+ mAppButton.setText(mMediaOutputController.getAppSourceName());
// Update title and subtitle
mHeaderTitle.setText(getHeaderText());
final CharSequence subTitle = getHeaderSubtitle();
@@ -229,6 +254,22 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
mStopButton.setVisibility(getStopButtonVisibility());
}
+ private Drawable resizeDrawable(Drawable drawable, int size) {
+ if (drawable == null) {
+ return null;
+ }
+ int width = drawable.getIntrinsicWidth();
+ int height = drawable.getIntrinsicHeight();
+ Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
+ : Bitmap.Config.RGB_565;
+ Bitmap bitmap = Bitmap.createBitmap(width, height, config);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, width, height);
+ drawable.draw(canvas);
+ return new BitmapDrawable(mContext.getResources(),
+ Bitmap.createScaledBitmap(bitmap, size, size, false));
+ }
+
abstract Drawable getAppSourceIcon();
abstract int getHeaderIconRes();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 1c6b7dc222bb4..e141cccc5b0f8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -22,6 +22,7 @@ import android.app.Notification;
import android.app.WallpaperColors;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
@@ -45,6 +46,8 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.drawable.IconCompat;
+import androidx.mediarouter.media.MediaRouter;
+import androidx.mediarouter.media.MediaRouterParams;
import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -171,6 +174,12 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mLocalMediaManager.startScan();
}
+ boolean shouldShowLaunchSection() {
+ MediaRouterParams routerParams = MediaRouter.getInstance(mContext).getRouterParams();
+ Log.d(TAG, "try to get routerParams: " + routerParams);
+ return routerParams != null && !routerParams.isMediaTransferReceiverEnabled();
+ }
+
void stop() {
if (mMediaController != null) {
mMediaController.unregisterCallback(mCb);
@@ -220,6 +229,32 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
}
}
+ String getAppSourceName() {
+ if (mPackageName.isEmpty()) {
+ return null;
+ }
+ final PackageManager packageManager = mContext.getPackageManager();
+ ApplicationInfo applicationInfo;
+ try {
+ applicationInfo = packageManager.getApplicationInfo(mPackageName,
+ PackageManager.ApplicationInfoFlags.of(0));
+ } catch (PackageManager.NameNotFoundException e) {
+ applicationInfo = null;
+ }
+ final String applicationName =
+ (String) (applicationInfo != null ? packageManager.getApplicationLabel(
+ applicationInfo)
+ : mContext.getString(R.string.media_output_dialog_unknown_launch_app_name));
+ return applicationName;
+ }
+
+ Intent getAppLaunchIntent() {
+ if (mPackageName.isEmpty()) {
+ return null;
+ }
+ return mContext.getPackageManager().getLaunchIntentForPackage(mPackageName);
+ }
+
CharSequence getHeaderTitle() {
if (mMediaController != null) {
final MediaMetadata metadata = mMediaController.getMetadata();