Implementation for new createUser call
Bug: 199446283 CTS-Coverage-Bug: 199446283 Test: m Change-Id: Ib15377cdac667b3ab6842aa894bb0890e341d610
This commit is contained in:
23
core/api/system-current.txt
Executable file → Normal file
23
core/api/system-current.txt
Executable file → Normal 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);
|
||||
|
||||
@@ -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):
|
||||
|
||||
170
core/java/android/os/NewUserRequest.java
Normal file
170
core/java/android/os/NewUserRequest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
core/java/android/os/NewUserResponse.java
Normal file
59
core/java/android/os/NewUserResponse.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user