Fix crash and QQS session issues, visual updates

- Fix crash when null session token
- Only update QQS when it gets a different and active media session
- Fix crash when changing dark mode, due to QQS width/height calculated as 0
- Move QS carousel layout to xml
- Increase horizontal spacing for QQS player
- Tapping QQS player opens the app
- Use play button icon instead of restart icon when media session was ended

Fixes: 146897913
Fixes: 146561456
Test: manual, switch between two different sessions from QS and observe QQS
updates correctly

Change-Id: I5a93a2a9d7037572561a0479365c022013e05ec7
This commit is contained in:
Beth Thibodeau
2020-01-07 17:50:07 -05:00
parent 8404b4ab97
commit 899b595028
7 changed files with 89 additions and 44 deletions

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 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
-->
<!-- Carousel for media controls -->
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/qs_media_height"
android:padding="@dimen/qs_media_padding"
android:scrollbars="none"
android:visibility="gone"
>
<LinearLayout
android:id="@+id/media_carousel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<!-- QSMediaPlayers will be added here dynamically -->
</LinearLayout>
</HorizontalScrollView>

View File

@@ -68,7 +68,7 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
override fun updateResources(): Boolean {
with(mContext.resources) {
smallTileSize = getDimensionPixelSize(R.dimen.qs_quick_tile_size)
cellMarginHorizontal = getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal)
cellMarginHorizontal = getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal) / 2
cellMarginVertical = getDimensionPixelSize(R.dimen.new_qs_vertical_margin)
}
requestLayout()

View File

@@ -124,7 +124,7 @@ public class QSMediaPlayer {
}
}
});
btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_replay));
btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_play));
btn.setImageTintList(ColorStateList.valueOf(mForegroundColor));
btn.setVisibility(View.VISIBLE);
@@ -199,8 +199,7 @@ public class QSMediaPlayer {
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);
if (inf.activityInfo.packageName.equals(mController.getPackageName())) {
mRecvComponent = inf.getComponentInfo().getComponentName();
}
}

View File

@@ -184,21 +184,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
// Add media carousel
if (useQsMediaPlayer(context)) {
HorizontalScrollView mediaScrollView = new HorizontalScrollView(mContext);
mediaScrollView.setHorizontalScrollBarEnabled(false);
int playerHeight = (int) getResources().getDimension(R.dimen.qs_media_height);
int padding = (int) getResources().getDimension(R.dimen.qs_media_padding);
LayoutParams lpView = new LayoutParams(LayoutParams.MATCH_PARENT, playerHeight);
lpView.setMarginStart(padding);
lpView.setMarginEnd(padding);
addView(mediaScrollView, lpView);
LayoutParams lpCarousel = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
mMediaCarousel = new LinearLayout(mContext);
mMediaCarousel.setOrientation(LinearLayout.HORIZONTAL);
mediaScrollView.addView(mMediaCarousel, lpCarousel);
mediaScrollView.setVisibility(View.GONE);
HorizontalScrollView mediaScrollView = (HorizontalScrollView) LayoutInflater.from(
mContext).inflate(R.layout.media_carousel, this, false);
mMediaCarousel = mediaScrollView.findViewById(R.id.media_carousel);
addView(mediaScrollView);
} else {
mMediaCarousel = null;
}

View File

@@ -106,7 +106,7 @@ public class QuickQSMediaPlayer {
}
}
});
btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_replay));
btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_play));
btn.setImageTintList(ColorStateList.valueOf(mForegroundColor));
btn.setVisibility(View.VISIBLE);
}
@@ -136,14 +136,25 @@ public class QuickQSMediaPlayer {
* @param actionsContainer a LinearLayout containing the media action buttons
* @param actionsToShow indices of which actions to display in the mini player
* (max 3: Notification.MediaStyle.MAX_MEDIA_BUTTONS_IN_COMPACT)
* @param contentIntent Intent to send when user taps on the view
*/
public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor, int bgColor,
View actionsContainer, int[] actionsToShow) {
Log.d(TAG, "Setting media session: " + token);
View actionsContainer, int[] actionsToShow, PendingIntent contentIntent) {
mToken = token;
mForegroundColor = iconColor;
mBackgroundColor = bgColor;
mController = new MediaController(mContext, token);
String oldPackage = "";
if (mController != null) {
oldPackage = mController.getPackageName();
}
MediaController controller = new MediaController(mContext, token);
boolean samePlayer = mToken.equals(token) && oldPackage.equals(controller.getPackageName());
if (mController != null && !samePlayer && !isPlaying(controller)) {
// Only update if this is a different session and currently playing
return;
}
mController = controller;
MediaMetadata mMediaMetadata = mController.getMetadata();
// Try to find a receiver for the media button that matches this app
@@ -153,7 +164,6 @@ public class QuickQSMediaPlayer {
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();
}
}
@@ -165,6 +175,16 @@ public class QuickQSMediaPlayer {
return;
}
// Action
mMediaNotifView.setOnClickListener(v -> {
try {
contentIntent.send();
mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Pending intent was canceled: " + e.getMessage());
}
});
// Album art
addAlbumArtBackground(mMediaMetadata, mBackgroundColor);
@@ -237,12 +257,12 @@ public class QuickQSMediaPlayer {
* Check whether the media controlled by this player is currently playing
* @return whether it is playing, or false if no controller information
*/
public boolean isPlaying() {
if (mController == null) {
public boolean isPlaying(MediaController controller) {
if (controller == null) {
return false;
}
PlaybackState state = mController.getPlaybackState();
PlaybackState state = controller.getPlaybackState();
if (state == null) {
return false;
}
@@ -261,12 +281,11 @@ 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);
int width = bounds.width();
int height = bounds.height();
Rect bounds = new Rect();
mMediaNotifView.getBoundsOnScreen(bounds);
int width = bounds.width();
int height = bounds.height();
if (albumArt != null && width > 0 && height > 0) {
Bitmap original = albumArt.copy(Bitmap.Config.ARGB_8888, true);
Bitmap scaled = scaleBitmap(original, width, height);
Canvas canvas = new Canvas(scaled);

View File

@@ -85,20 +85,19 @@ public class QuickQSPanel extends QSPanel {
mHorizontalLinearLayout.setClipChildren(false);
mHorizontalLinearLayout.setClipToPadding(false);
LayoutParams lp = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
mTileLayout = new DoubleLineTileLayout(context);
mMediaTileLayout = mTileLayout;
mRegularTileLayout = new HeaderTileLayout(context);
LayoutParams lp = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
lp.setMarginEnd(10);
lp.setMarginStart(0);
mHorizontalLinearLayout.addView((View) mTileLayout, lp);
mMediaPlayer = new QuickQSMediaPlayer(mContext, mHorizontalLinearLayout);
lp.setMarginEnd(0);
lp.setMarginStart(10);
mHorizontalLinearLayout.addView(mMediaPlayer.getView(), lp);
LayoutParams lp2 = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
lp2.setMarginEnd(0);
lp2.setMarginStart(25);
mHorizontalLinearLayout.addView(mMediaPlayer.getView(), lp2);
sDefaultMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);

View File

@@ -28,6 +28,7 @@ import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.metrics.LogMaker;
import android.os.Handler;
import android.service.notification.StatusBarNotification;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -176,27 +177,30 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
final MediaSession.Token token = mRow.getEntry().getSbn().getNotification().extras
.getParcelable(Notification.EXTRA_MEDIA_SESSION);
if (Utils.useQsMediaPlayer(mContext)) {
if (Utils.useQsMediaPlayer(mContext) && token != null) {
final int[] compactActions = mRow.getEntry().getSbn().getNotification().extras
.getIntArray(Notification.EXTRA_COMPACT_ACTIONS);
int tintColor = getNotificationHeader().getOriginalIconColor();
StatusBarWindowController ctrl = Dependency.get(StatusBarWindowController.class);
QuickQSPanel panel = ctrl.getStatusBarView().findViewById(
com.android.systemui.R.id.quick_qs_panel);
StatusBarNotification sbn = mRow.getEntry().getSbn();
Notification notif = sbn.getNotification();
panel.getMediaPlayer().setMediaSession(token,
mRow.getEntry().getSbn().getNotification().getSmallIcon(),
notif.getSmallIcon(),
tintColor,
mBackgroundColor,
mActions,
compactActions);
compactActions,
notif.contentIntent);
QSPanel bigPanel = ctrl.getStatusBarView().findViewById(
com.android.systemui.R.id.quick_settings_panel);
bigPanel.addMediaSession(token,
mRow.getEntry().getSbn().getNotification().getSmallIcon(),
notif.getSmallIcon(),
tintColor,
mBackgroundColor,
mActions,
mRow.getEntry().getSbn());
sbn);
}
boolean showCompactSeekbar = mMediaManager.getShowCompactMediaSeekbar();