summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peter Li <lpeter@google.com> 2024-10-17 07:18:09 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-10-17 07:18:09 +0000
commit7bdf2dcfa42e0892713f6066cdbde491c8791fea (patch)
tree56231bc1d28222f9d483136d3726085f30bbf1dd
parentd7588243196f80fe78357dafd826976a42702ed8 (diff)
parent3ad584f1e6da48cc5971c5fda9c15698f4b0b8c8 (diff)
Merge changes from topic "reduce_broadcast_intent" into main
* changes: Add a new feature flag and a new permission Refactor BroadcastHelper to pass requiredPermissions parameter.
-rw-r--r--core/java/android/content/pm/flags.aconfig8
-rw-r--r--core/res/AndroidManifest.xml12
-rw-r--r--services/core/java/com/android/server/pm/BroadcastHelper.java95
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java25
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt3
5 files changed, 92 insertions, 51 deletions
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 52d733314eb6..5b38942d468d 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -334,3 +334,11 @@ flag {
bug: "364771256"
is_fixed_read_only: true
}
+
+flag {
+ name: "reduce_broadcasts_for_component_state_changes"
+ namespace: "package_manager_service"
+ description: "Feature flag to limit sending of the PACKAGE_CHANGED broadcast to only the system and the application itself during component state changes."
+ bug: "292261144"
+ is_fixed_read_only: true
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5693d666adc2..5522aa09a32e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8479,6 +8479,18 @@
android:protectionLevel="internal"
android:featureFlag="android.content.pm.verification_service" />
+ <!--
+ This permission allows the system to receive PACKAGE_CHANGED broadcasts when the component
+ state of a non-exported component has been changed.
+ <p>Not for use by third-party applications. </p>
+ <p>Protection level: internal
+ @hide
+ -->
+ <permission
+ android:name="android.permission.RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED"
+ android:protectionLevel="internal"
+ android:featureFlag="android.content.pm.reduce_broadcasts_for_component_state_changes"/>
+
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index 369029adac59..84a5f2b0e8bc 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -80,11 +80,6 @@ import java.util.function.BiFunction;
*/
public final class BroadcastHelper {
private static final boolean DEBUG_BROADCASTS = false;
- /**
- * Permissions required in order to receive instant application lifecycle broadcasts.
- */
- private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
- new String[]{android.Manifest.permission.ACCESS_INSTANT_APPS};
private final UserManagerInternal mUmInternal;
private final ActivityManagerInternal mAmInternal;
@@ -115,7 +110,7 @@ public final class BroadcastHelper {
SparseArray<int[]> broadcastAllowList = new SparseArray<>();
broadcastAllowList.put(userId, visibilityAllowList);
broadcastIntent(intent, finishedReceiver, isInstantApp, userId, broadcastAllowList,
- filterExtrasForReceiver, bOptions);
+ filterExtrasForReceiver, bOptions, null /* requiredPermissions */);
}
void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
@@ -123,7 +118,7 @@ public final class BroadcastHelper {
final int[] userIds, int[] instantUserIds,
@Nullable SparseArray<int[]> broadcastAllowList,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
- @Nullable Bundle bOptions) {
+ @Nullable Bundle bOptions, @Nullable String[] requiredPermissions) {
try {
final IActivityManager am = ActivityManager.getService();
if (am == null) return;
@@ -137,12 +132,12 @@ public final class BroadcastHelper {
if (ArrayUtils.isEmpty(instantUserIds)) {
doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver,
resolvedUserIds, false /* isInstantApp */, broadcastAllowList,
- filterExtrasForReceiver, bOptions);
+ filterExtrasForReceiver, bOptions, requiredPermissions);
} else {
// send restricted broadcasts for instant apps
doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver,
- instantUserIds, true /* isInstantApp */, null,
- null /* filterExtrasForReceiver */, bOptions);
+ instantUserIds, true /* isInstantApp */, null /* broadcastAllowList */,
+ null /* filterExtrasForReceiver */, bOptions, requiredPermissions);
}
} catch (RemoteException ex) {
}
@@ -166,7 +161,8 @@ public final class BroadcastHelper {
boolean isInstantApp,
@Nullable SparseArray<int[]> broadcastAllowList,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
- @Nullable Bundle bOptions) {
+ @Nullable Bundle bOptions,
+ @Nullable String[] requiredPermissions) {
for (int userId : userIds) {
final Intent intent = new Intent(action,
pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
@@ -189,17 +185,18 @@ public final class BroadcastHelper {
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
broadcastIntent(intent, finishedReceiver, isInstantApp, userId, broadcastAllowList,
- filterExtrasForReceiver, bOptions);
+ filterExtrasForReceiver, bOptions, requiredPermissions);
}
}
-
private void broadcastIntent(Intent intent, IIntentReceiver finishedReceiver,
boolean isInstantApp, int userId, @Nullable SparseArray<int[]> broadcastAllowList,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
- @Nullable Bundle bOptions) {
- final String[] requiredPermissions =
- isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
+ @Nullable Bundle bOptions, @Nullable String[] requiredPermissions) {
+ if (isInstantApp) {
+ requiredPermissions = ArrayUtils.appendElement(String.class, requiredPermissions,
+ android.Manifest.permission.ACCESS_INSTANT_APPS);
+ }
if (DEBUG_BROADCASTS) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
@@ -234,7 +231,7 @@ public final class BroadcastHelper {
null /* instantUserIds */, null /* broadcastAllowList */,
(callingUid, intentExtras) -> filterExtrasChangedPackageList(
snapshot, callingUid, intentExtras),
- null /* bOptions */);
+ null /* bOptions */, null /* requiredPermissions */);
}
/**
@@ -294,14 +291,29 @@ public final class BroadcastHelper {
return bOptions;
}
- private void sendPackageChangedBroadcast(@NonNull String packageName,
- boolean dontKillApp,
- @NonNull ArrayList<String> componentNames,
- int packageUid,
- @Nullable String reason,
- @Nullable int[] userIds,
- @Nullable int[] instantUserIds,
- @Nullable SparseArray<int[]> broadcastAllowList) {
+ private void sendPackageChangedBroadcastInternal(@NonNull String packageName,
+ boolean dontKillApp,
+ @NonNull ArrayList<String> componentNames,
+ int packageUid,
+ @Nullable String reason,
+ @Nullable int[] userIds,
+ @Nullable int[] instantUserIds,
+ @Nullable SparseArray<int[]> broadcastAllowList) {
+ sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp, componentNames,
+ packageUid, reason, userIds, instantUserIds, broadcastAllowList,
+ null /* targetPackageName */, null /* requiredPermissions */);
+ }
+
+ private void sendPackageChangedBroadcastWithPermissions(@NonNull String packageName,
+ boolean dontKillApp,
+ @NonNull ArrayList<String> componentNames,
+ int packageUid,
+ @Nullable String reason,
+ @Nullable int[] userIds,
+ @Nullable int[] instantUserIds,
+ @Nullable SparseArray<int[]> broadcastAllowList,
+ @Nullable String targetPackageName,
+ @Nullable String[] requiredPermissions) {
if (DEBUG_INSTALL) {
Log.v(TAG, "Sending package changed: package=" + packageName + " components="
+ componentNames);
@@ -321,9 +333,10 @@ public final class BroadcastHelper {
// little component state change.
final int flags = !componentNames.contains(packageName)
? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
- sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
- userIds, instantUserIds, broadcastAllowList, null /* filterExtrasForReceiver */,
- null /* bOptions */);
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags,
+ targetPackageName, null /* finishedReceiver */, userIds, instantUserIds,
+ broadcastAllowList, null /* filterExtrasForReceiver */, null /* bOptions */,
+ requiredPermissions);
}
static void sendDeviceCustomizationReadyBroadcast() {
@@ -680,7 +693,8 @@ public final class BroadcastHelper {
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, 0, null, null, userIds, instantUserIds,
- broadcastAllowlist, null /* filterExtrasForReceiver */, null);
+ broadcastAllowlist, null /* filterExtrasForReceiver */, null /* bOptions */,
+ null /* requiredPermissions */);
// Send to PermissionController for all new users, even if it may not be running for some
// users
if (isPrivacySafetyLabelChangeNotificationsEnabled(mContext)) {
@@ -688,7 +702,8 @@ public final class BroadcastHelper {
packageName, extras, 0,
mContext.getPackageManager().getPermissionControllerPackageName(),
null, userIds, instantUserIds,
- broadcastAllowlist, null /* filterExtrasForReceiver */, null);
+ broadcastAllowlist, null /* filterExtrasForReceiver */, null /* bOptions */,
+ null /* requiredPermissions */);
}
}
@@ -719,7 +734,8 @@ public final class BroadcastHelper {
int[] userIds, int[] instantUserIds) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
installerPkg, null, userIds, instantUserIds, null /* broadcastAllowList */,
- null /* filterExtrasForReceiver */, null);
+ null /* filterExtrasForReceiver */, null /* bOptions */,
+ null /* requiredPermissions */);
}
/**
@@ -824,7 +840,7 @@ public final class BroadcastHelper {
final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
final SparseArray<int[]> broadcastAllowList =
isInstantApp ? null : snapshot.getVisibilityAllowLists(packageName, userIds);
- mHandler.post(() -> sendPackageChangedBroadcast(
+ mHandler.post(() -> sendPackageChangedBroadcastInternal(
packageName, dontKillApp, componentNames, packageUid, reason, userIds,
instantUserIds, broadcastAllowList));
mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames,
@@ -843,7 +859,7 @@ public final class BroadcastHelper {
@Nullable Bundle bOptions) {
mHandler.post(() -> sendPackageBroadcast(action, pkg, extras, flags,
targetPkg, finishedReceiver, userIds, instantUserIds, broadcastAllowList,
- null /* filterExtrasForReceiver */, bOptions));
+ null /* filterExtrasForReceiver */, bOptions, null /* requiredPermissions */));
if (targetPkg == null) {
// For some broadcast action, e.g. ACTION_PACKAGE_ADDED, this method will be called
// many times to different targets, e.g. installer app, permission controller, other
@@ -1014,7 +1030,7 @@ public final class BroadcastHelper {
extras, flags, null /* targetPkg */, null /* finishedReceiver */,
new int[]{userId}, null /* instantUserIds */, null /* broadcastAllowList */,
filterExtrasForReceiver,
- options));
+ options, null /* requiredPermissions */));
notifyPackageMonitor(intent, null /* pkg */, extras, new int[]{userId},
null /* instantUserIds */, null /* broadcastAllowList */, filterExtrasForReceiver);
}
@@ -1046,9 +1062,12 @@ public final class BroadcastHelper {
} else {
intentExtras = null;
}
- doSendBroadcast(action, null, intentExtras,
- Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
- targetUserIds, false, null, null, null);
+ doSendBroadcast(action, null /* pkg */, intentExtras,
+ Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName,
+ null /* finishedReceiver */,
+ targetUserIds, false /* isInstantApp */, null /* broadcastAllowList */,
+ null /* filterExtrasForReceiver */, null /* bOptions */,
+ null /* requiredPermissions */);
}
});
}
@@ -1077,7 +1096,7 @@ public final class BroadcastHelper {
null /* broadcastAllowList */,
(callingUid, intentExtras) -> filterExtrasChangedPackageList(
snapshot, callingUid, intentExtras),
- null /* bOptions */));
+ null /* bOptions */, null /* requiredPermissions */));
}
void sendResourcesChangedBroadcastAndNotify(@NonNull Computer snapshot,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 455776993c56..d78f12217271 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4709,10 +4709,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService
extras.putLong(Intent.EXTRA_TIME, SystemClock.elapsedRealtime());
mHandler.post(() -> {
mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_UNSTOPPED,
- packageName, extras,
- Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
- userIds, null, broadcastAllowList, null,
- null);
+ packageName, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY,
+ null /* targetPkg */, null /* finishedReceiver */, userIds,
+ null /* instantUserIds */, broadcastAllowList,
+ null /* filterExtrasForReceiver */, null /* bOptions */,
+ null /* requiredPermissions */);
});
mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_UNSTOPPED,
packageName, extras, userIds, null /* instantUserIds */,
@@ -7169,17 +7170,17 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// Sent async using the PM handler, to maintain ordering with PACKAGE_UNSTOPPED
mHandler.post(() -> {
mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_RESTARTED,
- packageName, extras,
- flags, null, null,
- userIds, null, broadcastAllowList, null,
- null);
+ packageName, extras, flags, null /* targetPkg */,
+ null /* finishedReceiver */, userIds, null /* instantUserIds */,
+ broadcastAllowList, null /* filterExtrasForReceiver */,
+ null /* bOptions */, null /* requiredPermissions */);
});
} else {
mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_RESTARTED,
- packageName, extras,
- flags, null, null,
- userIds, null, broadcastAllowList, null,
- null);
+ packageName, extras, flags, null /* targetPkg */,
+ null /* finishedReceiver */, userIds, null /* instantUserIds */,
+ broadcastAllowList, null /* filterExtrasForReceiver */, null /* bOptions */,
+ null /* requiredPermissions */);
}
mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_RESTARTED,
packageName, extras, userIds, null /* instantUserIds */,
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
index e131a98b52d0..de029e0d770f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
@@ -185,7 +185,8 @@ class DistractingPackageHelperTest : PackageHelperTestBase() {
verify(pms, never()).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
verify(broadcastHelper, never()).sendPackageBroadcast(eq(
Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), nullable(), anyInt(),
- nullable(), nullable(), any(), nullable(), nullable(), nullable(), nullable())
+ nullable(), nullable(), any(), nullable(), nullable(), nullable(), nullable(),
+ nullable())
distractingPackageHelper.removeDistractingPackageRestrictions(pms.snapshotComputer(),
arrayOfNulls(0), TEST_USER_ID)