summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Beth Thibodeau <ethibodeau@google.com> 2020-04-28 16:29:36 -0400
committer Beth Thibodeau <ethibodeau@google.com> 2020-04-29 04:23:09 +0000
commitd664de2cd5eba8d95092b4ea68540e7f91c2081f (patch)
treed1f93bb5623f9eedd7eb550f2489a5e713c38854
parent0920ccba1a00a468cd2364e1603e1b709e2c7323 (diff)
Update when media controls get cleared
Some apps include an action to dismiss a media notification, so we should listen for that happening and clear controls in that case. Also, remove STATE_CONNECTING as a condition to clear controls - This was originally added in ag/11056932 as a workaround for an issue with YouTube cast sessions. However this caused issues with other apps like Spotify which set STATE_CONNECTING while still active. YT was using that as a workaround for legacy behavior and will update to use STATE_NONE for R+ builds (b/155213698). In the meantime, listening for when the notification is removed will also work to clear YT's controls as expected. Fixes: 154953276 Fixes: 155029855 Test: manual Change-Id: Ie9320e1406c1f457a39f67705ec1ffcb3a983488
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java5
5 files changed, 51 insertions, 10 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index ddc9c9d7c314..5ccfd8c516ad 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -124,11 +124,7 @@ public class MediaControlPanel {
@Override
public void onPlaybackStateChanged(PlaybackState state) {
final int s = state != null ? state.getState() : PlaybackState.STATE_NONE;
- // When the playback state is NONE or CONNECTING, transition the player to the
- // resumption state. State CONNECTING needs to be considered for Cast sessions. Ending
- // a cast session in YT results in the CONNECTING state, which makes sense if you
- // thinking of the session as waiting to connect to another cast device.
- if (s == PlaybackState.STATE_NONE || s == PlaybackState.STATE_CONNECTING) {
+ if (s == PlaybackState.STATE_NONE) {
Log.d(TAG, "playback state change will trigger resumption, state=" + state);
clearControls();
makeInactive();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java
index 302b84203641..9e532868427f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java
@@ -82,7 +82,7 @@ public class QSMediaBrowser {
public void onChildrenLoaded(String parentId,
List<MediaBrowser.MediaItem> children) {
if (children.size() == 0) {
- Log.e(TAG, "No children found");
+ Log.e(TAG, "No children found for " + mComponentName);
return;
}
// We ask apps to return a playable item as the first child when sending
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index cb3d5116a9cd..121e2aa94954 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -53,6 +53,7 @@ import android.widget.LinearLayout;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.NotificationVisibility;
import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.media.InfoMediaManager;
@@ -75,6 +76,9 @@ import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.settings.BrightnessController;
import com.android.systemui.settings.ToggleSliderView;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
import com.android.systemui.tuner.TunerService;
@@ -116,6 +120,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private final DelayableExecutor mBackgroundExecutor;
private boolean mUpdateCarousel = false;
private ActivityStarter mActivityStarter;
+ private NotificationEntryManager mNotificationEntryManager;
protected boolean mExpanded;
protected boolean mListening;
@@ -151,6 +156,15 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
};
+ private final NotificationEntryListener mNotificationEntryListener =
+ new NotificationEntryListener() {
+ @Override
+ public void onEntryRemoved(NotificationEntry entry, NotificationVisibility visibility,
+ boolean removedByUser, int reason) {
+ checkToRemoveMediaNotification(entry);
+ }
+ };
+
@Inject
public QSPanel(
@Named(VIEW_CONTEXT) Context context,
@@ -161,7 +175,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
@Main Executor foregroundExecutor,
@Background DelayableExecutor backgroundExecutor,
@Nullable LocalBluetoothManager localBluetoothManager,
- ActivityStarter activityStarter
+ ActivityStarter activityStarter,
+ NotificationEntryManager entryManager
) {
super(context, attrs);
mContext = context;
@@ -172,6 +187,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mLocalBluetoothManager = localBluetoothManager;
mBroadcastDispatcher = broadcastDispatcher;
mActivityStarter = activityStarter;
+ mNotificationEntryManager = entryManager;
setOrientation(VERTICAL);
@@ -407,6 +423,27 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mHasLoadedMediaControls = true;
}
+ private void checkToRemoveMediaNotification(NotificationEntry entry) {
+ if (!useQsMediaPlayer(mContext)) {
+ return;
+ }
+
+ if (!entry.isMediaNotification()) {
+ return;
+ }
+
+ // If this entry corresponds to an existing set of controls, clear the controls
+ // This will handle apps that use an action to clear their notification
+ for (QSMediaPlayer p : mMediaPlayers) {
+ if (p.getKey() != null && p.getKey().equals(entry.getKey())) {
+ Log.d(TAG, "Clearing controls since notification removed " + entry.getKey());
+ p.clearControls();
+ return;
+ }
+ }
+ Log.d(TAG, "Media notification removed but no player found " + entry.getKey());
+ }
+
protected void addDivider() {
mDivider = LayoutInflater.from(mContext).inflate(R.layout.qs_divider, this, false);
mDivider.setBackgroundColor(Utils.applyAlpha(mDivider.getAlpha(),
@@ -473,6 +510,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
loadMediaResumptionControls();
}
}
+ mNotificationEntryManager.addNotificationEntryListener(mNotificationEntryListener);
}
@Override
@@ -489,6 +527,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
mDumpManager.unregisterDumpable(getDumpableTag());
mBroadcastDispatcher.unregisterReceiver(mUserChangeReceiver);
+ mNotificationEntryManager.removeNotificationEntryListener(mNotificationEntryListener);
super.onDetachedFromWindow();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index becf9da800b3..38dea657242d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -40,6 +40,7 @@ import com.android.systemui.plugins.qs.QSTile.SignalState;
import com.android.systemui.plugins.qs.QSTile.State;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.Utils;
@@ -86,10 +87,12 @@ public class QuickQSPanel extends QSPanel {
@Main Executor foregroundExecutor,
@Background DelayableExecutor backgroundExecutor,
@Nullable LocalBluetoothManager localBluetoothManager,
- ActivityStarter activityStarter
+ ActivityStarter activityStarter,
+ NotificationEntryManager entryManager
) {
super(context, attrs, dumpManager, broadcastDispatcher, qsLogger,
- foregroundExecutor, backgroundExecutor, localBluetoothManager, activityStarter);
+ foregroundExecutor, backgroundExecutor, localBluetoothManager, activityStarter,
+ entryManager);
if (mFooter != null) {
removeView(mFooter.getView());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 9a32b1db2ff3..392adf99e511 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -44,6 +44,7 @@ import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.util.concurrency.DelayableExecutor;
import org.junit.Before;
@@ -91,6 +92,8 @@ public class QSPanelTest extends SysuiTestCase {
private LocalBluetoothManager mLocalBluetoothManager;
@Mock
private ActivityStarter mActivityStarter;
+ @Mock
+ private NotificationEntryManager mEntryManager;
@Before
public void setup() throws Exception {
@@ -101,7 +104,7 @@ public class QSPanelTest extends SysuiTestCase {
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher,
mQSLogger, mForegroundExecutor, mBackgroundExecutor,
- mLocalBluetoothManager, mActivityStarter);
+ mLocalBluetoothManager, mActivityStarter, mEntryManager);
// Provides a parent with non-zero size for QSPanel
mParentView = new FrameLayout(mContext);
mParentView.addView(mQsPanel);