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

Commit c200bb7b authored by Fyodor Kupolov's avatar Fyodor Kupolov
Browse files

Send BOOT_COMPLETED when updating system apps

Previously, when a system app was updated, it wasn't getting
BOOT_COMPLETED broadcast.
sendPackageAddedForUser was extended to support multiple userIds and also
send LOCKED_BOOT_COMPLETED. handlePackagePostInstall is now using the same
method as installExistingPackageAsUser

Test: pm install --user X -r systemAppV2.apk
Bug: 32242899
Change-Id: I75fe955aaf02d0a4c80b3604e3ef82316bf5dbc0
parent b8ce18a2
Loading
Loading
Loading
Loading
+50 −25
Original line number Diff line number Diff line
@@ -1670,8 +1670,6 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            final String packageName = res.pkg.applicationInfo.packageName;
            Bundle extras = new Bundle(1);
            extras.putInt(Intent.EXTRA_UID, res.uid);
            // Determine the set of users who are adding this package for
            // the first time vs. those who are seeing an update.
@@ -1701,11 +1699,14 @@ public class PackageManagerService extends IPackageManager.Stub {
                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
                // Send added for users that see the package for the first time
                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                        extras, 0 /*flags*/, null /*targetPackage*/,
                        null /*finishedReceiver*/, firstUsers);
                // sendPackageAddedForNewUsers also deals with system apps
                int appId = UserHandle.getAppId(res.uid);
                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
                // Send added for users that don't see the package for the first time
                Bundle extras = new Bundle(1);
                extras.putInt(Intent.EXTRA_UID, res.uid);
                if (update) {
                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
                }
@@ -11779,31 +11780,57 @@ public class PackageManagerService extends IPackageManager.Stub {
    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
            int userId) {
        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
        sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
    }
    private void sendPackageAddedForUser(String packageName, boolean isSystem,
            int appId, int userId) {
    private void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
            int appId, int... userIds) {
        if (ArrayUtils.isEmpty(userIds)) {
            return;
        }
        Bundle extras = new Bundle(1);
        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                packageName, extras, 0, null, null, new int[] {userId});
                packageName, extras, 0, null, null, userIds);
        if (isSystem) {
            mHandler.post(() -> {
                        for (int userId : userIds) {
                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
                        }
                    }
            );
        }
    }
    /**
     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
     * automatically without needing an explicit launch.
     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
     */
    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
        // If user is not running, the app didn't miss any broadcast
        if (!mUserManagerInternal.isUserRunning(userId)) {
            return;
        }
        final IActivityManager am = ActivityManagerNative.getDefault();
        try {
            IActivityManager am = ActivityManagerNative.getDefault();
            if (isSystem && am.isUserRunning(userId, 0)) {
                // The just-installed/enabled app is bundled on the system, so presumed
                // to be able to run automatically without needing an explicit launch.
                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
            // Deliver LOCKED_BOOT_COMPLETED first
            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
                    .setPackage(packageName);
                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
            // Deliver BOOT_COMPLETED only if user is unlocked
            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
            }
        } catch (RemoteException e) {
            // shouldn't happen
            Slog.w(TAG, "Unable to bootstrap installed package", e);
            throw e.rethrowFromSystemServer();
        }
    }
@@ -15933,10 +15960,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                    ? appearedChildPackages.size() : 0;
            for (int i = 0; i < packageCount; i++) {
                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
                for (int userId : installedInfo.newUsers) {
                    sendPackageAddedForUser(installedInfo.name, true,
                            UserHandle.getAppId(installedInfo.uid), userId);
                }
                sendPackageAddedForNewUsers(installedInfo.name, true,
                        UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
            }
        }