Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -34131,6 +34131,7 @@ package android.os { method public android.os.StrictMode.VmPolicy build(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectActivityLeaks(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectAll(); method @FlaggedApi("com.android.window.flags.bal_strict_mode") @NonNull public android.os.StrictMode.VmPolicy.Builder detectBlockedBackgroundActivityLaunch(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectCleartextNetwork(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectContentUriWithoutPermission(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectCredentialProtectedWhileLocked(); Loading @@ -34143,6 +34144,7 @@ package android.os { method @NonNull public android.os.StrictMode.VmPolicy.Builder detectNonSdkApiUsage(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectUnsafeIntentLaunch(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets(); method @FlaggedApi("com.android.window.flags.bal_strict_mode") @NonNull public android.os.StrictMode.VmPolicy.Builder ignoreBlockedBackgroundActivityLaunch(); method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeath(); method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork(); method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnFileUriExposure(); core/java/android/app/IActivityTaskManager.aidl +17 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,23 @@ interface IActivityTaskManager { android.window.BackNavigationInfo startBackNavigation( in RemoteCallback navigationObserver, in BackAnimationAdapter adaptor); /** * registers a callback to be invoked when a background activity launch is aborted. * * @param observer callback to be registered. * @return true if the callback was successfully registered, false otherwise. * @hide */ boolean registerBackgroundActivityStartCallback(in IBinder binder); /** * unregisters a callback to be invoked when a background activity launch is aborted. * * @param observer callback to be registered. * @hide */ void unregisterBackgroundActivityStartCallback(in IBinder binder); /** * registers a callback to be invoked when the screen is captured. * Loading core/java/android/app/IBackgroundActivityLaunchCallback.aidl 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright 2024, 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.app; /** * Callback to find out when a background activity launch is aborted. * @hide */ oneway interface IBackgroundActivityLaunchCallback { void onBackgroundActivityLaunchAborted(in String message); } core/java/android/os/StrictMode.java +81 −0 Original line number Diff line number Diff line Loading @@ -20,17 +20,22 @@ import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH; import static com.android.window.flags.Flags.balStrictMode; import android.animation.ValueAnimator; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.IActivityManager; import android.app.IBackgroundActivityLaunchCallback; import android.app.IUnsafeIntentStrictModeCallback; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; Loading @@ -45,6 +50,7 @@ import android.content.res.Configuration; import android.net.TrafficStats; import android.net.Uri; import android.os.storage.IStorageManager; import android.os.strictmode.BackgroundActivityLaunchViolation; import android.os.strictmode.CleartextNetworkViolation; import android.os.strictmode.ContentUriWithoutPermissionViolation; import android.os.strictmode.CredentialProtectedWhileLockedViolation; Loading Loading @@ -82,6 +88,7 @@ import com.android.internal.os.RuntimeInit; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.HexDump; import com.android.internal.util.Preconditions; import com.android.window.flags.Flags; import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; Loading Loading @@ -266,6 +273,7 @@ public final class StrictMode { DETECT_VM_IMPLICIT_DIRECT_BOOT, DETECT_VM_INCORRECT_CONTEXT_USE, DETECT_VM_UNSAFE_INTENT_LAUNCH, DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED, PENALTY_GATHER, PENALTY_LOG, PENALTY_DIALOG, Loading Loading @@ -309,6 +317,8 @@ public final class StrictMode { private static final int DETECT_VM_INCORRECT_CONTEXT_USE = 1 << 12; /** @hide */ private static final int DETECT_VM_UNSAFE_INTENT_LAUNCH = 1 << 13; /** @hide */ private static final int DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED = 1 << 14; /** @hide */ private static final int DETECT_VM_ALL = 0x0000ffff; Loading Loading @@ -902,6 +912,9 @@ public final class StrictMode { if (targetSdk >= Build.VERSION_CODES.S) { detectUnsafeIntentLaunch(); } if (balStrictMode() && targetSdk > Build.VERSION_CODES.VANILLA_ICE_CREAM) { detectBlockedBackgroundActivityLaunch(); } // TODO: Decide whether to detect non SDK API usage beyond a certain API level. // TODO: enable detectImplicitDirectBoot() once system is less noisy Loading Loading @@ -1139,6 +1152,39 @@ public final class StrictMode { return disable(DETECT_VM_UNSAFE_INTENT_LAUNCH); } /** * Detects when your app is blocked from launching a background activity or a * PendingIntent created by your app cannot be launched. * <p> * Starting an activity requires <a * href="https://developer.android.com/guide/components/activities/background-starts * ">specific permissions</a> which may depend on the state at runtime and especially * in case of {@link android.app.PendingIntent} starts on the collaborating app. * If the activity start is blocked methods like {@link Context#startActivity(Intent)} * or {@link PendingIntent#send()} have no way to return that information. Instead you * can use this strct mode feature to detect blocked starts. * <p> * Note that in some cases blocked starts may be unavoidable, e.g. when the user clicks * the home button while the app tries to start a new activity. */ @SuppressWarnings("BuilderSetStyle") @FlaggedApi(Flags.FLAG_BAL_STRICT_MODE) public @NonNull Builder detectBlockedBackgroundActivityLaunch() { return enable(DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED); } /** * Stops detecting whether your app is blocked from launching a background activity or * a PendingIntent created by your app cannot be launched. * <p> * This disables the effect of {@link #detectBlockedBackgroundActivityLaunch()}. */ @SuppressWarnings("BuilderSetStyle") @FlaggedApi(Flags.FLAG_BAL_STRICT_MODE) public @NonNull Builder ignoreBlockedBackgroundActivityLaunch() { return disable(DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED); } /** * Crashes the whole process on violation. This penalty runs at the end of all enabled * penalties so you'll still get your logging or other violations before the process Loading Loading @@ -2133,10 +2179,25 @@ public final class StrictMode { registerIntentMatchingRestrictionCallback(); } if ((sVmPolicy.mask & DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED) != 0) { registerBackgroundActivityLaunchCallback(); } setBlockGuardVmPolicy(sVmPolicy.mask); } } private static void registerBackgroundActivityLaunchCallback() { try { ActivityTaskManager.getService().registerBackgroundActivityStartCallback( new BackgroundActivityLaunchCallback()); } catch (DeadObjectException e) { // ignore } catch (RemoteException e) { Log.e(TAG, "RemoteException handling StrictMode violation", e); } } private static final class UnsafeIntentStrictModeCallback extends IUnsafeIntentStrictModeCallback.Stub { @Override Loading @@ -2161,6 +2222,16 @@ public final class StrictMode { } } private static final class BackgroundActivityLaunchCallback extends IBackgroundActivityLaunchCallback.Stub { @Override public void onBackgroundActivityLaunchAborted(String message) { if (StrictMode.vmBackgroundActivityLaunchEnabled()) { StrictMode.onBackgroundActivityLaunchAborted(message); } } } /** Gets the current VM policy. */ public static VmPolicy getVmPolicy() { synchronized (StrictMode.class) { Loading Loading @@ -2235,6 +2306,11 @@ public final class StrictMode { return (sVmPolicy.mask & DETECT_VM_UNSAFE_INTENT_LAUNCH) != 0; } /** @hide */ public static boolean vmBackgroundActivityLaunchEnabled() { return (sVmPolicy.mask & DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED) != 0; } /** @hide */ public static void onSqliteObjectLeaked(String message, Throwable originStack) { onVmPolicyViolation(new SqliteObjectLeakedViolation(message, originStack)); Loading Loading @@ -2402,6 +2478,11 @@ public final class StrictMode { onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent, msg + intent)); } /** @hide */ public static void onBackgroundActivityLaunchAborted(String message) { onVmPolicyViolation(new BackgroundActivityLaunchViolation(message)); } /** Assume locked until we hear otherwise */ private static volatile boolean sCeStorageUnlocked = false; Loading core/java/android/os/strictmode/BackgroundActivityLaunchViolation.java 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.os.strictmode; import android.annotation.NonNull; import android.app.Activity; /** * Violation raised when your app is blocked from launching an {@link Activity} * (from the background). * <p> * This occurs when the app: * <ul> * <li>Does not have sufficient privileges to launch the Activity.</li> * <li>Has not explicitly opted-in to launch the Activity.</li> * </ul> * Violations may affect the functionality of your app and should be addressed to ensure * proper behavior. * @hide */ public class BackgroundActivityLaunchViolation extends Violation { /** @hide */ public BackgroundActivityLaunchViolation(@NonNull String message) { super(message); } } Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -34131,6 +34131,7 @@ package android.os { method public android.os.StrictMode.VmPolicy build(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectActivityLeaks(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectAll(); method @FlaggedApi("com.android.window.flags.bal_strict_mode") @NonNull public android.os.StrictMode.VmPolicy.Builder detectBlockedBackgroundActivityLaunch(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectCleartextNetwork(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectContentUriWithoutPermission(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectCredentialProtectedWhileLocked(); Loading @@ -34143,6 +34144,7 @@ package android.os { method @NonNull public android.os.StrictMode.VmPolicy.Builder detectNonSdkApiUsage(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectUnsafeIntentLaunch(); method @NonNull public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets(); method @FlaggedApi("com.android.window.flags.bal_strict_mode") @NonNull public android.os.StrictMode.VmPolicy.Builder ignoreBlockedBackgroundActivityLaunch(); method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeath(); method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork(); method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnFileUriExposure();
core/java/android/app/IActivityTaskManager.aidl +17 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,23 @@ interface IActivityTaskManager { android.window.BackNavigationInfo startBackNavigation( in RemoteCallback navigationObserver, in BackAnimationAdapter adaptor); /** * registers a callback to be invoked when a background activity launch is aborted. * * @param observer callback to be registered. * @return true if the callback was successfully registered, false otherwise. * @hide */ boolean registerBackgroundActivityStartCallback(in IBinder binder); /** * unregisters a callback to be invoked when a background activity launch is aborted. * * @param observer callback to be registered. * @hide */ void unregisterBackgroundActivityStartCallback(in IBinder binder); /** * registers a callback to be invoked when the screen is captured. * Loading
core/java/android/app/IBackgroundActivityLaunchCallback.aidl 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright 2024, 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.app; /** * Callback to find out when a background activity launch is aborted. * @hide */ oneway interface IBackgroundActivityLaunchCallback { void onBackgroundActivityLaunchAborted(in String message); }
core/java/android/os/StrictMode.java +81 −0 Original line number Diff line number Diff line Loading @@ -20,17 +20,22 @@ import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH; import static com.android.window.flags.Flags.balStrictMode; import android.animation.ValueAnimator; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.IActivityManager; import android.app.IBackgroundActivityLaunchCallback; import android.app.IUnsafeIntentStrictModeCallback; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; Loading @@ -45,6 +50,7 @@ import android.content.res.Configuration; import android.net.TrafficStats; import android.net.Uri; import android.os.storage.IStorageManager; import android.os.strictmode.BackgroundActivityLaunchViolation; import android.os.strictmode.CleartextNetworkViolation; import android.os.strictmode.ContentUriWithoutPermissionViolation; import android.os.strictmode.CredentialProtectedWhileLockedViolation; Loading Loading @@ -82,6 +88,7 @@ import com.android.internal.os.RuntimeInit; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.HexDump; import com.android.internal.util.Preconditions; import com.android.window.flags.Flags; import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; Loading Loading @@ -266,6 +273,7 @@ public final class StrictMode { DETECT_VM_IMPLICIT_DIRECT_BOOT, DETECT_VM_INCORRECT_CONTEXT_USE, DETECT_VM_UNSAFE_INTENT_LAUNCH, DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED, PENALTY_GATHER, PENALTY_LOG, PENALTY_DIALOG, Loading Loading @@ -309,6 +317,8 @@ public final class StrictMode { private static final int DETECT_VM_INCORRECT_CONTEXT_USE = 1 << 12; /** @hide */ private static final int DETECT_VM_UNSAFE_INTENT_LAUNCH = 1 << 13; /** @hide */ private static final int DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED = 1 << 14; /** @hide */ private static final int DETECT_VM_ALL = 0x0000ffff; Loading Loading @@ -902,6 +912,9 @@ public final class StrictMode { if (targetSdk >= Build.VERSION_CODES.S) { detectUnsafeIntentLaunch(); } if (balStrictMode() && targetSdk > Build.VERSION_CODES.VANILLA_ICE_CREAM) { detectBlockedBackgroundActivityLaunch(); } // TODO: Decide whether to detect non SDK API usage beyond a certain API level. // TODO: enable detectImplicitDirectBoot() once system is less noisy Loading Loading @@ -1139,6 +1152,39 @@ public final class StrictMode { return disable(DETECT_VM_UNSAFE_INTENT_LAUNCH); } /** * Detects when your app is blocked from launching a background activity or a * PendingIntent created by your app cannot be launched. * <p> * Starting an activity requires <a * href="https://developer.android.com/guide/components/activities/background-starts * ">specific permissions</a> which may depend on the state at runtime and especially * in case of {@link android.app.PendingIntent} starts on the collaborating app. * If the activity start is blocked methods like {@link Context#startActivity(Intent)} * or {@link PendingIntent#send()} have no way to return that information. Instead you * can use this strct mode feature to detect blocked starts. * <p> * Note that in some cases blocked starts may be unavoidable, e.g. when the user clicks * the home button while the app tries to start a new activity. */ @SuppressWarnings("BuilderSetStyle") @FlaggedApi(Flags.FLAG_BAL_STRICT_MODE) public @NonNull Builder detectBlockedBackgroundActivityLaunch() { return enable(DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED); } /** * Stops detecting whether your app is blocked from launching a background activity or * a PendingIntent created by your app cannot be launched. * <p> * This disables the effect of {@link #detectBlockedBackgroundActivityLaunch()}. */ @SuppressWarnings("BuilderSetStyle") @FlaggedApi(Flags.FLAG_BAL_STRICT_MODE) public @NonNull Builder ignoreBlockedBackgroundActivityLaunch() { return disable(DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED); } /** * Crashes the whole process on violation. This penalty runs at the end of all enabled * penalties so you'll still get your logging or other violations before the process Loading Loading @@ -2133,10 +2179,25 @@ public final class StrictMode { registerIntentMatchingRestrictionCallback(); } if ((sVmPolicy.mask & DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED) != 0) { registerBackgroundActivityLaunchCallback(); } setBlockGuardVmPolicy(sVmPolicy.mask); } } private static void registerBackgroundActivityLaunchCallback() { try { ActivityTaskManager.getService().registerBackgroundActivityStartCallback( new BackgroundActivityLaunchCallback()); } catch (DeadObjectException e) { // ignore } catch (RemoteException e) { Log.e(TAG, "RemoteException handling StrictMode violation", e); } } private static final class UnsafeIntentStrictModeCallback extends IUnsafeIntentStrictModeCallback.Stub { @Override Loading @@ -2161,6 +2222,16 @@ public final class StrictMode { } } private static final class BackgroundActivityLaunchCallback extends IBackgroundActivityLaunchCallback.Stub { @Override public void onBackgroundActivityLaunchAborted(String message) { if (StrictMode.vmBackgroundActivityLaunchEnabled()) { StrictMode.onBackgroundActivityLaunchAborted(message); } } } /** Gets the current VM policy. */ public static VmPolicy getVmPolicy() { synchronized (StrictMode.class) { Loading Loading @@ -2235,6 +2306,11 @@ public final class StrictMode { return (sVmPolicy.mask & DETECT_VM_UNSAFE_INTENT_LAUNCH) != 0; } /** @hide */ public static boolean vmBackgroundActivityLaunchEnabled() { return (sVmPolicy.mask & DETECT_VM_BACKGROUND_ACTIVITY_LAUNCH_ABORTED) != 0; } /** @hide */ public static void onSqliteObjectLeaked(String message, Throwable originStack) { onVmPolicyViolation(new SqliteObjectLeakedViolation(message, originStack)); Loading Loading @@ -2402,6 +2478,11 @@ public final class StrictMode { onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent, msg + intent)); } /** @hide */ public static void onBackgroundActivityLaunchAborted(String message) { onVmPolicyViolation(new BackgroundActivityLaunchViolation(message)); } /** Assume locked until we hear otherwise */ private static volatile boolean sCeStorageUnlocked = false; Loading
core/java/android/os/strictmode/BackgroundActivityLaunchViolation.java 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.os.strictmode; import android.annotation.NonNull; import android.app.Activity; /** * Violation raised when your app is blocked from launching an {@link Activity} * (from the background). * <p> * This occurs when the app: * <ul> * <li>Does not have sufficient privileges to launch the Activity.</li> * <li>Has not explicitly opted-in to launch the Activity.</li> * </ul> * Violations may affect the functionality of your app and should be addressed to ensure * proper behavior. * @hide */ public class BackgroundActivityLaunchViolation extends Violation { /** @hide */ public BackgroundActivityLaunchViolation(@NonNull String message) { super(message); } }