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.internal.logging.UiEventLogger; 35 import com.android.settingslib.users.CreateUserDialogController; 36 import com.android.systemui.plugins.ActivityStarter; 37 import com.android.systemui.res.R; 38 39 import javax.inject.Inject; 40 41 /** 42 * This screen shows a Dialog for choosing nickname and photo for a new user, and then delegates the 43 * user creation to a UserCreator. 44 */ 45 public class CreateUserActivity extends Activity { 46 47 /** 48 * Creates an intent to start this activity. 49 */ createIntentForStart(Context context, boolean isKeyguardShowing)50 public static Intent createIntentForStart(Context context, boolean isKeyguardShowing) { 51 Intent intent = new Intent(context, CreateUserActivity.class); 52 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 53 intent.putExtra(EXTRA_IS_KEYGUARD_SHOWING, isKeyguardShowing); 54 return intent; 55 } 56 57 private static final String TAG = "CreateUserActivity"; 58 private static final String DIALOG_STATE_KEY = "create_user_dialog_state"; 59 private static final String EXTRA_IS_KEYGUARD_SHOWING = "extra_is_keyguard_showing"; 60 61 private final UserCreator mUserCreator; 62 private CreateUserDialogController mCreateUserDialogController; 63 private final IActivityManager mActivityManager; 64 private final ActivityStarter mActivityStarter; 65 private final UiEventLogger mUiEventLogger; 66 private Dialog mSetupUserDialog; 67 private final OnBackInvokedCallback mBackCallback = this::onBackInvoked; 68 @Inject CreateUserActivity(UserCreator userCreator, CreateUserDialogController createUserDialogController, IActivityManager activityManager, ActivityStarter activityStarter, UiEventLogger uiEventLogger)69 public CreateUserActivity(UserCreator userCreator, 70 CreateUserDialogController createUserDialogController, IActivityManager activityManager, 71 ActivityStarter activityStarter, UiEventLogger uiEventLogger) { 72 mUserCreator = userCreator; 73 mCreateUserDialogController = createUserDialogController; 74 mActivityManager = activityManager; 75 mActivityStarter = activityStarter; 76 mUiEventLogger = uiEventLogger; 77 } 78 79 @Override onCreate(@ullable Bundle savedInstanceState)80 protected void onCreate(@Nullable Bundle savedInstanceState) { 81 super.onCreate(savedInstanceState); 82 setShowWhenLocked(true); 83 setContentView(R.layout.activity_create_new_user); 84 if (savedInstanceState != null) { 85 mCreateUserDialogController.onRestoreInstanceState(savedInstanceState); 86 } 87 mSetupUserDialog = createDialog(); 88 mSetupUserDialog.show(); 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 mCreateUserDialogController.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 boolean isKeyguardShowing = getIntent().getBooleanExtra(EXTRA_IS_KEYGUARD_SHOWING, true); 116 return mCreateUserDialogController.createDialog( 117 this, 118 this::startActivity, 119 (mUserCreator.isMultipleAdminEnabled() && mUserCreator.isUserAdmin() 120 && !isKeyguardShowing), 121 this::addUserNow, 122 this::finish 123 ); 124 } 125 126 @Override onActivityResult(int requestCode, int resultCode, Intent data)127 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 128 super.onActivityResult(requestCode, resultCode, data); 129 mCreateUserDialogController.onActivityResult(requestCode, resultCode, data); 130 } 131 132 @Override onBackPressed()133 public void onBackPressed() { 134 onBackInvoked(); 135 } 136 onBackInvoked()137 private void onBackInvoked() { 138 if (mSetupUserDialog != null) { 139 mSetupUserDialog.dismiss(); 140 } 141 finish(); 142 } 143 144 @Override onDestroy()145 protected void onDestroy() { 146 getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mBackCallback); 147 super.onDestroy(); 148 } 149 addUserNow(String userName, Drawable userIcon, Boolean isAdmin)150 private void addUserNow(String userName, Drawable userIcon, Boolean isAdmin) { 151 mSetupUserDialog.dismiss(); 152 userName = (userName == null || userName.trim().isEmpty()) 153 ? getString(com.android.settingslib.R.string.user_new_user_name) 154 : userName; 155 156 mUserCreator.createUser(userName, userIcon, 157 userInfo -> { 158 if (isAdmin) { 159 mUserCreator.setUserAdmin(userInfo.id); 160 } 161 switchToUser(userInfo.id); 162 finishIfNeeded(); 163 }, () -> { 164 Log.e(TAG, "Unable to create user"); 165 finishIfNeeded(); 166 }); 167 } 168 finishIfNeeded()169 private void finishIfNeeded() { 170 if (!isFinishing() && !isDestroyed()) { 171 finish(); 172 } 173 } 174 switchToUser(int userId)175 private void switchToUser(int userId) { 176 try { 177 mActivityManager.switchUser(userId); 178 } catch (RemoteException e) { 179 Log.e(TAG, "Couldn't switch user.", e); 180 } 181 } 182 183 /** 184 * Lambda to start activity from an intent. Ensures that device is unlocked first. 185 * @param intent 186 * @param requestCode 187 */ startActivity(Intent intent, int requestCode)188 private void startActivity(Intent intent, int requestCode) { 189 mActivityStarter.dismissKeyguardThenExecute(() -> { 190 mCreateUserDialogController.startingActivityForResult(); 191 startActivityForResult(intent, requestCode); 192 return true; 193 }, /* cancel= */ null, /* afterKeyguardGone= */ true); 194 } 195 } 196