Fix Guest string was not translated in UMS.userWithName()

Guest users name was stuck with the language when it was created,
and it wasn't changing with the active language setting.
To solve that, removed name parameter from UM.createGuest() and
created the guest user with a null name, then made changes
in UMS.userWithName() to fill the name of guest user with the active
language's translation when it has a null name.
Creating a guest with a specific name is still supported
through UM.createUser API.

Bug: 185309160
Test: atest com.android.server.pm.UserManagerTest
Change-Id: I2745aed0ea722765a11c6da40fb4159146da54c7
Merged-In: I2745aed0ea722765a11c6da40fb4159146da54c7
(cherry picked from commit c556777ca4)
This commit is contained in:
Yasin Kilicdere
2022-02-10 23:04:56 +00:00
parent c4c1ac53fd
commit d03224f326
7 changed files with 44 additions and 21 deletions

View File

@@ -3322,7 +3322,7 @@ public class UserManager {
*
* <p>This method can be used by OEMs to "warm" up the user creation by pre-creating some users
* at the first boot, so they when the "real" user is created (for example,
* by {@link #createUser(String, String, int)} or {@link #createGuest(Context, String)}), it
* by {@link #createUser(String, String, int)} or {@link #createGuest(Context)}), it
* takes less time.
*
* <p>This method completes the majority of work necessary for user creation: it
@@ -3359,7 +3359,6 @@ public class UserManager {
/**
* Creates a guest user and configures it.
* @param context an application context
* @param name the name to set for the user
* @return the {@link UserInfo} object for the created user, or {@code null} if the user
* could not be created.
*
@@ -3367,20 +3366,19 @@ public class UserManager {
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
public UserInfo createGuest(Context context, String name) {
UserInfo guest = null;
public UserInfo createGuest(Context context) {
try {
guest = mService.createUserWithThrow(name, USER_TYPE_FULL_GUEST, 0);
final UserInfo guest = mService.createUserWithThrow(null, USER_TYPE_FULL_GUEST, 0);
if (guest != null) {
Settings.Secure.putStringForUser(context.getContentResolver(),
Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
}
return guest;
} catch (ServiceSpecificException e) {
return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
return guest;
}
/**

View File

@@ -4894,6 +4894,8 @@
<string name="user_logging_out_message">Logging out <xliff:g id="name" example="Bob">%1$s</xliff:g>\u2026</string>
<!-- Default name of the owner user [CHAR LIMIT=20] -->
<string name="owner_name" msgid="3879126011135546571">Owner</string>
<!-- Default name of the guest user [CHAR LIMIT=35] -->
<string name="guest_name">Guest</string>
<!-- Error message title [CHAR LIMIT=35] -->
<string name="error_message_title">Error</string>
<!-- Message informing user that the change was disallowed by an administrator. [CHAR LIMIT=none] -->

View File

@@ -1108,6 +1108,7 @@
<java-symbol type="string" name="media_route_status_not_available" />
<java-symbol type="string" name="media_route_status_in_use" />
<java-symbol type="string" name="owner_name" />
<java-symbol type="string" name="guest_name" />
<java-symbol type="string" name="config_chooseAccountActivity" />
<java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
<java-symbol type="string" name="config_chooserActivity" />

View File

@@ -855,8 +855,7 @@ public class UserSwitcherController implements Dumpable {
public @UserIdInt int createGuest() {
UserInfo guest;
try {
guest = mUserManager.createGuest(mContext,
mContext.getString(com.android.settingslib.R.string.guest_nickname));
guest = mUserManager.createGuest(mContext);
} catch (UserManager.UserOperationException e) {
Log.e(TAG, "Couldn't create guest user", e);
return UserHandle.USER_NULL;

View File

@@ -64,7 +64,6 @@ import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.anyString
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
@@ -207,7 +206,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
`when`(userTracker.userId).thenReturn(ownerId)
`when`(userTracker.userInfo).thenReturn(ownerInfo)
`when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
`when`(userManager.createGuest(any())).thenReturn(guestInfo)
userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, null)
testableLooper.processAllMessages()
@@ -232,7 +231,7 @@ class UserSwitcherControllerTest : SysuiTestCase() {
`when`(userTracker.userId).thenReturn(ownerId)
`when`(userTracker.userInfo).thenReturn(ownerInfo)
`when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
`when`(userManager.createGuest(any())).thenReturn(guestInfo)
userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, dialogShower)
testableLooper.processAllMessages()

View File

@@ -1399,21 +1399,28 @@ public class UserManagerService extends IUserManager.Stub {
}
/**
* Returns a UserInfo object with the name filled in, for Owner, or the original
* Returns a UserInfo object with the name filled in, for Owner and Guest, or the original
* if the name is already set.
*/
private UserInfo userWithName(UserInfo orig) {
if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
if (DBG_ALLOCATION) {
final int number = mUser0Allocations.incrementAndGet();
Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
if (orig != null && orig.name == null) {
String name = null;
if (orig.id == UserHandle.USER_SYSTEM) {
if (DBG_ALLOCATION) {
final int number = mUser0Allocations.incrementAndGet();
Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
}
name = getOwnerName();
} else if (orig.isGuest()) {
name = getGuestName();
}
if (name != null) {
final UserInfo withName = new UserInfo(orig);
withName.name = name;
return withName;
}
UserInfo withName = new UserInfo(orig);
withName.name = getOwnerName();
return withName;
} else {
return orig;
}
return orig;
}
/** Returns whether the given user type is one of the FULL user types. */
@@ -3259,6 +3266,10 @@ public class UserManagerService extends IUserManager.Stub {
return mOwnerName.get();
}
private String getGuestName() {
return mContext.getString(com.android.internal.R.string.guest_name);
}
private void invalidateOwnerNameIfNecessary(@NonNull Resources res, boolean forceUpdate) {
final int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
if (forceUpdate || (configChanges & mOwnerNameTypedValue.changingConfigurations) != 0) {

View File

@@ -1078,6 +1078,19 @@ public final class UserManagerTest {
assertThat(um.getUserName()).isEqualTo(userName);
}
@Test
public void testGetUserName_shouldReturnTranslatedTextForNullNamedGuestUser() throws Exception {
UserInfo guestWithNullName = createUser(null, UserManager.USER_TYPE_FULL_GUEST, 0);
assertThat(guestWithNullName).isNotNull();
UserManager um = (UserManager) mContext.createPackageContextAsUser(
"android", 0, guestWithNullName.getUserHandle())
.getSystemService(Context.USER_SERVICE);
assertThat(um.getUserName()).isEqualTo(
mContext.getString(com.android.internal.R.string.guest_name));
}
@Test
public void testGetUserIcon_withContextUserId() throws Exception {
assumeManagedUsersSupported();