Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8d31ebb authored by Mayank Garg's avatar Mayank Garg Committed by Android (Google) Code Review
Browse files

Merge "Implementation for new createUser call"

parents 08281210 04f9d971
Loading
Loading
Loading
Loading

core/api/system-current.txt

100755 → 100644
+23 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
/*
 * 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 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+33 −0
Original line number Diff line number Diff line
@@ -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.
     *