Merge "Disable smart lock when in power menu on lock screen" into sc-v2-dev am: 04b483b499
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15568809 Change-Id: I477ae7295f7335707a109fde183c6f64d7721e5a
This commit is contained in:
@@ -13,13 +13,12 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/global_actions_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center">
|
||||
<com.android.systemui.globalactions.GlobalActionsLayoutLite
|
||||
@@ -29,8 +28,11 @@
|
||||
android:orientation="vertical"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/global_actions_lite_background"
|
||||
android:padding="@dimen/global_actions_lite_padding">
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_weight="1">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -38,6 +40,8 @@
|
||||
android:gravity="center"
|
||||
android:translationZ="@dimen/global_actions_translate"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/global_actions_lite_background"
|
||||
android:padding="@dimen/global_actions_lite_padding"
|
||||
android:layoutDirection="ltr">
|
||||
<androidx.constraintlayout.helper.widget.Flow
|
||||
android:id="@+id/list_flow"
|
||||
@@ -53,4 +57,4 @@
|
||||
app:flow_horizontalStyle="packed"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.android.systemui.globalactions.GlobalActionsLayoutLite>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
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>
|
||||
@@ -1135,6 +1135,7 @@
|
||||
<dimen name="global_actions_button_padding">38dp</dimen>
|
||||
<dimen name="global_actions_corner_radius">28dp</dimen>
|
||||
<dimen name="global_actions_lite_padding">24dp</dimen>
|
||||
<dimen name="global_actions_info_margin">32dp</dimen>
|
||||
|
||||
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
|
||||
burn-in on AOD. -->
|
||||
|
||||
@@ -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;
|
||||
@@ -173,7 +174,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
|
||||
SysUiState sysUiState,
|
||||
@Main Handler handler,
|
||||
PackageManager packageManager,
|
||||
Optional<StatusBar> statusBarOptional) {
|
||||
Optional<StatusBar> 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<StatusBar> statusBarOptional) {
|
||||
Optional<StatusBar> 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
|
||||
|
||||
@@ -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<StatusBar> 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<StatusBar> statusBarOptional) {
|
||||
Optional<StatusBar> 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<StatusBar> 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<StatusBar> statusBarOptional) {
|
||||
Optional<StatusBar> 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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user