Loading core/api/module-lib-current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -24,8 +24,8 @@ package android.app { } public class BroadcastOptions { method public int getMaxManifestReceiverApiLevel(); method public void setMaxManifestReceiverApiLevel(int); method @Deprecated public int getMaxManifestReceiverApiLevel(); method @Deprecated public void setMaxManifestReceiverApiLevel(int); } public abstract class HomeVisibilityListener { Loading core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -724,12 +724,14 @@ package android.app { } public class BroadcastOptions { method public void clearRequireCompatChange(); method public boolean isPendingIntentBackgroundActivityLaunchAllowed(); method public static android.app.BroadcastOptions makeBasic(); method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean); method public void setDontSendToRestrictedApps(boolean); method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean); method public void setRequireAllOfPermissions(@Nullable String[]); method public void setRequireCompatChange(long, boolean); method public void setRequireNoneOfPermissions(@Nullable String[]); method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long); core/api/test-current.txt +5 −2 Original line number Diff line number Diff line Loading @@ -248,12 +248,15 @@ package android.app { public class BroadcastOptions { ctor public BroadcastOptions(@NonNull android.os.Bundle); method public int getMaxManifestReceiverApiLevel(); method @Deprecated public int getMaxManifestReceiverApiLevel(); method public long getTemporaryAppAllowlistDuration(); method @Nullable public String getTemporaryAppAllowlistReason(); method public int getTemporaryAppAllowlistReasonCode(); method public int getTemporaryAppAllowlistType(); method public void setMaxManifestReceiverApiLevel(int); method @Deprecated public void setMaxManifestReceiverApiLevel(int); method public boolean testRequireCompatChange(int); field public static final long CHANGE_ALWAYS_DISABLED = 210856463L; // 0xc916a0fL field public static final long CHANGE_ALWAYS_ENABLED = 209888056L; // 0xc82a338L } public class DownloadManager { Loading core/java/android/app/BroadcastOptions.java +136 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,11 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.EnabledSince; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.PowerExemptionManager; Loading @@ -45,6 +50,35 @@ public class BroadcastOptions extends ComponentOptions { private boolean mAllowBackgroundActivityStarts; private String[] mRequireAllOfPermissions; private String[] mRequireNoneOfPermissions; private long mRequireCompatChangeId = CHANGE_INVALID; private boolean mRequireCompatChangeEnabled = true; /** * Change ID which is invalid. * * @hide */ public static final long CHANGE_INVALID = Long.MIN_VALUE; /** * Change ID which is always enabled, for testing purposes. * * @hide */ @TestApi @ChangeId @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE) public static final long CHANGE_ALWAYS_ENABLED = 209888056L; /** * Change ID which is always disabled, for testing purposes. * * @hide */ @TestApi @ChangeId @Disabled public static final long CHANGE_ALWAYS_DISABLED = 210856463L; /** * How long to temporarily put an app on the power allowlist when executing this broadcast Loading Loading @@ -100,6 +134,18 @@ public class BroadcastOptions extends ComponentOptions { public static final String KEY_REQUIRE_NONE_OF_PERMISSIONS = "android:broadcast.requireNoneOfPermissions"; /** * Corresponds to {@link #setRequireCompatChange(long, boolean)} */ private static final String KEY_REQUIRE_COMPAT_CHANGE_ID = "android:broadcast.requireCompatChangeId"; /** * Corresponds to {@link #setRequireCompatChange(long, boolean)} */ private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = "android:broadcast.requireCompatChangeEnabled"; /** * @hide * @deprecated Use {@link android.os.PowerExemptionManager# Loading Loading @@ -150,6 +196,8 @@ public class BroadcastOptions extends ComponentOptions { false); mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS); mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); } /** Loading Loading @@ -270,16 +318,32 @@ public class BroadcastOptions extends ComponentOptions { * Set the minimum target API level of receivers of the broadcast. If an application * is targeting an API level less than this, the broadcast will not be delivered to * them. This only applies to receivers declared in the app's AndroidManifest.xml. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @Deprecated public void setMinManifestReceiverApiLevel(int apiLevel) { mMinManifestReceiverApiLevel = apiLevel; } /** * Return {@link #setMinManifestReceiverApiLevel}. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @Deprecated public int getMinManifestReceiverApiLevel() { return mMinManifestReceiverApiLevel; } Loading @@ -288,20 +352,36 @@ public class BroadcastOptions extends ComponentOptions { * Set the maximum target API level of receivers of the broadcast. If an application * is targeting an API level greater than this, the broadcast will not be delivered to * them. This only applies to receivers declared in the app's AndroidManifest.xml. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @TestApi @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Deprecated public void setMaxManifestReceiverApiLevel(int apiLevel) { mMaxManifestReceiverApiLevel = apiLevel; } /** * Return {@link #setMaxManifestReceiverApiLevel}. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @TestApi @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Deprecated public int getMaxManifestReceiverApiLevel() { return mMaxManifestReceiverApiLevel; } Loading Loading @@ -378,6 +458,58 @@ public class BroadcastOptions extends ComponentOptions { mRequireNoneOfPermissions = excludedPermissions; } /** * When set, this broadcast will only be delivered to apps which have the * given {@link ChangeId} in the given state. * <p> * Each {@link BroadcastOptions} instance supports only a single * {@link ChangeId} requirement, so any subsequent calls will override any * previously defined requirement. * <p> * This requirement applies to both manifest registered and runtime * registered receivers. * * @param changeId the {@link ChangeId} to inspect * @param enabled the required enabled state of the inspected * {@link ChangeId} for this broadcast to be delivered * @see CompatChanges#isChangeEnabled * @see #clearRequireCompatChange() */ public void setRequireCompatChange(long changeId, boolean enabled) { mRequireCompatChangeId = changeId; mRequireCompatChangeEnabled = enabled; } /** * Clear any previously defined requirement for this broadcast requested via * {@link #setRequireCompatChange(long, boolean)}. */ public void clearRequireCompatChange() { mRequireCompatChangeId = CHANGE_INVALID; mRequireCompatChangeEnabled = true; } /** {@hide} */ public long getRequireCompatChangeId() { return mRequireCompatChangeId; } /** * Test if the given app meets the {@link ChangeId} state required by this * broadcast, if any. * * @hide */ @TestApi public boolean testRequireCompatChange(int uid) { if (mRequireCompatChangeId != CHANGE_INVALID) { return CompatChanges.isChangeEnabled(mRequireCompatChangeId, uid) == mRequireCompatChangeEnabled; } else { return true; } } /** * Returns the created options as a Bundle, which can be passed to * {@link android.content.Context#sendBroadcast(android.content.Intent) Loading Loading @@ -413,6 +545,10 @@ public class BroadcastOptions extends ComponentOptions { if (mRequireNoneOfPermissions != null) { b.putStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS, mRequireNoneOfPermissions); } if (mRequireCompatChangeId != CHANGE_INVALID) { b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId); b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled); } return b.isEmpty() ? null : b; } } services/core/java/com/android/server/am/BroadcastQueue.java +13 −0 Original line number Diff line number Diff line Loading @@ -632,6 +632,12 @@ public final class BroadcastQueue { private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index) { boolean skip = false; if (r.options != null && !r.options.testRequireCompatChange(filter.owningUid)) { Slog.w(TAG, "Compat change filtered: broadcasting " + r.intent.toString() + " to uid " + filter.owningUid + " due to compat change " + r.options.getRequireCompatChangeId()); skip = true; } if (!mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid, filter.packageName, filter.owningUid)) { Slog.w(TAG, "Association not allowed: broadcasting " Loading Loading @@ -1407,6 +1413,13 @@ public final class BroadcastQueue { + "] broadcasting " + broadcastDescription(r, component)); skip = true; } if (brOptions != null && !brOptions.testRequireCompatChange(info.activityInfo.applicationInfo.uid)) { Slog.w(TAG, "Compat change filtered: broadcasting " + broadcastDescription(r, component) + " to uid " + info.activityInfo.applicationInfo.uid + " due to compat change " + r.options.getRequireCompatChangeId()); skip = true; } if (!skip && !mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid, component.getPackageName(), info.activityInfo.applicationInfo.uid)) { Slog.w(TAG, "Association not allowed: broadcasting " Loading Loading
core/api/module-lib-current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -24,8 +24,8 @@ package android.app { } public class BroadcastOptions { method public int getMaxManifestReceiverApiLevel(); method public void setMaxManifestReceiverApiLevel(int); method @Deprecated public int getMaxManifestReceiverApiLevel(); method @Deprecated public void setMaxManifestReceiverApiLevel(int); } public abstract class HomeVisibilityListener { Loading
core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -724,12 +724,14 @@ package android.app { } public class BroadcastOptions { method public void clearRequireCompatChange(); method public boolean isPendingIntentBackgroundActivityLaunchAllowed(); method public static android.app.BroadcastOptions makeBasic(); method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean); method public void setDontSendToRestrictedApps(boolean); method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean); method public void setRequireAllOfPermissions(@Nullable String[]); method public void setRequireCompatChange(long, boolean); method public void setRequireNoneOfPermissions(@Nullable String[]); method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long);
core/api/test-current.txt +5 −2 Original line number Diff line number Diff line Loading @@ -248,12 +248,15 @@ package android.app { public class BroadcastOptions { ctor public BroadcastOptions(@NonNull android.os.Bundle); method public int getMaxManifestReceiverApiLevel(); method @Deprecated public int getMaxManifestReceiverApiLevel(); method public long getTemporaryAppAllowlistDuration(); method @Nullable public String getTemporaryAppAllowlistReason(); method public int getTemporaryAppAllowlistReasonCode(); method public int getTemporaryAppAllowlistType(); method public void setMaxManifestReceiverApiLevel(int); method @Deprecated public void setMaxManifestReceiverApiLevel(int); method public boolean testRequireCompatChange(int); field public static final long CHANGE_ALWAYS_DISABLED = 210856463L; // 0xc916a0fL field public static final long CHANGE_ALWAYS_ENABLED = 209888056L; // 0xc82a338L } public class DownloadManager { Loading
core/java/android/app/BroadcastOptions.java +136 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,11 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.EnabledSince; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.PowerExemptionManager; Loading @@ -45,6 +50,35 @@ public class BroadcastOptions extends ComponentOptions { private boolean mAllowBackgroundActivityStarts; private String[] mRequireAllOfPermissions; private String[] mRequireNoneOfPermissions; private long mRequireCompatChangeId = CHANGE_INVALID; private boolean mRequireCompatChangeEnabled = true; /** * Change ID which is invalid. * * @hide */ public static final long CHANGE_INVALID = Long.MIN_VALUE; /** * Change ID which is always enabled, for testing purposes. * * @hide */ @TestApi @ChangeId @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE) public static final long CHANGE_ALWAYS_ENABLED = 209888056L; /** * Change ID which is always disabled, for testing purposes. * * @hide */ @TestApi @ChangeId @Disabled public static final long CHANGE_ALWAYS_DISABLED = 210856463L; /** * How long to temporarily put an app on the power allowlist when executing this broadcast Loading Loading @@ -100,6 +134,18 @@ public class BroadcastOptions extends ComponentOptions { public static final String KEY_REQUIRE_NONE_OF_PERMISSIONS = "android:broadcast.requireNoneOfPermissions"; /** * Corresponds to {@link #setRequireCompatChange(long, boolean)} */ private static final String KEY_REQUIRE_COMPAT_CHANGE_ID = "android:broadcast.requireCompatChangeId"; /** * Corresponds to {@link #setRequireCompatChange(long, boolean)} */ private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = "android:broadcast.requireCompatChangeEnabled"; /** * @hide * @deprecated Use {@link android.os.PowerExemptionManager# Loading Loading @@ -150,6 +196,8 @@ public class BroadcastOptions extends ComponentOptions { false); mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS); mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); } /** Loading Loading @@ -270,16 +318,32 @@ public class BroadcastOptions extends ComponentOptions { * Set the minimum target API level of receivers of the broadcast. If an application * is targeting an API level less than this, the broadcast will not be delivered to * them. This only applies to receivers declared in the app's AndroidManifest.xml. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @Deprecated public void setMinManifestReceiverApiLevel(int apiLevel) { mMinManifestReceiverApiLevel = apiLevel; } /** * Return {@link #setMinManifestReceiverApiLevel}. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @Deprecated public int getMinManifestReceiverApiLevel() { return mMinManifestReceiverApiLevel; } Loading @@ -288,20 +352,36 @@ public class BroadcastOptions extends ComponentOptions { * Set the maximum target API level of receivers of the broadcast. If an application * is targeting an API level greater than this, the broadcast will not be delivered to * them. This only applies to receivers declared in the app's AndroidManifest.xml. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @TestApi @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Deprecated public void setMaxManifestReceiverApiLevel(int apiLevel) { mMaxManifestReceiverApiLevel = apiLevel; } /** * Return {@link #setMaxManifestReceiverApiLevel}. * * @deprecated to give developers the most flexibility during beta releases, * we strongly encourage using {@link ChangeId} instead of * target SDK checks; callers should use * {@link #setRequireCompatChange(long, boolean)} instead, * possibly combined with * {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}. * @hide */ @TestApi @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Deprecated public int getMaxManifestReceiverApiLevel() { return mMaxManifestReceiverApiLevel; } Loading Loading @@ -378,6 +458,58 @@ public class BroadcastOptions extends ComponentOptions { mRequireNoneOfPermissions = excludedPermissions; } /** * When set, this broadcast will only be delivered to apps which have the * given {@link ChangeId} in the given state. * <p> * Each {@link BroadcastOptions} instance supports only a single * {@link ChangeId} requirement, so any subsequent calls will override any * previously defined requirement. * <p> * This requirement applies to both manifest registered and runtime * registered receivers. * * @param changeId the {@link ChangeId} to inspect * @param enabled the required enabled state of the inspected * {@link ChangeId} for this broadcast to be delivered * @see CompatChanges#isChangeEnabled * @see #clearRequireCompatChange() */ public void setRequireCompatChange(long changeId, boolean enabled) { mRequireCompatChangeId = changeId; mRequireCompatChangeEnabled = enabled; } /** * Clear any previously defined requirement for this broadcast requested via * {@link #setRequireCompatChange(long, boolean)}. */ public void clearRequireCompatChange() { mRequireCompatChangeId = CHANGE_INVALID; mRequireCompatChangeEnabled = true; } /** {@hide} */ public long getRequireCompatChangeId() { return mRequireCompatChangeId; } /** * Test if the given app meets the {@link ChangeId} state required by this * broadcast, if any. * * @hide */ @TestApi public boolean testRequireCompatChange(int uid) { if (mRequireCompatChangeId != CHANGE_INVALID) { return CompatChanges.isChangeEnabled(mRequireCompatChangeId, uid) == mRequireCompatChangeEnabled; } else { return true; } } /** * Returns the created options as a Bundle, which can be passed to * {@link android.content.Context#sendBroadcast(android.content.Intent) Loading Loading @@ -413,6 +545,10 @@ public class BroadcastOptions extends ComponentOptions { if (mRequireNoneOfPermissions != null) { b.putStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS, mRequireNoneOfPermissions); } if (mRequireCompatChangeId != CHANGE_INVALID) { b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId); b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled); } return b.isEmpty() ? null : b; } }
services/core/java/com/android/server/am/BroadcastQueue.java +13 −0 Original line number Diff line number Diff line Loading @@ -632,6 +632,12 @@ public final class BroadcastQueue { private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index) { boolean skip = false; if (r.options != null && !r.options.testRequireCompatChange(filter.owningUid)) { Slog.w(TAG, "Compat change filtered: broadcasting " + r.intent.toString() + " to uid " + filter.owningUid + " due to compat change " + r.options.getRequireCompatChangeId()); skip = true; } if (!mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid, filter.packageName, filter.owningUid)) { Slog.w(TAG, "Association not allowed: broadcasting " Loading Loading @@ -1407,6 +1413,13 @@ public final class BroadcastQueue { + "] broadcasting " + broadcastDescription(r, component)); skip = true; } if (brOptions != null && !brOptions.testRequireCompatChange(info.activityInfo.applicationInfo.uid)) { Slog.w(TAG, "Compat change filtered: broadcasting " + broadcastDescription(r, component) + " to uid " + info.activityInfo.applicationInfo.uid + " due to compat change " + r.options.getRequireCompatChangeId()); skip = true; } if (!skip && !mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid, component.getPackageName(), info.activityInfo.applicationInfo.uid)) { Slog.w(TAG, "Association not allowed: broadcasting " Loading