summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java1
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java38
-rw-r--r--services/core/java/com/android/server/am/UserSwitchingDialog.java79
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;
+ }
+ }
+ };
+}