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

Commit 2b04a58d authored by Lenka Trochtova's avatar Lenka Trochtova Committed by Android (Google) Code Review
Browse files

Merge "Add policy for enforcing that all users are ephemeral."

parents 21d21131 f348e8e2
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -2769,6 +2769,45 @@ public class DevicePolicyManager {
        return false;
    }

    /**
     * Called by a device owner to set whether all users created on the device should be ephemeral.
     *
     * <p>The system user is exempt from this policy - it is never ephemeral.
     *
     * <p>The calling device admin must be the device owner. If it is not, a security exception will
     * be thrown.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param forceEphemeralUsers If true, all the existing users will be deleted and all
     *         subsequently created users will be ephemeral.
     * @hide
     */
    public void setForceEphemeralUsers(
            @NonNull ComponentName admin, boolean forceEphemeralUsers) {
        if (mService != null) {
            try {
                mService.setForceEphemeralUsers(admin, forceEphemeralUsers);
            } catch (RemoteException e) {
                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
            }
        }
    }

    /**
     * @return true if all users are created ephemeral.
     * @hide
     */
    public boolean getForceEphemeralUsers(@NonNull ComponentName admin) {
        if (mService != null) {
            try {
                return mService.getForceEphemeralUsers(admin);
            } catch (RemoteException e) {
                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
            }
        }
        return false;
    }

    /**
     * Called by an application that is administering the device to disable keyguard customizations,
     * such as widgets. After setting this, keyguard features will be disabled according to the
+3 −0
Original line number Diff line number Diff line
@@ -230,6 +230,9 @@ interface IDevicePolicyManager {
    void setAutoTimeRequired(in ComponentName who, boolean required);
    boolean getAutoTimeRequired();

    void setForceEphemeralUsers(in ComponentName who, boolean forceEpehemeralUsers);
    boolean getForceEphemeralUsers(in ComponentName who);

    boolean isRemovingAdmin(in ComponentName adminReceiver, int userHandle);

    void setUserIcon(in ComponentName admin, in Bitmap icon);
+15 −0
Original line number Diff line number Diff line
@@ -91,4 +91,19 @@ public abstract class UserManagerInternal {
     * the icon is in this method.
     */
    public abstract void setUserIcon(int userId, Bitmap bitmap);

    /**
     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to inform the
     * user manager whether all users should be created ephemeral.
     */
    public abstract void setForceEphemeralUsers(boolean forceEphemeralUsers);

    /**
     * Switches to the system user and deletes all other users.
     *
     * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
     * the force-ephemeral-users policy is toggled on to make sure there are no pre-existing
     * non-ephemeral users left.
     */
    public abstract void removeAllUsers();
}
+79 −14
Original line number Diff line number Diff line
@@ -25,9 +25,11 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -302,6 +304,12 @@ public class UserManagerService extends IUserManager.Stub {

    private final LockPatternUtils mLockPatternUtils;

    /**
     * Whether all users should be created ephemeral.
     */
    @GuardedBy("mUsersLock")
    private boolean mForceEphemeralUsers;

    private static UserManagerService sInstance;

    public static UserManagerService getInstance() {
@@ -1836,14 +1844,18 @@ public class UserManagerService extends IUserManager.Stub {
                    }
                }

                // Add ephemeral flag to guests if required. Also inherit it from parent.
                userId = getNextAvailableId();
                Environment.getUserSystemDirectory(userId).mkdirs();
                boolean ephemeralGuests = Resources.getSystem()
                        .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
                if ((isGuest && ephemeralGuests)

                synchronized (mUsersLock) {
                    // Add ephemeral flag to guests/users if required. Also inherit it from parent.
                    if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
                            || (parent != null && parent.info.isEphemeral())) {
                        flags |= UserInfo.FLAG_EPHEMERAL;
                    }
                userId = getNextAvailableId();

                    userInfo = new UserInfo(userId, name, null, flags);
                    userInfo.serialNumber = mNextSerialNumber++;
                    long now = System.currentTimeMillis();
@@ -1851,8 +1863,6 @@ public class UserManagerService extends IUserManager.Stub {
                    userInfo.partial = true;
                    userData = new UserData();
                    userData.info = userInfo;
                Environment.getUserSystemDirectory(userInfo.id).mkdirs();
                synchronized (mUsersLock) {
                    mUsers.put(userId, userData);
                }
                writeUserListLP();
@@ -2914,6 +2924,61 @@ public class UserManagerService extends IUserManager.Stub {
                Binder.restoreCallingIdentity(ident);
            }
        }

        @Override
        public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
            synchronized (mUsersLock) {
                mForceEphemeralUsers = forceEphemeralUsers;
            }
        }

        @Override
        public void removeAllUsers() {
            if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
                // Remove the non-system users straight away.
                removeNonSystemUsers();
            } else {
                // Switch to the system user first and then remove the other users.
                BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        int userId =
                                intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                        if (userId != UserHandle.USER_SYSTEM) {
                            return;
                        }
                        mContext.unregisterReceiver(this);
                        removeNonSystemUsers();
                    }
                };
                IntentFilter userSwitchedFilter = new IntentFilter();
                userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
                mContext.registerReceiver(
                        userSwitchedReceiver, userSwitchedFilter, null, mHandler);

                // Switch to the system user.
                ActivityManager am =
                        (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
                am.switchUser(UserHandle.USER_SYSTEM);
            }
        }
    }

    /* Remove all the users except of the system one. */
    private void removeNonSystemUsers() {
        ArrayList<UserInfo> usersToRemove = new ArrayList<>();
        synchronized (mUsersLock) {
            final int userSize = mUsers.size();
            for (int i = 0; i < userSize; i++) {
                UserInfo ui = mUsers.valueAt(i).info;
                if (ui.id != UserHandle.USER_SYSTEM) {
                    usersToRemove.add(ui);
                }
            }
        }
        for (UserInfo ui: usersToRemove) {
            removeUser(ui.id);
        }
    }

    private class Shell extends ShellCommand {
+63 −1
Original line number Diff line number Diff line
@@ -471,6 +471,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
        private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
        private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
        private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
        private static final String TAG_ACCOUNT_TYPE = "account-type";
        private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
                = "permitted-accessiblity-services";
@@ -559,6 +560,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        boolean disableBluetoothContactSharing = true;
        boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
        boolean requireAutoTime = false; // Can only be set by a device owner.
        boolean forceEphemeralUsers = false; // Can only be set by a device owner.

        ActiveAdmin parentAdmin;
        final boolean isParent;
@@ -749,6 +751,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                out.attribute(null, ATTR_VALUE, Boolean.toString(requireAutoTime));
                out.endTag(null, TAG_REQUIRE_AUTO_TIME);
            }
            if (forceEphemeralUsers) {
                out.startTag(null, TAG_FORCE_EPHEMERAL_USERS);
                out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
                out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
            }
            if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
                out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
                out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
@@ -921,6 +928,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                } else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
                    requireAutoTime = Boolean.parseBoolean(
                            parser.getAttributeValue(null, ATTR_VALUE));
                } else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
                    forceEphemeralUsers = Boolean.parseBoolean(
                            parser.getAttributeValue(null, ATTR_VALUE));
                } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
                    disabledKeyguardFeatures = Integer.parseInt(
                            parser.getAttributeValue(null, ATTR_VALUE));
@@ -1150,6 +1160,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    pw.println(disableScreenCapture);
            pw.print(prefix); pw.print("requireAutoTime=");
                    pw.println(requireAutoTime);
            pw.print(prefix); pw.print("forceEphemeralUsers=");
                    pw.println(forceEphemeralUsers);
            pw.print(prefix); pw.print("disabledKeyguardFeatures=");
                    pw.println(disabledKeyguardFeatures);
            pw.print(prefix); pw.print("crossProfileWidgetProviders=");
@@ -2408,6 +2420,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        if (packageList != null) {
            mInjector.getPackageManagerInternal().setKeepUninstalledPackages(packageList);
        }

        synchronized (this) {
            // push the force-ephemeral-users policy to the user manager.
            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
            if (deviceOwner != null) {
                mUserManagerInternal.setForceEphemeralUsers(deviceOwner.forceEphemeralUsers);
            }
        }
    }

    private void ensureDeviceOwnerUserStarted() {
@@ -4789,6 +4809,46 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
    }

    @Override
    public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) {
        if (!mHasFeature) {
            return;
        }
        Preconditions.checkNotNull(who, "ComponentName is null");
        boolean removeAllUsers = false;
        synchronized (this) {
            final ActiveAdmin deviceOwner =
                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
            if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) {
                deviceOwner.forceEphemeralUsers = forceEphemeralUsers;
                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
                mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers);
                removeAllUsers = forceEphemeralUsers;
            }
        }
        if (removeAllUsers) {
            long identitity = mInjector.binderClearCallingIdentity();
            try {
                mUserManagerInternal.removeAllUsers();
            } finally {
                mInjector.binderRestoreCallingIdentity(identitity);
            }
        }
    }

    @Override
    public boolean getForceEphemeralUsers(ComponentName who) {
        if (!mHasFeature) {
            return false;
        }
        Preconditions.checkNotNull(who, "ComponentName is null");
        synchronized (this) {
            final ActiveAdmin deviceOwner =
                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
            return deviceOwner.forceEphemeralUsers;
        }
    }

    private void ensureDeviceOwnerManagingSingleUser(ComponentName who) throws SecurityException {
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
@@ -5319,6 +5379,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            if (admin != null) {
                admin.disableCamera = false;
                admin.userRestrictions = null;
                admin.forceEphemeralUsers = false;
                mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
            }

            clearUserPoliciesLocked(new UserHandle(UserHandle.USER_SYSTEM));