Loading packages/SystemUI/res/layout/media_output_dialog.xml +30 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,36 @@ android:overScrollMode="never"/> </LinearLayout> <LinearLayout android:id="@+id/cast_app_section" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginStart="@dimen/dialog_side_padding" android:layout_marginEnd="@dimen/dialog_side_padding" android:layout_marginBottom="@dimen/dialog_bottom_padding" android:orientation="vertical" android:visibility="gone"> <TextView android:id="@+id/launch_app_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|start" android:ellipsize="end" android:textColor="?android:attr/textColorPrimary" android:text="@string/media_output_dialog_launch_app_text" android:maxLines="1" android:fontFamily="@*android:string/config_headlineFontFamilyMedium" android:textSize="16sp"/> <Button android:id="@+id/launch_app_button" style="@style/Widget.Dialog.Button.BorderButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="5dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" Loading packages/SystemUI/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1121,6 +1121,7 @@ <dimen name="media_output_dialog_header_icon_padding">16dp</dimen> <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen> <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen> <dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen> <!-- Distance that the full shade transition takes in order for qs to fully transition to the shade --> Loading packages/SystemUI/res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -2205,6 +2205,11 @@ <string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string> <!-- Title for pairing item [CHAR LIMIT=60] --> <string name="media_output_dialog_pairing_new">Pair new device</string> <!-- Title for launch app [CHAR LIMIT=60] --> <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string> <!-- App name when can't get app name [CHAR LIMIT=60] --> <string name="media_output_dialog_unknown_launch_app_name">Unknown app</string> <!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]--> <string name="build_number_clip_data_label">Build number</string> Loading packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +41 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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 Loading @@ -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); } Loading Loading @@ -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(); Loading @@ -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(); Loading packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +35 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading Loading
packages/SystemUI/res/layout/media_output_dialog.xml +30 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,36 @@ android:overScrollMode="never"/> </LinearLayout> <LinearLayout android:id="@+id/cast_app_section" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginStart="@dimen/dialog_side_padding" android:layout_marginEnd="@dimen/dialog_side_padding" android:layout_marginBottom="@dimen/dialog_bottom_padding" android:orientation="vertical" android:visibility="gone"> <TextView android:id="@+id/launch_app_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|start" android:ellipsize="end" android:textColor="?android:attr/textColorPrimary" android:text="@string/media_output_dialog_launch_app_text" android:maxLines="1" android:fontFamily="@*android:string/config_headlineFontFamilyMedium" android:textSize="16sp"/> <Button android:id="@+id/launch_app_button" style="@style/Widget.Dialog.Button.BorderButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="5dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" Loading
packages/SystemUI/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1121,6 +1121,7 @@ <dimen name="media_output_dialog_header_icon_padding">16dp</dimen> <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen> <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen> <dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen> <!-- Distance that the full shade transition takes in order for qs to fully transition to the shade --> Loading
packages/SystemUI/res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -2205,6 +2205,11 @@ <string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string> <!-- Title for pairing item [CHAR LIMIT=60] --> <string name="media_output_dialog_pairing_new">Pair new device</string> <!-- Title for launch app [CHAR LIMIT=60] --> <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string> <!-- App name when can't get app name [CHAR LIMIT=60] --> <string name="media_output_dialog_unknown_launch_app_name">Unknown app</string> <!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]--> <string name="build_number_clip_data_label">Build number</string> Loading
packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +41 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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 Loading @@ -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); } Loading Loading @@ -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(); Loading @@ -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(); Loading
packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +35 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading