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

Commit a044c1d2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Introduce more user management APIs"

parents 0e86a249 af9bb8d9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -6371,6 +6371,7 @@ package android.app.admin {
    method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
    method public long getRequiredStrongAuthTimeout(android.content.ComponentName);
    method public boolean getScreenCaptureDisabled(android.content.ComponentName);
    method public java.util.List<android.os.UserHandle> getSecondaryUsers(android.content.ComponentName);
    method public java.lang.CharSequence getShortSupportMessage(android.content.ComponentName);
    method public boolean getStorageEncryption(android.content.ComponentName);
    method public int getStorageEncryptionStatus();
@@ -6403,6 +6404,7 @@ package android.app.admin {
    method public boolean isUninstallBlocked(android.content.ComponentName, java.lang.String);
    method public void lockNow();
    method public void lockNow(int);
    method public boolean logoutUser(android.content.ComponentName);
    method public void reboot(android.content.ComponentName);
    method public void removeActiveAdmin(android.content.ComponentName);
    method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -6477,6 +6479,7 @@ package android.app.admin {
    method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
    method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
    method public void setUserIcon(android.content.ComponentName, android.graphics.Bitmap);
    method public boolean stopUser(android.content.ComponentName, android.os.UserHandle);
    method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
    method public void uninstallAllUserCaCerts(android.content.ComponentName);
    method public void uninstallCaCert(android.content.ComponentName, byte[]);
+61 −1
Original line number Diff line number Diff line
@@ -6219,7 +6219,7 @@ public class DevicePolicyManager {
     * @return {@code true} if the user was removed, {@code false} otherwise.
     * @throws SecurityException if {@code admin} is not a device owner.
     */
    public boolean removeUser(@NonNull ComponentName admin, UserHandle userHandle) {
    public boolean removeUser(@NonNull ComponentName admin, @NonNull UserHandle userHandle) {
        throwIfParentInstance("removeUser");
        try {
            return mService.removeUser(admin, userHandle);
@@ -6230,6 +6230,7 @@ public class DevicePolicyManager {

    /**
     * Called by a device owner to switch the specified user to the foreground.
     * <p> This cannot be used to switch to a managed profile.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param userHandle the user to switch to; null will switch to primary.
@@ -6246,6 +6247,65 @@ public class DevicePolicyManager {
        }
    }

    /**
     * Called by a device owner to stop the specified secondary user.
     * <p> This cannot be used to stop the primary user or a managed profile.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param userHandle the user to be stopped.
     * @return {@code true} if the user can be stopped, {@code false} otherwise.
     * @throws SecurityException if {@code admin} is not a device owner.
     */
    public boolean stopUser(@NonNull ComponentName admin, @NonNull UserHandle userHandle) {
        throwIfParentInstance("stopUser");
        try {
            return mService.stopUser(admin, userHandle);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Called by a profile owner that is affiliated with the device owner to stop the calling user
     * and switch back to primary.
     * <p> This has no effect when called on a managed profile.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @return {@code true} if the exit was successful, {@code false} otherwise.
     * @throws SecurityException if {@code admin} is not a profile owner affiliated with the device
     * owner.
     */
    public boolean logoutUser(@NonNull ComponentName admin) {
        throwIfParentInstance("logoutUser");
        try {
            return mService.logoutUser(admin);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Called by a device owner to list all secondary users on the device, excluding managed
     * profiles.
     * <p> Used for various user management APIs, including {@link #switchUser}, {@link #removeUser}
     * and {@link #stopUser}.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @return list of other {@link UserHandle}s on the device.
     * @throws SecurityException if {@code admin} is not a device owner.
     * @see #switchUser
     * @see #removeUser
     * @see #stopUser
     */
    public List<UserHandle> getSecondaryUsers(@NonNull ComponentName admin) {
        throwIfParentInstance("getSecondaryUsers");
        try {
            return mService.getSecondaryUsers(admin);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Retrieves the application restrictions for a given target application running in the calling
     * user.
+3 −0
Original line number Diff line number Diff line
@@ -215,6 +215,9 @@ interface IDevicePolicyManager {
    UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags);
    boolean removeUser(in ComponentName who, in UserHandle userHandle);
    boolean switchUser(in ComponentName who, in UserHandle userHandle);
    boolean stopUser(in ComponentName who, in UserHandle userHandle);
    boolean logoutUser(in ComponentName who);
    List<UserHandle> getSecondaryUsers(in ComponentName who);

    void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName);
    int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);
+85 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.devicepolicy;
import static android.Manifest.permission.BIND_DEVICE_ADMIN;
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.USER_OP_SUCCESS;
import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY;
import static android.app.admin.DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED;
import static android.app.admin.DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE;
@@ -8402,6 +8403,90 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
    }

    @Override
    public boolean stopUser(ComponentName who, UserHandle userHandle) {
        Preconditions.checkNotNull(who, "ComponentName is null");

        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
        }

        final int userId = userHandle.getIdentifier();
        if (isManagedProfile(userId)) {
            Log.w(LOG_TAG, "Managed profile cannot be stopped");
            return false;
        }

        final long id = mInjector.binderClearCallingIdentity();
        try {
            return mInjector.getIActivityManager().stopUser(userId, true /*force*/, null)
                    == USER_OP_SUCCESS;
        } catch (RemoteException e) {
            // Same process, should not happen.
            return false;
        } finally {
            mInjector.binderRestoreCallingIdentity(id);
        }
    }

    @Override
    public boolean logoutUser(ComponentName who) {
        Preconditions.checkNotNull(who, "ComponentName is null");

        final int callingUserId = mInjector.userHandleGetCallingUserId();
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
            if (!isUserAffiliatedWithDeviceLocked(callingUserId)) {
                throw new SecurityException("Admin " + who +
                        " is neither the device owner or affiliated user's profile owner.");
            }
        }

        if (isManagedProfile(callingUserId)) {
            Log.w(LOG_TAG, "Managed profile cannot be logout");
            return false;
        }

        final long id = mInjector.binderClearCallingIdentity();
        try {
            if (!mInjector.getIActivityManager().switchUser(UserHandle.USER_SYSTEM)) {
                Log.w(LOG_TAG, "Failed to switch to primary user");
                return false;
            }
            return mInjector.getIActivityManager().stopUser(callingUserId, true /*force*/, null)
                    == USER_OP_SUCCESS;
        } catch (RemoteException e) {
            // Same process, should not happen.
            return false;
        } finally {
            mInjector.binderRestoreCallingIdentity(id);
        }
    }

    @Override
    public List<UserHandle> getSecondaryUsers(ComponentName who) {
        Preconditions.checkNotNull(who, "ComponentName is null");
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
        }

        final long id = mInjector.binderClearCallingIdentity();
        try {
            final List<UserInfo> userInfos = mInjector.getUserManager().getUsers(true
                    /*excludeDying*/);
            final List<UserHandle> userHandles = new ArrayList<>();
            for (UserInfo userInfo : userInfos) {
                UserHandle userHandle = userInfo.getUserHandle();
                if (!userHandle.isSystem() && !isManagedProfile(userHandle.getIdentifier())) {
                    userHandles.add(userInfo.getUserHandle());
                }
            }
            return userHandles;
        } finally {
            mInjector.binderRestoreCallingIdentity(id);
        }
    }

    @Override
    public Bundle getApplicationRestrictions(ComponentName who, String callerPackage,
            String packageName) {