From c7d1402707ea106b58fa9297585ae22d5c09d7f9 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Fri, 16 Feb 2024 10:14:15 -0500 Subject: Block clipboard UI when device is locked In some situations (see bug for details) it's possible to enter the clipboard even while the device is locked, and from there access the provided intents. Users should not be able to access intents from this state; this change adds an additional check before showing the interactive UI. The behavior is identical to what we do when user setup is not complete (b/251778420): we show a toast to note that content has been copied, but no interactive UI. Interactive UI is only blocked when device is locked (i.e. requiring pin entry/password/biometric/etc), not if the keyguard is up but trivially dismissable. Bug: 317048495 Test: atest ClipboardListenerTest; verification using steps in linked bug as well as forcing text content to appear client-side, to verify that even if text content is received in the ClipboardListener, no interactive UI appears. Change-Id: I1a48cbe64852dce3fba69915ca11dad8878f66eb Merged-In: I1a48cbe64852dce3fba69915ca11dad8878f66eb (cherry picked from commit 2976ca86d5c5be558191a1fe706d4cd0d7ccdecb) --- .../clipboardoverlay/ClipboardListener.java | 13 ++++-- .../clipboardoverlay/ClipboardListenerTest.java | 47 +++++++++++++++++++++- .../ClipboardOverlayEventTest.java | 5 ++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index da602caac0dc..cdf58db58a15 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -25,6 +25,7 @@ import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBO import static com.google.android.setupcompat.util.WizardManagerHelper.SETTINGS_SECURE_USER_SETUP_COMPLETE; +import android.app.KeyguardManager; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -59,18 +60,21 @@ public class ClipboardListener extends CoreStartable private final ClipboardOverlayControllerFactory mOverlayFactory; private final ClipboardToast mClipboardToast; private final ClipboardManager mClipboardManager; + private final KeyguardManager mKeyguardManager; private final UiEventLogger mUiEventLogger; private ClipboardOverlayController mClipboardOverlayController; @Inject public ClipboardListener(Context context, DeviceConfigProxy deviceConfigProxy, ClipboardOverlayControllerFactory overlayFactory, ClipboardManager clipboardManager, - ClipboardToast clipboardToast,UiEventLogger uiEventLogger) { + ClipboardToast clipboardToast, KeyguardManager keyguardManager, + UiEventLogger uiEventLogger) { super(context); mDeviceConfig = deviceConfigProxy; mOverlayFactory = overlayFactory; mClipboardToast = clipboardToast; mClipboardManager = clipboardManager; + mKeyguardManager = keyguardManager; mUiEventLogger = uiEventLogger; } @@ -96,8 +100,11 @@ public class ClipboardListener extends CoreStartable return; } - if (!isUserSetupComplete()) { - // just show a toast, user should not access intents from this state + // user should not access intents before setup or while device is locked + if (mKeyguardManager.isDeviceLocked() + || !isUserSetupComplete() + || clipData == null // shouldn't happen, but just in case + || clipData.getItemCount() == 0) { if (shouldShowToast(clipData)) { mUiEventLogger.log(CLIPBOARD_TOAST_SHOWN, 0, clipSource); mClipboardToast.showCopiedToast(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java index 86402b3202d4..11803d68d5ac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import android.app.KeyguardManager; import android.content.ClipData; import android.content.ClipDescription; import android.content.ClipboardManager; @@ -51,6 +52,8 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; + @SmallTest @RunWith(AndroidJUnit4.class) public class ClipboardListenerTest extends SysuiTestCase { @@ -60,6 +63,8 @@ public class ClipboardListenerTest extends SysuiTestCase { @Mock private ClipboardOverlayControllerFactory mClipboardOverlayControllerFactory; @Mock + private KeyguardManager mKeyguardManager; + @Mock private ClipboardOverlayController mOverlayController; @Mock private ClipboardToast mClipboardToast; @@ -97,7 +102,7 @@ public class ClipboardListenerTest extends SysuiTestCase { mClipboardListener = new ClipboardListener(getContext(), mDeviceConfigProxy, mClipboardOverlayControllerFactory, mClipboardManager,mClipboardToast, - mUiEventLogger); + mKeyguardManager, mUiEventLogger); } @Test @@ -201,4 +206,44 @@ public class ClipboardListenerTest extends SysuiTestCase { verify(mClipboardToast, times(1)).showCopiedToast(); verifyZeroInteractions(mClipboardOverlayControllerFactory); } + + @Test + public void test_deviceLocked_showsToast() { + when(mKeyguardManager.isDeviceLocked()).thenReturn(true); + + mClipboardListener.start(); + mClipboardListener.onPrimaryClipChanged(); + + verify(mUiEventLogger, times(1)).log( + ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN, 0, mSampleSource); + verify(mClipboardToast, times(1)).showCopiedToast(); + verifyZeroInteractions(mClipboardOverlayControllerFactory); + } + + @Test + public void test_nullClipData_showsNothing() { + when(mClipboardManager.getPrimaryClip()).thenReturn(null); + + mClipboardListener.start(); + mClipboardListener.onPrimaryClipChanged(); + + verifyZeroInteractions(mUiEventLogger); + verifyZeroInteractions(mClipboardToast); + verifyZeroInteractions(mClipboardOverlayControllerFactory); + } + + @Test + public void test_emptyClipData_showsToast() { + ClipDescription description = new ClipDescription("Test", new String[0]); + ClipData noItems = new ClipData(description, new ArrayList<>()); + when(mClipboardManager.getPrimaryClip()).thenReturn(noItems); + + mClipboardListener.start(); + mClipboardListener.onPrimaryClipChanged(); + + verify(mUiEventLogger, times(1)).log( + ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN, 0, mSampleSource); + verify(mClipboardToast, times(1)).showCopiedToast(); + verifyZeroInteractions(mClipboardOverlayControllerFactory); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java index 5e2f6a0f7a70..022d1a2b411b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.KeyguardManager; import android.content.ClipData; import android.content.ClipboardManager; import android.provider.DeviceConfig; @@ -51,6 +52,8 @@ public class ClipboardOverlayEventTest extends SysuiTestCase { @Mock private ClipboardOverlayController mOverlayController; @Mock + private KeyguardManager mKeyguardManager; + @Mock private ClipboardToast mClipboardToast; @Mock private UiEventLogger mUiEventLogger; @@ -78,7 +81,7 @@ public class ClipboardOverlayEventTest extends SysuiTestCase { mClipboardListener = new ClipboardListener(getContext(), deviceConfigProxy, mClipboardOverlayControllerFactory, mClipboardManager, mClipboardToast, - mUiEventLogger); + mKeyguardManager, mUiEventLogger); } @Test -- cgit v1.2.3-59-g8ed1b