From f1e2a2e9758b52bb1f2cc7c782c59c7f6babbda0 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Tue, 12 Apr 2022 23:38:02 +0000 Subject: [PATCH] Don't bring up keyguard when activity can show over lockscreen Use the same logic as notification content intent opening - if the activity that the intent goes to is allowed to open over the lockscreen, don't bring up keyguard when user taps on the media control view Bug: 220035696 Test: manual with test app Test: atest MediaControlPanelTest Change-Id: Iacc6887ac10bdec6e6c93f43e136c7477d1f2e1a --- .../systemui/media/MediaControlPanel.java | 32 ++++++++++- .../systemui/media/MediaControlPanelTest.kt | 55 ++++++++++++++++++- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 1b6d1d5825da2..f3120e55371c9 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -61,6 +61,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.InstanceId; import com.android.settingslib.widget.AdaptiveIcon; +import com.android.systemui.ActivityIntentHelper; import com.android.systemui.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.GhostedViewLaunchAnimatorController; @@ -73,6 +74,8 @@ import com.android.systemui.monet.ColorScheme; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shared.system.SysUiStatsLog; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.animation.TransitionLayout; import com.android.systemui.util.time.SystemClock; @@ -161,6 +164,10 @@ public class MediaControlPanel { private int mArtworkBoundId = 0; private int mArtworkNextBindRequestId = 0; + private final KeyguardStateController mKeyguardStateController; + private final ActivityIntentHelper mActivityIntentHelper; + private final NotificationLockscreenUserManager mLockscreenUserManager; + // Used for logging. protected boolean mIsImpressed = false; private SystemClock mSystemClock; @@ -196,7 +203,10 @@ public class MediaControlPanel { MediaCarouselController mediaCarouselController, FalsingManager falsingManager, SystemClock systemClock, - MediaUiEventLogger logger) { + MediaUiEventLogger logger, + KeyguardStateController keyguardStateController, + ActivityIntentHelper activityIntentHelper, + NotificationLockscreenUserManager lockscreenUserManager) { mContext = context; mBackgroundExecutor = backgroundExecutor; mMainExecutor = mainExecutor; @@ -210,6 +220,9 @@ public class MediaControlPanel { mFalsingManager = falsingManager; mSystemClock = systemClock; mLogger = logger; + mKeyguardStateController = keyguardStateController; + mActivityIntentHelper = activityIntentHelper; + mLockscreenUserManager = lockscreenUserManager; mSeekBarViewModel.setLogSeek(() -> { if (mPackageName != null && mInstanceId != null) { @@ -416,8 +429,21 @@ public class MediaControlPanel { if (mMediaViewController.isGutsVisible()) return; mLogger.logTapContentView(mUid, mPackageName, mInstanceId); logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT); - mActivityStarter.postStartActivityDismissingKeyguard(clickIntent, - buildLaunchAnimatorController(mMediaViewHolder.getPlayer())); + + // See StatusBarNotificationActivityStarter#onNotificationClicked + 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, + buildLaunchAnimatorController(mMediaViewHolder.getPlayer())); + } }); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index a39ae6c231bda..f50e40b38fb32 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -52,17 +52,22 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.LiveData import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId +import com.android.systemui.ActivityIntentHelper import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.media.dialog.MediaOutputDialogFactory import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager +import com.android.systemui.statusbar.NotificationLockscreenUserManager +import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.KotlinArgumentCaptor import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.nullable import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat @@ -76,7 +81,6 @@ import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyLong import org.mockito.Mock -import org.mockito.Mockito.any import org.mockito.Mockito.anyString import org.mockito.Mockito.mock import org.mockito.Mockito.never @@ -160,6 +164,9 @@ public class MediaControlPanelTest : SysuiTestCase() { @Mock private lateinit var instanceId: InstanceId @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var applicationInfo: ApplicationInfo + @Mock private lateinit var keyguardStateController: KeyguardStateController + @Mock private lateinit var activityIntentHelper: ActivityIntentHelper + @Mock private lateinit var lockscreenUserManager: NotificationLockscreenUserManager @Mock private lateinit var recommendationViewHolder: RecommendationViewHolder @Mock private lateinit var smartspaceAction: SmartspaceAction @@ -199,7 +206,10 @@ public class MediaControlPanelTest : SysuiTestCase() { mediaCarouselController, falsingManager, clock, - logger) { + logger, + keyguardStateController, + activityIntentHelper, + lockscreenUserManager) { override fun loadAnimator( animId: Int, otionInterpolator: Interpolator, @@ -1060,6 +1070,47 @@ public class MediaControlPanelTest : SysuiTestCase() { verify(logger).logSeek(anyInt(), eq(PACKAGE), eq(instanceId)) } + @Test + fun tapContentView_showOverLockscreen_openActivity() { + // WHEN we are on lockscreen and this activity can show over lockscreen + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(activityIntentHelper.wouldShowOverLockscreen(any(), any())).thenReturn(true) + + val clickIntent = mock(Intent::class.java) + val pendingIntent = mock(PendingIntent::class.java) + whenever(pendingIntent.intent).thenReturn(clickIntent) + val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java) + val data = mediaData.copy(clickIntent = pendingIntent) + player.attachPlayer(viewHolder) + player.bindPlayer(data, KEY) + verify(viewHolder.player).setOnClickListener(captor.capture()) + + // THEN it shows without dismissing keyguard first + captor.value.onClick(viewHolder.player) + verify(activityStarter).startActivity(eq(clickIntent), eq(true), + nullable(), eq(true)) + } + + @Test + fun tapContentView_noShowOverLockscreen_dismissKeyguard() { + // WHEN we are on lockscreen and the activity cannot show over lockscreen + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(activityIntentHelper.wouldShowOverLockscreen(any(), any())).thenReturn(false) + + val clickIntent = mock(Intent::class.java) + val pendingIntent = mock(PendingIntent::class.java) + whenever(pendingIntent.intent).thenReturn(clickIntent) + val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java) + val data = mediaData.copy(clickIntent = pendingIntent) + player.attachPlayer(viewHolder) + player.bindPlayer(data, KEY) + verify(viewHolder.player).setOnClickListener(captor.capture()) + + // THEN keyguard has to be dismissed + captor.value.onClick(viewHolder.player) + verify(activityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent), any()) + } + @Test fun recommendation_gutsClosed_longPressOpens() { player.attachRecommendation(recommendationViewHolder)