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
This commit is contained in:
44
packages/SystemUI/res/layout/global_actions_toast.xml
Normal file
44
packages/SystemUI/res/layout/global_actions_toast.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|bottom"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="@dimen/global_actions_info_margin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintWidth_max="382dp"
|
||||
android:layout_weight="0"
|
||||
android:background="@drawable/global_actions_lite_background"
|
||||
android:theme="@style/Theme.SystemUI.QuickSettings"
|
||||
android:paddingTop="14dp"
|
||||
android:paddingBottom="14dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:text="@string/global_action_smart_lock_disabled" />
|
||||
</LinearLayout>
|
||||
@@ -211,6 +211,8 @@
|
||||
|
||||
<!-- Power menu item for taking a screenshot [CHAR LIMIT=20]-->
|
||||
<string name="global_action_screenshot">Screenshot</string>
|
||||
<!-- Message shown in power menu when smart lock has been disabled [CHAR_LIMIT=NONE] -->
|
||||
<string name="global_action_smart_lock_disabled">Smart Lock disabled</string>
|
||||
|
||||
<!-- text to show in place of RemoteInput images when they cannot be shown.
|
||||
[CHAR LIMIT=50] -->
|
||||
|
||||
@@ -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;
|
||||
@@ -172,7 +173,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
|
||||
SysUiState sysUiState,
|
||||
@Main Handler handler,
|
||||
PackageManager packageManager,
|
||||
StatusBar statusBar) {
|
||||
StatusBar statusBar,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor) {
|
||||
|
||||
super(context,
|
||||
windowManagerFuncs,
|
||||
@@ -204,7 +206,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
|
||||
sysUiState,
|
||||
handler,
|
||||
packageManager,
|
||||
statusBar);
|
||||
statusBar,
|
||||
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,12 +337,13 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
|
||||
NotificationShadeWindowController notificationShadeWindowController,
|
||||
SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
|
||||
MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
|
||||
StatusBar statusBar) {
|
||||
StatusBar statusBar, 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, null,
|
||||
statusBar);
|
||||
statusBar, keyguardUpdateMonitor, lockPatternUtils);
|
||||
mWalletFactory = walletFactory;
|
||||
|
||||
// Update window attributes
|
||||
|
||||
@@ -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;
|
||||
@@ -170,6 +172,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 StatusBar mStatusBar;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
|
||||
@VisibleForTesting
|
||||
public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum {
|
||||
@@ -338,7 +346,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
SysUiState sysUiState,
|
||||
@Main Handler handler,
|
||||
PackageManager packageManager,
|
||||
StatusBar statusBar) {
|
||||
StatusBar statusBar,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor) {
|
||||
mContext = context;
|
||||
mWindowManagerFuncs = windowManagerFuncs;
|
||||
mAudioManager = audioManager;
|
||||
@@ -369,6 +378,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
mMainHandler = handler;
|
||||
mSmallestScreenWidthDp = resources.getConfiguration().smallestScreenWidthDp;
|
||||
mStatusBar = statusBar;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
|
||||
// receive broadcasts
|
||||
IntentFilter filter = new IntentFilter();
|
||||
@@ -422,6 +432,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
return mStatusBar;
|
||||
}
|
||||
|
||||
protected KeyguardUpdateMonitor getKeyguardUpdateMonitor() {
|
||||
return mKeyguardUpdateMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the global actions dialog (creating if necessary)
|
||||
*
|
||||
@@ -653,7 +667,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
mAdapter, mOverflowAdapter, mSysuiColorExtractor,
|
||||
mStatusBarService, mNotificationShadeWindowController,
|
||||
mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger,
|
||||
mInfoProvider, mStatusBar);
|
||||
mInfoProvider, mStatusBar, mKeyguardUpdateMonitor, mLockPatternUtils);
|
||||
|
||||
dialog.setOnDismissListener(this);
|
||||
dialog.setOnShowListener(this);
|
||||
@@ -2122,6 +2136,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
private GlobalActionsInfoProvider mInfoProvider;
|
||||
private GestureDetector mGestureDetector;
|
||||
private StatusBar mStatusBar;
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
|
||||
protected ViewGroup mContainer;
|
||||
|
||||
@@ -2173,7 +2189,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
NotificationShadeWindowController notificationShadeWindowController,
|
||||
SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
|
||||
MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
|
||||
@Nullable GlobalActionsInfoProvider infoProvider, StatusBar statusBar) {
|
||||
@Nullable GlobalActionsInfoProvider infoProvider, StatusBar statusBar,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor, LockPatternUtils lockPatternUtils) {
|
||||
super(context, themeRes);
|
||||
mContext = context;
|
||||
mAdapter = adapter;
|
||||
@@ -2188,6 +2205,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mInfoProvider = infoProvider;
|
||||
mStatusBar = statusBar;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
|
||||
mGestureDetector = new GestureDetector(mContext, mGestureListener);
|
||||
|
||||
@@ -2308,6 +2327,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
||||
if (mInfoProvider != null && mInfoProvider.shouldShowMessage()) {
|
||||
mInfoProvider.addPanel(mContext, mContainer, mAdapter.getCount(), () -> dismiss());
|
||||
}
|
||||
|
||||
// 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() {
|
||||
@@ -2319,6 +2346,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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -156,7 +159,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
|
||||
mSysUiState,
|
||||
mHandler,
|
||||
mPackageManager,
|
||||
mStatusBar
|
||||
mStatusBar,
|
||||
mKeyguardUpdateMonitor
|
||||
);
|
||||
mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting();
|
||||
|
||||
@@ -422,4 +426,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 = {
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
|
||||
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
|
||||
GlobalActionsDialog.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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -126,6 +127,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;
|
||||
|
||||
@@ -169,7 +171,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
mSysUiState,
|
||||
mHandler,
|
||||
mPackageManager,
|
||||
mStatusBar
|
||||
mStatusBar,
|
||||
mKeyguardUpdateMonitor
|
||||
);
|
||||
mGlobalActionsDialog.setZeroDialogPressDelayForTesting();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user