From 525fd252966b81006e1da7a059b581752aed7a0a Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Fri, 13 Aug 2021 19:33:02 -0400 Subject: [PATCH] Disable smart lock when in power menu on lock screen When entering the power menu, if the user is on the lock screen and currently has smart lock on, disable smart lock and show a message Fixes: 185618953 Test: atest com.android.systemui.globalactions Test: manual Change-Id: Id353faa1176882b6b9dfb9acd72288a3e0173aa0 Merged-In: Id353faa1176882b6b9dfb9acd72288a3e0173aa0 --- .../res/layout/global_actions_grid_lite.xml | 14 ++-- .../res/layout/global_actions_toast.xml | 44 +++++++++++++ packages/SystemUI/res/values/dimens.xml | 1 + packages/SystemUI/res/values/strings.xml | 2 + .../globalactions/GlobalActionsDialog.java | 15 +++-- .../GlobalActionsDialogLite.java | 64 ++++++++++++++++++- .../GlobalActionsDialogLiteTest.java | 33 +++++++++- .../GlobalActionsDialogTest.java | 5 +- 8 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 packages/SystemUI/res/layout/global_actions_toast.xml diff --git a/packages/SystemUI/res/layout/global_actions_grid_lite.xml b/packages/SystemUI/res/layout/global_actions_grid_lite.xml index 2430eec776781..5588fd391681e 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_lite.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_lite.xml @@ -13,13 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. --> - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + android:layout_weight="1"> - + diff --git a/packages/SystemUI/res/layout/global_actions_toast.xml b/packages/SystemUI/res/layout/global_actions_toast.xml new file mode 100644 index 0000000000000..1f0899623ddf8 --- /dev/null +++ b/packages/SystemUI/res/layout/global_actions_toast.xml @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index b13b34c8fb313..d4a414a84d367 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1138,6 +1138,7 @@ 38dp 28dp 24dp + 32dp diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 47f4740613010..a93eaab899241 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -211,6 +211,8 @@ Screenshot + + Smart Lock disabled diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 04a0226aa0b4c..df6aa348ed848 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -62,6 +62,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.view.RotationPolicy; import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.animation.Interpolators; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -173,7 +174,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite SysUiState sysUiState, @Main Handler handler, PackageManager packageManager, - Optional statusBarOptional) { + Optional statusBarOptional, + KeyguardUpdateMonitor keyguardUpdateMonitor) { super(context, windowManagerFuncs, @@ -204,7 +206,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite sysUiState, handler, packageManager, - statusBarOptional); + statusBarOptional, + keyguardUpdateMonitor); mLockPatternUtils = lockPatternUtils; mKeyguardStateController = keyguardStateController; @@ -266,7 +269,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite this::getWalletViewController, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter, getEventLogger(), - getStatusBar()); + getStatusBar(), getKeyguardUpdateMonitor(), mLockPatternUtils); if (shouldShowLockMessage(dialog)) { dialog.showLockMessage(); @@ -334,11 +337,13 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite NotificationShadeWindowController notificationShadeWindowController, SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing, MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger, - Optional statusBarOptional) { + Optional statusBarOptional, KeyguardUpdateMonitor keyguardUpdateMonitor, + LockPatternUtils lockPatternUtils) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions, adapter, overflowAdapter, sysuiColorExtractor, statusBarService, notificationShadeWindowController, sysuiState, onRotateCallback, - keyguardShowing, powerAdapter, uiEventLogger, statusBarOptional); + keyguardShowing, powerAdapter, uiEventLogger, statusBarOptional, + keyguardUpdateMonitor, lockPatternUtils); mWalletFactory = walletFactory; // Update window attributes diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index 6cd5f91653fc2..b06b024a63a46 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -84,6 +84,7 @@ import android.view.Window; import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ImageView.ScaleType; @@ -108,6 +109,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.EmergencyAffordanceManager; import com.android.internal.util.ScreenshotHelper; import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.MultiListLayout; import com.android.systemui.MultiListLayout.MultiListAdapter; import com.android.systemui.animation.Interpolators; @@ -171,6 +173,11 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency"; static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot"; + // See NotificationManagerService#scheduleDurationReachedLocked + private static final long TOAST_FADE_TIME = 333; + // See NotificationManagerService.LONG_DELAY + private static final int TOAST_VISIBLE_TIME = 3500; + private final Context mContext; private final GlobalActionsManager mWindowManagerFuncs; private final AudioManager mAudioManager; @@ -231,6 +238,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected Handler mMainHandler; private int mSmallestScreenWidthDp; private final Optional mStatusBarOptional; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; @VisibleForTesting public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum { @@ -337,7 +345,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene SysUiState sysUiState, @Main Handler handler, PackageManager packageManager, - Optional statusBarOptional) { + Optional statusBarOptional, + KeyguardUpdateMonitor keyguardUpdateMonitor) { mContext = context; mWindowManagerFuncs = windowManagerFuncs; mAudioManager = audioManager; @@ -367,6 +376,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mMainHandler = handler; mSmallestScreenWidthDp = resources.getConfiguration().smallestScreenWidthDp; mStatusBarOptional = statusBarOptional; + mKeyguardUpdateMonitor = keyguardUpdateMonitor; // receive broadcasts IntentFilter filter = new IntentFilter(); @@ -420,6 +430,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene return mStatusBarOptional; } + protected KeyguardUpdateMonitor getKeyguardUpdateMonitor() { + return mKeyguardUpdateMonitor; + } + /** * Show the global actions dialog (creating if necessary) * @@ -651,7 +665,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mAdapter, mOverflowAdapter, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger, - mStatusBarOptional); + mStatusBarOptional, mKeyguardUpdateMonitor, mLockPatternUtils); dialog.setOnDismissListener(this); dialog.setOnShowListener(this); @@ -2119,6 +2133,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene private UiEventLogger mUiEventLogger; private GestureDetector mGestureDetector; private Optional mStatusBarOptional; + private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private LockPatternUtils mLockPatternUtils; protected ViewGroup mContainer; @@ -2172,7 +2188,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene NotificationShadeWindowController notificationShadeWindowController, SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing, MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger, - Optional statusBarOptional) { + Optional statusBarOptional, + KeyguardUpdateMonitor keyguardUpdateMonitor, LockPatternUtils lockPatternUtils) { super(context, themeRes); mContext = context; mAdapter = adapter; @@ -2186,6 +2203,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mKeyguardShowing = keyguardShowing; mUiEventLogger = uiEventLogger; mStatusBarOptional = statusBarOptional; + mKeyguardUpdateMonitor = keyguardUpdateMonitor; + mLockPatternUtils = lockPatternUtils; mGestureDetector = new GestureDetector(mContext, mGestureListener); @@ -2304,6 +2323,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mBackgroundDrawable = new ScrimDrawable(); mScrimAlpha = 1.0f; } + + // If user entered from the lock screen and smart lock was enabled, disable it + int user = KeyguardUpdateMonitor.getCurrentUser(); + boolean userHasTrust = mKeyguardUpdateMonitor.getUserHasTrust(user); + if (mKeyguardShowing && userHasTrust) { + mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser()); + showSmartLockDisabledMessage(); + } } protected void fixNavBarClipping() { @@ -2315,6 +2342,37 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene contentParent.setClipToPadding(false); } + private void showSmartLockDisabledMessage() { + // Since power menu is the top window, make a Toast-like view that will show up + View message = LayoutInflater.from(mContext) + .inflate(com.android.systemui.R.layout.global_actions_toast, mContainer, false); + + // Set up animation + AccessibilityManager mAccessibilityManager = + (AccessibilityManager) getContext().getSystemService( + Context.ACCESSIBILITY_SERVICE); + final int visibleTime = mAccessibilityManager.getRecommendedTimeoutMillis( + TOAST_VISIBLE_TIME, AccessibilityManager.FLAG_CONTENT_TEXT); + message.setVisibility(View.VISIBLE); + message.setAlpha(0f); + mContainer.addView(message); + + // Fade in + message.animate() + .alpha(1f) + .setDuration(TOAST_FADE_TIME) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // Then fade out + message.animate() + .alpha(0f) + .setDuration(TOAST_FADE_TIME) + .setStartDelay(visibleTime); + } + }); + } + @Override protected void onStart() { super.onStart(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java index 8c0d21e911dae..0e344a6269b74 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -51,6 +52,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -112,6 +114,7 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { @Mock private Handler mHandler; @Mock private UserContextProvider mUserContextProvider; @Mock private StatusBar mStatusBar; + @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; private TestableLooper mTestableLooper; @@ -155,7 +158,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { mSysUiState, mHandler, mPackageManager, - Optional.of(mStatusBar) + Optional.of(mStatusBar), + mKeyguardUpdateMonitor ); mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting(); @@ -421,4 +425,31 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { restartAction.onLongPress(); verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_REBOOT_LONG_PRESS); } + + @Test + public void testOnLockScreen_disableSmartLock() { + mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite); + int user = KeyguardUpdateMonitor.getCurrentUser(); + doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems(); + doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any()); + doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any()); + doReturn(false).when(mStatusBar).isKeyguardShowing(); + String[] actions = { + GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY, + GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN, + GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER, + GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART, + }; + doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions(); + + // When entering power menu from lockscreen, with smart lock enabled + when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); + mGlobalActionsDialogLite.showOrHideDialog(true, true); + + // Then smart lock will be disabled + verify(mLockPatternUtils).requireCredentialEntry(eq(user)); + + // hide dialog again + mGlobalActionsDialogLite.showOrHideDialog(true, true); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java index 6d1db378bf2ab..f8ab42fe3df58 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -56,6 +56,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -127,6 +128,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase { @Mock private PackageManager mPackageManager; @Mock private SecureSettings mSecureSettings; @Mock private StatusBar mStatusBar; + @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; private TestableLooper mTestableLooper; @@ -170,7 +172,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase { mSysUiState, mHandler, mPackageManager, - Optional.of(mStatusBar) + Optional.of(mStatusBar), + mKeyguardUpdateMonitor ); mGlobalActionsDialog.setZeroDialogPressDelayForTesting();