Merge changes Idfd40156,Ic903fc25
* changes:
Make user-switch transitions customizable
Add support for custom user-switch UI
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 3fcc253..cfd016e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -749,6 +749,15 @@
}
/**
+ * @return Whether guest user is always ephemeral
+ * @hide
+ */
+ public static boolean isGuestUserEphemeral() {
+ return Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
+ }
+
+ /**
* Returns whether switching users is currently allowed.
* <p>For instance switching users is not allowed if the current user is in a phone call,
* or system user hasn't been unlocked yet
@@ -871,6 +880,16 @@
}
/**
+ * Checks if a user is a guest user.
+ * @return whether user is a guest user.
+ * @hide
+ */
+ public boolean isGuestUser(int id) {
+ UserInfo user = getUserInfo(id);
+ return user != null && user.isGuest();
+ }
+
+ /**
* Checks if the calling app is running as a guest user.
* @return whether the caller is a guest user.
* @hide
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 3d786f1..7de7d8a 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -210,6 +210,19 @@
void dismissKeyguard();
void keyguardGoingAway(int flags);
+ /**
+ * Called to tell WindowManager whether the keyguard is animating in. While this property
+ * is true, WindowManager won't assume that the keyguard is opaque (eg. WindowAnimator won't
+ * force-hide windows just because keyguard is visible and WallpaperController won't occlude
+ * app windows with the system wallpaper.
+ *
+ * <p>Requires CONTROL_KEYGUARD permission</p>
+ */
+ void setKeyguardAnimatingIn(boolean animating);
+
+ // Requires INTERACT_ACROSS_USERS_FULL permission
+ void setSwitchingUser(boolean switching);
+
void closeSystemDialogs(String reason);
// These can only be called with the SET_ANIMATON_SCALE permission.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 87595f9..f1fa216 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1347,6 +1347,15 @@
public void setCurrentUserLw(int newUserId);
/**
+ * For a given user-switch operation, this will be called once with switching=true before the
+ * user-switch and once with switching=false afterwards (or if the user-switch was cancelled).
+ * This gives the policy a chance to alter its behavior for the duration of a user-switch.
+ *
+ * @param switching true if a user-switch is in progress
+ */
+ void setSwitchingUser(boolean switching);
+
+ /**
* Print the WindowManagerPolicy's state into the given stream.
*
* @param prefix Text to print at the front of each line.
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 83d75fb..02e8af0 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -80,6 +80,7 @@
void setKeyguardEnabled(boolean enabled);
void onSystemReady();
void doKeyguardTimeout(in Bundle options);
+ void setSwitchingUser(boolean switching);
void setCurrentUser(int userId);
void onBootCompleted();
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 13e1ba7d..d15b175 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2540,4 +2540,9 @@
<string name="config_networkOverLimitComponent" translatable="false">com.android.systemui/com.android.systemui.net.NetworkOverLimitActivity</string>
<string name="config_dataUsageSummaryComponent" translatable="false">com.android.settings/com.android.settings.Settings$DataUsageSummaryActivity</string>
+
+ <!-- Flag specifying whether user-switch operations have custom UI. When false, user-switch
+ UI is handled by ActivityManagerService -->
+ <bool name="config_customUserSwitchUi">false</bool>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index df8d61a..384e9850 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1482,6 +1482,7 @@
<java-symbol type="bool" name="config_allowAllRotations" />
<java-symbol type="bool" name="config_annoy_dianne" />
<java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
+ <java-symbol type="bool" name="config_customUserSwitchUi" />
<java-symbol type="bool" name="config_deskDockEnablesAccelerometer" />
<java-symbol type="bool" name="config_disableMenuKeyInLockScreen" />
<java-symbol type="bool" name="config_enableCarDockHomeLaunch" />
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1b83ccd..daa1d88 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1185,9 +1185,6 @@
* Handle {@link #MSG_USER_SWITCHING}
*/
protected void handleUserSwitching(int userId, IRemoteCallback reply) {
- mSwitchingUser = true;
- updateFingerprintListeningState();
-
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1204,9 +1201,6 @@
* Handle {@link #MSG_USER_SWITCH_COMPLETE}
*/
protected void handleUserSwitchComplete(int userId) {
- mSwitchingUser = false;
- updateFingerprintListeningState();
-
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1511,6 +1505,15 @@
sendUpdates(callback);
}
+ public boolean isSwitchingUser() {
+ return mSwitchingUser;
+ }
+
+ public void setSwitchingUser(boolean switching) {
+ mSwitchingUser = switching;
+ updateFingerprintListeningState();
+ }
+
private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
// Notify listener of the current state
callback.onRefreshBatteryInfo(mBatteryStatus);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 84901ee..7ec6a03 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -178,6 +178,12 @@
}
@Override // Binder interface
+ public void setSwitchingUser(boolean switching) {
+ checkPermission();
+ mKeyguardViewMediator.setSwitchingUser(switching);
+ }
+
+ @Override // Binder interface
public void setCurrentUser(int userId) {
checkPermission();
mKeyguardViewMediator.setCurrentUser(userId);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 0dc5f74..8b592c2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -191,13 +191,18 @@
*/
private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
+ /**
+ * Boolean option for doKeyguardLocked/doKeyguardTimeout which, when set to true, forces the
+ * keyguard to show even if it is disabled for the current user.
+ */
+ public static final String OPTION_FORCE_SHOW = "force_show";
+
/** The stream type that the lock sounds are tied to. */
private int mUiSoundsStreamType;
private AlarmManager mAlarmManager;
private AudioManager mAudioManager;
private StatusBarManager mStatusBarManager;
- private boolean mSwitchingUser;
private boolean mSystemReady;
private boolean mBootCompleted;
@@ -349,7 +354,6 @@
// We need to force a reset of the views, since lockNow (called by
// ActivityManagerService) will not reconstruct the keyguard if it is already showing.
synchronized (KeyguardViewMediator.this) {
- mSwitchingUser = true;
resetKeyguardDonePendingLocked();
resetStateLocked();
adjustStatusBarLocked();
@@ -358,7 +362,6 @@
@Override
public void onUserSwitchComplete(int userId) {
- mSwitchingUser = false;
if (userId != UserHandle.USER_SYSTEM) {
UserInfo info = UserManager.get(mContext).getUserInfo(userId);
if (info != null && (info.isGuest() || info.isDemo())) {
@@ -1243,8 +1246,9 @@
return;
}
+ boolean forceShow = options != null && options.getBoolean(OPTION_FORCE_SHOW, false);
if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
- && !lockedOrMissing) {
+ && !lockedOrMissing && !forceShow) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
return;
}
@@ -1364,8 +1368,16 @@
}
public boolean isSecure() {
- return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())
- || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
+ return isSecure(KeyguardUpdateMonitor.getCurrentUser());
+ }
+
+ public boolean isSecure(int userId) {
+ return mLockPatternUtils.isSecure(userId)
+ || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
+ }
+
+ public void setSwitchingUser(boolean switching) {
+ KeyguardUpdateMonitor.getInstance(mContext).setSwitchingUser(switching);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index bc05ff1..706abdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -97,7 +97,7 @@
final int activeUserId = ActivityManager.getCurrentUser();
final boolean allowDismissKeyguard =
- !(UserManager.isSplitSystemUser() && activeUserId == UserHandle.USER_SYSTEM)
+ !UserManager.isSplitSystemUser()
&& activeUserId == keyguardUserId;
// If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern) is
// set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 586741e..4638c85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -129,7 +129,9 @@
public void setCurrentUser(int user) {
if (user != mCurrentUserId) {
- mCached = false;
+ if (mSelectedUser == null || user != mSelectedUser.getIdentifier()) {
+ mCached = false;
+ }
mCurrentUserId = user;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 6460b5f..e95cc6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -892,8 +892,7 @@
mLightStatusBarController = new LightStatusBarController(mIconController,
mBatteryController);
mKeyguardMonitor = new KeyguardMonitor(mContext);
- mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
- mHandler, this);
+ mUserSwitcherController = createUserSwitcherController();
if (UserManager.get(mContext).isUserSwitcherEnabled()) {
createUserSwitcher();
}
@@ -1096,6 +1095,10 @@
mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
}
+ protected UserSwitcherController createUserSwitcherController() {
+ return new UserSwitcherController(mContext, mKeyguardMonitor, mHandler, this);
+ }
+
protected void inflateStatusBarWindow(Context context) {
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
@@ -3621,6 +3624,10 @@
resetUserSetupObserver();
setControllerUsers();
clearCurrentMediaNotification();
+ setLockscreenUser(newUserId);
+ }
+
+ protected void setLockscreenUser(int newUserId) {
mLockscreenWallpaper.setCurrentUser(newUserId);
mScrimController.setCurrentUser(newUserId);
updateMediaMetaData(true, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index c883bba..c3becb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -50,6 +50,7 @@
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.util.UserIcons;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.GuestResumeSessionReceiver;
import com.android.systemui.R;
@@ -86,13 +87,13 @@
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
- private final Context mContext;
- private final UserManager mUserManager;
+ protected final Context mContext;
+ protected final UserManager mUserManager;
private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
private final GuestResumeSessionReceiver mGuestResumeSessionReceiver
= new GuestResumeSessionReceiver();
private final KeyguardMonitor mKeyguardMonitor;
- private final Handler mHandler;
+ protected final Handler mHandler;
private final ActivityStarter mActivityStarter;
private ArrayList<UserRecord> mUsers = new ArrayList<>();
@@ -363,13 +364,23 @@
id = record.info.id;
}
- if (ActivityManager.getCurrentUser() == id) {
+ int currUserId = ActivityManager.getCurrentUser();
+ if (currUserId == id) {
if (record.isGuest) {
showExitGuestDialog(id);
}
return;
}
+ if (UserManager.isGuestUserEphemeral()) {
+ // If switching from guest, we want to bring up the guest exit dialog instead of switching
+ UserInfo currUserInfo = mUserManager.getUserInfo(currUserId);
+ if (currUserInfo != null && currUserInfo.isGuest()) {
+ showExitGuestDialog(currUserId, record.resolveId());
+ return;
+ }
+ }
+
switchToUserId(id);
}
@@ -398,7 +409,7 @@
return count;
}
- private void switchToUserId(int id) {
+ protected void switchToUserId(int id) {
try {
pauseRefreshUsers();
ActivityManagerNative.getDefault().switchUser(id);
@@ -408,10 +419,21 @@
}
private void showExitGuestDialog(int id) {
+ int newId = UserHandle.USER_SYSTEM;
+ if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
+ UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
+ if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) {
+ newId = info.id;
+ }
+ }
+ showExitGuestDialog(id, newId);
+ }
+
+ protected void showExitGuestDialog(int id, int targetId) {
if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
mExitGuestDialog.cancel();
}
- mExitGuestDialog = new ExitGuestDialog(mContext, id);
+ mExitGuestDialog = new ExitGuestDialog(mContext, id, targetId);
mExitGuestDialog.show();
}
@@ -423,15 +445,8 @@
mAddUserDialog.show();
}
- private void exitGuest(int id) {
- int newId = UserHandle.USER_SYSTEM;
- if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
- UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
- if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) {
- newId = info.id;
- }
- }
- switchToUserId(newId);
+ protected void exitGuest(int id, int targetId) {
+ switchToUserId(targetId);
mUserManager.removeUser(id);
}
@@ -830,8 +845,9 @@
DialogInterface.OnClickListener {
private final int mGuestId;
+ private final int mTargetId;
- public ExitGuestDialog(Context context, int guestId) {
+ public ExitGuestDialog(Context context, int guestId, int targetId) {
super(context);
setTitle(R.string.guest_exit_guest_dialog_title);
setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
@@ -841,6 +857,7 @@
context.getString(R.string.guest_exit_guest_dialog_remove), this);
setCanceledOnTouchOutside(false);
mGuestId = guestId;
+ mTargetId = targetId;
}
@Override
@@ -849,7 +866,7 @@
cancel();
} else {
dismiss();
- exitGuest(mGuestId);
+ exitGuest(mGuestId, mTargetId);
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index dbff4be..908b8e0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1533,6 +1533,7 @@
static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 71;
+ static final int START_USER_SWITCH_FG_MSG = 712;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1954,6 +1955,10 @@
thread.start();
break;
}
+ case START_USER_SWITCH_FG_MSG: {
+ mUserController.startUserInForeground(msg.arg1);
+ break;
+ }
case REPORT_USER_SWITCH_MSG: {
mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
@@ -13110,6 +13115,8 @@
com.android.internal.R.string.config_defaultPictureInPictureBounds));
mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
com.android.internal.R.string.config_appsNotReportingCrashes));
+ mUserController.mUserSwitchUiEnabled = !res.getBoolean(
+ com.android.internal.R.bool.config_customUserSwitchUi);
if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
mFullscreenThumbnailScale = (float) res
.getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
@@ -21526,11 +21533,10 @@
@Override
public boolean switchUser(final int targetUserId) {
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
- UserInfo currentUserInfo;
+ int currentUserId;
UserInfo targetUserInfo;
synchronized (this) {
- int currentUserId = mUserController.getCurrentUserIdLocked();
- currentUserInfo = mUserController.getUserInfo(currentUserId);
+ currentUserId = mUserController.getCurrentUserIdLocked();
targetUserInfo = mUserController.getUserInfo(targetUserId);
if (targetUserInfo == null) {
Slog.w(TAG, "No user info for user #" + targetUserId);
@@ -21551,9 +21557,17 @@
}
mUserController.setTargetUserIdLocked(targetUserId);
}
- Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
- mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
- mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
+ if (mUserController.mUserSwitchUiEnabled) {
+ UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
+ Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
+ mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
+ mUiHandler.sendMessage(mHandler.obtainMessage(
+ START_USER_SWITCH_UI_MSG, userNames));
+ } else {
+ mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
+ mHandler.sendMessage(mHandler.obtainMessage(
+ START_USER_SWITCH_FG_MSG, targetUserId, 0));
+ }
return true;
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index a5245a2..35b7a43 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -161,6 +161,8 @@
private final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
= new RemoteCallbackList<>();
+ boolean mUserSwitchUiEnabled;
+
/**
* Currently active user switch callbacks.
*/
@@ -797,7 +799,7 @@
return false;
}
- if (foreground) {
+ if (foreground && mUserSwitchUiEnabled) {
mInjector.getWindowManager().startFreezingScreen(
R.anim.screen_user_exit, R.anim.screen_user_enter);
}
@@ -827,7 +829,10 @@
mInjector.getWindowManager().setCurrentUser(userId, mCurrentProfileIds);
// Once the internal notion of the active user has switched, we lock the device
// with the option to show the user switcher on the keyguard.
- mInjector.getWindowManager().lockNow(null);
+ if (mUserSwitchUiEnabled) {
+ mInjector.getWindowManager().setSwitchingUser(true);
+ mInjector.getWindowManager().lockNow(null);
+ }
} else {
final Integer currentUserIdInt = mCurrentUserId;
updateCurrentProfileIdsLocked();
@@ -920,10 +925,11 @@
/**
* Start user, if its not already running, and bring it to foreground.
*/
- boolean startUserInForeground(final int userId, Dialog dlg) {
- boolean result = startUser(userId, /* foreground */ true);
- dlg.dismiss();
- return result;
+ void startUserInForeground(final int targetUserId) {
+ boolean success = startUser(targetUserId, /* foreground */ true);
+ if (!success) {
+ mInjector.getWindowManager().setSwitchingUser(false);
+ }
}
boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
@@ -1036,6 +1042,7 @@
/** Called on handler thread */
void dispatchUserSwitchComplete(int userId) {
+ mInjector.getWindowManager().setSwitchingUser(false);
final int observerCount = mUserSwitchObservers.beginBroadcast();
for (int i = 0; i < observerCount; i++) {
try {
@@ -1126,8 +1133,10 @@
void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
- synchronized (mLock) {
- mInjector.getWindowManager().stopFreezingScreen();
+ if (mUserSwitchUiEnabled) {
+ synchronized (mLock) {
+ mInjector.getWindowManager().stopFreezingScreen();
+ }
}
uss.switching = false;
mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index 7022856..3e6934f 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -112,7 +112,8 @@
void startUser() {
synchronized (this) {
if (!mStartedUser) {
- mService.mUserController.startUserInForeground(mUserId, this);
+ mService.mUserController.startUserInForeground(mUserId);
+ dismiss();
mStartedUser = true;
final View decorView = getWindow().getDecorView();
if (decorView != null) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5385a50..60fbabf 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -7783,6 +7783,11 @@
}
@Override
+ public void setSwitchingUser(boolean switching) {
+ mKeyguardDelegate.setSwitchingUser(switching);
+ }
+
+ @Override
public boolean canMagnifyWindow(int windowType) {
switch (windowType) {
case WindowManager.LayoutParams.TYPE_INPUT_METHOD:
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 0c76aeb..ef6d92f 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -346,6 +346,12 @@
mKeyguardState.currentUser = newUserId;
}
+ public void setSwitchingUser(boolean switching) {
+ if (mKeyguardService != null) {
+ mKeyguardService.setSwitchingUser(switching);
+ }
+ }
+
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardService != null) {
mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration);
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index bea3167..0274cb5 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -189,6 +189,15 @@
}
@Override // Binder interface
+ public void setSwitchingUser(boolean switching) {
+ try {
+ mService.setSwitchingUser(switching);
+ } catch (RemoteException e) {
+ Slog.w(TAG , "Remote Exception", e);
+ }
+ }
+
+ @Override // Binder interface
public void setCurrentUser(int userId) {
mKeyguardStateMonitor.setCurrentUser(userId);
try {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 1010400..6515fbd 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -104,6 +104,7 @@
boolean mKeyguardGoingAway;
int mKeyguardGoingAwayFlags;
+ boolean mKeyguardAnimatingIn;
/** Use one animation for all entering activities after keyguard is dismissed. */
Animation mPostKeyguardExitAnimation;
@@ -241,7 +242,8 @@
// Only hide windows if the keyguard is active and not animating away.
boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded()
- && mForceHiding != KEYGUARD_ANIMATING_OUT;
+ && mForceHiding != KEYGUARD_ANIMATING_OUT
+ && !mKeyguardAnimatingIn;
boolean hideDockDivider = win.mAttrs.type == TYPE_DOCK_DIVIDER
&& win.getDisplayContent().getDockedStackLocked() == null;
return keyguardOn && !allowWhenLocked && (win.getDisplayId() == Display.DEFAULT_DISPLAY)
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c4196bb..8f7896e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -581,6 +581,7 @@
int mLastDisplayFreezeDuration = 0;
Object mLastFinishedFreezeSource = null;
boolean mWaitingForConfig = false;
+ boolean mSwitchingUser = false;
final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
@@ -4508,6 +4509,35 @@
}
}
+ @Override
+ public void setKeyguardAnimatingIn(boolean animating) {
+ if (!checkCallingPermission(Manifest.permission.CONTROL_KEYGUARD,
+ "keyguardAnimatingIn()")) {
+ throw new SecurityException("Requires CONTROL_KEYGUARD permission");
+ }
+ synchronized (mWindowMap) {
+ mAnimator.mKeyguardAnimatingIn = animating;
+ }
+ }
+
+ public boolean isKeyguardAnimatingIn() {
+ synchronized (mWindowMap) {
+ return mAnimator.mKeyguardAnimatingIn;
+ }
+ }
+
+ @Override
+ public void setSwitchingUser(boolean switching) {
+ if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "setSwitchingUser()")) {
+ throw new SecurityException("Requires INTERACT_ACROSS_USERS_FULL permission");
+ }
+ mPolicy.setSwitchingUser(switching);
+ synchronized (mWindowMap) {
+ mSwitchingUser = switching;
+ }
+ }
+
void showGlobalActions() {
mPolicy.showGlobalActions();
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index b54cbe1..00e71f2 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -623,12 +623,14 @@
}
// Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
- // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
+ // layer. For keyguard over wallpaper put the wallpaper under the keyguard unless
+ // the keyguard is still animating in.
int insertionIndex = 0;
if (visible && wallpaperTarget != null) {
final int type = wallpaperTarget.mAttrs.type;
final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
- if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || type == TYPE_KEYGUARD_SCRIM) {
+ if (((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || type == TYPE_KEYGUARD_SCRIM)
+ && !mService.isKeyguardAnimatingIn()) {
insertionIndex = windowList.indexOf(wallpaperTarget);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index aa97b35..8c6b007 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -663,6 +663,11 @@
}
@Override
+ public void setSwitchingUser(boolean switching) {
+
+ }
+
+ @Override
public void dump(String prefix, PrintWriter writer, String[] args) {
}