From ee3b42af3f23c37cbd2799c1527f89ac623844be Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 11 Apr 2017 11:30:10 -0700 Subject: [PATCH] Introduce PACKAGE_FIRST_ADDED broadcast When an app first appears on a device, this new broadcast is issued including to manifest receivers. The more general PACKAGE_ADDED broadcast continues to be issued for both first install and updates, but is not delivered to manifest receivers of apps that target O+. Bug 37219124 Test: manual Change-Id: I59b0a0b0dce96a909076b41280771f63e59584be --- api/current.txt | 1 + api/system-current.txt | 1 + api/test-current.txt | 1 + core/java/android/content/Intent.java | 22 ++++++++++++++++--- core/res/AndroidManifest.xml | 1 + .../server/pm/PackageManagerService.java | 10 +++++++-- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/api/current.txt b/api/current.txt index c490b17b51b2d..18408e8e8a3f9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9347,6 +9347,7 @@ package android.content { field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; + field public static final java.lang.String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED"; field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; diff --git a/api/system-current.txt b/api/system-current.txt index ed486b8eae329..6a0ef7712d9d3 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -9873,6 +9873,7 @@ package android.content { field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; + field public static final java.lang.String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED"; field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; diff --git a/api/test-current.txt b/api/test-current.txt index 35e5bfc63b9f9..4a9a8355200a5 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -9381,6 +9381,7 @@ package android.content { field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; + field public static final java.lang.String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED"; field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index a4b5ffd63ae18..52a87609001d7 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2062,13 +2062,13 @@ public class Intent implements Parcelable, Cloneable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; /** - * Broadcast Action: A new application package has been installed on the + * Broadcast Action: An application package has been installed or updated on the * device. The data contains the name of the package. Note that the * newly installed package does not receive this broadcast. *

May include the following extras: *

* @@ -2077,6 +2077,22 @@ public class Intent implements Parcelable, Cloneable { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; + /** + * Broadcast Action: A new application package has been installed on the + * device. The data contains the name of the package. Note that the + * newly installed package does not receive this broadcast. + *

Unlike {@link #ACTION_PACKAGE_ADDED}, this broadcast is delivered + * to manifest receivers as well as those registered at runtime. + *

May include the following extras: + *

+ * + *

This is a protected intent that can only be sent + * by the system. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED"; /** * Broadcast Action: A new version of an application package has been * installed, replacing an existing version that was previously installed. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 8895877350143..57dfeb56d11cc 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -37,6 +37,7 @@ + diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 66bb1cb0edd94..44be90e1def16 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1832,6 +1832,10 @@ public class PackageManagerService extends IPackageManager.Stub { extras.putInt(Intent.EXTRA_UID, res.uid); if (update) { extras.putBoolean(Intent.EXTRA_REPLACING, true); + } else { + sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName, + extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, + null /*targetPackage*/, null /*finishedReceiver*/, updateUsers); } sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, extras, 0 /*flags*/, null /*targetPackage*/, @@ -13266,8 +13270,10 @@ public class PackageManagerService extends IPackageManager.Stub { // 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, userIds); + sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName, + extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, userIds); + sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, + extras, 0, null, null, userIds); if (isSystem) { mHandler.post(() -> { for (int userId : userIds) {