Loading core/api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -851,6 +851,10 @@ package android.app { field public static final int SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY = 11; // 0xb } public static class Notification.MediaStyle extends android.app.Notification.Style { method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public android.app.Notification.MediaStyle setRemotePlaybackInfo(@NonNull CharSequence, @DrawableRes int, @Nullable android.app.PendingIntent); } public static final class Notification.TvExtender implements android.app.Notification.Extender { ctor public Notification.TvExtender(); ctor public Notification.TvExtender(android.app.Notification); core/api/test-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -300,6 +300,9 @@ package android.app { public class Notification implements android.os.Parcelable { method public boolean shouldShowForegroundImmediately(); field public static final String EXTRA_MEDIA_REMOTE_DEVICE = "android.mediaRemoteDevice"; field public static final String EXTRA_MEDIA_REMOTE_ICON = "android.mediaRemoteIcon"; field public static final String EXTRA_MEDIA_REMOTE_INTENT = "android.mediaRemoteIntent"; } public final class NotificationChannel implements android.os.Parcelable { Loading core/java/android/app/Notification.java +73 −0 Original line number Diff line number Diff line Loading @@ -1329,6 +1329,32 @@ public class Notification implements Parcelable */ public static final String EXTRA_MEDIA_SESSION = "android.mediaSession"; /** * {@link #extras} key: A {@code CharSequence} name of a remote device used for a media session * associated with a {@link Notification.MediaStyle} notification. This will show in the media * controls output switcher instead of the local device name. * @hide */ @TestApi public static final String EXTRA_MEDIA_REMOTE_DEVICE = "android.mediaRemoteDevice"; /** * {@link #extras} key: A {@code int} resource ID for an icon that should show in the output * switcher of the media controls for a {@link Notification.MediaStyle} notification. * @hide */ @TestApi public static final String EXTRA_MEDIA_REMOTE_ICON = "android.mediaRemoteIcon"; /** * {@link #extras} key: A {@code PendingIntent} that will replace the default action for the * media controls output switcher chip, associated with a {@link Notification.MediaStyle} * notification. This should launch an activity. * @hide */ @TestApi public static final String EXTRA_MEDIA_REMOTE_INTENT = "android.mediaRemoteIntent"; /** * {@link #extras} key: the indices of actions to be shown in the compact view, * as supplied to (e.g.) {@link MediaStyle#setShowActionsInCompactView(int...)}. Loading Loading @@ -8943,6 +8969,9 @@ public class Notification implements Parcelable private int[] mActionsToShowInCompact = null; private MediaSession.Token mToken; private CharSequence mDeviceName; private int mDeviceIcon; private PendingIntent mDeviceIntent; public MediaStyle() { } Loading Loading @@ -8975,6 +9004,32 @@ public class Notification implements Parcelable return this; } /** * For media notifications associated with playback on a remote device, provide device * information that will replace the default values for the output switcher chip on the * media control, as well as an intent to use when the output switcher chip is tapped, * on devices where this is supported. * * @param deviceName The name of the remote device to display * @param iconResource Icon resource representing the device * @param chipIntent PendingIntent to send when the output switcher is tapped. May be * {@code null}, in which case the output switcher will be disabled. * This intent should open an Activity or it will be ignored. * @return MediaStyle * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) @NonNull public MediaStyle setRemotePlaybackInfo(@NonNull CharSequence deviceName, @DrawableRes int iconResource, @Nullable PendingIntent chipIntent) { mDeviceName = deviceName; mDeviceIcon = iconResource; mDeviceIntent = chipIntent; return this; } /** * @hide */ Loading Loading @@ -9023,6 +9078,15 @@ public class Notification implements Parcelable if (mActionsToShowInCompact != null) { extras.putIntArray(EXTRA_COMPACT_ACTIONS, mActionsToShowInCompact); } if (mDeviceName != null) { extras.putCharSequence(EXTRA_MEDIA_REMOTE_DEVICE, mDeviceName); } if (mDeviceIcon > 0) { extras.putInt(EXTRA_MEDIA_REMOTE_ICON, mDeviceIcon); } if (mDeviceIntent != null) { extras.putParcelable(EXTRA_MEDIA_REMOTE_INTENT, mDeviceIntent); } } /** Loading @@ -9038,6 +9102,15 @@ public class Notification implements Parcelable if (extras.containsKey(EXTRA_COMPACT_ACTIONS)) { mActionsToShowInCompact = extras.getIntArray(EXTRA_COMPACT_ACTIONS); } if (extras.containsKey(EXTRA_MEDIA_REMOTE_DEVICE)) { mDeviceName = extras.getCharSequence(EXTRA_MEDIA_REMOTE_DEVICE); } if (extras.containsKey(EXTRA_MEDIA_REMOTE_ICON)) { mDeviceIcon = extras.getInt(EXTRA_MEDIA_REMOTE_ICON); } if (extras.containsKey(EXTRA_MEDIA_REMOTE_INTENT)) { mDeviceIntent = extras.getParcelable(EXTRA_MEDIA_REMOTE_INTENT); } } /** Loading packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +24 −12 Original line number Diff line number Diff line Loading @@ -371,13 +371,6 @@ public class MediaControlPanel { // Output switcher chip ViewGroup seamlessView = mMediaViewHolder.getSeamless(); seamlessView.setVisibility(View.VISIBLE); seamlessView.setOnClickListener( v -> { if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { mMediaOutputDialogFactory.create(data.getPackageName(), true, mMediaViewHolder.getSeamlessButton()); } }); ImageView iconView = mMediaViewHolder.getSeamlessIcon(); TextView deviceName = mMediaViewHolder.getSeamlessText(); final MediaDeviceData device = data.getDevice(); Loading @@ -387,8 +380,8 @@ public class MediaControlPanel { final float seamlessAlpha = seamlessDisabled ? DISABLED_ALPHA : 1.0f; mMediaViewHolder.getSeamlessButton().setAlpha(seamlessAlpha); seamlessView.setEnabled(!seamlessDisabled); String deviceString = null; if (device != null && device.getEnabled()) { CharSequence deviceString = mContext.getString(R.string.media_seamless_other_device); if (device != null) { Drawable icon = device.getIcon(); if (icon instanceof AdaptiveIcon) { AdaptiveIcon aIcon = (AdaptiveIcon) icon; Loading @@ -399,13 +392,32 @@ public class MediaControlPanel { } deviceString = device.getName(); } else { // Reset to default Log.w(TAG, "Device is null or not enabled: " + device + ", not binding output chip."); // Set to default icon iconView.setImageResource(R.drawable.ic_media_home_devices); deviceString = mContext.getString(R.string.media_seamless_other_device); } deviceName.setText(deviceString); seamlessView.setContentDescription(deviceString); seamlessView.setOnClickListener( v -> { if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { return; } if (device.getIntent() != null) { if (device.getIntent().isActivity()) { mActivityStarter.startActivity( device.getIntent().getIntent(), true); } else { try { device.getIntent().send(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Device pending intent was canceled"); } } } else { mMediaOutputDialogFactory.create(data.getPackageName(), true, mMediaViewHolder.getSeamlessButton()); } }); // Dismiss mMediaViewHolder.getDismissText().setAlpha(isDismissible ? 1 : DISABLED_ALPHA); Loading packages/SystemUI/src/com/android/systemui/media/MediaData.kt +11 −2 Original line number Diff line number Diff line Loading @@ -164,8 +164,17 @@ data class MediaAction( ) /** State of the media device. */ data class MediaDeviceData( data class MediaDeviceData @JvmOverloads constructor( /** Whether or not to enable the chip */ val enabled: Boolean, /** Device icon to show in the chip */ val icon: Drawable?, val name: String? /** Device display name */ val name: CharSequence?, /** Optional intent to override the default output switcher for this control */ val intent: PendingIntent? = null ) Loading
core/api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -851,6 +851,10 @@ package android.app { field public static final int SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY = 11; // 0xb } public static class Notification.MediaStyle extends android.app.Notification.Style { method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public android.app.Notification.MediaStyle setRemotePlaybackInfo(@NonNull CharSequence, @DrawableRes int, @Nullable android.app.PendingIntent); } public static final class Notification.TvExtender implements android.app.Notification.Extender { ctor public Notification.TvExtender(); ctor public Notification.TvExtender(android.app.Notification);
core/api/test-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -300,6 +300,9 @@ package android.app { public class Notification implements android.os.Parcelable { method public boolean shouldShowForegroundImmediately(); field public static final String EXTRA_MEDIA_REMOTE_DEVICE = "android.mediaRemoteDevice"; field public static final String EXTRA_MEDIA_REMOTE_ICON = "android.mediaRemoteIcon"; field public static final String EXTRA_MEDIA_REMOTE_INTENT = "android.mediaRemoteIntent"; } public final class NotificationChannel implements android.os.Parcelable { Loading
core/java/android/app/Notification.java +73 −0 Original line number Diff line number Diff line Loading @@ -1329,6 +1329,32 @@ public class Notification implements Parcelable */ public static final String EXTRA_MEDIA_SESSION = "android.mediaSession"; /** * {@link #extras} key: A {@code CharSequence} name of a remote device used for a media session * associated with a {@link Notification.MediaStyle} notification. This will show in the media * controls output switcher instead of the local device name. * @hide */ @TestApi public static final String EXTRA_MEDIA_REMOTE_DEVICE = "android.mediaRemoteDevice"; /** * {@link #extras} key: A {@code int} resource ID for an icon that should show in the output * switcher of the media controls for a {@link Notification.MediaStyle} notification. * @hide */ @TestApi public static final String EXTRA_MEDIA_REMOTE_ICON = "android.mediaRemoteIcon"; /** * {@link #extras} key: A {@code PendingIntent} that will replace the default action for the * media controls output switcher chip, associated with a {@link Notification.MediaStyle} * notification. This should launch an activity. * @hide */ @TestApi public static final String EXTRA_MEDIA_REMOTE_INTENT = "android.mediaRemoteIntent"; /** * {@link #extras} key: the indices of actions to be shown in the compact view, * as supplied to (e.g.) {@link MediaStyle#setShowActionsInCompactView(int...)}. Loading Loading @@ -8943,6 +8969,9 @@ public class Notification implements Parcelable private int[] mActionsToShowInCompact = null; private MediaSession.Token mToken; private CharSequence mDeviceName; private int mDeviceIcon; private PendingIntent mDeviceIntent; public MediaStyle() { } Loading Loading @@ -8975,6 +9004,32 @@ public class Notification implements Parcelable return this; } /** * For media notifications associated with playback on a remote device, provide device * information that will replace the default values for the output switcher chip on the * media control, as well as an intent to use when the output switcher chip is tapped, * on devices where this is supported. * * @param deviceName The name of the remote device to display * @param iconResource Icon resource representing the device * @param chipIntent PendingIntent to send when the output switcher is tapped. May be * {@code null}, in which case the output switcher will be disabled. * This intent should open an Activity or it will be ignored. * @return MediaStyle * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) @NonNull public MediaStyle setRemotePlaybackInfo(@NonNull CharSequence deviceName, @DrawableRes int iconResource, @Nullable PendingIntent chipIntent) { mDeviceName = deviceName; mDeviceIcon = iconResource; mDeviceIntent = chipIntent; return this; } /** * @hide */ Loading Loading @@ -9023,6 +9078,15 @@ public class Notification implements Parcelable if (mActionsToShowInCompact != null) { extras.putIntArray(EXTRA_COMPACT_ACTIONS, mActionsToShowInCompact); } if (mDeviceName != null) { extras.putCharSequence(EXTRA_MEDIA_REMOTE_DEVICE, mDeviceName); } if (mDeviceIcon > 0) { extras.putInt(EXTRA_MEDIA_REMOTE_ICON, mDeviceIcon); } if (mDeviceIntent != null) { extras.putParcelable(EXTRA_MEDIA_REMOTE_INTENT, mDeviceIntent); } } /** Loading @@ -9038,6 +9102,15 @@ public class Notification implements Parcelable if (extras.containsKey(EXTRA_COMPACT_ACTIONS)) { mActionsToShowInCompact = extras.getIntArray(EXTRA_COMPACT_ACTIONS); } if (extras.containsKey(EXTRA_MEDIA_REMOTE_DEVICE)) { mDeviceName = extras.getCharSequence(EXTRA_MEDIA_REMOTE_DEVICE); } if (extras.containsKey(EXTRA_MEDIA_REMOTE_ICON)) { mDeviceIcon = extras.getInt(EXTRA_MEDIA_REMOTE_ICON); } if (extras.containsKey(EXTRA_MEDIA_REMOTE_INTENT)) { mDeviceIntent = extras.getParcelable(EXTRA_MEDIA_REMOTE_INTENT); } } /** Loading
packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +24 −12 Original line number Diff line number Diff line Loading @@ -371,13 +371,6 @@ public class MediaControlPanel { // Output switcher chip ViewGroup seamlessView = mMediaViewHolder.getSeamless(); seamlessView.setVisibility(View.VISIBLE); seamlessView.setOnClickListener( v -> { if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { mMediaOutputDialogFactory.create(data.getPackageName(), true, mMediaViewHolder.getSeamlessButton()); } }); ImageView iconView = mMediaViewHolder.getSeamlessIcon(); TextView deviceName = mMediaViewHolder.getSeamlessText(); final MediaDeviceData device = data.getDevice(); Loading @@ -387,8 +380,8 @@ public class MediaControlPanel { final float seamlessAlpha = seamlessDisabled ? DISABLED_ALPHA : 1.0f; mMediaViewHolder.getSeamlessButton().setAlpha(seamlessAlpha); seamlessView.setEnabled(!seamlessDisabled); String deviceString = null; if (device != null && device.getEnabled()) { CharSequence deviceString = mContext.getString(R.string.media_seamless_other_device); if (device != null) { Drawable icon = device.getIcon(); if (icon instanceof AdaptiveIcon) { AdaptiveIcon aIcon = (AdaptiveIcon) icon; Loading @@ -399,13 +392,32 @@ public class MediaControlPanel { } deviceString = device.getName(); } else { // Reset to default Log.w(TAG, "Device is null or not enabled: " + device + ", not binding output chip."); // Set to default icon iconView.setImageResource(R.drawable.ic_media_home_devices); deviceString = mContext.getString(R.string.media_seamless_other_device); } deviceName.setText(deviceString); seamlessView.setContentDescription(deviceString); seamlessView.setOnClickListener( v -> { if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { return; } if (device.getIntent() != null) { if (device.getIntent().isActivity()) { mActivityStarter.startActivity( device.getIntent().getIntent(), true); } else { try { device.getIntent().send(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Device pending intent was canceled"); } } } else { mMediaOutputDialogFactory.create(data.getPackageName(), true, mMediaViewHolder.getSeamlessButton()); } }); // Dismiss mMediaViewHolder.getDismissText().setAlpha(isDismissible ? 1 : DISABLED_ALPHA); Loading
packages/SystemUI/src/com/android/systemui/media/MediaData.kt +11 −2 Original line number Diff line number Diff line Loading @@ -164,8 +164,17 @@ data class MediaAction( ) /** State of the media device. */ data class MediaDeviceData( data class MediaDeviceData @JvmOverloads constructor( /** Whether or not to enable the chip */ val enabled: Boolean, /** Device icon to show in the chip */ val icon: Drawable?, val name: String? /** Device display name */ val name: CharSequence?, /** Optional intent to override the default output switcher for this control */ val intent: PendingIntent? = null )