Merge "Tapping dream media chip opens media instead of UMO if flag is set." into tm-qpr-dev
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamMediaEntryComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamMediaEntryComplication.java
index 21a51d1..c07d402 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamMediaEntryComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamMediaEntryComplication.java
@@ -18,13 +18,21 @@
import static com.android.systemui.dreams.complication.dagger.DreamMediaEntryComplicationComponent.DreamMediaEntryModule.DREAM_MEDIA_ENTRY_VIEW;
import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_MEDIA_ENTRY_LAYOUT_PARAMS;
+import static com.android.systemui.flags.Flags.DREAM_MEDIA_TAP_TO_OPEN;
+import android.app.PendingIntent;
import android.util.Log;
import android.view.View;
+import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamMediaEntryComplicationComponent;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.media.MediaCarouselController;
import com.android.systemui.media.dream.MediaDreamComplication;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
@@ -87,6 +95,15 @@
private final DreamOverlayStateController mDreamOverlayStateController;
private final MediaDreamComplication mMediaComplication;
+ private final MediaCarouselController mMediaCarouselController;
+
+ private final ActivityStarter mActivityStarter;
+ private final ActivityIntentHelper mActivityIntentHelper;
+ private final KeyguardStateController mKeyguardStateController;
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+
+ private final FeatureFlags mFeatureFlags;
+ private boolean mIsTapToOpenEnabled;
private boolean mMediaComplicationAdded;
@@ -94,15 +111,28 @@
DreamMediaEntryViewController(
@Named(DREAM_MEDIA_ENTRY_VIEW) View view,
DreamOverlayStateController dreamOverlayStateController,
- MediaDreamComplication mediaComplication) {
+ MediaDreamComplication mediaComplication,
+ MediaCarouselController mediaCarouselController,
+ ActivityStarter activityStarter,
+ ActivityIntentHelper activityIntentHelper,
+ KeyguardStateController keyguardStateController,
+ NotificationLockscreenUserManager lockscreenUserManager,
+ FeatureFlags featureFlags) {
super(view);
mDreamOverlayStateController = dreamOverlayStateController;
mMediaComplication = mediaComplication;
+ mMediaCarouselController = mediaCarouselController;
+ mActivityStarter = activityStarter;
+ mActivityIntentHelper = activityIntentHelper;
+ mKeyguardStateController = keyguardStateController;
+ mLockscreenUserManager = lockscreenUserManager;
+ mFeatureFlags = featureFlags;
mView.setOnClickListener(this::onClickMediaEntry);
}
@Override
protected void onViewAttached() {
+ mIsTapToOpenEnabled = mFeatureFlags.isEnabled(DREAM_MEDIA_TAP_TO_OPEN);
}
@Override
@@ -113,6 +143,31 @@
private void onClickMediaEntry(View v) {
if (DEBUG) Log.d(TAG, "media entry complication tapped");
+ if (mIsTapToOpenEnabled) {
+ final PendingIntent clickIntent =
+ mMediaCarouselController.getCurrentVisibleMediaContentIntent();
+
+ if (clickIntent == null) {
+ return;
+ }
+
+ // See StatusBarNotificationActivityStarter#onNotificationClicked
+ final boolean showOverLockscreen = mKeyguardStateController.isShowing()
+ && mActivityIntentHelper.wouldShowOverLockscreen(clickIntent.getIntent(),
+ mLockscreenUserManager.getCurrentUserId());
+
+ if (showOverLockscreen) {
+ mActivityStarter.startActivity(clickIntent.getIntent(),
+ /* dismissShade */ true,
+ /* animationController */ null,
+ /* showOverLockscreenWhenLocked */ true);
+ } else {
+ mActivityStarter.postStartActivityDismissingKeyguard(clickIntent, null);
+ }
+
+ return;
+ }
+
if (!mMediaComplicationAdded) {
addMediaComplication();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 938332d..48f5f9e 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -200,7 +200,8 @@
public static final UnreleasedFlag MEDIA_SESSION_ACTIONS = new UnreleasedFlag(901);
public static final ReleasedFlag MEDIA_NEARBY_DEVICES = new ReleasedFlag(903);
public static final ReleasedFlag MEDIA_MUTE_AWAIT = new ReleasedFlag(904);
- public static final UnreleasedFlag MEDIA_DREAM_COMPLICATION = new UnreleasedFlag(905);
+ public static final UnreleasedFlag DREAM_MEDIA_COMPLICATION = new UnreleasedFlag(905);
+ public static final UnreleasedFlag DREAM_MEDIA_TAP_TO_OPEN = new UnreleasedFlag(906);
// 1000 - dock
public static final ReleasedFlag SIMULATE_DOCK_THROUGH_CHARGING =
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index e25f5da..f8c6a57 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -1,5 +1,6 @@
package com.android.systemui.media
+import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
@@ -945,6 +946,11 @@
mediaManager.onSwipeToDismiss()
}
+ fun getCurrentVisibleMediaContentIntent(): PendingIntent? {
+ return MediaPlayerData.playerKeys()
+ .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)?.data?.clickIntent
+ }
+
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.apply {
println("keysNeedRemoval: $keysNeedRemoval")
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
index dc1488e..53b4d43 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
@@ -16,7 +16,7 @@
package com.android.systemui.media.dream;
-import static com.android.systemui.flags.Flags.MEDIA_DREAM_COMPLICATION;
+import static com.android.systemui.flags.Flags.DREAM_MEDIA_COMPLICATION;
import android.content.Context;
import android.util.Log;
@@ -77,7 +77,7 @@
public void onMediaDataLoaded(@NonNull String key, @Nullable String oldKey,
@NonNull MediaData data, boolean immediately, int receivedSmartspaceCardLatency,
boolean isSsReactivated) {
- if (!mFeatureFlags.isEnabled(MEDIA_DREAM_COMPLICATION)) {
+ if (!mFeatureFlags.isEnabled(DREAM_MEDIA_COMPLICATION)) {
return;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamMediaEntryComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamMediaEntryComplicationTest.java
index bc94440..522b5b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamMediaEntryComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamMediaEntryComplicationTest.java
@@ -16,17 +16,28 @@
package com.android.systemui.dreams.complication;
-import static org.mockito.Mockito.verify;
+import static com.android.systemui.flags.Flags.DREAM_MEDIA_TAP_TO_OPEN;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.PendingIntent;
+import android.content.Intent;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
import androidx.test.filters.SmallTest;
+import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.media.MediaCarouselController;
import com.android.systemui.media.dream.MediaDreamComplication;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
import org.junit.Test;
@@ -48,21 +59,52 @@
@Mock
private MediaDreamComplication mMediaComplication;
+ @Mock
+ private MediaCarouselController mMediaCarouselController;
+
+ @Mock
+ private ActivityStarter mActivityStarter;
+
+ @Mock
+ private ActivityIntentHelper mActivityIntentHelper;
+
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
+
+ @Mock
+ private NotificationLockscreenUserManager mLockscreenUserManager;
+
+ @Mock
+ private FeatureFlags mFeatureFlags;
+
+ @Mock
+ private PendingIntent mPendingIntent;
+
+ private final Intent mIntent = new Intent("android.test.TEST_ACTION");
+ private final Integer mCurrentUserId = 99;
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ when(mFeatureFlags.isEnabled(DREAM_MEDIA_TAP_TO_OPEN)).thenReturn(false);
}
/**
* Ensures clicking media entry chip adds/removes media complication.
*/
@Test
- public void testClick() {
+ public void testClickToOpenUMO() {
final DreamMediaEntryComplication.DreamMediaEntryViewController viewController =
new DreamMediaEntryComplication.DreamMediaEntryViewController(
mView,
mDreamOverlayStateController,
- mMediaComplication);
+ mMediaComplication,
+ mMediaCarouselController,
+ mActivityStarter,
+ mActivityIntentHelper,
+ mKeyguardStateController,
+ mLockscreenUserManager,
+ mFeatureFlags);
final ArgumentCaptor<View.OnClickListener> clickListenerCaptor =
ArgumentCaptor.forClass(View.OnClickListener.class);
@@ -85,10 +127,90 @@
new DreamMediaEntryComplication.DreamMediaEntryViewController(
mView,
mDreamOverlayStateController,
- mMediaComplication);
+ mMediaComplication,
+ mMediaCarouselController,
+ mActivityStarter,
+ mActivityIntentHelper,
+ mKeyguardStateController,
+ mLockscreenUserManager,
+ mFeatureFlags);
viewController.onViewDetached();
verify(mView).setSelected(false);
verify(mDreamOverlayStateController).removeComplication(mMediaComplication);
}
+
+ /**
+ * Ensures clicking media entry chip opens media when flag is set.
+ */
+ @Test
+ public void testClickToOpenMediaOverLockscreen() {
+ when(mFeatureFlags.isEnabled(DREAM_MEDIA_TAP_TO_OPEN)).thenReturn(true);
+
+ when(mMediaCarouselController.getCurrentVisibleMediaContentIntent()).thenReturn(
+ mPendingIntent);
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mPendingIntent.getIntent()).thenReturn(mIntent);
+ when(mLockscreenUserManager.getCurrentUserId()).thenReturn(mCurrentUserId);
+
+ final DreamMediaEntryComplication.DreamMediaEntryViewController viewController =
+ new DreamMediaEntryComplication.DreamMediaEntryViewController(
+ mView,
+ mDreamOverlayStateController,
+ mMediaComplication,
+ mMediaCarouselController,
+ mActivityStarter,
+ mActivityIntentHelper,
+ mKeyguardStateController,
+ mLockscreenUserManager,
+ mFeatureFlags);
+ viewController.onViewAttached();
+
+ final ArgumentCaptor<View.OnClickListener> clickListenerCaptor =
+ ArgumentCaptor.forClass(View.OnClickListener.class);
+ verify(mView).setOnClickListener(clickListenerCaptor.capture());
+
+ when(mActivityIntentHelper.wouldShowOverLockscreen(mIntent, mCurrentUserId)).thenReturn(
+ true);
+
+ clickListenerCaptor.getValue().onClick(mView);
+ verify(mActivityStarter).startActivity(mIntent, true, null, true);
+ }
+
+ /**
+ * Ensures clicking media entry chip opens media when flag is set.
+ */
+ @Test
+ public void testClickToOpenMediaDismissingLockscreen() {
+ when(mFeatureFlags.isEnabled(DREAM_MEDIA_TAP_TO_OPEN)).thenReturn(true);
+
+ when(mMediaCarouselController.getCurrentVisibleMediaContentIntent()).thenReturn(
+ mPendingIntent);
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mPendingIntent.getIntent()).thenReturn(mIntent);
+ when(mLockscreenUserManager.getCurrentUserId()).thenReturn(mCurrentUserId);
+
+ final DreamMediaEntryComplication.DreamMediaEntryViewController viewController =
+ new DreamMediaEntryComplication.DreamMediaEntryViewController(
+ mView,
+ mDreamOverlayStateController,
+ mMediaComplication,
+ mMediaCarouselController,
+ mActivityStarter,
+ mActivityIntentHelper,
+ mKeyguardStateController,
+ mLockscreenUserManager,
+ mFeatureFlags);
+ viewController.onViewAttached();
+
+ final ArgumentCaptor<View.OnClickListener> clickListenerCaptor =
+ ArgumentCaptor.forClass(View.OnClickListener.class);
+ verify(mView).setOnClickListener(clickListenerCaptor.capture());
+
+ when(mActivityIntentHelper.wouldShowOverLockscreen(mIntent, mCurrentUserId)).thenReturn(
+ false);
+
+ clickListenerCaptor.getValue().onClick(mView);
+ verify(mActivityStarter).postStartActivityDismissingKeyguard(mPendingIntent, null);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
index 5dd1cfc..e3e3b74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import android.app.PendingIntent
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
@@ -43,6 +44,7 @@
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
+import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when` as whenever
@@ -366,7 +368,7 @@
playerIndex,
mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
)
- assertEquals( playerIndex, 0)
+ assertEquals(playerIndex, 0)
// Replaying the same media player one more time.
// And check that the card stays in its position.
@@ -402,4 +404,44 @@
visualStabilityCallback.value.onReorderingAllowed()
assertEquals(true, result)
}
+
+ @Test
+ fun testGetCurrentVisibleMediaContentIntent() {
+ val clickIntent1 = mock(PendingIntent::class.java)
+ val player1 = Triple("player1",
+ DATA.copy(clickIntent = clickIntent1),
+ 1000L)
+ clock.setCurrentTimeMillis(player1.third)
+ MediaPlayerData.addMediaPlayer(player1.first,
+ player1.second.copy(notificationKey = player1.first),
+ panel, clock, isSsReactivated = false)
+
+ assertEquals(mediaCarouselController.getCurrentVisibleMediaContentIntent(), clickIntent1)
+
+ val clickIntent2 = mock(PendingIntent::class.java)
+ val player2 = Triple("player2",
+ DATA.copy(clickIntent = clickIntent2),
+ 2000L)
+ clock.setCurrentTimeMillis(player2.third)
+ MediaPlayerData.addMediaPlayer(player2.first,
+ player2.second.copy(notificationKey = player2.first),
+ panel, clock, isSsReactivated = false)
+
+ // mediaCarouselScrollHandler.visibleMediaIndex is unchanged (= 0), and the new player is
+ // added to the front because it was active more recently.
+ assertEquals(mediaCarouselController.getCurrentVisibleMediaContentIntent(), clickIntent2)
+
+ val clickIntent3 = mock(PendingIntent::class.java)
+ val player3 = Triple("player3",
+ DATA.copy(clickIntent = clickIntent3),
+ 500L)
+ clock.setCurrentTimeMillis(player3.third)
+ MediaPlayerData.addMediaPlayer(player3.first,
+ player3.second.copy(notificationKey = player3.first),
+ panel, clock, isSsReactivated = false)
+
+ // mediaCarouselScrollHandler.visibleMediaIndex is unchanged (= 0), and the new player is
+ // added to the end because it was active less recently.
+ assertEquals(mediaCarouselController.getCurrentVisibleMediaContentIntent(), clickIntent2)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
index 0bfc034..2f52950 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
@@ -16,7 +16,7 @@
package com.android.systemui.media.dream;
-import static com.android.systemui.flags.Flags.MEDIA_DREAM_COMPLICATION;
+import static com.android.systemui.flags.Flags.DREAM_MEDIA_COMPLICATION;
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.any;
@@ -68,7 +68,7 @@
public void setup() {
MockitoAnnotations.initMocks(this);
- when(mFeatureFlags.isEnabled(MEDIA_DREAM_COMPLICATION)).thenReturn(true);
+ when(mFeatureFlags.isEnabled(DREAM_MEDIA_COMPLICATION)).thenReturn(true);
}
@Test
@@ -137,7 +137,7 @@
@Test
public void testOnMediaDataLoaded_mediaComplicationDisabled_doesNotAddComplication() {
- when(mFeatureFlags.isEnabled(MEDIA_DREAM_COMPLICATION)).thenReturn(false);
+ when(mFeatureFlags.isEnabled(DREAM_MEDIA_COMPLICATION)).thenReturn(false);
final MediaDreamSentinel sentinel = new MediaDreamSentinel(mContext, mMediaDataManager,
mDreamOverlayStateController, mMediaEntryComplication, mFeatureFlags);