diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index e5df278f2cc1d..75d4f32055e27 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -21,8 +21,11 @@ import static android.Manifest.permission.GET_ACCOUNTS; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; import android.annotation.Size; import android.annotation.SystemApi; +import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.BroadcastBehavior; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -335,6 +338,8 @@ public class AccountManager { * * @deprecated use #addOnAccountsUpdatedListener to get account updates in runtime. */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(includeBackground = true) public static final String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; diff --git a/core/java/android/annotation/BroadcastBehavior.java b/core/java/android/annotation/BroadcastBehavior.java new file mode 100644 index 0000000000000..9b2ca3120290f --- /dev/null +++ b/core/java/android/annotation/BroadcastBehavior.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.annotation; + +import android.content.Intent; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Description of how the annotated broadcast action behaves. + * + * @hide + */ +@Target({ ElementType.FIELD }) +@Retention(RetentionPolicy.SOURCE) +public @interface BroadcastBehavior { + /** + * This broadcast will only be delivered to an explicit target. + * + * @see Intent#setPackage(String) + * @see Intent#setComponent(android.content.ComponentName) + */ + boolean explicitOnly() default false; + + /** + * This broadcast will only be delivered to registered receivers. + * + * @see Intent#FLAG_RECEIVER_REGISTERED_ONLY + */ + boolean registeredOnly() default false; + + /** + * This broadcast will include all {@code AndroidManifest.xml} receivers + * regardless of process state. + * + * @see Intent#FLAG_RECEIVER_INCLUDE_BACKGROUND + */ + boolean includeBackground() default false; +} diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 0fb59668a201f..d9b6eed4fc4d7 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -17,6 +17,7 @@ package android.app.admin; import android.accounts.AccountManager; +import android.annotation.BroadcastBehavior; import android.annotation.IntDef; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -81,6 +82,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * that other applications can not abuse it. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED"; @@ -94,6 +96,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * to the user before they disable your admin. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED"; @@ -115,6 +118,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * its intent filter. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED"; @@ -131,6 +135,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * this broadcast. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_PASSWORD_CHANGED = "android.app.action.ACTION_PASSWORD_CHANGED"; @@ -147,6 +152,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * this broadcast. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED"; @@ -160,6 +166,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * this broadcast. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED"; @@ -173,6 +180,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * this broadcast. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING"; @@ -187,6 +195,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @see DevicePolicyManager#isLockTaskPermitted(String) */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_LOCK_TASK_ENTERING = "android.app.action.LOCK_TASK_ENTERING"; @@ -200,6 +209,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @see DevicePolicyManager#isLockTaskPermitted(String) */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_LOCK_TASK_EXITING = "android.app.action.LOCK_TASK_EXITING"; @@ -232,6 +242,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { *
Output: Nothing
*/ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE"; @@ -244,6 +255,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_BUGREPORT_SHARING_DECLINED = "android.app.action.BUGREPORT_SHARING_DECLINED"; @@ -256,6 +268,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED"; /** @@ -266,6 +279,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_BUGREPORT_SHARE = "android.app.action.BUGREPORT_SHARE"; @@ -274,6 +288,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_SECURITY_LOGS_AVAILABLE = "android.app.action.SECURITY_LOGS_AVAILABLE"; @@ -283,6 +298,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_NETWORK_LOGS_AVAILABLE = "android.app.action.NETWORK_LOGS_AVAILABLE"; @@ -314,7 +330,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_USER_ADDED = "android.app.action.USER_ADDED"; + @BroadcastBehavior(explicitOnly = true) + public static final String ACTION_USER_ADDED = "android.app.action.USER_ADDED"; /** * Broadcast action: notify the device owner that a user or profile has been removed. @@ -323,6 +340,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_USER_REMOVED = "android.app.action.USER_REMOVED"; /** @@ -401,6 +419,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE = "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE"; diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 67c791df3c9a5..74a39e85e029a 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -16,8 +16,11 @@ package android.appwidget; +import android.annotation.BroadcastBehavior; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; @@ -81,12 +84,14 @@ public class AppWidgetManager { * * @see #ACTION_APPWIDGET_CONFIGURE */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK"; /** * Similar to ACTION_APPWIDGET_PICK, but used from keyguard * @hide */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK"; @@ -133,6 +138,7 @@ public class AppWidgetManager { * @see #ACTION_APPWIDGET_CONFIGURE * */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND"; /** @@ -157,6 +163,7 @@ public class AppWidgetManager { * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} * broadcast. */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE"; /** @@ -290,6 +297,8 @@ public class AppWidgetManager { * * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; /** @@ -302,6 +311,8 @@ public class AppWidgetManager { * AppWidgetProvider.onAppWidgetOptionsChanged(Context context, * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras) */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS"; /** @@ -312,6 +323,8 @@ public class AppWidgetManager { * * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds) */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; /** @@ -322,6 +335,8 @@ public class AppWidgetManager { * * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context) */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; /** @@ -334,6 +349,8 @@ public class AppWidgetManager { * * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"; /** @@ -365,6 +382,8 @@ public class AppWidgetManager { * * @see #ACTION_APPWIDGET_HOST_RESTORED */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED"; @@ -402,6 +421,8 @@ public class AppWidgetManager { * * @see #ACTION_APPWIDGET_RESTORED */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(explicitOnly = true) public static final String ACTION_APPWIDGET_HOST_RESTORED = "android.appwidget.action.APPWIDGET_HOST_RESTORED"; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 1f01e28ea0b04..4dc6fd227243f 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -17,6 +17,7 @@ package android.content; import android.annotation.AnyRes; +import android.annotation.BroadcastBehavior; import android.annotation.IntDef; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -1992,6 +1993,7 @@ public class Intent implements Parcelable, Cloneable { * This is a protected intent that can only be sent by the system. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(includeBackground = true) public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; /** diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index e15a0e240711e..5a28e87ac65f7 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -211,6 +211,14 @@ public class PackageParser { CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT); } + private static final boolean LOG_UNSAFE_BROADCASTS = false; + + // Set of broadcast actions that are safe for manifest receivers + private static final Set