Update PermissionChecker usages to avoid unnecessary attribution.

We had accidental usages of the PermissionChecker for cases where no
private data was provided to the app but the checkPermission API on
the latter also did blame data access on the app. The PermissionChecker
was designed to handle IPC calls and not for generic API checks.

To avoid future accidental incorrect PermissionChecker usages this
change renames the existing APIs of the latter to clearly indicate
that they should be used for data delivery and also adds sibling
methods for doing the same permission checks for preflight purposes.
Also the documentation is improved to furhter assist developers.

In addition, this change fixes accidental permission checker usages
that blame when they should not by using the new preflight flavor
of the permission check APIs.

Test:
    atest com.android.settingslib.location.RecentLocationAppsTest
    atest CtsPermissionTestCases
    added: LocationAccessCheckTest#notificationOnlyForAccessesSinceFeatureWasEnabled
    added: LocationAccessCheckTest#noNotificationIfFeatureDisabled
    added: LocationAccessCheckTest#noNotificationIfBlamerNotSystemOrLocationProvider
    added: LocationAccessCheckTest#testOpeningLocationSettingsDoesNotTriggerAccess

bug:141028068
Merged-In: I65c71569d0dd8a40bc6fecabb22c5373dd6e806e
Change-Id: I65c71569d0dd8a40bc6fecabb22c5373dd6e806e
(cherry picked from commit 7fe065eb660cfe8ae54f8cd1e1e615f47d7b311c)
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index 6fe6e99..95286e4 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -50,6 +50,19 @@
  * permission model for which the user had disabled the "permission"
  * which is achieved by disallowing the corresponding app op.
  * </p>
+ * <p>
+ * 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
  */
@@ -63,6 +76,9 @@
     /** 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,
@@ -78,6 +94,57 @@
      * 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.
      *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>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}.
+     *
+     * @see #checkPermissionForPreflight(Context, String, int, int, String)
+     */
+    @PermissionResult
+    public static int checkPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission, int pid, int uid, @Nullable String packageName) {
+        return checkPermissionCommon(context, permission, pid, uid, packageName,
+                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.
+     *
+     * <strong>NOTE:</strong> 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.
+     *
+     * <p>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)} 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.
@@ -86,10 +153,229 @@
      *     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 #checkPermissionForDataDelivery(Context, String, int, int, String)
      */
     @PermissionResult
-    public static int checkPermission(@NonNull Context context, @NonNull String permission,
-            int pid, int uid, @Nullable String packageName) {
+    public static int checkPermissionForPreflight(@NonNull Context context,
+            @NonNull String permission, int pid, int uid, @Nullable String packageName) {
+        return checkPermissionCommon(context, permission, pid, uid, packageName,
+                false /*forDataDelivery*/);
+    }
+
+    /**
+     * Checks whether your app has a given permission and whether the app op
+     * that corresponds to this permission is allowed.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>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.
+     *
+     * <p>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 #checkSelfPermissionForPreflight(Context, String)
+     */
+    @PermissionResult
+    public static int checkSelfPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission) {
+        return checkPermissionForDataDelivery(context, permission, Process.myPid(),
+                Process.myUid(), context.getPackageName());
+    }
+
+    /**
+     * Checks whether your app has a given permission and whether the app op
+     * that corresponds to this permission is allowed.
+     *
+     * <strong>NOTE:</strong> 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.
+     *
+     * <p>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.
+     *
+     * <p>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)
+     */
+    @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.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>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}.
+     *
+     * @see #checkCallingPermissionForPreflight(Context, String, String)
+     */
+    @PermissionResult
+    public static int checkCallingPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission, @Nullable String packageName) {
+        if (Binder.getCallingPid() == Process.myPid()) {
+            return PERMISSION_DENIED;
+        }
+        return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
+                Binder.getCallingUid(), packageName);
+    }
+
+    /**
+     * Checks whether the IPC you are handling has a given permission and whether
+     * the app op that corresponds to this permission is allowed.
+     *
+     * <strong>NOTE:</strong> 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.
+     *
+     * <p>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)} 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)
+     */
+    @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.
+     *
+     * <strong>NOTE:</strong> Use this method only for permission checks at the
+     * point where you will deliver the permission protected data to clients.
+     *
+     * <p>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}.
+     *
+     * @see #checkCallingOrSelfPermissionForPreflight(Context, String)
+     */
+    @PermissionResult
+    public static int checkCallingOrSelfPermissionForDataDelivery(@NonNull Context context,
+            @NonNull String permission) {
+        String packageName = (Binder.getCallingPid() == Process.myPid())
+                ? context.getPackageName() : null;
+        return checkPermissionForDataDelivery(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.
+     *
+     * <strong>NOTE:</strong> 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.
+     *
+     * <p>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)} 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)
+     */
+    @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, boolean forDataDelivery) {
         if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
             return PERMISSION_DENIED;
         }
@@ -108,68 +394,18 @@
             packageName = packageNames[0];
         }
 
-        if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid) != AppOpsManager.MODE_ALLOWED) {
-            return PERMISSION_DENIED_APP_OP;
+        if (forDataDelivery) {
+            if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid)
+                    != 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.
-     *
-     * <p>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());
-    }
-
-    /**
-     * 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.
-     * @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) {
-        if (Binder.getCallingPid() == Process.myPid()) {
-            return PERMISSION_DENIED;
-        }
-        return checkPermission(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.
-     *
-     * @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 checkCallingOrSelfPermission(@NonNull Context context,
-            @NonNull String permission) {
-        String packageName = (Binder.getCallingPid() == Process.myPid())
-                ? context.getPackageName() : null;
-        return checkPermission(context, permission, Binder.getCallingPid(),
-                Binder.getCallingUid(), packageName);
-    }
 }
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 70dfef5..fb13c1f 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -170,13 +170,23 @@
      * 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)
+                             == 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 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 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 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 ea39317..81ca9ea 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 @@
             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 6fd8749..c623909 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -106,9 +106,9 @@
                     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/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index c6a1867..369e7fc 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -49,7 +49,6 @@
 import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.os.UserManagerInternal;
-import android.provider.Telephony;
 import android.service.sms.FinancialSmsService;
 import android.telephony.IFinancialSmsCallback;
 import android.text.TextUtils;
@@ -681,7 +680,7 @@
         @Override
         public void getSmsMessagesForFinancialApp(
                 String callingPkg, Bundle params, IFinancialSmsCallback callback) {
-            int mode = PermissionChecker.checkCallingOrSelfPermission(
+            int mode = PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(
                     getContext(),
                     AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS);
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e5518d0..37931be 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11830,10 +11830,13 @@
                     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,