Fix issue #17752399: Multiple apps broken by GET_TASKS permission change Keep around GET_TASKS as a permission available to apps, so apps still think they have it and don't get all uppity because they don't. Add a new REAL_GET_TASKS that is the actual permission now. Plus some temporary compatibility code until everyone can transition fromn GET_TASKS to REAL_GET_TASKS. Change-Id: I12c1102eed24844685dcbd2fa3b612811603958f
diff --git a/api/current.txt b/api/current.txt index eb7891a..17c9dcc 100644 --- a/api/current.txt +++ b/api/current.txt
@@ -67,7 +67,7 @@ field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK"; field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"; field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE"; - field public static final java.lang.String GET_TASKS = "android.permission.GET_TASKS"; + field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS"; field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO"; field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH"; field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index cd6088f..84a7f5d 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java
@@ -931,7 +931,7 @@ * purposes of control flow will be incorrect.</p> * * @deprecated As of {@link android.os.Build.VERSION_CODES#L}, this method is - * no longer available to third party applications: as the introduction of + * no longer available to third party applications: the introduction of * document-centric recents means * it can leak personal information to the caller. For backwards compatibility, * it will still return a small subset of its data: at least the caller's @@ -947,9 +947,6 @@ * * @return Returns a list of RecentTaskInfo records describing each of * the recent tasks. - * - * @throws SecurityException Throws SecurityException if the caller does - * not hold the {@link android.Manifest.permission#GET_TASKS} permission. */ @Deprecated public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags) @@ -976,9 +973,6 @@ * @return Returns a list of RecentTaskInfo records describing each of * the recent tasks. * - * @throws SecurityException Throws SecurityException if the caller does - * not hold the {@link android.Manifest.permission#GET_TASKS} or the - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permissions. * @hide */ public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId) @@ -1236,9 +1230,6 @@ * * @return Returns a list of RunningTaskInfo records describing each of * the running tasks. - * - * @throws SecurityException Throws SecurityException if the caller does - * not hold the {@link android.Manifest.permission#GET_TASKS} permission. */ @Deprecated public List<RunningTaskInfo> getRunningTasks(int maxNum)
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 6d9c58b..c37534a 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -111,6 +111,8 @@ int getFlagsForUid(int uid); + boolean isUidPrivileged(int uid); + String[] getAppOpPermissionPackages(String permissionName); ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 03a5e23..6d78127 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml
@@ -1382,10 +1382,25 @@ android:description="@string/permgroupdesc_appInfo" android:priority="220" /> - <!-- @SystemApi Allows an application to get information about the currently - or recently running tasks. --> + <!-- @deprecated No longer enforced. --> <permission android:name="android.permission.GET_TASKS" android:permissionGroup="android.permission-group.APP_INFO" + android:protectionLevel="normal" + android:label="@string/permlab_getTasks" + android:description="@string/permdesc_getTasks" /> + + <!-- New version of GET_TASKS that apps can request, since GET_TASKS doesn't really + give access to task information. We need this new one because there are + many existing apps that use add libraries and such that have validation + code to ensure the app has requested the GET_TASKS permission by seeing + if it has been granted the permission... if it hasn't, it kills the app + with a message about being upset. So we need to have it continue to look + like the app is getting that permission, even though it will never be + checked, and new privileged apps can now request this one for real access. + @hide + @SystemApi --> + <permission android:name="android.permission.REAL_GET_TASKS" + android:permissionGroup="android.permission-group.APP_INFO" android:protectionLevel="signature|system" android:label="@string/permlab_getTasks" android:description="@string/permdesc_getTasks" />
diff --git a/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml index 0c502c0..0898fae 100644 --- a/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml +++ b/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/AndroidManifest.xml
@@ -60,7 +60,7 @@ <uses-permission android:name="android.permission.FORCE_BACK" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> - <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.REAL_GET_TASKS" /> <uses-permission android:name="android.permission.GLOBAL_SEARCH" /> <uses-permission android:name="android.permission.HARDWARE_TEST" /> <uses-permission android:name="android.permission.INJECT_EVENTS" />
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 9f9dc23..7e6afa6 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml
@@ -39,7 +39,7 @@ <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <!-- System tool permissions granted to the shell. --> - <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.REAL_GET_TASKS" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="android.permission.REORDER_TASKS" /> <uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 1d629fd..eeb79b9 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml
@@ -64,7 +64,7 @@ <uses-permission android:name="android.permission.VIBRATE" /> <!-- ActivityManager --> - <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.REAL_GET_TASKS" /> <uses-permission android:name="android.permission.GET_DETAILED_TASKS" /> <uses-permission android:name="android.permission.REORDER_TASKS" /> <uses-permission android:name="android.permission.REMOVE_TASKS" />
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4a10b73..9e0483d 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8175,13 +8175,8 @@ if (localLOGV) Slog.v( TAG, "getTasks: max=" + maxNum + ", flags=" + flags); - final boolean allowed = checkCallingPermission( - android.Manifest.permission.GET_TASKS) - == PackageManager.PERMISSION_GRANTED; - if (!allowed) { - Slog.w(TAG, "getTasks: caller " + callingUid - + " does not hold GET_TASKS; limiting output"); - } + final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), + callingUid); // TODO: Improve with MRU list from all ActivityStacks. mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); @@ -8218,6 +8213,33 @@ return rti; } + private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { + boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, + callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; + if (!allowed) { + if (checkPermission(android.Manifest.permission.GET_TASKS, + callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { + // Temporary compatibility: some existing apps on the system image may + // still be requesting the old permission and not switched to the new + // one; if so, we'll still allow them full access. This means we need + // to see if they are holding the old permission and are a system app. + try { + if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { + allowed = true; + Slog.w(TAG, caller + ": caller " + callingUid + + " is using old GET_TASKS but privileged; allowing"); + } + } catch (RemoteException e) { + } + } + } + if (!allowed) { + Slog.w(TAG, caller + ": caller " + callingUid + + " does not hold GET_TASKS; limiting output"); + } + return allowed; + } + @Override public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { final int callingUid = Binder.getCallingUid(); @@ -8227,12 +8249,8 @@ final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; synchronized (this) { - final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) - == PackageManager.PERMISSION_GRANTED; - if (!allowed) { - Slog.w(TAG, "getRecentTasks: caller " + callingUid - + " does not hold GET_TASKS; limiting output"); - } + final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), + callingUid); final boolean detailed = checkCallingPermission( android.Manifest.permission.GET_DETAILED_TASKS) == PackageManager.PERMISSION_GRANTED;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 50cb5fc..2dad67521 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2880,6 +2880,28 @@ } @Override + public boolean isUidPrivileged(int uid) { + uid = UserHandle.getAppId(uid); + // reader + synchronized (mPackages) { + Object obj = mSettings.getUserIdLPr(uid); + if (obj instanceof SharedUserSetting) { + final SharedUserSetting sus = (SharedUserSetting) obj; + final Iterator<PackageSetting> it = sus.packages.iterator(); + while (it.hasNext()) { + if (it.next().isPrivileged()) { + return true; + } + } + } else if (obj instanceof PackageSetting) { + final PackageSetting ps = (PackageSetting) obj; + return ps.isPrivileged(); + } + } + return false; + } + + @Override public String[] getAppOpPermissionPackages(String permissionName) { synchronized (mPackages) { ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml index f31f4f2..3930fd6 100644 --- a/tests/ActivityTests/AndroidManifest.xml +++ b/tests/ActivityTests/AndroidManifest.xml
@@ -16,7 +16,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.test.activity"> - <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.REAL_GET_TASKS" /> <uses-permission android:name="android.permission.REORDER_TASKS" /> <uses-permission android:name="android.permission.REMOVE_TASKS" /> <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />