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

Commit dabae886 authored by Benjamin Franz's avatar Benjamin Franz Committed by Alex Chau
Browse files

Allow secondary user POs on affiliated devices more DPM APIs

- DevicePolicyManager.setKeyguardDisabled
- DevicePolicyManager.setStatusBarDisabled
- DevicePolicyManager.setDeviceOwnerLockScreenInfo
- PackageInstaller install and uninstall apps

Bug: 64383519
Test: Can set keyguard disabled, status bar disabled and lock screen message in
      affliated PO
Test: Can install and uninstall apps in affiliated PO
Test: CTS tracked in b/68925683

Change-Id: I71be25098436ba0b42050478c049850c2b21f6f4
parent 1dd06c0e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -101,4 +101,18 @@ public abstract class DevicePolicyManagerInternal {
     * not enforced by the profile/device owner.
     */
    public abstract Intent createUserRestrictionSupportIntent(int userId, String userRestriction);

    /**
     * Returns whether this user/profile is affiliated with the device.
     *
     * <p>
     * By definition, the user that the device owner runs on is always affiliated with the device.
     * Any other user/profile is considered affiliated with the device if the set specified by its
     * profile owner via {@link DevicePolicyManager#setAffiliationIds} intersects with the device
     * owner's.
     * <p>
     * Profile owner on the primary user will never be considered as affiliated as there is no
     * device owner to be affiliated with.
     */
    public abstract boolean isUserAffiliatedWithDevice(int userId);
}
+15 −9
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PackageDeleteObserver;
import android.app.PackageInstallObserver;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@@ -704,20 +705,25 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
            mAppOps.checkPackage(callingUid, callerPackageName);
        }

        // Check whether the caller is device owner, in which case we do it silently.
        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
                Context.DEVICE_POLICY_SERVICE);
        boolean isDeviceOwner = (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser(
                callerPackageName);
        // Check whether the caller is device owner or affiliated profile owner, in which case we do
        // it silently.
        final int callingUserId = UserHandle.getUserId(callingUid);
        DevicePolicyManagerInternal dpmi =
                LocalServices.getService(DevicePolicyManagerInternal.class);
        final boolean isDeviceOwnerOrAffiliatedProfileOwner =
                dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
                        DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)
                        && dpmi.isUserAffiliatedWithDevice(callingUserId);

        final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                statusReceiver, versionedPackage.getPackageName(), isDeviceOwner, userId);
                statusReceiver, versionedPackage.getPackageName(),
                isDeviceOwnerOrAffiliatedProfileOwner, userId);
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
                    == PackageManager.PERMISSION_GRANTED) {
            // Sweet, call straight through!
            mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);
        } else if (isDeviceOwner) {
            // Allow the DeviceOwner to silently delete packages
        } else if (isDeviceOwnerOrAffiliatedProfileOwner) {
            // Allow the device owner and affiliated profile owner to silently delete packages
            // Need to clear the calling identity to get DELETE_PACKAGES permission
            long ident = Binder.clearCallingIdentity();
            try {
+15 −12
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@ import static com.android.server.pm.PackageInstallerService.prepareStageDir;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@@ -91,6 +92,7 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter;

@@ -311,14 +313,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    };

    /**
     * @return {@code true} iff the installing is app an device owner?
     * @return {@code true} iff the installing is app an device owner or affiliated profile owner.
     */
    private boolean isInstallerDeviceOwnerLocked() {
        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
                Context.DEVICE_POLICY_SERVICE);

        return (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser(
                mInstallerPackageName);
    private boolean isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked() {
        DevicePolicyManagerInternal dpmi =
                LocalServices.getService(DevicePolicyManagerInternal.class);
        return dpmi != null && dpmi.isActiveAdminWithPolicy(mInstallerUid,
                DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) && dpmi.isUserAffiliatedWithDevice(
                userId);
    }

    /**
@@ -347,10 +349,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        final boolean forcePermissionPrompt =
                (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0;

        // Device owners are allowed to silently install packages, so the permission check is
        // waived if the installer is the device owner.
        // Device owners and affiliated profile owners  are allowed to silently install packages, so
        // the permission check is waived if the installer is the device owner.
        return forcePermissionPrompt || !(isPermissionGranted || isInstallerRoot
                || isInstallerDeviceOwnerLocked());
                || isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked());
    }

    public PackageInstallerSession(PackageInstallerService.InternalCallback callback,
@@ -705,7 +707,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            assertPreparedAndNotDestroyedLocked("commit");

            final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(
                    mContext, statusReceiver, sessionId, isInstallerDeviceOwnerLocked(), userId);
                    mContext, statusReceiver, sessionId,
                    isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId);
            mRemoteObserver = adapter.getBinder();

            if (forTransfer) {
+22 −4
Original line number Diff line number Diff line
@@ -6943,8 +6943,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return;
        }

        final int userId = mInjector.userHandleGetCallingUserId();
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
            if (!isUserAffiliatedWithDeviceLocked(userId)) {
                throw new SecurityException("Admin " + who +
                        " is neither the device owner or affiliated user's profile owner.");
            }
            long token = mInjector.binderClearCallingIdentity();
            try {
                mLockPatternUtils.setDeviceOwnerInfo(info != null ? info.toString() : null);
@@ -9236,10 +9241,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    @Override
    public boolean setKeyguardDisabled(ComponentName who, boolean disabled) {
        Preconditions.checkNotNull(who, "ComponentName is null");
        final int userId = mInjector.userHandleGetCallingUserId();
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
            if (!isUserAffiliatedWithDeviceLocked(userId)) {
                throw new SecurityException("Admin " + who +
                        " is neither the device owner or affiliated user's profile owner.");
            }
        }
        final int userId = UserHandle.getCallingUserId();

        long ident = mInjector.binderClearCallingIdentity();
        try {
@@ -9261,7 +9270,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    public boolean setStatusBarDisabled(ComponentName who, boolean disabled) {
        int userId = UserHandle.getCallingUserId();
        synchronized (this) {
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
            if (!isUserAffiliatedWithDeviceLocked(userId)) {
                throw new SecurityException("Admin " + who +
                        " is neither the device owner or affiliated user's profile owner.");
            }
            DevicePolicyData policy = getUserData(userId);
            if (policy.mStatusBarDisabled != disabled) {
                boolean isLockTaskMode = false;
@@ -9526,6 +9539,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
            return null;
        }

        @Override
        public boolean isUserAffiliatedWithDevice(int userId) {
            return DevicePolicyManagerService.this.isUserAffiliatedWithDeviceLocked(userId);
        }
    }

    private Intent createShowAdminSupportIntent(ComponentName admin, int userId) {