Put "Add user" dialog within activity to capture focus

Dialogs are not a part of view hierarchy so if the dialog loses focus, it cannot be reached by traversing.

When it is places within full-screen activity, then the focus is captured within activity and returns to the dialog. If the activity was embedded in the right side pane, like the dialog used to look, the dialog would be accessible by traversing but the focus would  be granted to the left pane of Settings app. Therefore this UI change is required.

Bug: 376815882
Test: atest UserSettingsTest
Flag: android.multiuser.place_add_user_dialog_within_activity
Change-Id: If9f280573d2b0da8deedcdeaeffc9db6160f27a0
This commit is contained in:
Tetiana Meronyk
2024-12-16 10:30:16 +00:00
parent a219b4dabc
commit 977025ff16
2 changed files with 44 additions and 8 deletions

View File

@@ -52,6 +52,7 @@ import com.android.settings.privatespace.PrivateSpaceSetupActivity;
import com.android.settings.privatespace.delete.PrivateSpaceDeleteActivity; import com.android.settings.privatespace.delete.PrivateSpaceDeleteActivity;
import com.android.settings.remoteauth.RemoteAuthActivity; import com.android.settings.remoteauth.RemoteAuthActivity;
import com.android.settings.remoteauth.RemoteAuthActivityInternal; import com.android.settings.remoteauth.RemoteAuthActivityInternal;
import com.android.settingslib.users.CreateUserActivity;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@@ -278,6 +279,10 @@ public class ActivityEmbeddingRulesController {
String action = mContext.getString(R.string.config_avatar_picker_action); String action = mContext.getString(R.string.config_avatar_picker_action);
addActivityFilter(activityFilters, new Intent(action)); addActivityFilter(activityFilters, new Intent(action));
if (android.multiuser.Flags.placeAddUserDialogWithinActivity()) {
addActivityFilter(activityFilters, CreateUserActivity.class);
}
ActivityRule activityRule = new ActivityRule.Builder(activityFilters).setAlwaysExpand(true) ActivityRule activityRule = new ActivityRule.Builder(activityFilters).setAlwaysExpand(true)
.build(); .build();
mRuleController.addRule(activityRule); mRuleController.addRule(activityRule);

View File

@@ -18,6 +18,9 @@ package com.android.settings.users;
import static com.android.settingslib.Utils.getColorAttrDefaultColor; import static com.android.settingslib.Utils.getColorAttrDefaultColor;
import android.Manifest;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.Dialog; import android.app.Dialog;
@@ -83,6 +86,7 @@ import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.drawable.CircleFramedDrawable; import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.search.SearchIndexableRaw; import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.users.CreateUserActivity;
import com.android.settingslib.users.CreateUserDialogController; import com.android.settingslib.users.CreateUserDialogController;
import com.android.settingslib.users.EditUserInfoController; import com.android.settingslib.users.EditUserInfoController;
import com.android.settingslib.users.GrantAdminDialogController; import com.android.settingslib.users.GrantAdminDialogController;
@@ -91,6 +95,7 @@ import com.android.settingslib.utils.ThreadUtils;
import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupcompat.util.WizardManagerHelper;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@@ -171,6 +176,7 @@ public class UserSettings extends SettingsPreferenceFragment
private static final int REQUEST_CHOOSE_LOCK = 10; private static final int REQUEST_CHOOSE_LOCK = 10;
private static final int REQUEST_EDIT_GUEST = 11; private static final int REQUEST_EDIT_GUEST = 11;
private static final int REQUEST_ADD_USER = 12;
static final int RESULT_GUEST_REMOVED = 100; static final int RESULT_GUEST_REMOVED = 100;
@@ -234,6 +240,8 @@ public class UserSettings extends SettingsPreferenceFragment
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private CharSequence mPendingUserName; private CharSequence mPendingUserName;
@Nullable
private String mPendingUserIconPath;
private Drawable mPendingUserIcon; private Drawable mPendingUserIcon;
private boolean mPendingUserIsAdmin; private boolean mPendingUserIsAdmin;
@@ -570,6 +578,14 @@ public class UserSettings extends SettingsPreferenceFragment
if (resultCode != Activity.RESULT_CANCELED && hasLockscreenSecurity()) { if (resultCode != Activity.RESULT_CANCELED && hasLockscreenSecurity()) {
addUserNow(USER_TYPE_RESTRICTED_PROFILE); addUserNow(USER_TYPE_RESTRICTED_PROFILE);
} }
} else if (Flags.placeAddUserDialogWithinActivity() && requestCode == REQUEST_ADD_USER) {
if (resultCode == Activity.RESULT_OK) {
mPendingUserName = data.getStringExtra(CreateUserActivity.EXTRA_USER_NAME);
mPendingUserIsAdmin = data.getBooleanExtra(CreateUserActivity.EXTRA_IS_ADMIN,
false);
mPendingUserIconPath = data.getStringExtra(CreateUserActivity.EXTRA_USER_ICON_PATH);
addUserNow(USER_TYPE_USER);
}
} else if (mGuestUserAutoCreated && requestCode == REQUEST_EDIT_GUEST } else if (mGuestUserAutoCreated && requestCode == REQUEST_EDIT_GUEST
&& resultCode == RESULT_GUEST_REMOVED) { && resultCode == RESULT_GUEST_REMOVED) {
scheduleGuestCreation(); scheduleGuestCreation();
@@ -921,7 +937,7 @@ public class UserSettings extends SettingsPreferenceFragment
getActivity(), getActivity(),
this::startActivityForResult, this::startActivityForResult,
canCreateAdminUser(), canCreateAdminUser(),
(userName, userIcon, isAdmin) -> { (userName, userIcon, iconPath, isAdmin) -> {
mPendingUserIcon = userIcon; mPendingUserIcon = userIcon;
mPendingUserName = userName; mPendingUserName = userName;
mPendingUserIsAdmin = isAdmin; mPendingUserIsAdmin = isAdmin;
@@ -1040,6 +1056,8 @@ public class UserSettings extends SettingsPreferenceFragment
createUser(userType, mAddingUserName); createUser(userType, mAddingUserName);
} }
@RequiresPermission(allOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.INTERACT_ACROSS_USERS_FULL})
@VisibleForTesting @VisibleForTesting
void createUser(final int userType, String userName) { void createUser(final int userType, String userName) {
Context context = getContext(); Context context = getContext();
@@ -1065,18 +1083,25 @@ public class UserSettings extends SettingsPreferenceFragment
mAddingUser = false; mAddingUser = false;
mPendingUserIcon = null; mPendingUserIcon = null;
mPendingUserName = null; mPendingUserName = null;
mPendingUserIconPath = null;
onUserCreationFailed(); onUserCreationFailed();
return; return;
} }
Future<?> unusedSettingIconFuture = ThreadUtils.postOnBackgroundThread(() -> { Future<?> unusedSettingIconFuture = ThreadUtils.postOnBackgroundThread(() -> {
Drawable newUserIcon = selectedUserIcon; if (Flags.placeAddUserDialogWithinActivity() && mPendingUserIconPath != null) {
if (newUserIcon == null) { Bitmap bitmap = BitmapFactory.decodeFile(mPendingUserIconPath);
newUserIcon = UserIcons.getDefaultUserIcon(resources, user.id, false); mUserManager.setUserIcon(user.id, bitmap);
new File(mPendingUserIconPath).delete();
mPendingUserIconPath = null;
} else {
Drawable newUserIcon = selectedUserIcon;
if (newUserIcon == null) {
newUserIcon = UserIcons.getDefaultUserIcon(resources, user.id, false);
}
mUserManager.setUserIcon(user.id, UserIcons.convertToBitmapAtUserIconSize(
resources, newUserIcon));
} }
mUserManager.setUserIcon(
user.id, UserIcons.convertToBitmapAtUserIconSize(
resources, newUserIcon));
}); });
mPendingUserIcon = null; mPendingUserIcon = null;
@@ -1687,7 +1712,13 @@ public class UserSettings extends SettingsPreferenceFragment
if (mUserCaps.mCanAddRestrictedProfile) { if (mUserCaps.mCanAddRestrictedProfile) {
showDialog(DIALOG_CHOOSE_USER_TYPE); showDialog(DIALOG_CHOOSE_USER_TYPE);
} else { } else {
onAddUserClicked(USER_TYPE_USER); if (Flags.placeAddUserDialogWithinActivity()) {
startActivityForResult(CreateUserActivity.createIntentForStart(getActivity(),
canCreateAdminUser(), Utils.FILE_PROVIDER_AUTHORITY),
REQUEST_ADD_USER);
} else {
onAddUserClicked(USER_TYPE_USER);
}
} }
return true; return true;
} else if (pref == mAddSupervisedUser) { } else if (pref == mAddSupervisedUser) {