Merge "Disable smart lock when in power menu on lock screen" into sc-v2-dev

This commit is contained in:
Beth Thibodeau
2021-08-18 21:57:58 +00:00
committed by Android (Google) Code Review
8 changed files with 163 additions and 15 deletions

View File

@@ -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>

View 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>

View File

@@ -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. -->

View File

@@ -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] -->

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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();