diff options
6 files changed, 120 insertions, 3 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 7809c71..0a395e1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2869,7 +2869,7 @@ android:label="@string/managed_profile_label"> </activity-alias> <activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity" - android:theme="@style/Theme.Holo.Dialog" + android:theme="@style/Theme.Material.Dialog" android:label="@string/heavy_weight_switcher_title" android:finishOnCloseSystemDialogs="true" android:excludeFromRecents="true" diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index bbbe1ae..1453e15 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4543,6 +4543,8 @@ <string name="enable_accessibility_canceled">Accessibility canceled.</string> <!-- Text spoken when the current user is switched if accessibility is enabled. [CHAR LIMIT=none] --> <string name="user_switched">Current user <xliff:g id="name" example="Bob">%1$s</xliff:g>.</string> + <!-- Message shown when switching to a user [CHAR LIMIT=none] --> + <string name="user_switching_message">Switching to user <xliff:g id="name" example="Bob">%1$s</xliff:g></string> <!-- Default name of the owner user [CHAR LIMIT=20] --> <string name="owner_name" msgid="3879126011135546571">Owner</string> <!-- Error message title [CHAR LIMIT=35] --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index ed7afeb..aabdd26 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -836,6 +836,7 @@ <java-symbol type="string" name="time_picker_increment_set_pm_button" /> <java-symbol type="string" name="upload_file" /> <java-symbol type="string" name="user_switched" /> + <java-symbol type="string" name="user_switching_message" /> <java-symbol type="string" name="volume_alarm" /> <java-symbol type="string" name="volume_icon_description_bluetooth" /> <java-symbol type="string" name="volume_icon_description_incall" /> 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 735fbfc..adb71e7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -246,7 +246,6 @@ public class UserSwitcherController { private void switchToUserId(int id) { try { - WindowManagerGlobal.getWindowManagerService().lockNow(null); ActivityManagerNative.getDefault().switchUser(id); } catch (RemoteException e) { Log.e(TAG, "Couldn't switch user.", e); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f36f25f..2286236 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1179,6 +1179,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int SYSTEM_USER_CURRENT_MSG = 43; static final int ENTER_ANIMATION_COMPLETE_MSG = 44; static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; + static final int START_USER_SWITCH_MSG = 46; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1771,6 +1772,10 @@ public final class ActivityManagerService extends ActivityManagerNative thread.start(); break; } + case START_USER_SWITCH_MSG: { + showUserSwitchDialog(msg.arg1, (String) msg.obj); + break; + } case REPORT_USER_SWITCH_MSG: { dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); break; @@ -17439,6 +17444,15 @@ public final class ActivityManagerService extends ActivityManagerNative } /** + * 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; + } + + /** * Refreshes the list of users related to the current user when either a * user switch happens or when a new related user is started in the * background. @@ -17476,7 +17490,29 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public boolean switchUser(final int userId) { - return startUser(userId, /* foregound */ true); + String userName; + synchronized (this) { + UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); + if (userInfo == null) { + Slog.w(TAG, "No user info for user #" + userId); + return false; + } + if (userInfo.isManagedProfile()) { + Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); + return false; + } + userName = userInfo.name; + } + mHandler.removeMessages(START_USER_SWITCH_MSG); + mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); + return true; + } + + private void showUserSwitchDialog(int userId, String userName) { + // The dialog will show and then initiate the user switch by calling startUserInForeground + Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, + true /* above system */); + d.show(); } private boolean startUser(final int userId, boolean foreground) { diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java new file mode 100644 index 0000000..59d53ec --- /dev/null +++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.server.am; + +import android.app.Service; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.Resources; +import android.os.Handler; +import android.os.Message; +import android.util.Slog; +import android.view.WindowManager; + +/** + * Dialog to show when a user switch it about to happen. The intent is to snapshot the screen + * immediately after the dialog shows so that the user is informed that something is happening + * in the background rather than just freeze the screen and not know if the user-switch affordance + * was being handled. + */ +final class UserSwitchingDialog extends BaseErrorDialog { + private static final String TAG = "ActivityManagerUserSwitchingDialog"; + + private static final int MSG_START_USER = 1; + + private final ActivityManagerService mService; + private final int mUserId; + + public UserSwitchingDialog(ActivityManagerService service, Context context, + int userId, String userName, boolean aboveSystem) { + super(context); + + mService = service; + mUserId = userId; + Resources res = context.getResources(); + setCancelable(false); + setMessage(res.getString(com.android.internal.R.string.user_switching_message, userName)); + if (aboveSystem) { + getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); + } + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR | + WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; + getWindow().setAttributes(attrs); + } + + @Override + public void show() { + super.show(); + // TODO: Instead of just an arbitrary delay, wait for a signal that the window was fully + // displayed by the window manager + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER), 250); + } + + private final Handler mHandler = new Handler() { + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_START_USER: + mService.startUserInForeground(mUserId, UserSwitchingDialog.this); + break; + } + } + }; +} |