diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java index e24512ac525da..c3daad1887927 100644 --- a/core/java/android/content/PermissionChecker.java +++ b/core/java/android/content/PermissionChecker.java @@ -16,8 +16,6 @@ package android.content; -import static android.app.AppOpsManager.strOpToOp; - import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -52,6 +50,19 @@ import java.lang.annotation.RetentionPolicy; * permission model for which the user had disabled the "permission" * which is achieved by disallowing the corresponding app op. *
+ *+ * This class has two types of methods and you should be careful which + * type to call based on whether permission protected data is being + * passed to the app or you are just checking whether the app holds a + * permission. The reason is that a permission check requires checking + * the runtime permission and if it is granted checking the corresponding + * app op as for apps not supporting the runtime mode we never revoke + * permissions but disable app ops. Since there are two types of app op + * checks, one that does not leave a record an action was performed and + * another the does, one needs to call the preflight flavor of the checks + * named xxxForPreflight only if no private data is being delivered but + * a permission check is what is needed and the xxxForDataDelivery where + * the permission check is right before private data delivery. * * @hide */ @@ -65,6 +76,9 @@ public final class PermissionChecker { /** Permission result: The permission is denied because the app op is not allowed. */ public static final int PERMISSION_DENIED_APP_OP = PackageManager.PERMISSION_DENIED - 1; + /** Constant when the PID for which we check permissions is unknown. */ + public static final int PID_UNKNOWN = -1; + /** @hide */ @IntDef({PERMISSION_GRANTED, PERMISSION_DENIED, @@ -77,33 +91,297 @@ public final class PermissionChecker { } /** - * @deprecated Use {@link #checkPermission(Context, String, int, int, String, String)} instead + * Checks whether a given package in a UID and PID has a given permission + * and whether the app op that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * point where you will deliver the permission protected data to clients. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use {@link #checkPermissionForPreflight(Context, String, int, int, String)} + * to determine if the app has or may have location permission (if app has only foreground + * location the grant state depends on the app's fg/gb state) and this check will not + * leave a trace that permission protected data was delivered. When you are about to + * deliver the location data to a registered listener you should use this method which + * will evaluate the permission access based on the current fg/bg state of the app and + * leave a record that the data was accessed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID + * is not known. + * @param uid The uid for which to check. + * @param packageName The package name for which to check. If null the + * the first package for the calling UID will be used. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * @param message A message describing the reason the permission was checked + * + * @see #checkPermissionForPreflight(Context, String, int, int, String) */ - @Deprecated @PermissionResult - public static int checkPermission(@NonNull Context context, @NonNull String permission, - int pid, int uid, @Nullable String packageName) { - return checkPermission(context, permission, pid, uid, packageName, null); + public static int checkPermissionForDataDelivery(@NonNull Context context, + @NonNull String permission, int pid, int uid, @Nullable String packageName, + @Nullable String message) { + return checkPermissionCommon(context, permission, pid, uid, packageName, message, + true /*forDataDelivery*/); } /** * Checks whether a given package in a UID and PID has a given permission * and whether the app op that corresponds to this permission is allowed. * + * NOTE: Use this method only for permission checks at the + * preflight point where you will not deliver the permission protected data + * to clients but schedule permission data delivery, apps register listeners, + * etc. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use this method to determine if the app has or may have location + * permission (if app has only foreground location the grant state depends on the app's + * fg/gb state) and this check will not leave a trace that permission protected data + * was delivered. When you are about to deliver the location data to a registered + * listener you should use {@link #checkPermissionForDataDelivery(Context, String, + * int, int, String, String)} which will evaluate the permission access based on the current + * fg/bg state of the app and leave a record that the data was accessed. + * * @param context Context for accessing resources. * @param permission The permission to check. * @param pid The process id for which to check. * @param uid The uid for which to check. * @param packageName The package name for which to check. If null the * the first package for the calling UID will be used. - * @param message A message describing the reason the permission was checked - * * @return The permission check result which is either {@link #PERMISSION_GRANTED} * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * + * @see #checkPermissionForDataDelivery(Context, String, int, int, String, String) */ @PermissionResult - public static int checkPermission(@NonNull Context context, @NonNull String permission, - int pid, int uid, @Nullable String packageName, @Nullable String message) { + public static int checkPermissionForPreflight(@NonNull Context context, + @NonNull String permission, int pid, int uid, @Nullable String packageName) { + return checkPermissionCommon(context, permission, pid, uid, packageName, null /*message*/, + false /*forDataDelivery*/); + } + + /** + * Checks whether your app has a given permission and whether the app op + * that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * point where you will deliver the permission protected data to clients. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use {@link #checkSelfPermissionForPreflight(Context, String)} + * to determine if the app has or may have location permission (if app has only foreground + * location the grant state depends on the app's fg/gb state) and this check will not + * leave a trace that permission protected data was delivered. When you are about to + * deliver the location data to a registered listener you should use this method + * which will evaluate the permission access based on the current fg/bg state of the + * app and leave a record that the data was accessed. + * + *
This API assumes the the {@link Binder#getCallingUid()} is the same as + * {@link Process#myUid()}. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * @param message A message describing the reason the permission was checked + * + * @see #checkSelfPermissionForPreflight(Context, String) + */ + @PermissionResult + public static int checkSelfPermissionForDataDelivery(@NonNull Context context, + @NonNull String permission, @Nullable String message) { + return checkPermissionForDataDelivery(context, permission, Process.myPid(), + Process.myUid(), context.getPackageName(), message); + } + + /** + * Checks whether your app has a given permission and whether the app op + * that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * preflight point where you will not deliver the permission protected data + * to clients but schedule permission data delivery, apps register listeners, + * etc. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use this method to determine if the app has or may have location + * permission (if app has only foreground location the grant state depends on the + * app's fg/gb state) and this check will not leave a trace that permission protected + * data was delivered. When you are about to deliver the location data to a registered + * listener you should use this method which will evaluate the permission access based + * on the current fg/bg state of the app and leave a record that the data was accessed. + * + *
This API assumes the the {@link Binder#getCallingUid()} is the same as + * {@link Process#myUid()}. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * + * @see #checkSelfPermissionForDataDelivery(Context, String, String) + */ + @PermissionResult + public static int checkSelfPermissionForPreflight(@NonNull Context context, + @NonNull String permission) { + return checkPermissionForPreflight(context, permission, Process.myPid(), + Process.myUid(), context.getPackageName()); + } + + /** + * Checks whether the IPC you are handling has a given permission and whether + * the app op that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * point where you will deliver the permission protected data to clients. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use {@link #checkCallingPermissionForPreflight(Context, String, String)} + * to determine if the app has or may have location permission (if app has only foreground + * location the grant state depends on the app's fg/gb state) and this check will not + * leave a trace that permission protected data was delivered. When you are about to + * deliver the location data to a registered listener you should use this method which + * will evaluate the permission access based on the current fg/bg state of the app and + * leave a record that the data was accessed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @param packageName The package name making the IPC. If null the + * the first package for the calling UID will be used. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * @param message A message describing the reason the permission was checked + * + * @see #checkCallingPermissionForPreflight(Context, String, String) + */ + @PermissionResult + public static int checkCallingPermissionForDataDelivery(@NonNull Context context, + @NonNull String permission, @Nullable String packageName, @Nullable String message) { + if (Binder.getCallingPid() == Process.myPid()) { + return PERMISSION_DENIED; + } + return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(), + Binder.getCallingUid(), packageName, message); + } + + /** + * Checks whether the IPC you are handling has a given permission and whether + * the app op that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * preflight point where you will not deliver the permission protected data + * to clients but schedule permission data delivery, apps register listeners, + * etc. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use this method to determine if the app has or may have location + * permission (if app has only foreground location the grant state depends on the app's + * fg/gb state) and this check will not leave a trace that permission protected data + * was delivered. When you are about to deliver the location data to a registered + * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context, + * String, String)} which will evaluate the permission access based on the current fg/bg state + * of the app and leave a record that the data was accessed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @param packageName The package name making the IPC. If null the + * the first package for the calling UID will be used. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * + * @see #checkCallingPermissionForDataDelivery(Context, String, String, String) + */ + @PermissionResult + public static int checkCallingPermissionForPreflight(@NonNull Context context, + @NonNull String permission, @Nullable String packageName) { + if (Binder.getCallingPid() == Process.myPid()) { + return PERMISSION_DENIED; + } + return checkPermissionForPreflight(context, permission, Binder.getCallingPid(), + Binder.getCallingUid(), packageName); + } + + /** + * Checks whether the IPC you are handling or your app has a given permission + * and whether the app op that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * point where you will deliver the permission protected data to clients. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use {@link #checkCallingOrSelfPermissionForPreflight(Context, String)} + * to determine if the app has or may have location permission (if app has only foreground + * location the grant state depends on the app's fg/gb state) and this check will not + * leave a trace that permission protected data was delivered. When you are about to + * deliver the location data to a registered listener you should use this method which + * will evaluate the permission access based on the current fg/bg state of the app and + * leave a record that the data was accessed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * @param message A message describing the reason the permission was checked + * + * @see #checkCallingOrSelfPermissionForPreflight(Context, String) + */ + @PermissionResult + public static int checkCallingOrSelfPermissionForDataDelivery(@NonNull Context context, + @NonNull String permission, @Nullable String message) { + String packageName = (Binder.getCallingPid() == Process.myPid()) + ? context.getPackageName() : null; + return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(), + Binder.getCallingUid(), packageName, message); + } + + /** + * Checks whether the IPC you are handling or your app has a given permission + * and whether the app op that corresponds to this permission is allowed. + * + * NOTE: Use this method only for permission checks at the + * preflight point where you will not deliver the permission protected data + * to clients but schedule permission data delivery, apps register listeners, + * etc. + * + *
For example, if an app registers a location listener it should have the location + * permission but no data is actually sent to the app at the moment of registration + * and you should use this method to determine if the app has or may have location + * permission (if app has only foreground location the grant state depends on the + * app's fg/gb state) and this check will not leave a trace that permission protected + * data was delivered. When you are about to deliver the location data to a registered + * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context, + * String, String)} which will evaluate the permission access based on the current fg/bg state + * of the app and leave a record that the data was accessed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + * + * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String) + */ + @PermissionResult + public static int checkCallingOrSelfPermissionForPreflight(@NonNull Context context, + @NonNull String permission) { + String packageName = (Binder.getCallingPid() == Process.myPid()) + ? context.getPackageName() : null; + return checkPermissionForPreflight(context, permission, Binder.getCallingPid(), + Binder.getCallingUid(), packageName); + } + + private static int checkPermissionCommon(@NonNull Context context, @NonNull String permission, + int pid, int uid, @Nullable String packageName, @Nullable String message, + boolean forDataDelivery) { if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) { return PERMISSION_DENIED; } @@ -122,93 +400,18 @@ public final class PermissionChecker { packageName = packageNames[0]; } - if (appOpsManager.noteProxyOpNoThrow(strOpToOp(op), packageName, uid, message) - != AppOpsManager.MODE_ALLOWED) { - return PERMISSION_DENIED_APP_OP; + if (forDataDelivery) { + if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid, message) + != AppOpsManager.MODE_ALLOWED) { + return PERMISSION_DENIED_APP_OP; + } + } else { + final int mode = appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName); + if (mode != AppOpsManager.MODE_ALLOWED && mode != AppOpsManager.MODE_FOREGROUND) { + return PERMISSION_DENIED_APP_OP; + } } return PERMISSION_GRANTED; } - - /** - * Checks whether your app has a given permission and whether the app op - * that corresponds to this permission is allowed. - * - *
This API assumes the the {@link Binder#getCallingUid()} is the same as - * {@link Process#myUid()}. - * - * @param context Context for accessing resources. - * @param permission The permission to check. - * @return The permission check result which is either {@link #PERMISSION_GRANTED} - * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. - */ - @PermissionResult - public static int checkSelfPermission(@NonNull Context context, - @NonNull String permission) { - return checkPermission(context, permission, Process.myPid(), - Process.myUid(), context.getPackageName(), null /* self access */); - } - - /** - * @deprecated Use {@link #checkCallingPermission(Context, String, String, String)} instead - */ - @Deprecated - @PermissionResult - public static int checkCallingPermission(@NonNull Context context, - @NonNull String permission, @Nullable String packageName) { - return checkCallingPermission(context, permission, packageName, null); - } - - /** - * Checks whether the IPC you are handling has a given permission and whether - * the app op that corresponds to this permission is allowed. - * - * @param context Context for accessing resources. - * @param permission The permission to check. - * @param packageName The package name making the IPC. If null the - * the first package for the calling UID will be used. - * @param message A message describing the reason the permission was checked - * - * @return The permission check result which is either {@link #PERMISSION_GRANTED} - * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. - */ - @PermissionResult - public static int checkCallingPermission(@NonNull Context context, - @NonNull String permission, @Nullable String packageName, @Nullable String message) { - if (Binder.getCallingPid() == Process.myPid()) { - return PERMISSION_DENIED; - } - return checkPermission(context, permission, Binder.getCallingPid(), - Binder.getCallingUid(), packageName, message); - } - - /** - * @deprecated Use {@link #checkCallingOrSelfPermission(Context, String, String)} instead - */ - @Deprecated - @PermissionResult - public static int checkCallingOrSelfPermission(@NonNull Context context, - @NonNull String permission) { - return checkCallingOrSelfPermission(context, permission, null); - } - - /** - * Checks whether the IPC you are handling or your app has a given permission - * and whether the app op that corresponds to this permission is allowed. - * - * @param context Context for accessing resources. - * @param permission The permission to check. - * @param message A message describing the reason the permission was checked - * - * @return The permission check result which is either {@link #PERMISSION_GRANTED} - * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. - */ - @PermissionResult - public static int checkCallingOrSelfPermission(@NonNull Context context, - @NonNull String permission, @Nullable String message) { - String packageName = (Binder.getCallingPid() == Process.myPid()) - ? context.getPackageName() : null; - return checkPermission(context, permission, Binder.getCallingPid(), - Binder.getCallingUid(), packageName, message); - } -} +} \ No newline at end of file diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java index 70dfef574ca53..dfc5c8217fda1 100644 --- a/core/java/android/speech/RecognitionService.java +++ b/core/java/android/speech/RecognitionService.java @@ -170,13 +170,23 @@ public abstract class RecognitionService extends Service { * Checks whether the caller has sufficient permissions * * @param listener to send the error message to in case of error + * @param forDataDelivery If the permission check is for delivering the sensitive data. * @return {@code true} if the caller has enough permissions, {@code false} otherwise */ - private boolean checkPermissions(IRecognitionListener listener) { + private boolean checkPermissions(IRecognitionListener listener, boolean forDataDelivery) { if (DBG) Log.d(TAG, "checkPermissions"); - if (PermissionChecker.checkCallingOrSelfPermission(this, - android.Manifest.permission.RECORD_AUDIO) == PermissionChecker.PERMISSION_GRANTED) { - return true; + if (forDataDelivery) { + if (PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(this, + android.Manifest.permission.RECORD_AUDIO, null /*message*/) + == PermissionChecker.PERMISSION_GRANTED) { + return true; + } + } else { + if (PermissionChecker.checkCallingOrSelfPermissionForPreflight(this, + android.Manifest.permission.RECORD_AUDIO) + == PermissionChecker.PERMISSION_GRANTED) { + return true; + } } try { Log.e(TAG, "call for recognition service without RECORD_AUDIO permissions"); @@ -342,7 +352,7 @@ public abstract class RecognitionService extends Service { public void startListening(Intent recognizerIntent, IRecognitionListener listener) { if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder()); final RecognitionService service = mServiceRef.get(); - if (service != null && service.checkPermissions(listener)) { + if (service != null && service.checkPermissions(listener, true /*forDataDelivery*/)) { service.mHandler.sendMessage(Message.obtain(service.mHandler, MSG_START_LISTENING, service.new StartListeningArgs( recognizerIntent, listener, Binder.getCallingUid()))); @@ -353,7 +363,7 @@ public abstract class RecognitionService extends Service { public void stopListening(IRecognitionListener listener) { if (DBG) Log.d(TAG, "stopListening called by:" + listener.asBinder()); final RecognitionService service = mServiceRef.get(); - if (service != null && service.checkPermissions(listener)) { + if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/)) { service.mHandler.sendMessage(Message.obtain(service.mHandler, MSG_STOP_LISTENING, listener)); } @@ -363,7 +373,7 @@ public abstract class RecognitionService extends Service { public void cancel(IRecognitionListener listener) { if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder()); final RecognitionService service = mServiceRef.get(); - if (service != null && service.checkPermissions(listener)) { + if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/)) { service.mHandler.sendMessage(Message.obtain(service.mHandler, MSG_CANCEL, listener)); } diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java index ea39317fb045b..81ca9eaf8e36b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java @@ -111,8 +111,9 @@ public class RecentLocationAccesses { for (int op : LOCATION_OPS) { final String permission = AppOpsManager.opToPermission(op); final int permissionFlags = pm.getPermissionFlags(permission, packageName, user); - if (PermissionChecker.checkPermission(mContext, permission, -1, uid, packageName) - == PermissionChecker.PERMISSION_GRANTED) { + if (PermissionChecker.checkPermissionForPreflight(mContext, permission, + PermissionChecker.PID_UNKNOWN, uid, packageName) + == PermissionChecker.PERMISSION_GRANTED) { if ((permissionFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) == 0) { showApp = false; diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java index 60c9984e5ed4c..104cc8f9841c2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java @@ -110,9 +110,9 @@ public class RecentLocationApps { final String permission = AppOpsManager.opToPermission(op); final int permissionFlags = pm.getPermissionFlags(permission, packageName, user); - if (PermissionChecker.checkPermission(mContext, permission, -1, uid, - packageName) - == PermissionChecker.PERMISSION_GRANTED) { + if (PermissionChecker.checkPermissionForPreflight(mContext, permission, + PermissionChecker.PID_UNKNOWN, uid, packageName) + == PermissionChecker.PERMISSION_GRANTED) { if ((permissionFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) == 0) { diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java index cd1f0cc13297d..47b56e097ec98 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java @@ -92,7 +92,7 @@ public class UsbPermissionActivity extends AlertActivity mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory); } else { boolean hasRecordPermission = - PermissionChecker.checkPermission( + PermissionChecker.checkPermissionForPreflight( this, android.Manifest.permission.RECORD_AUDIO, -1, aInfo.uid, mPackageName) == android.content.pm.PackageManager.PERMISSION_GRANTED; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c3ff28530b7fa..b118cdfeb84d2 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -11902,10 +11902,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { try { int uid = packageManager.getPackageUidAsUser(packageName, user.getIdentifier()); - - // TODO: Prevent noting the app-op - granted = PermissionChecker.checkPermission(mContext, permission, -1, - uid, packageName); + if (PermissionChecker.checkPermissionForPreflight(mContext, permission, + PermissionChecker.PID_UNKNOWN, uid, packageName) + != PermissionChecker.PERMISSION_GRANTED) { + granted = PackageManager.PERMISSION_DENIED; + } else { + granted = PackageManager.PERMISSION_GRANTED; + } } catch (NameNotFoundException e) { throw new RemoteException( "Cannot check if " + permission + "is a runtime permission", e,