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

Commit 04f9d971 authored by Mayank Garg's avatar Mayank Garg Committed by Felipe Leme
Browse files

Implementation for new createUser call

Bug: 199446283
CTS-Coverage-Bug: 199446283
Test: m
Change-Id: Ib15377cdac667b3ab6842aa894bb0890e341d610
parent 2a29c3f4
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.
     *