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

Commit 4e9335aa authored by Jason Parks's avatar Jason Parks
Browse files

Allow the DO/PO to call PackageManager.setPackagesSuspended() directly.

This fixes the issue where the DO/PO can not set the suspend dialog.

Bug: 120618908
Test: atest WmTests:ActivityStartInterceptorTest
Test: atest FrameworksServicesTests:SuspendPackagesTest
Test: atest GtsSuspendAppsTestCases

Change-Id: Ic99bd25e5bb5ec578df2b0910f5dfb3027650d3c
parent baa0d898
Loading
Loading
Loading
Loading
+28 −14
Original line number Original line Diff line number Diff line
@@ -13663,30 +13663,44 @@ public class PackageManagerService extends IPackageManager.Stub
        return unactionedPackages.toArray(new String[0]);
        return unactionedPackages.toArray(new String[0]);
    }
    }
    @Override
    private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
            int userId, String callingMethod) {
            PersistableBundle appExtras, PersistableBundle launcherExtras,
        if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
            SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
            return;
        }
        final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
        if (ownerPackage != null) {
            final int ownerUid = getPackageUid(ownerPackage, 0, userId);
            if (ownerUid == callingUid) {
                return;
            }
            throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
                    + userId + " has an active DO or PO");
        }
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
                "setPackagesSuspendedAsUser");
                callingMethod);
        final int callingUid = Binder.getCallingUid();
        final int packageUid = getPackageUid(callingPackage, 0, userId);
        final int packageUid = getPackageUid(callingPackage, 0, userId);
        final boolean allowedCallingUid = callingUid == Process.ROOT_UID
                || callingUid == Process.SYSTEM_UID;
        final boolean allowedPackageUid = packageUid == callingUid;
        final boolean allowedPackageUid = packageUid == callingUid;
        final boolean allowedShell = callingUid == SHELL_UID
        final boolean allowedShell = callingUid == SHELL_UID
                && UserHandle.isSameApp(packageUid, callingUid);
                && UserHandle.isSameApp(packageUid, callingUid);
        if (!allowedCallingUid && !allowedShell && !allowedPackageUid) {
        if (!allowedShell && !allowedPackageUid) {
            throw new SecurityException("Calling package " + callingPackage + " in user "
            throw new SecurityException("Calling package " + callingPackage + " in user "
                    + userId + " does not belong to calling uid " + callingUid);
                    + userId + " does not belong to calling uid " + callingUid);
        }
        }
        if (!PLATFORM_PACKAGE_NAME.equals(callingPackage)
                && mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId) != null) {
            throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
                    + userId + " has an active DO or PO");
    }
    }
    @Override
    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
            PersistableBundle appExtras, PersistableBundle launcherExtras,
            SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
        final int callingUid = Binder.getCallingUid();
        enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
                "setPackagesSuspendedAsUser");
        if (ArrayUtils.isEmpty(packageNames)) {
        if (ArrayUtils.isEmpty(packageNames)) {
            return packageNames;
            return packageNames;
        }
        }
+4 −12
Original line number Original line Diff line number Diff line
@@ -509,25 +509,17 @@ public class SuspendPackagesTest {
    }
    }


    @Test
    @Test
    public void testCannotSuspendWhenProfileOwner() throws IOException {
    public void testCanSuspendWhenProfileOwner() throws IOException {
        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
        assertTrue("Profile-owner could not be set", setProfileOwner());
        assertTrue("Profile-owner could not be set", setProfileOwner());
        try {
        suspendTestPackage(null, null, null);
        suspendTestPackage(null, null, null);
            fail("Suspend succeeded. Expected UnsupportedOperationException");
        } catch (UnsupportedOperationException uex) {
        }
    }
    }


    @Test
    @Test
    public void testCannotSuspendWhenDeviceOwner() throws IOException {
    public void testCanSuspendWhenDeviceOwner() throws IOException {
        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
        assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
        assertTrue("Device-owner could not be set", setDeviceOwner());
        assertTrue("Device-owner could not be set", setDeviceOwner());
        try {
        suspendTestPackage(null, null, null);
        suspendTestPackage(null, null, null);
            fail("Suspend succeeded. Expected UnsupportedOperationException");
        } catch (UnsupportedOperationException uex) {
        }
    }
    }


    @Test
    @Test