blob: 98f5557903d6c7226c007f820fff7e1f74ae295d [file] [log] [blame]
Amith Yamasani7805a102014-08-22 09:27:25 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Amith Yamasanic2a8d152014-08-25 14:15:25 -070019import android.app.AlertDialog;
Amith Yamasani7805a102014-08-22 09:27:25 -070020import android.content.Context;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080021import android.content.pm.UserInfo;
Amith Yamasani7805a102014-08-22 09:27:25 -070022import android.content.res.Resources;
Amith Yamasani5e5cb462015-02-09 15:45:26 -080023import android.os.Handler;
24import android.os.Message;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080025import android.os.UserHandle;
26import android.os.UserManager;
Amith Yamasanic2a8d152014-08-25 14:15:25 -070027import android.view.LayoutInflater;
28import android.view.View;
Craig Mautner9c795042014-10-28 19:59:59 -070029import android.view.ViewTreeObserver;
Amith Yamasani7805a102014-08-22 09:27:25 -070030import android.view.WindowManager;
Amith Yamasanic2a8d152014-08-25 14:15:25 -070031import android.widget.TextView;
32
33import com.android.internal.R;
Amith Yamasani5e5cb462015-02-09 15:45:26 -080034import com.android.internal.annotations.GuardedBy;
Amith Yamasani7805a102014-08-22 09:27:25 -070035
36/**
37 * Dialog to show when a user switch it about to happen. The intent is to snapshot the screen
38 * immediately after the dialog shows so that the user is informed that something is happening
39 * in the background rather than just freeze the screen and not know if the user-switch affordance
40 * was being handled.
41 */
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070042class UserSwitchingDialog extends AlertDialog
Craig Mautner9c795042014-10-28 19:59:59 -070043 implements ViewTreeObserver.OnWindowShownListener {
Amith Yamasani7805a102014-08-22 09:27:25 -070044 private static final String TAG = "ActivityManagerUserSwitchingDialog";
45
Amith Yamasani5e5cb462015-02-09 15:45:26 -080046 // Time to wait for the onWindowShown() callback before continuing the user switch
47 private static final int WINDOW_SHOWN_TIMEOUT_MS = 3000;
48
Amith Yamasani7805a102014-08-22 09:27:25 -070049 private final ActivityManagerService mService;
50 private final int mUserId;
Amith Yamasani5e5cb462015-02-09 15:45:26 -080051 private static final int MSG_START_USER = 1;
52 @GuardedBy("this")
53 private boolean mStartedUser;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070054 final protected UserInfo mOldUser;
55 final protected UserInfo mNewUser;
56 final private String mSwitchingFromSystemUserMessage;
57 final private String mSwitchingToSystemUserMessage;
58 final protected Context mContext;
Amith Yamasani7805a102014-08-22 09:27:25 -070059
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080060 public UserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
Alex Chau93ae42b2018-01-11 15:10:12 +000061 UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
62 String switchingToSystemUserMessage) {
Amith Yamasani7805a102014-08-22 09:27:25 -070063 super(context);
64
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070065 mContext = context;
Amith Yamasani7805a102014-08-22 09:27:25 -070066 mService = service;
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080067 mUserId = newUser.id;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070068 mOldUser = oldUser;
69 mNewUser = newUser;
70 mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
71 mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
Amith Yamasanic2a8d152014-08-25 14:15:25 -070072
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070073 inflateContent();
74
75 if (aboveSystem) {
76 getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
77 }
78
79 WindowManager.LayoutParams attrs = getWindow().getAttributes();
80 attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR |
81 WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
82 getWindow().setAttributes(attrs);
83 }
84
85 void inflateContent() {
Amith Yamasanic2a8d152014-08-25 14:15:25 -070086 // Set up the dialog contents
Amith Yamasani7805a102014-08-22 09:27:25 -070087 setCancelable(false);
Amith Yamasanic2a8d152014-08-25 14:15:25 -070088 Resources res = getContext().getResources();
89 // Custom view due to alignment and font size requirements
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070090 View view = LayoutInflater.from(getContext()).inflate(R.layout.user_switching_dialog,
91 null);
Suprabh Shukla4fe508b2015-11-20 18:22:57 -080092
Alex Chau93ae42b2018-01-11 15:10:12 +000093 String viewMessage = null;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070094 if (UserManager.isSplitSystemUser() && mNewUser.id == UserHandle.USER_SYSTEM) {
95 viewMessage = res.getString(R.string.user_logging_out_message, mOldUser.name);
96 } else if (UserManager.isDeviceInDemoMode(mContext)) {
97 if (mOldUser.isDemo()) {
Suprabh Shuklaff0939b2016-06-01 23:19:06 -070098 viewMessage = res.getString(R.string.demo_restarting_message);
99 } else {
100 viewMessage = res.getString(R.string.demo_starting_message);
101 }
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800102 } else {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -0700103 if (mOldUser.id == UserHandle.USER_SYSTEM) {
104 viewMessage = mSwitchingFromSystemUserMessage;
105 } else if (mNewUser.id == UserHandle.USER_SYSTEM) {
106 viewMessage = mSwitchingToSystemUserMessage;
Alex Chau93ae42b2018-01-11 15:10:12 +0000107 }
108
109 // If switchingFromSystemUserMessage or switchingToSystemUserMessage is null, fallback
110 // to system message.
111 if (viewMessage == null) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -0700112 viewMessage = res.getString(R.string.user_switching_message, mNewUser.name);
Alex Chau93ae42b2018-01-11 15:10:12 +0000113 }
Suprabh Shukla4fe508b2015-11-20 18:22:57 -0800114 }
115 ((TextView) view.findViewById(R.id.message)).setText(viewMessage);
Amith Yamasanic2a8d152014-08-25 14:15:25 -0700116 setView(view);
Amith Yamasani7805a102014-08-22 09:27:25 -0700117 }
118
119 @Override
120 public void show() {
Craig Mautner9c795042014-10-28 19:59:59 -0700121 // Slog.v(TAG, "show called");
Amith Yamasani7805a102014-08-22 09:27:25 -0700122 super.show();
Craig Mautner9c795042014-10-28 19:59:59 -0700123 final View decorView = getWindow().getDecorView();
124 if (decorView != null) {
125 decorView.getViewTreeObserver().addOnWindowShownListener(this);
126 }
Amith Yamasani5e5cb462015-02-09 15:45:26 -0800127 // Add a timeout as a safeguard, in case a race in screen on/off causes the window
128 // callback to never come.
129 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER),
130 WINDOW_SHOWN_TIMEOUT_MS);
Amith Yamasani7805a102014-08-22 09:27:25 -0700131 }
132
Craig Mautner9c795042014-10-28 19:59:59 -0700133 @Override
134 public void onWindowShown() {
135 // Slog.v(TAG, "onWindowShown called");
Amith Yamasani5e5cb462015-02-09 15:45:26 -0800136 startUser();
137 }
138
139 void startUser() {
140 synchronized (this) {
141 if (!mStartedUser) {
Evan Rosky18396452016-07-27 15:19:37 -0700142 mService.mUserController.startUserInForeground(mUserId);
143 dismiss();
Amith Yamasani5e5cb462015-02-09 15:45:26 -0800144 mStartedUser = true;
145 final View decorView = getWindow().getDecorView();
146 if (decorView != null) {
147 decorView.getViewTreeObserver().removeOnWindowShownListener(this);
148 }
149 mHandler.removeMessages(MSG_START_USER);
150 }
Amith Yamasani7805a102014-08-22 09:27:25 -0700151 }
Craig Mautner9c795042014-10-28 19:59:59 -0700152 }
Amith Yamasani5e5cb462015-02-09 15:45:26 -0800153
154 private final Handler mHandler = new Handler() {
155 @Override
156 public void handleMessage(Message msg) {
157 switch (msg.what) {
158 case MSG_START_USER:
159 startUser();
160 break;
161 }
162 }
163 };
Amith Yamasani7805a102014-08-22 09:27:25 -0700164}