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...