From ae35c7c8e91f0f739491c448c02ed0e617b75657 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 27 Sep 2022 20:51:01 +0000 Subject: [PATCH] Adding flag configuration for runtime receiver enforcement. Adding flag configuration to allow us to gradually turn on runtime receiver EXPORTED/NOT_EXPORTED flag enforcement. This should allow us to slowly ramp up the enforcement and catch more errors without having to revert CLs. This will also allow teams to temporarily disable the flags during their testing while they fix issues. Bug: 234659204 Test: Manually verified receiver flag was enforced when DeviceConfig flag was set to true Change-Id: I33e3925ec6879421805efe786a55ede36fc1cd85 --- .../server/am/ActivityManagerConstants.java | 27 +++++++++++++++++++ .../server/am/ActivityManagerService.java | 7 ++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index 5e7d814b241b1..16fe121fecb77 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -735,6 +735,9 @@ final class ActivityManagerConstants extends ContentObserver { // initialized in the constructor. public int CUR_MAX_EMPTY_PROCESSES; + /** @see mEnforceReceiverExportedFlagRequirement */ + private static final String KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT = + "enforce_exported_flag_requirement"; /** @see #mNoKillCachedProcessesUntilBootCompleted */ private static final String KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED = @@ -744,6 +747,9 @@ final class ActivityManagerConstants extends ContentObserver { private static final String KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS = "no_kill_cached_processes_post_boot_completed_duration_millis"; + /** @see mEnforceReceiverExportedFlagRequirement */ + private static final boolean DEFAULT_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT = false; + /** @see #mNoKillCachedProcessesUntilBootCompleted */ private static final boolean DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED = true; @@ -751,6 +757,15 @@ final class ActivityManagerConstants extends ContentObserver { private static final long DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS = 600_000; + /** + * If true, enforce the requirement that dynamically registered receivers specify one of + * {@link android.content.Context#RECEIVER_EXPORTED} or + * {@link android.content.Context#RECEIVER_NOT_EXPORTED} if registering for any non-system + * broadcasts. + */ + volatile boolean mEnforceReceiverExportedFlagRequirement = + DEFAULT_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT; + /** * If true, do not kill excessive cached processes proactively, until user-0 is unlocked. * @see #mNoKillCachedProcessesPostBootCompletedDurationMillis @@ -1010,6 +1025,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED: updateNoKillCachedProcessesUntilBootCompleted(); break; + case KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT: + updateEnforceReceiverExportedFlagRequirement(); + break; case KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS: updateNoKillCachedProcessesPostBootCompletedDurationMillis(); break; @@ -1482,6 +1500,13 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST); } + private void updateEnforceReceiverExportedFlagRequirement() { + mEnforceReceiverExportedFlagRequirement = DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT, + DEFAULT_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT); + } + private void updateNoKillCachedProcessesUntilBootCompleted() { mNoKillCachedProcessesUntilBootCompleted = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, @@ -1819,6 +1844,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.print("="); pw.println(mPrioritizeAlarmBroadcasts); pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED); pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted); + pw.print(" "); pw.print(KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT); + pw.print("="); pw.println(mEnforceReceiverExportedFlagRequirement); pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS); pw.print("="); pw.println(mNoKillCachedProcessesPostBootCompletedDurationMillis); pw.print(" "); pw.print(KEY_MAX_EMPTY_TIME_MILLIS); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 50b47a6b22f14..cb623f2ec1d50 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -214,8 +214,8 @@ import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManagerInternal; import android.compat.annotation.ChangeId; -import android.compat.annotation.Disabled; import android.compat.annotation.EnabledAfter; +import android.compat.annotation.EnabledSince; import android.content.AttributionSource; import android.content.AutofillOptions; import android.content.BroadcastReceiver; @@ -584,7 +584,7 @@ public class ActivityManagerService extends IActivityManager.Stub * unprotected broadcast in code. */ @ChangeId - @Disabled + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) private static final long DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED = 161145287L; /** @@ -13400,7 +13400,8 @@ public class ActivityManagerService extends IActivityManager.Stub // broadcasts, or the receiver is null (a sticky broadcast). Sticky broadcasts should // not be used generally, so we will be marking them as exported by default final boolean requireExplicitFlagForDynamicReceivers = CompatChanges.isChangeEnabled( - DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED, callingUid); + DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED, callingUid) + && mConstants.mEnforceReceiverExportedFlagRequirement; if (!onlyProtectedBroadcasts) { if (receiver == null && !explicitExportStateDefined) { // sticky broadcast, no flag specified (flag isn't required)