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

Commit 43f3af7e authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Optimizing getUnsuspendablePackages

Test: atest GtsSuspendAppsTestCases

Locally with 274 packages, I plugged in StatLogger:
Before the change:
  Stats:
    getUnsuspendablePackages: count=105, total=18679.5ms, avg=177.900ms, max calls/s=2 max dur/s=226.0ms max time=214.1ms
    getActiveLauncher: count=28392, total=9856.3ms, avg=0.347ms, max calls/s=946 max dur/s=308.0ms max time=5.1ms
    getDialer: count=28080, total=160.3ms, avg=0.006ms, max calls/s=0 max dur/s=0.0ms max time=1.3ms

After the change:
  Stats:
    getUnsuspendablePackages: count=104, total=7193.4ms, avg=69.167ms, max calls/s=21 max dur/s=1459.0ms max time=105.8ms
    getActiveLauncher: count=127, total=138.2ms, avg=1.088ms, max calls/s=11 max dur/s=16.0ms max time=2.0ms
    getDialer: count=127, total=4.2ms, avg=0.033ms, max calls/s=0 max dur/s=0.0ms max time=0.9ms

Fixes: 120908380
Change-Id: I4554fa7e3b72dfd5d66ad63fdf51528537d686b4
parent 47bfb774
Loading
Loading
Loading
Loading
+81 −67
Original line number Diff line number Diff line
@@ -12937,6 +12937,8 @@ public class PackageManagerService extends IPackageManager.Stub
        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
        final IntArray changedUids = new IntArray(packageNames.length);
        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
        final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
                packageNames, userId) : null;
        for (int i = 0; i < packageNames.length; i++) {
            final String packageName = packageNames[i];
@@ -12950,7 +12952,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    continue;
                }
            }
            if (restrictionFlags != 0 && !canSuspendPackageForUserInternal(packageName, userId)) {
            if (canRestrict != null && !canRestrict[i]) {
                unactionedPackages.add(packageName);
                continue;
            }
@@ -13007,6 +13009,8 @@ public class PackageManagerService extends IPackageManager.Stub
        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
        final IntArray changedUids = new IntArray(packageNames.length);
        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
        final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
                userId) : null;
        for (int i = 0; i < packageNames.length; i++) {
            final String packageName = packageNames[i];
@@ -13026,7 +13030,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    continue;
                }
            }
            if (suspended && !canSuspendPackageForUserInternal(packageName, userId)) {
            if (canSuspend != null && !canSuspend[i]) {
                unactionedPackages.add(packageName);
                continue;
            }
@@ -13190,65 +13194,74 @@ public class PackageManagerService extends IPackageManager.Stub
                    + " cannot query getUnsuspendablePackagesForUser for user " + userId);
        }
        final ArraySet<String> unactionablePackages = new ArraySet<>();
        for (String packageName : packageNames) {
            if (!canSuspendPackageForUserInternal(packageName, userId)) {
                unactionablePackages.add(packageName);
        final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
        for (int i = 0; i < packageNames.length; i++) {
            if (!canSuspend[i]) {
                unactionablePackages.add(packageNames[i]);
            }
        }
        return unactionablePackages.toArray(new String[unactionablePackages.size()]);
    }
    private boolean canSuspendPackageForUserInternal(String packageName, int userId) {
    /**
     * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
     * be suspended or not.
     *
     * @param packageNames  The package names to check suspendability for.
     * @param userId The user to check in
     * @return An array containing results of the checks
     */
    @NonNull
    private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
        final boolean[] canSuspend = new boolean[packageNames.length];
        final long callingId = Binder.clearCallingIdentity();
        try {
            final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
            final String dialerPackageName = getDefaultDialerPackageName(userId);
            for (int i = 0; i < packageNames.length; i++) {
                canSuspend[i] = false;
                final String packageName = packageNames[i];
                if (isPackageDeviceAdmin(packageName, userId)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": has an active device admin");
                return false;
                    continue;
                }
            String activeLauncherPackageName = getActiveLauncherPackageName(userId);
                if (packageName.equals(activeLauncherPackageName)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": contains the active launcher");
                return false;
                    continue;
                }
                if (packageName.equals(mRequiredInstallerPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for package installation");
                return false;
                    continue;
                }
                if (packageName.equals(mRequiredUninstallerPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for package uninstallation");
                return false;
                    continue;
                }
                if (packageName.equals(mRequiredVerifierPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for package verification");
                return false;
                    continue;
                }
            if (packageName.equals(getDefaultDialerPackageName(userId))) {
                if (packageName.equals(dialerPackageName)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": is the default dialer");
                return false;
                    continue;
                }
                if (packageName.equals(mRequiredPermissionControllerPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for permissions management");
                return false;
                    continue;
                }
                synchronized (mPackages) {
                    if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
                        Slog.w(TAG, "Cannot suspend package \"" + packageName
                                + "\": protected package");
                    return false;
                        continue;
                    }
                    // Cannot suspend static shared libs as they are considered
@@ -13259,18 +13272,19 @@ public class PackageManagerService extends IPackageManager.Stub
                        Slog.w(TAG, "Cannot suspend package: " + packageName
                                + " providing static shared library: "
                                + pkg.staticSharedLibName);
                    return false;
                        continue;
                    }
                }
                if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
                    Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
                return false;
                    continue;
                }
                canSuspend[i] = true;
            }
            return true;
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
        return canSuspend;
    }
    private String getActiveLauncherPackageName(int userId) {