Implementation for new createUser call

Bug: 199446283
CTS-Coverage-Bug: 199446283
Test: m
Change-Id: Ib15377cdac667b3ab6842aa894bb0890e341d610
This commit is contained in:
Mayank Garg
2021-10-13 13:58:04 -07:00
committed by Felipe Leme
parent 2a29c3f422
commit 04f9d971cc
5 changed files with 289 additions and 0 deletions

23
core/api/system-current.txt Executable file → Normal file
View File

@@ -8677,6 +8677,28 @@ package android.os {
method public boolean hasSingleFileDescriptor();
}
public final class NewUserRequest {
method @Nullable public String getName();
method @NonNull public String getUserType();
method public boolean isAdmin();
method public boolean isEphemeral();
}
public static final class NewUserRequest.Builder {
ctor public NewUserRequest.Builder();
method @NonNull public android.os.NewUserRequest build();
method @NonNull public android.os.NewUserRequest.Builder setAdmin();
method @NonNull public android.os.NewUserRequest.Builder setEphemeral();
method @NonNull public android.os.NewUserRequest.Builder setName(@Nullable String);
method @NonNull public android.os.NewUserRequest.Builder setUserType(@NonNull String);
}
public final class NewUserResponse {
method public int getOperationResult();
method @Nullable public android.os.UserHandle getUser();
method public boolean isSuccessful();
}
public interface Parcelable {
field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0
field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1
@@ -8913,6 +8935,7 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean canHaveRestrictedProfile();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void clearSeedAccountData();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle createProfile(@NonNull String, @NonNull String, @NonNull java.util.Set<java.lang.String>) throws android.os.UserManager.UserOperationException;
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.NewUserResponse createUser(@NonNull android.os.NewUserRequest);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public java.util.List<android.os.UserHandle> getAllProfiles();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public java.util.List<android.os.UserHandle> getEnabledProfiles();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public android.os.UserHandle getProfileParent(@NonNull android.os.UserHandle);

View File

@@ -31,6 +31,10 @@ KotlinKeyword: android.app.Notification#when:
MissingGetterMatchingBuilder: android.os.NewUserRequest.Builder#setAdmin():
android.os.NewUserRequest does not declare a `getAdmin()` method matching method android.os.NewUserRequest.Builder.setAdmin()
MissingGetterMatchingBuilder: android.os.NewUserRequest.Builder#setEphemeral():
android.os.NewUserRequest does not declare a `getEphemeral()` method matching method android.os.NewUserRequest.Builder.setEphemeral()
MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUid(int):
android.security.keystore.KeyGenParameterSpec does not declare a `getUid()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUid(int)
MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation):

View File

@@ -0,0 +1,170 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
/**
* Contains necessary information to create user using
* {@link UserManager#createUser(NewUserRequest)}.
*
* @hide
*/
@SystemApi
public final class NewUserRequest {
@Nullable
private final String mName;
private final boolean mAdmin;
private final boolean mEphemeral;
@NonNull
private final String mUserType;
private NewUserRequest(Builder builder) {
mName = builder.mName;
mAdmin = builder.mAdmin;
mEphemeral = builder.mEphemeral;
mUserType = builder.mUserType;
}
/**
* Gets the user name.
*/
@Nullable
public String getName() {
return mName;
}
/**
* Is user Ephemenral?
*
* <p> Ephemeral user will be removed after leaving the foreground.
*/
public boolean isEphemeral() {
return mEphemeral;
}
/**
* Is user Admin?
*
* <p> Admin user is with administrative privileges and such user can create and
* delete users.
*/
public boolean isAdmin() {
return mAdmin;
}
/**
* Gets user type.
*
* <p> Supported types are {@link UserManager.USER_TYPE_FULL_SECONDARY} and
* {@link USER_TYPE_FULL_GUEST}
*/
@NonNull
public String getUserType() {
return mUserType;
}
@Override
public String toString() {
return String.format(
"NewUserRequest- UserName:%s, userType:%s, IsAdmin:%s, IsEphemeral:%s.", mName,
mUserType, mAdmin, mEphemeral);
}
/**
* Builder for building {@link NewUserRequest}
*/
public static final class Builder {
private String mName;
private boolean mAdmin;
private boolean mEphemeral;
private String mUserType = UserManager.USER_TYPE_FULL_SECONDARY;
/**
* Sets user name.
*/
@NonNull
public Builder setName(@Nullable String name) {
mName = name;
return this;
}
/**
* Sets user as admin.
*
* <p> Admin user is with administrative privileges and such user can create
* and delete users.
*/
@NonNull
public Builder setAdmin() {
mAdmin = true;
return this;
}
/**
* Sets user as ephemeral.
*
* <p> Ephemeral user will be removed after leaving the foreground.
*/
@NonNull
public Builder setEphemeral() {
mEphemeral = true;
return this;
}
/**
* Sets user type.
* <p>
* Supported types are {@link UserManager.USER_TYPE_FULL_SECONDARY} and
* {@link UserManager.USER_TYPE_FULL_GUEST}. Default value is
* {@link UserManager.USER_TYPE_FULL_SECONDARY}.
*/
@NonNull
public Builder setUserType(@NonNull String type) {
mUserType = type;
return this;
}
/**
* Builds {@link NewUserRequest}
*
* @throws IllegalStateException if builder is configured with incompatible properties and
* it is not possible to create such user. For example - a guest admin user.
*/
@NonNull
public NewUserRequest build() {
checkIfPropertiesAreCompatible();
return new NewUserRequest(this);
}
private void checkIfPropertiesAreCompatible() {
// Conditions which can't be true simultaneously
// A guest user can't be admin user
if (mAdmin && mUserType == UserManager.USER_TYPE_FULL_GUEST) {
throw new IllegalStateException("A guest user can't be admin.");
}
// check for only supported user types
if (mUserType != UserManager.USER_TYPE_FULL_SECONDARY
&& mUserType != UserManager.USER_TYPE_FULL_GUEST) {
throw new IllegalStateException("Unsupported user type: " + mUserType);
}
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os;
import android.annotation.Nullable;
import android.annotation.SystemApi;
/**
* Contains the response of the call {@link UserManager#createUser(NewUserRequest)}.
*
* @hide
*/
@SystemApi
public final class NewUserResponse {
private final @Nullable UserHandle mUser;
private final @UserManager.UserOperationResult int mOperationResult;
NewUserResponse(@Nullable UserHandle user,
@UserManager.UserOperationResult int operationResult) {
mUser = user;
mOperationResult = operationResult;
}
/**
* Is user creation successful?
*/
public boolean isSuccessful() {
return mUser != null;
}
// TODO(b/199446283): If UserHandle.NULL is systemAPI, that can be returned here instead of null
/**
* Gets the created user handle.
*/
public @Nullable UserHandle getUser() {
return mUser;
}
/**
* Gets operation results.
*/
public @UserManager.UserOperationResult int getOperationResult() {
return mOperationResult;
}
}

View File

@@ -3148,6 +3148,39 @@ public class UserManager {
}
}
/**
* Creates a user with the specified {@link NewUserRequest}.
*
* @param newUserRequest specify the user information
*
* @hide
*/
@SystemApi
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
public @NonNull NewUserResponse createUser(@NonNull NewUserRequest newUserRequest) {
UserInfo user = null;
int operationResult = USER_OPERATION_ERROR_UNKNOWN;
try {
user = createUser(newUserRequest.getName(), newUserRequest.getUserType(),
determineFlagsForUserCreation(newUserRequest));
} catch (UserOperationException e) {
Log.w(TAG, "Exception while creating user " + newUserRequest, e);
operationResult = e.getUserOperationResult();
}
if (user == null) {
return new NewUserResponse(null, operationResult);
}
return new NewUserResponse(user.getUserHandle(), USER_OPERATION_SUCCESS);
}
private int determineFlagsForUserCreation(NewUserRequest newUserRequest) {
int flags = 0;
if (newUserRequest.isAdmin()) flags |= UserInfo.FLAG_ADMIN;
if (newUserRequest.isEphemeral()) flags |= UserInfo.FLAG_EPHEMERAL;
return flags;
}
/**
* Pre-creates a user of the specified type. Default user restrictions will be applied.
*