From cbe540f94691b595ca2eaede2871d885c38a845c Mon Sep 17 00:00:00 2001 From: Billy Lau Date: Thu, 25 Jun 2015 01:51:44 +0100 Subject: [PATCH] Bug: 21589105 Rescoping the SYSTEM_ALERT_WINDOW permission to an explicit toggle to be manually enabled in Settings. Raised the protection level of SYSTEM_ALERT_WINDOW from dangerous to system|signature|appop. Added a new API in Settings for developers to invoke the main configuration setting. Also added a new metrics in MetricsLogger. Finally, also made changes to PhoneWindowManager to check the permission to draw overlay properly. Change-Id: I4a073e6f038b8b8d2fa5bd6ad60abda496be9701 --- api/current.txt | 1 + api/system-current.txt | 1 + core/java/android/provider/Settings.java | 15 ++++++++++++ .../internal/logging/MetricsLogger.java | 1 + core/res/AndroidManifest.xml | 2 +- .../server/policy/PhoneWindowManager.java | 23 +++++++++++++++++++ 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/api/current.txt b/api/current.txt index 3cd3ee25e3374..7fdd597c7e8e7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -26421,6 +26421,7 @@ package android.provider { field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS"; field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS"; field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS"; + field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION"; field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS"; field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS"; field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS"; diff --git a/api/system-current.txt b/api/system-current.txt index 574f0c825759d..4f33a380e7a5e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -28482,6 +28482,7 @@ package android.provider { field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS"; field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS"; field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS"; + field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION"; field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS"; field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS"; field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9b5fbfaf562ac..6fb1b37ce1f9f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -561,6 +561,21 @@ public final class Settings { public static final String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS"; + /** + * Activity Action: Show settings to toggle permission to draw on top of + * other apps. + *

+ * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + *

+ * Input: Nothing. + *

+ * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_MANAGE_OVERLAY_PERMISSION = + "android.settings.MANAGE_OVERLAY_PERMISSION"; + /** * Activity Action: Show screen of details about a particular application. *

diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index b78eca7a7f73f..6dc66eae787f1 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -40,6 +40,7 @@ public class MetricsLogger implements MetricsConstants { public static final int ACTION_BRIGHTNESS = 218; public static final int ACTION_BRIGHTNESS_AUTO = 219; public static final int BRIGHTNESS_DIALOG = 220; + public static final int SYSTEM_ALERT_WINDOW_APPS = 221; // Temporary constants go here, to await migration to MetricsConstants. public static void visible(Context context, int category) throws IllegalArgumentException { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2cbfae26220df..27f5121b29c8f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1414,7 +1414,7 @@ + android:protectionLevel="signature|system|appop" /> diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 93e1f187b5434..234c4b2ae7ae3 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -51,6 +51,7 @@ import android.media.IAudioService; import android.media.Ringtone; import android.media.RingtoneManager; import android.media.session.MediaSessionLegacyHelper; +import android.os.Binder; import android.os.Bundle; import android.os.Debug; import android.os.FactoryTest; @@ -61,6 +62,7 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -267,6 +269,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { SearchManager mSearchManager; AccessibilityManager mAccessibilityManager; BurnInProtectionHelper mBurnInProtectionHelper; + AppOpsManager mAppOpsManager; // Vibrator pattern for haptic feedback of a long press. long[] mLongPressVibePattern; @@ -1255,6 +1258,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); + mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); // Init display burn-in protection boolean burnInProtectionEnabled = context.getResources().getBoolean( @@ -1810,6 +1814,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; } if (permission != null) { + if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) { + final int callingUid = Binder.getCallingUid(); + // check if this is a system uid first before bothering with + // obtaining package name + if (callingUid == Process.SYSTEM_UID) { + return WindowManagerGlobal.ADD_OKAY; + } + + final int mode = mAppOpsManager.checkOp(outAppOp[0], callingUid, + attrs.packageName); + if (mode == AppOpsManager.MODE_DEFAULT) { + if (mContext.checkCallingPermission(permission) != + PackageManager.PERMISSION_GRANTED) { + return WindowManagerGlobal.ADD_PERMISSION_DENIED; + } + } + return WindowManagerGlobal.ADD_OKAY; + } + if (mContext.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { return WindowManagerGlobal.ADD_PERMISSION_DENIED;