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

Commit 436d093b authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Refactoring canSuspendPackage to support batch queries

Taking a list of packages to reduce the number of IPCs the
client has to make.

Test: atest GtsSuspendAppsTestCases:SuspendPackagesTest

Bug: 120908380
Bug: 117968270
Change-Id: Ife7a6acfe2f21e7f4419bcf67630e7b8be50a560
parent 8823fa23
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1214,7 +1214,6 @@ package android.content.pm {
  public abstract class PackageManager {
    method public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
    method public abstract boolean arePermissionsIndividuallyControlled();
    method public boolean canSuspendPackage(java.lang.String);
    method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(java.lang.String);
    method public android.content.pm.ApplicationInfo getApplicationInfoAsUser(java.lang.String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.dex.ArtManager getArtManager();
@@ -1228,6 +1227,7 @@ package android.content.pm {
    method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
    method public abstract int getIntentVerificationStatusAsUser(java.lang.String, int);
    method public abstract int getPermissionFlags(java.lang.String, java.lang.String, android.os.UserHandle);
    method public java.lang.String[] getUnsuspendablePackages(java.lang.String[]);
    method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
    method public abstract int installExistingPackage(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract int installExistingPackage(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+2 −2
Original line number Diff line number Diff line
@@ -2275,9 +2275,9 @@ public class ApplicationPackageManager extends PackageManager {
    }

    @Override
    public boolean canSuspendPackage(String packageName) {
    public String[] getUnsuspendablePackages(String[] packageNames) {
        try {
            return mPM.canSuspendPackageForUser(packageName, mContext.getUserId());
            return mPM.getUnsuspendablePackagesForUser(packageNames, mContext.getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+1 −1
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ interface IPackageManager {
            in PersistableBundle appExtras, in PersistableBundle launcherExtras,
            in SuspendDialogInfo dialogInfo, String callingPackage, int userId);

    boolean canSuspendPackageForUser(String packageName, int userId);
    String[] getUnsuspendablePackagesForUser(in String[] packageNames, int userId);

    boolean isPackageSuspendedForUser(String packageName, int userId);

+11 −10
Original line number Diff line number Diff line
@@ -5916,27 +5916,28 @@ public abstract class PackageManager {
    }

    /**
     * Returns whether or not a given package can be suspended via a call to {@link
     * Returns any packages in a given set of packages that cannot be suspended via a call to {@link
     * #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle,
     * SuspendDialogInfo) setPackagesSuspended}. The platform prevents suspending certain critical
     * packages to keep the device in a functioning state, e.g. the default dialer.
     * Apps need to hold {@link Manifest.permission#SUSPEND_APPS SUSPEND_APPS} to call this api.
     *
     * <p>
     * Note that this set of critical packages can change with time, so <em>a value of {@code true}
     * returned by this api does not guarantee that a following call to {@link
     * #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle,
     * SuspendDialogInfo) setPackagesSuspended} for the same package will succeed</em>, especially
     * if considerable time elapsed between the two calls.
     * Note that this set of critical packages can change with time, so even though a package name
     * was not returned by this call, it does not guarantee that a subsequent call to
     * {@link #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle,
     * SuspendDialogInfo) setPackagesSuspended} for that package will succeed, especially if
     * significant time elapsed between the two calls.
     *
     * @param packageName The package to check.
     * @return {@code true} if the given package can be suspended, {@code false} otherwise.
     * @param packageNames The packages to check.
     * @return A list of packages that can not be currently suspended by the system.
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.SUSPEND_APPS)
    public boolean canSuspendPackage(@NonNull String packageName) {
        throw new UnsupportedOperationException("canSuspendPackage not implemented");
    @NonNull
    public String[] getUnsuspendablePackages(@NonNull String[] packageNames) {
        throw new UnsupportedOperationException("canSuspendPackages not implemented");
    }

    /**
+10 −4
Original line number Diff line number Diff line
@@ -13008,20 +13008,26 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    @Override
    public boolean canSuspendPackageForUser(String packageName, int userId) {
    public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
        mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
                "canSuspendPackageForUser");
                "getUnsuspendablePackagesForUser");
        final int callingUid = Binder.getCallingUid();
        if (UserHandle.getUserId(callingUid) != userId) {
            throw new SecurityException("Calling uid " + callingUid
                    + " cannot query canSuspendPackageForUser for user " + userId);
                    + " cannot query getUnsuspendablePackagesForUser for user " + userId);
        }
        final ArraySet<String> unactionablePackages = new ArraySet<>();
        final long identity = Binder.clearCallingIdentity();
        try {
            return canSuspendPackageForUserInternal(packageName, userId);
            for (String packageName : packageNames) {
                if (!canSuspendPackageForUserInternal(packageName, userId)) {
                    unactionablePackages.add(packageName);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        return unactionablePackages.toArray(new String[unactionablePackages.size()]);
    }
    private boolean canSuspendPackageForUserInternal(String packageName, int userId) {