Loading packages/SystemUI/res/layout/qs_media_panel_options.xml 0 → 100644 +41 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2019 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 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/qs_media_controls_options" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:gravity="center" android:layout_gravity="center" android:padding="10dp" > <ImageButton android:id="@+id/remove" android:layout_width="48dp" android:layout_height="48dp" android:src="@android:drawable/ic_menu_delete" android:padding="8dp" /> <ImageButton android:id="@+id/cancel" android:layout_width="48dp" android:layout_height="48dp" android:src="@android:drawable/ic_menu_revert" android:padding="8dp" /> </LinearLayout> packages/SystemUI/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1179,4 +1179,5 @@ <dimen name="qs_media_height">150dp</dimen> <dimen name="qs_media_width">350dp</dimen> <dimen name="qs_media_padding">8dp</dimen> <dimen name="qs_media_corner_radius">10dp</dimen> </resources> packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java +112 −8 Original line number Diff line number Diff line Loading @@ -18,8 +18,11 @@ package com.android.systemui.qs; import android.app.Notification; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Canvas; Loading @@ -35,6 +38,7 @@ import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -54,6 +58,8 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import java.util.List; /** * Single media player for carousel in QSPanel */ Loading @@ -70,6 +76,83 @@ public class QSMediaPlayer { private int mHeight; private int mForegroundColor; private int mBackgroundColor; private ComponentName mRecvComponent; private QSPanel mParent; private MediaController.Callback mSessionCallback = new MediaController.Callback() { @Override public void onSessionDestroyed() { Log.d(TAG, "session destroyed"); mController.unregisterCallback(mSessionCallback); // Hide all the old buttons final int[] actionIds = { R.id.action0, R.id.action1, R.id.action2, R.id.action3, R.id.action4 }; for (int i = 0; i < actionIds.length; i++) { ImageButton thisBtn = mMediaNotifView.findViewById(actionIds[i]); if (thisBtn != null) { thisBtn.setVisibility(View.GONE); } } // Add a restart button ImageButton btn = mMediaNotifView.findViewById(actionIds[0]); btn.setOnClickListener(v -> { Log.d(TAG, "Attempting to restart session"); // Send a media button event to previously found receiver if (mRecvComponent != null) { Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); intent.setComponent(mRecvComponent); int keyCode = KeyEvent.KEYCODE_MEDIA_PLAY; intent.putExtra( Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); mContext.sendBroadcast(intent); } else { Log.d(TAG, "No receiver to restart"); // If we don't have a receiver, try relaunching the activity instead try { mController.getSessionActivity().send(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Pending intent was canceled"); e.printStackTrace(); } } }); btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_replay)); btn.setImageTintList(ColorStateList.valueOf(mForegroundColor)); btn.setVisibility(View.VISIBLE); // Add long-click option to remove the player ViewGroup mMediaCarousel = (ViewGroup) mMediaNotifView.getParent(); mMediaNotifView.setOnLongClickListener(v -> { // Replace player view with delete/cancel view v.setVisibility(View.GONE); View options = LayoutInflater.from(mContext).inflate( R.layout.qs_media_panel_options, null, false); ImageButton btnDelete = options.findViewById(R.id.remove); btnDelete.setOnClickListener(b -> { mMediaCarousel.removeView(options); mParent.removeMediaPlayer(QSMediaPlayer.this); }); ImageButton btnCancel = options.findViewById(R.id.cancel); btnCancel.setOnClickListener(b -> { mMediaCarousel.removeView(options); v.setVisibility(View.VISIBLE); }); int pos = mMediaCarousel.indexOfChild(v); mMediaCarousel.addView(options, pos, v.getLayoutParams()); return true; // consumed click }); } }; /** * Loading @@ -92,7 +175,8 @@ public class QSMediaPlayer { } /** * * Create or update the player view for the given media session * @param parent the parent QSPanel * @param token token for this media session * @param icon app notification icon * @param iconColor foreground color (for text, icons) Loading @@ -101,13 +185,30 @@ public class QSMediaPlayer { * @param notif reference to original notification * @param device current playback device */ public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor, int bgColor, View actionsContainer, Notification notif, MediaDevice device) { Log.d(TAG, "got media session: " + token); public void setMediaSession(QSPanel parent, MediaSession.Token token, Icon icon, int iconColor, int bgColor, View actionsContainer, Notification notif, MediaDevice device) { mParent = parent; mToken = token; mForegroundColor = iconColor; mBackgroundColor = bgColor; mController = new MediaController(mContext, token); // Try to find a receiver for the media button that matches this app PackageManager pm = mContext.getPackageManager(); Intent it = new Intent(Intent.ACTION_MEDIA_BUTTON); List<ResolveInfo> info = pm.queryBroadcastReceiversAsUser(it, 0, mContext.getUser()); if (info != null) { for (ResolveInfo inf : info) { if (inf.activityInfo.packageName.equals(notif.contentIntent.getCreatorPackage())) { Log.d(TAG, "Found receiver for package: " + inf); mRecvComponent = inf.getComponentInfo().getComponentName(); } } } // reset in case we had previously restarted the stream mMediaNotifView.setOnLongClickListener(null); mController.registerCallback(mSessionCallback); MediaMetadata mMediaMetadata = mController.getMetadata(); if (mMediaMetadata == null) { Log.e(TAG, "Media metadata was null"); Loading Loading @@ -235,7 +336,6 @@ public class QSMediaPlayer { for (; i < actionIds.length; i++) { ImageButton thisBtn = mMediaNotifView.findViewById(actionIds[i]); thisBtn.setVisibility(View.GONE); Log.d(TAG, "hid a button"); } } Loading Loading @@ -266,8 +366,9 @@ public class QSMediaPlayer { private void addAlbumArtBackground(MediaMetadata metadata, int bgColor, int width, int height) { Bitmap albumArt = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); float radius = mContext.getResources().getDimension(R.dimen.qs_media_corner_radius); if (albumArt != null) { Log.d(TAG, "updating album art"); Bitmap original = albumArt.copy(Bitmap.Config.ARGB_8888, true); Bitmap scaled = scaleBitmap(original, width, height); Canvas canvas = new Canvas(scaled); Loading @@ -281,12 +382,15 @@ public class QSMediaPlayer { RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create( mContext.getResources(), scaled); roundedDrawable.setCornerRadius(20); roundedDrawable.setCornerRadius(radius); mMediaNotifView.setBackground(roundedDrawable); } else { Log.e(TAG, "No album art available"); mMediaNotifView.setBackground(null); GradientDrawable rect = new GradientDrawable(); rect.setCornerRadius(radius); rect.setColor(bgColor); mMediaNotifView.setBackground(rect); } } Loading packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +22 −1 Original line number Diff line number Diff line Loading @@ -284,7 +284,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } Log.d(TAG, "setting player session"); player.setMediaSession(token, icon, iconColor, bgColor, actionsContainer, player.setMediaSession(this, token, icon, iconColor, bgColor, actionsContainer, notif.getNotification(), mDevice); if (mMediaPlayers.size() > 0) { Loading @@ -303,6 +303,27 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne return mMediaCarousel; } /** * Remove the media player from the carousel * @param player Player to remove * @return true if removed, false if player was not found */ protected boolean removeMediaPlayer(QSMediaPlayer player) { // Remove from list if (!mMediaPlayers.remove(player)) { return false; } // Check if we need to collapse the carousel now mMediaCarousel.removeView(player.getView()); if (mMediaPlayers.size() == 0) { ((View) mMediaCarousel.getParent()).setVisibility(View.GONE); mLocalMediaManager.stopScan(); mLocalMediaManager.unregisterCallback(mDeviceCallback); } return true; } protected void addDivider() { mDivider = LayoutInflater.from(mContext).inflate(R.layout.qs_divider, this, false); mDivider.setBackgroundColor(Utils.applyAlpha(mDivider.getAlpha(), Loading packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java +84 −6 Original line number Diff line number Diff line Loading @@ -16,19 +16,27 @@ package com.android.systemui.qs; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.Icon; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -42,6 +50,8 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.systemui.R; import java.util.List; /** * QQS mini media player */ Loading @@ -53,6 +63,54 @@ public class QuickQSMediaPlayer { private LinearLayout mMediaNotifView; private MediaSession.Token mToken; private MediaController mController; private int mBackgroundColor; private int mForegroundColor; private ComponentName mRecvComponent; private MediaController.Callback mSessionCallback = new MediaController.Callback() { @Override public void onSessionDestroyed() { Log.d(TAG, "session destroyed"); mController.unregisterCallback(mSessionCallback); // Hide all the old buttons final int[] actionIds = {R.id.action0, R.id.action1, R.id.action2}; for (int i = 0; i < actionIds.length; i++) { ImageButton thisBtn = mMediaNotifView.findViewById(actionIds[i]); if (thisBtn != null) { thisBtn.setVisibility(View.GONE); } } // Add a restart button ImageButton btn = mMediaNotifView.findViewById(actionIds[0]); btn.setOnClickListener(v -> { Log.d(TAG, "Attempting to restart session"); // Send a media button event to previously found receiver if (mRecvComponent != null) { Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); intent.setComponent(mRecvComponent); int keyCode = KeyEvent.KEYCODE_MEDIA_PLAY; intent.putExtra( Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); mContext.sendBroadcast(intent); } else { Log.d(TAG, "No receiver to restart"); // If we don't have a receiver, try relaunching the activity instead try { mController.getSessionActivity().send(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Pending intent was canceled"); e.printStackTrace(); } } }); btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_replay)); btn.setImageTintList(ColorStateList.valueOf(mForegroundColor)); btn.setVisibility(View.VISIBLE); } }; /** * Loading Loading @@ -83,34 +141,50 @@ public class QuickQSMediaPlayer { View actionsContainer, int[] actionsToShow) { Log.d(TAG, "Setting media session: " + token); mToken = token; mForegroundColor = iconColor; mBackgroundColor = bgColor; mController = new MediaController(mContext, token); MediaMetadata mMediaMetadata = mController.getMetadata(); // Try to find a receiver for the media button that matches this app PackageManager pm = mContext.getPackageManager(); Intent it = new Intent(Intent.ACTION_MEDIA_BUTTON); List<ResolveInfo> info = pm.queryBroadcastReceiversAsUser(it, 0, mContext.getUser()); if (info != null) { for (ResolveInfo inf : info) { if (inf.activityInfo.packageName.equals(mController.getPackageName())) { Log.d(TAG, "Found receiver for package: " + inf); mRecvComponent = inf.getComponentInfo().getComponentName(); } } } mController.registerCallback(mSessionCallback); if (mMediaMetadata == null) { Log.e(TAG, "Media metadata was null"); return; } // Album art addAlbumArtBackground(mMediaMetadata, bgColor); addAlbumArtBackground(mMediaMetadata, mBackgroundColor); // App icon ImageView appIcon = mMediaNotifView.findViewById(R.id.icon); Drawable iconDrawable = icon.loadDrawable(mContext); iconDrawable.setTint(iconColor); iconDrawable.setTint(mForegroundColor); appIcon.setImageDrawable(iconDrawable); // Artist name TextView appText = mMediaNotifView.findViewById(R.id.header_title); String artistName = mMediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST); appText.setText(artistName); appText.setTextColor(iconColor); appText.setTextColor(mForegroundColor); // Song name TextView titleText = mMediaNotifView.findViewById(R.id.header_text); String songName = mMediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE); titleText.setText(songName); titleText.setTextColor(iconColor); titleText.setTextColor(mForegroundColor); // Buttons we can display final int[] actionIds = {R.id.action0, R.id.action1, R.id.action2}; Loading Loading @@ -178,6 +252,7 @@ public class QuickQSMediaPlayer { private void addAlbumArtBackground(MediaMetadata metadata, int bgColor) { Bitmap albumArt = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); float radius = mContext.getResources().getDimension(R.dimen.qs_media_corner_radius); if (albumArt != null) { Rect bounds = new Rect(); mMediaNotifView.getBoundsOnScreen(bounds); Loading @@ -197,12 +272,15 @@ public class QuickQSMediaPlayer { RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create( mContext.getResources(), scaled); roundedDrawable.setCornerRadius(20); roundedDrawable.setCornerRadius(radius); mMediaNotifView.setBackground(roundedDrawable); } else { Log.e(TAG, "No album art available"); mMediaNotifView.setBackground(null); GradientDrawable rect = new GradientDrawable(); rect.setCornerRadius(radius); rect.setColor(bgColor); mMediaNotifView.setBackground(rect); } } Loading Loading
packages/SystemUI/res/layout/qs_media_panel_options.xml 0 → 100644 +41 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2019 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 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/qs_media_controls_options" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:gravity="center" android:layout_gravity="center" android:padding="10dp" > <ImageButton android:id="@+id/remove" android:layout_width="48dp" android:layout_height="48dp" android:src="@android:drawable/ic_menu_delete" android:padding="8dp" /> <ImageButton android:id="@+id/cancel" android:layout_width="48dp" android:layout_height="48dp" android:src="@android:drawable/ic_menu_revert" android:padding="8dp" /> </LinearLayout>
packages/SystemUI/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1179,4 +1179,5 @@ <dimen name="qs_media_height">150dp</dimen> <dimen name="qs_media_width">350dp</dimen> <dimen name="qs_media_padding">8dp</dimen> <dimen name="qs_media_corner_radius">10dp</dimen> </resources>
packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java +112 −8 Original line number Diff line number Diff line Loading @@ -18,8 +18,11 @@ package com.android.systemui.qs; import android.app.Notification; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Canvas; Loading @@ -35,6 +38,7 @@ import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -54,6 +58,8 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import java.util.List; /** * Single media player for carousel in QSPanel */ Loading @@ -70,6 +76,83 @@ public class QSMediaPlayer { private int mHeight; private int mForegroundColor; private int mBackgroundColor; private ComponentName mRecvComponent; private QSPanel mParent; private MediaController.Callback mSessionCallback = new MediaController.Callback() { @Override public void onSessionDestroyed() { Log.d(TAG, "session destroyed"); mController.unregisterCallback(mSessionCallback); // Hide all the old buttons final int[] actionIds = { R.id.action0, R.id.action1, R.id.action2, R.id.action3, R.id.action4 }; for (int i = 0; i < actionIds.length; i++) { ImageButton thisBtn = mMediaNotifView.findViewById(actionIds[i]); if (thisBtn != null) { thisBtn.setVisibility(View.GONE); } } // Add a restart button ImageButton btn = mMediaNotifView.findViewById(actionIds[0]); btn.setOnClickListener(v -> { Log.d(TAG, "Attempting to restart session"); // Send a media button event to previously found receiver if (mRecvComponent != null) { Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); intent.setComponent(mRecvComponent); int keyCode = KeyEvent.KEYCODE_MEDIA_PLAY; intent.putExtra( Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); mContext.sendBroadcast(intent); } else { Log.d(TAG, "No receiver to restart"); // If we don't have a receiver, try relaunching the activity instead try { mController.getSessionActivity().send(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Pending intent was canceled"); e.printStackTrace(); } } }); btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_replay)); btn.setImageTintList(ColorStateList.valueOf(mForegroundColor)); btn.setVisibility(View.VISIBLE); // Add long-click option to remove the player ViewGroup mMediaCarousel = (ViewGroup) mMediaNotifView.getParent(); mMediaNotifView.setOnLongClickListener(v -> { // Replace player view with delete/cancel view v.setVisibility(View.GONE); View options = LayoutInflater.from(mContext).inflate( R.layout.qs_media_panel_options, null, false); ImageButton btnDelete = options.findViewById(R.id.remove); btnDelete.setOnClickListener(b -> { mMediaCarousel.removeView(options); mParent.removeMediaPlayer(QSMediaPlayer.this); }); ImageButton btnCancel = options.findViewById(R.id.cancel); btnCancel.setOnClickListener(b -> { mMediaCarousel.removeView(options); v.setVisibility(View.VISIBLE); }); int pos = mMediaCarousel.indexOfChild(v); mMediaCarousel.addView(options, pos, v.getLayoutParams()); return true; // consumed click }); } }; /** * Loading @@ -92,7 +175,8 @@ public class QSMediaPlayer { } /** * * Create or update the player view for the given media session * @param parent the parent QSPanel * @param token token for this media session * @param icon app notification icon * @param iconColor foreground color (for text, icons) Loading @@ -101,13 +185,30 @@ public class QSMediaPlayer { * @param notif reference to original notification * @param device current playback device */ public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor, int bgColor, View actionsContainer, Notification notif, MediaDevice device) { Log.d(TAG, "got media session: " + token); public void setMediaSession(QSPanel parent, MediaSession.Token token, Icon icon, int iconColor, int bgColor, View actionsContainer, Notification notif, MediaDevice device) { mParent = parent; mToken = token; mForegroundColor = iconColor; mBackgroundColor = bgColor; mController = new MediaController(mContext, token); // Try to find a receiver for the media button that matches this app PackageManager pm = mContext.getPackageManager(); Intent it = new Intent(Intent.ACTION_MEDIA_BUTTON); List<ResolveInfo> info = pm.queryBroadcastReceiversAsUser(it, 0, mContext.getUser()); if (info != null) { for (ResolveInfo inf : info) { if (inf.activityInfo.packageName.equals(notif.contentIntent.getCreatorPackage())) { Log.d(TAG, "Found receiver for package: " + inf); mRecvComponent = inf.getComponentInfo().getComponentName(); } } } // reset in case we had previously restarted the stream mMediaNotifView.setOnLongClickListener(null); mController.registerCallback(mSessionCallback); MediaMetadata mMediaMetadata = mController.getMetadata(); if (mMediaMetadata == null) { Log.e(TAG, "Media metadata was null"); Loading Loading @@ -235,7 +336,6 @@ public class QSMediaPlayer { for (; i < actionIds.length; i++) { ImageButton thisBtn = mMediaNotifView.findViewById(actionIds[i]); thisBtn.setVisibility(View.GONE); Log.d(TAG, "hid a button"); } } Loading Loading @@ -266,8 +366,9 @@ public class QSMediaPlayer { private void addAlbumArtBackground(MediaMetadata metadata, int bgColor, int width, int height) { Bitmap albumArt = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); float radius = mContext.getResources().getDimension(R.dimen.qs_media_corner_radius); if (albumArt != null) { Log.d(TAG, "updating album art"); Bitmap original = albumArt.copy(Bitmap.Config.ARGB_8888, true); Bitmap scaled = scaleBitmap(original, width, height); Canvas canvas = new Canvas(scaled); Loading @@ -281,12 +382,15 @@ public class QSMediaPlayer { RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create( mContext.getResources(), scaled); roundedDrawable.setCornerRadius(20); roundedDrawable.setCornerRadius(radius); mMediaNotifView.setBackground(roundedDrawable); } else { Log.e(TAG, "No album art available"); mMediaNotifView.setBackground(null); GradientDrawable rect = new GradientDrawable(); rect.setCornerRadius(radius); rect.setColor(bgColor); mMediaNotifView.setBackground(rect); } } Loading
packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +22 −1 Original line number Diff line number Diff line Loading @@ -284,7 +284,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } Log.d(TAG, "setting player session"); player.setMediaSession(token, icon, iconColor, bgColor, actionsContainer, player.setMediaSession(this, token, icon, iconColor, bgColor, actionsContainer, notif.getNotification(), mDevice); if (mMediaPlayers.size() > 0) { Loading @@ -303,6 +303,27 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne return mMediaCarousel; } /** * Remove the media player from the carousel * @param player Player to remove * @return true if removed, false if player was not found */ protected boolean removeMediaPlayer(QSMediaPlayer player) { // Remove from list if (!mMediaPlayers.remove(player)) { return false; } // Check if we need to collapse the carousel now mMediaCarousel.removeView(player.getView()); if (mMediaPlayers.size() == 0) { ((View) mMediaCarousel.getParent()).setVisibility(View.GONE); mLocalMediaManager.stopScan(); mLocalMediaManager.unregisterCallback(mDeviceCallback); } return true; } protected void addDivider() { mDivider = LayoutInflater.from(mContext).inflate(R.layout.qs_divider, this, false); mDivider.setBackgroundColor(Utils.applyAlpha(mDivider.getAlpha(), Loading
packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java +84 −6 Original line number Diff line number Diff line Loading @@ -16,19 +16,27 @@ package com.android.systemui.qs; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.Icon; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -42,6 +50,8 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.systemui.R; import java.util.List; /** * QQS mini media player */ Loading @@ -53,6 +63,54 @@ public class QuickQSMediaPlayer { private LinearLayout mMediaNotifView; private MediaSession.Token mToken; private MediaController mController; private int mBackgroundColor; private int mForegroundColor; private ComponentName mRecvComponent; private MediaController.Callback mSessionCallback = new MediaController.Callback() { @Override public void onSessionDestroyed() { Log.d(TAG, "session destroyed"); mController.unregisterCallback(mSessionCallback); // Hide all the old buttons final int[] actionIds = {R.id.action0, R.id.action1, R.id.action2}; for (int i = 0; i < actionIds.length; i++) { ImageButton thisBtn = mMediaNotifView.findViewById(actionIds[i]); if (thisBtn != null) { thisBtn.setVisibility(View.GONE); } } // Add a restart button ImageButton btn = mMediaNotifView.findViewById(actionIds[0]); btn.setOnClickListener(v -> { Log.d(TAG, "Attempting to restart session"); // Send a media button event to previously found receiver if (mRecvComponent != null) { Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); intent.setComponent(mRecvComponent); int keyCode = KeyEvent.KEYCODE_MEDIA_PLAY; intent.putExtra( Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); mContext.sendBroadcast(intent); } else { Log.d(TAG, "No receiver to restart"); // If we don't have a receiver, try relaunching the activity instead try { mController.getSessionActivity().send(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Pending intent was canceled"); e.printStackTrace(); } } }); btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_replay)); btn.setImageTintList(ColorStateList.valueOf(mForegroundColor)); btn.setVisibility(View.VISIBLE); } }; /** * Loading Loading @@ -83,34 +141,50 @@ public class QuickQSMediaPlayer { View actionsContainer, int[] actionsToShow) { Log.d(TAG, "Setting media session: " + token); mToken = token; mForegroundColor = iconColor; mBackgroundColor = bgColor; mController = new MediaController(mContext, token); MediaMetadata mMediaMetadata = mController.getMetadata(); // Try to find a receiver for the media button that matches this app PackageManager pm = mContext.getPackageManager(); Intent it = new Intent(Intent.ACTION_MEDIA_BUTTON); List<ResolveInfo> info = pm.queryBroadcastReceiversAsUser(it, 0, mContext.getUser()); if (info != null) { for (ResolveInfo inf : info) { if (inf.activityInfo.packageName.equals(mController.getPackageName())) { Log.d(TAG, "Found receiver for package: " + inf); mRecvComponent = inf.getComponentInfo().getComponentName(); } } } mController.registerCallback(mSessionCallback); if (mMediaMetadata == null) { Log.e(TAG, "Media metadata was null"); return; } // Album art addAlbumArtBackground(mMediaMetadata, bgColor); addAlbumArtBackground(mMediaMetadata, mBackgroundColor); // App icon ImageView appIcon = mMediaNotifView.findViewById(R.id.icon); Drawable iconDrawable = icon.loadDrawable(mContext); iconDrawable.setTint(iconColor); iconDrawable.setTint(mForegroundColor); appIcon.setImageDrawable(iconDrawable); // Artist name TextView appText = mMediaNotifView.findViewById(R.id.header_title); String artistName = mMediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST); appText.setText(artistName); appText.setTextColor(iconColor); appText.setTextColor(mForegroundColor); // Song name TextView titleText = mMediaNotifView.findViewById(R.id.header_text); String songName = mMediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE); titleText.setText(songName); titleText.setTextColor(iconColor); titleText.setTextColor(mForegroundColor); // Buttons we can display final int[] actionIds = {R.id.action0, R.id.action1, R.id.action2}; Loading Loading @@ -178,6 +252,7 @@ public class QuickQSMediaPlayer { private void addAlbumArtBackground(MediaMetadata metadata, int bgColor) { Bitmap albumArt = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); float radius = mContext.getResources().getDimension(R.dimen.qs_media_corner_radius); if (albumArt != null) { Rect bounds = new Rect(); mMediaNotifView.getBoundsOnScreen(bounds); Loading @@ -197,12 +272,15 @@ public class QuickQSMediaPlayer { RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create( mContext.getResources(), scaled); roundedDrawable.setCornerRadius(20); roundedDrawable.setCornerRadius(radius); mMediaNotifView.setBackground(roundedDrawable); } else { Log.e(TAG, "No album art available"); mMediaNotifView.setBackground(null); GradientDrawable rect = new GradientDrawable(); rect.setCornerRadius(radius); rect.setColor(bgColor); mMediaNotifView.setBackground(rect); } } Loading