• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
17 package com.android.systemui.user;
18 
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.app.IActivityManager;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.graphics.drawable.Drawable;
25 import android.os.Bundle;
26 import android.os.RemoteException;
27 import android.util.Log;
28 import android.window.OnBackInvokedCallback;
29 import android.window.OnBackInvokedDispatcher;
30 
31 import androidx.annotation.NonNull;
32 import androidx.annotation.Nullable;
33 
34 import com.android.settingslib.users.EditUserInfoController;
35 import com.android.systemui.R;
36 import com.android.systemui.plugins.ActivityStarter;
37 
38 import javax.inject.Inject;
39 
40 /**
41  * This screen shows a Dialog for choosing nickname and photo for a new user, and then delegates the
42  * user creation to a UserCreator.
43  */
44 public class CreateUserActivity extends Activity {
45 
46     /**
47      * Creates an intent to start this activity.
48      */
createIntentForStart(Context context)49     public static Intent createIntentForStart(Context context) {
50         Intent intent = new Intent(context, CreateUserActivity.class);
51         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
52         return intent;
53     }
54 
55     private static final String TAG = "CreateUserActivity";
56     private static final String DIALOG_STATE_KEY = "create_user_dialog_state";
57 
58     private final UserCreator mUserCreator;
59     private final EditUserInfoController mEditUserInfoController;
60     private final IActivityManager mActivityManager;
61     private final ActivityStarter mActivityStarter;
62 
63     private Dialog mSetupUserDialog;
64     private final OnBackInvokedCallback mBackCallback = this::onBackInvoked;
65 
66     @Inject
CreateUserActivity(UserCreator userCreator, EditUserInfoController editUserInfoController, IActivityManager activityManager, ActivityStarter activityStarter)67     public CreateUserActivity(UserCreator userCreator,
68             EditUserInfoController editUserInfoController, IActivityManager activityManager,
69             ActivityStarter activityStarter) {
70         mUserCreator = userCreator;
71         mEditUserInfoController = editUserInfoController;
72         mActivityManager = activityManager;
73         mActivityStarter = activityStarter;
74     }
75 
76     @Override
onCreate(@ullable Bundle savedInstanceState)77     protected void onCreate(@Nullable Bundle savedInstanceState) {
78         super.onCreate(savedInstanceState);
79         setShowWhenLocked(true);
80         setContentView(R.layout.activity_create_new_user);
81 
82         if (savedInstanceState != null) {
83             mEditUserInfoController.onRestoreInstanceState(savedInstanceState);
84         }
85 
86         mSetupUserDialog = createDialog();
87         mSetupUserDialog.show();
88 
89         getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
90                         OnBackInvokedDispatcher.PRIORITY_DEFAULT,
91                         mBackCallback);
92     }
93 
94     @Override
onSaveInstanceState(@onNull Bundle outState)95     protected void onSaveInstanceState(@NonNull Bundle outState) {
96         if (mSetupUserDialog != null && mSetupUserDialog.isShowing()) {
97             outState.putBundle(DIALOG_STATE_KEY, mSetupUserDialog.onSaveInstanceState());
98         }
99 
100         mEditUserInfoController.onSaveInstanceState(outState);
101         super.onSaveInstanceState(outState);
102     }
103 
104     @Override
onRestoreInstanceState(@onNull Bundle savedInstanceState)105     protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
106         super.onRestoreInstanceState(savedInstanceState);
107         Bundle savedDialogState = savedInstanceState.getBundle(DIALOG_STATE_KEY);
108         if (savedDialogState != null && mSetupUserDialog != null) {
109             mSetupUserDialog.onRestoreInstanceState(savedDialogState);
110         }
111     }
112 
createDialog()113     private Dialog createDialog() {
114         String defaultUserName = getString(com.android.settingslib.R.string.user_new_user_name);
115 
116         return mEditUserInfoController.createDialog(
117                 this,
118                 this::startActivity,
119                 null,
120                 defaultUserName,
121                 getString(com.android.settingslib.R.string.user_add_user),
122                 this::addUserNow,
123                 this::finish
124         );
125     }
126 
127     @Override
onActivityResult(int requestCode, int resultCode, Intent data)128     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
129         super.onActivityResult(requestCode, resultCode, data);
130         mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
131     }
132 
133     @Override
onBackPressed()134     public void onBackPressed() {
135         onBackInvoked();
136     }
137 
onBackInvoked()138     private void onBackInvoked() {
139         if (mSetupUserDialog != null) {
140             mSetupUserDialog.dismiss();
141         }
142         finish();
143     }
144 
145     @Override
onDestroy()146     protected void onDestroy() {
147         getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mBackCallback);
148         super.onDestroy();
149     }
150 
addUserNow(String userName, Drawable userIcon)151     private void addUserNow(String userName, Drawable userIcon) {
152         mSetupUserDialog.dismiss();
153 
154         userName = (userName == null || userName.trim().isEmpty())
155                 ? getString(com.android.settingslib.R.string.user_new_user_name)
156                 : userName;
157 
158         mUserCreator.createUser(userName, userIcon,
159                 userInfo -> {
160                     switchToUser(userInfo.id);
161                     finishIfNeeded();
162                 }, () -> {
163                     Log.e(TAG, "Unable to create user");
164                     finishIfNeeded();
165                 });
166     }
167 
finishIfNeeded()168     private void finishIfNeeded() {
169         if (!isFinishing() && !isDestroyed()) {
170             finish();
171         }
172     }
173 
switchToUser(int userId)174     private void switchToUser(int userId) {
175         try {
176             mActivityManager.switchUser(userId);
177         } catch (RemoteException e) {
178             Log.e(TAG, "Couldn't switch user.", e);
179         }
180     }
181 
182     /**
183      * Lambda to start activity from an intent. Ensures that device is unlocked first.
184      * @param intent
185      * @param requestCode
186      */
startActivity(Intent intent, int requestCode)187     private void startActivity(Intent intent, int requestCode) {
188         mActivityStarter.dismissKeyguardThenExecute(() -> {
189             mEditUserInfoController.startingActivityForResult();
190             startActivityForResult(intent, requestCode);
191             return true;
192         }, /* cancel= */ null, /* afterKeyguardGone= */ true);
193     }
194 }
195