Loading services/core/java/com/android/server/am/PendingIntentRecord.java +35 −4 Original line number Diff line number Diff line Loading @@ -22,16 +22,21 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.BackgroundStartPrivileges; import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.IIntentReceiver; import android.content.IIntentSender; import android.content.Intent; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.PowerWhitelistManager; Loading @@ -40,6 +45,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.TransactionTooLargeException; import android.os.UserHandle; import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; Loading @@ -56,6 +62,13 @@ import java.util.Objects; public final class PendingIntentRecord extends IIntentSender.Stub { private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentRecord" : TAG_AM; /** If enabled BAL are prevented by default in applications targeting U and later. */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER = 244637991; private static final String ENABLE_DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER = "enable_default_rescind_bal_privileges_from_pending_intent_sender"; public static final int FLAG_ACTIVITY_SENDER = 1 << 0; public static final int FLAG_BROADCAST_SENDER = 1 << 1; public static final int FLAG_SERVICE_SENDER = 1 << 2; Loading Loading @@ -357,17 +370,35 @@ public final class PendingIntentRecord extends IIntentSender.Stub { : BackgroundStartPrivileges.NONE; } private static boolean isDefaultRescindBalPrivilegesFromPendingIntentSenderEnabled() { return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_WINDOW_MANAGER, ENABLE_DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, true); // assume true if the property is unknown } /** * Default {@link BackgroundStartPrivileges} to be used if the intent sender has not made an * explicit choice. * * @hide */ public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges(int callingUid) { // TODO: In the next step this will return ALLOW_FGS instead, if the app that sent the // PendingIntent is targeting Android U @RequiresPermission( allOf = { android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, android.Manifest.permission.LOG_COMPAT_CHANGE }) public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges( int callingUid) { boolean isFlagEnabled = isDefaultRescindBalPrivilegesFromPendingIntentSenderEnabled(); boolean isChangeEnabledForApp = CompatChanges.isChangeEnabled( DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingUid); if (isFlagEnabled && isChangeEnabledForApp) { return BackgroundStartPrivileges.ALLOW_FGS; } else { return BackgroundStartPrivileges.ALLOW_BAL; } } @Deprecated public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken, Loading services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +6 −6 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; Loading Loading @@ -749,16 +750,15 @@ public class ActivityStarterTests extends WindowTestsBase { } /** * This test ensures that supported usecases aren't aborted when background starts are * disallowed. Each scenarios tests one condition that makes them supported in isolation. In * this case the real calling process (pending intent) has a visible window. * The sending app has a visible window, but does not (by default) allow the pending intent to * start the background activity. */ @Test public void testBackgroundActivityStartsDisallowed_realCallingUidHasVisibleWindowNotAborted() { public void testBackgroundActivityStartsDisallowed_realCallingUidHasVisibleWindowAborted() { doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidHasVisibleWindow_notAborted", false, "disallowed_realCallingUidHasVisibleWindow_abortedInU", true, UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP, UNIMPORTANT_UID2, true, PROCESS_STATE_BOUND_TOP, false, false, false, false, false, false); Loading Loading
services/core/java/com/android/server/am/PendingIntentRecord.java +35 −4 Original line number Diff line number Diff line Loading @@ -22,16 +22,21 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.BackgroundStartPrivileges; import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.IIntentReceiver; import android.content.IIntentSender; import android.content.Intent; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.PowerWhitelistManager; Loading @@ -40,6 +45,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.TransactionTooLargeException; import android.os.UserHandle; import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; Loading @@ -56,6 +62,13 @@ import java.util.Objects; public final class PendingIntentRecord extends IIntentSender.Stub { private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentRecord" : TAG_AM; /** If enabled BAL are prevented by default in applications targeting U and later. */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER = 244637991; private static final String ENABLE_DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER = "enable_default_rescind_bal_privileges_from_pending_intent_sender"; public static final int FLAG_ACTIVITY_SENDER = 1 << 0; public static final int FLAG_BROADCAST_SENDER = 1 << 1; public static final int FLAG_SERVICE_SENDER = 1 << 2; Loading Loading @@ -357,17 +370,35 @@ public final class PendingIntentRecord extends IIntentSender.Stub { : BackgroundStartPrivileges.NONE; } private static boolean isDefaultRescindBalPrivilegesFromPendingIntentSenderEnabled() { return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_WINDOW_MANAGER, ENABLE_DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, true); // assume true if the property is unknown } /** * Default {@link BackgroundStartPrivileges} to be used if the intent sender has not made an * explicit choice. * * @hide */ public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges(int callingUid) { // TODO: In the next step this will return ALLOW_FGS instead, if the app that sent the // PendingIntent is targeting Android U @RequiresPermission( allOf = { android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, android.Manifest.permission.LOG_COMPAT_CHANGE }) public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges( int callingUid) { boolean isFlagEnabled = isDefaultRescindBalPrivilegesFromPendingIntentSenderEnabled(); boolean isChangeEnabledForApp = CompatChanges.isChangeEnabled( DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingUid); if (isFlagEnabled && isChangeEnabledForApp) { return BackgroundStartPrivileges.ALLOW_FGS; } else { return BackgroundStartPrivileges.ALLOW_BAL; } } @Deprecated public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken, Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +6 −6 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; Loading Loading @@ -749,16 +750,15 @@ public class ActivityStarterTests extends WindowTestsBase { } /** * This test ensures that supported usecases aren't aborted when background starts are * disallowed. Each scenarios tests one condition that makes them supported in isolation. In * this case the real calling process (pending intent) has a visible window. * The sending app has a visible window, but does not (by default) allow the pending intent to * start the background activity. */ @Test public void testBackgroundActivityStartsDisallowed_realCallingUidHasVisibleWindowNotAborted() { public void testBackgroundActivityStartsDisallowed_realCallingUidHasVisibleWindowAborted() { doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidHasVisibleWindow_notAborted", false, "disallowed_realCallingUidHasVisibleWindow_abortedInU", true, UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP, UNIMPORTANT_UID2, true, PROCESS_STATE_BOUND_TOP, false, false, false, false, false, false); Loading