Add MANAGE_APP_OVERLAY_PERMISSION intent action
In order to support system use-cases, such as when the user wants do
revoke SYSTEM_ALERT_WINDOW (SAW) permission via notification, we are
introducing a new intent, MANAGE_APP_OVERLAY_PERMISSION (notice the
"APP_"), that directs the user to the app-specific screen to toggle SAW
permission.
The intent can only be started if the caller has INTERNAL_SYSTEM_WINDOW
permission, which sysui and the system have. This is verified in CTS.
In this change we also update usage in NotificationGutsManager and
AlertWindowNotification.
Test: Builds
Test: atest TestManageOverlayPermissionIntents
(cts in one of the topic CLs)
Test: Let an app draw on top of other apps, via its notification go to
settings, verify that the screen for controlling such capability
for the app is dispayed.
Bug: 145198756
Bug: 135920175
Change-Id: Iba29e1eaee729268a4dec9561946f6ed74b36619
diff --git a/api/system-current.txt b/api/system-current.txt
index c13afb6..95667b6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6359,6 +6359,7 @@
field public static final String ACTION_ACCESSIBILITY_DETAILS_SETTINGS = "android.settings.ACCESSIBILITY_DETAILS_SETTINGS";
field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS";
+ field public static final String ACTION_MANAGE_APP_OVERLAY_PERMISSION = "android.settings.MANAGE_APP_OVERLAY_PERMISSION";
field public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS";
field public static final String ACTION_MANAGE_MORE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_MORE_DEFAULT_APPS_SETTINGS";
field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS";
diff --git a/api/test-current.txt b/api/test-current.txt
index 897e825..ee92443 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2435,6 +2435,7 @@
public final class Settings {
field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
+ field public static final String ACTION_MANAGE_APP_OVERLAY_PERMISSION = "android.settings.MANAGE_APP_OVERLAY_PERMISSION";
field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
field public static final int RESET_MODE_PACKAGE_DEFAULTS = 1; // 0x1
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3ac7deb..846214a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -833,8 +833,7 @@
/**
* Activity Action: Show screen for controlling which apps can draw on top of other apps.
* <p>
- * In some cases, a matching Activity may not exist, so ensure you
- * safeguard against this.
+ * In some cases, a matching Activity may not exist, so ensure you safeguard against this.
* <p>
* Input: Optionally, in versions of Android prior to 11, the Intent's data URI can specify the
* application package name to directly invoke the management GUI specific to the package name.
@@ -847,6 +846,31 @@
"android.settings.action.MANAGE_OVERLAY_PERMISSION";
/**
+ * Activity Action: Show screen for controlling if the app specified in the data URI of the
+ * intent can draw on top of other apps.
+ * <p>
+ * Unlike {@link #ACTION_MANAGE_OVERLAY_PERMISSION}, which in Android 11 can't be used to show
+ * a GUI for a specific package, permission {@code android.permission.INTERNAL_SYSTEM_WINDOW} is
+ * needed to start an activity with this intent.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: The Intent's data URI MUST specify the application package name whose ability of
+ * drawing on top of other apps you want to control.
+ * For example "package:com.my.app".
+ * <p>
+ * Output: Nothing.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_APP_OVERLAY_PERMISSION =
+ "android.settings.MANAGE_APP_OVERLAY_PERMISSION";
+
+ /**
* Activity Action: Show screen for controlling which apps are allowed to write/modify
* system settings.
* <p>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 5a5f9e9..9dd7f48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -174,7 +174,7 @@
if (ops.contains(OP_CAMERA) || ops.contains(OP_RECORD_AUDIO)) {
startAppDetailsSettingsActivity(pkg, uid, null, row);
} else {
- Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
+ Intent intent = new Intent(Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION);
intent.setData(Uri.fromParts("package", pkg, null));
mNotificationActivityStarter.startNotificationGutsIntent(intent, uid, row);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 4b3249d..43d39a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -274,7 +274,7 @@
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mNotificationActivityStarter, times(1))
.startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, captor.getValue().getAction());
+ assertEquals(Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION, captor.getValue().getAction());
}
@Test
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index 9177d25..0de94d9 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -21,7 +21,7 @@
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;
+import static android.provider.Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -29,13 +29,11 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
-
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
-
import android.net.Uri;
import android.os.Bundle;
@@ -137,7 +135,7 @@
}
private PendingIntent getContentIntent(Context context, String packageName) {
- final Intent intent = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION,
+ final Intent intent = new Intent(ACTION_MANAGE_APP_OVERLAY_PERMISSION,
Uri.fromParts("package", packageName, null));
intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
// Calls into activity manager...