Revert^2 "Clear the BAL allowlist duration"
Clearing BAL privileges of a PendingIntent only cleared the tokens,
but kept the duration based entries to allow FGS starts. With this
change the duration token is downgraded to NOT allow FGS starts.
`clearAllowBgActivityStarts` is exclusively used by SystemUI
(in NotificationManagerService) and fixing this is part of
fixing a security vulnerability.
The original fix is caused issues when dismissing notifications
from some apps, therefore it is flag guarded now.
This reverts commit 2e971059454eeea9b606ef82207d74da8e329ffb.
Reason for revert: roll forward with changes
BYPASS_INCLUSIVE_LANGUAGE_REASON=Using an existing API
Bug: 322159724
Flag: com.android.window.flags.bal_clear_allowlist_duration
Test: atest PendingIntentControllerTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c4021093e6d0a29d30c48b6bcaf672944555359c)
Merged-In: Iac2f9ba4be2dc3addbf04d996c6cb90fe5c6385f
Change-Id: Iac2f9ba4be2dc3addbf04d996c6cb90fe5c6385f
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index d5ba32c..3621981 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -75,4 +75,16 @@
bug: "362575865"
}
+flag {
+ name: "bal_strict_mode_grace_period"
+ namespace: "responsible_apis"
+ description: "Strict mode violation triggered by grace period usage"
+ bug: "384807495"
+}
+flag {
+ name: "bal_clear_allowlist_duration"
+ namespace: "responsible_apis"
+ description: "Clear the allowlist duration when clearAllowBgActivityStarts is called"
+ bug: "322159724"
+}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 3817ba1..2c0366e 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -24,11 +24,14 @@
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE;
+import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SYSTEM_UID;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.window.flags.Flags.balClearAllowlistDuration;
import android.annotation.IntDef;
import android.annotation.Nullable;
@@ -305,6 +308,10 @@
this.stringName = null;
}
+ @VisibleForTesting TempAllowListDuration getAllowlistDurationLocked(IBinder allowlistToken) {
+ return mAllowlistDuration.get(allowlistToken);
+ }
+
void setAllowBgActivityStarts(IBinder token, int flags) {
if (token == null) return;
if ((flags & FLAG_ACTIVITY_SENDER) != 0) {
@@ -323,6 +330,13 @@
mAllowBgActivityStartsForActivitySender.remove(token);
mAllowBgActivityStartsForBroadcastSender.remove(token);
mAllowBgActivityStartsForServiceSender.remove(token);
+ if (mAllowlistDuration != null && balClearAllowlistDuration()) {
+ TempAllowListDuration duration = mAllowlistDuration.get(token);
+ if (duration != null
+ && duration.type == TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
+ duration.type = TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
+ }
+ }
}
public void registerCancelListenerLocked(IResultReceiver receiver) {
@@ -703,7 +717,7 @@
return res;
}
- private BackgroundStartPrivileges getBackgroundStartPrivilegesForActivitySender(
+ @VisibleForTesting BackgroundStartPrivileges getBackgroundStartPrivilegesForActivitySender(
IBinder allowlistToken) {
return mAllowBgActivityStartsForActivitySender.contains(allowlistToken)
? BackgroundStartPrivileges.allowBackgroundActivityStarts(allowlistToken)
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
index 89b48ba..d6349fc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE;
+import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
import static android.os.Process.INVALID_UID;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -27,9 +30,12 @@
import static com.android.server.am.PendingIntentRecord.CANCEL_REASON_OWNER_FORCE_STOPPED;
import static com.android.server.am.PendingIntentRecord.CANCEL_REASON_SUPERSEDED;
import static com.android.server.am.PendingIntentRecord.CANCEL_REASON_USER_STOPPED;
+import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.cancelReasonToString;
+import static com.android.window.flags.Flags.balClearAllowlistDuration;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
@@ -39,9 +45,11 @@
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
+import android.app.BackgroundStartPrivileges;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.IPackageManager;
+import android.os.Binder;
import android.os.Looper;
import android.os.UserHandle;
@@ -179,6 +187,41 @@
}
}
+ @Test
+ public void testClearAllowBgActivityStartsClearsToken() {
+ final PendingIntentRecord pir = createPendingIntentRecord(0);
+ Binder token = new Binder();
+ pir.setAllowBgActivityStarts(token, FLAG_ACTIVITY_SENDER);
+ assertEquals(BackgroundStartPrivileges.allowBackgroundActivityStarts(token),
+ pir.getBackgroundStartPrivilegesForActivitySender(token));
+ pir.clearAllowBgActivityStarts(token);
+ assertEquals(BackgroundStartPrivileges.NONE,
+ pir.getBackgroundStartPrivilegesForActivitySender(token));
+ }
+
+ @Test
+ public void testClearAllowBgActivityStartsClearsDuration() {
+ final PendingIntentRecord pir = createPendingIntentRecord(0);
+ Binder token = new Binder();
+ pir.setAllowlistDurationLocked(token, 1000,
+ TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, REASON_NOTIFICATION_SERVICE,
+ "NotificationManagerService");
+ PendingIntentRecord.TempAllowListDuration allowlistDurationLocked =
+ pir.getAllowlistDurationLocked(token);
+ assertEquals(1000, allowlistDurationLocked.duration);
+ assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+ allowlistDurationLocked.type);
+ pir.clearAllowBgActivityStarts(token);
+ PendingIntentRecord.TempAllowListDuration allowlistDurationLockedAfterClear =
+ pir.getAllowlistDurationLocked(token);
+ assertNotNull(allowlistDurationLockedAfterClear);
+ assertEquals(1000, allowlistDurationLockedAfterClear.duration);
+ assertEquals(balClearAllowlistDuration()
+ ? TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED
+ : TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+ allowlistDurationLocked.type);
+ }
+
private void assertCancelReason(int expectedReason, int actualReason) {
final String errMsg = "Expected: " + cancelReasonToString(expectedReason)
+ "; Actual: " + cancelReasonToString(actualReason);