summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java75
1 files changed, 50 insertions, 25 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 59c4fb9e7591..b74eaa079822 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -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)
- .setPackage(packageName);
- am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
+ // Deliver LOCKED_BOOT_COMPLETED first
+ Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
+ .setPackage(packageName);
+ 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);
}
}