Merge "Switch media fw permissions checks to AttributionSource (native)" into sc-dev
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp
index 3243a6b..0eeca54 100644
--- a/libs/permission/Android.bp
+++ b/libs/permission/Android.bp
@@ -11,19 +11,24 @@
     name: "framework-permission-aidl",
     unstable: true,
     local_include_dir: "aidl",
-    backend: {
-        ndk: {
-            enabled: false
-        }
-    },
+    host_supported: true,
+    vendor_available: true,
+    double_loadable: true,
     srcs: [
         "aidl/android/content/AttributionSourceState.aidl",
         "aidl/android/permission/IPermissionChecker.aidl",
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libpermission",
+    host_supported: true,
+    double_loadable: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
     cflags: [
         "-Wall",
         "-Wextra",
@@ -45,5 +50,7 @@
     static_libs: [
         "framework-permission-aidl-cpp",
     ],
-    export_static_lib_headers: ["framework-permission-aidl-cpp"],
+    export_static_lib_headers: [
+        "framework-permission-aidl-cpp"
+    ],
 }
diff --git a/libs/permission/aidl/android/content/AttributionSourceState.aidl b/libs/permission/aidl/android/content/AttributionSourceState.aidl
index b6e54bf..ed1b37d 100644
--- a/libs/permission/aidl/android/content/AttributionSourceState.aidl
+++ b/libs/permission/aidl/android/content/AttributionSourceState.aidl
@@ -23,8 +23,10 @@
  * {@hide}
  */
 parcelable AttributionSourceState {
+    /** The PID that is accessing the permission protected data. */
+    int pid = -1;
     /** The UID that is accessing the permission protected data. */
-    int uid;
+    int uid = -1;
     /** The package that is accessing the permission protected data. */
     @nullable @utf8InCpp String packageName;
     /** The attribution tag of the app accessing the permission protected data. */
@@ -36,5 +38,5 @@
     /** The next app to receive the permission protected data. */
     // TODO: We use an array as a workaround - the C++ backend doesn't
     // support referring to the parcelable as it expects ctor/dtor
-    @nullable AttributionSourceState[] next;
+    AttributionSourceState[] next;
 }
diff --git a/libs/permission/aidl/android/permission/IPermissionChecker.aidl b/libs/permission/aidl/android/permission/IPermissionChecker.aidl
index 1f0e32d..d3a331e 100644
--- a/libs/permission/aidl/android/permission/IPermissionChecker.aidl
+++ b/libs/permission/aidl/android/permission/IPermissionChecker.aidl
@@ -28,9 +28,10 @@
 
     int checkPermission(String permission, in AttributionSourceState attributionSource,
             @nullable String message, boolean forDataDelivery, boolean startDataDelivery,
-            boolean fromDatasource);
+            boolean fromDatasource, int attributedOp);
 
-    void finishDataDelivery(String op, in AttributionSourceState attributionSource);
+    void finishDataDelivery(int op, in AttributionSourceState attributionSource,
+            boolean fromDatasource);
 
     int checkOp(int op, in AttributionSourceState attributionSource,
             String message, boolean forDataDelivery, boolean startDataDelivery);
diff --git a/libs/permission/android/permission/PermissionChecker.cpp b/libs/permission/android/permission/PermissionChecker.cpp
index a8083ee..008afad 100644
--- a/libs/permission/android/permission/PermissionChecker.cpp
+++ b/libs/permission/android/permission/PermissionChecker.cpp
@@ -29,7 +29,7 @@
 #endif
 #define LOG_TAG "PermissionChecker"
 
-namespace android {
+namespace android::permission {
 
 using android::content::AttributionSourceState;
 
@@ -37,7 +37,7 @@
 {
 }
 
-sp<IPermissionChecker> PermissionChecker::getService()
+sp<android::permission::IPermissionChecker> PermissionChecker::getService()
 {
     static String16 permission_checker("permission_checker");
 
@@ -59,56 +59,66 @@
             sleep(1);
         } else {
             mService = interface_cast<IPermissionChecker>(binder);
+            break;
         }
     }
     return mService;
 }
 
-PermissionChecker::PermissionResult
-    PermissionChecker::checkPermissionForDataDeliveryFromDatasource(
-        const String16& permission, AttributionSourceState& attributionSource,
-        const String16& message)
+PermissionChecker::PermissionResult PermissionChecker::checkPermissionForDataDeliveryFromDatasource(
+        const String16& permission, const AttributionSourceState& attributionSource,
+        const String16& message, int32_t attributedOpCode)
 {
-    return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message,
-            /*forDataDelivery*/ true, /*startDataDelivery*/ false,/*fromDatasource*/ true));
+    return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true,
+            /*startDataDelivery*/ false,/*fromDatasource*/ true, attributedOpCode);
 }
 
 PermissionChecker::PermissionResult
-    PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource(
-        const String16& permission, AttributionSourceState& attributionSource,
-        const String16& message)
+        PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource(
+        const String16& permission, const AttributionSourceState& attributionSource,
+        const String16& message, int32_t attributedOpCode)
 {
-    return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message,
-            /*forDataDelivery*/ true, /*startDataDelivery*/ true, /*fromDatasource*/ true));
+    return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true,
+            /*startDataDelivery*/ true, /*fromDatasource*/ true, attributedOpCode);
 }
 
-void PermissionChecker::finishDataDelivery(const String16& op,
-        AttributionSourceState& attributionSource)
+PermissionChecker::PermissionResult PermissionChecker::checkPermissionForPreflightFromDatasource(
+        const String16& permission, const AttributionSourceState& attributionSource,
+        const String16& message, int32_t attributedOpCode)
+{
+    return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ false,
+            /*startDataDelivery*/ false, /*fromDatasource*/ true, attributedOpCode);
+}
+
+void PermissionChecker::finishDataDeliveryFromDatasource(int32_t op,
+        const AttributionSourceState& attributionSource)
 {
     sp<IPermissionChecker> service = getService();
     if (service != nullptr) {
-        binder::Status status = service->finishDataDelivery(op, attributionSource);
+        binder::Status status = service->finishDataDelivery(op, attributionSource,
+                /*fromDatasource*/ true);
         if (!status.isOk()) {
             ALOGE("finishDataDelivery failed: %s", status.exceptionMessage().c_str());
         }
     }
 }
 
-int32_t PermissionChecker::checkPermission(const String16& permission,
-        AttributionSourceState& attributionSource, const String16& message,
-        bool forDataDelivery, bool startDataDelivery, bool fromDatasource)
+PermissionChecker::PermissionResult PermissionChecker::checkPermission(const String16& permission,
+        const AttributionSourceState& attributionSource, const String16& message,
+        bool forDataDelivery, bool startDataDelivery, bool fromDatasource,
+        int32_t attributedOpCode)
 {
     sp<IPermissionChecker> service = getService();
     if (service != nullptr) {
         int32_t result;
         binder::Status status = service->checkPermission(permission, attributionSource, message,
-                forDataDelivery, startDataDelivery, fromDatasource, &result);
+                forDataDelivery, startDataDelivery, fromDatasource, attributedOpCode, &result);
         if (status.isOk()) {
-            return result;
+            return static_cast<PermissionResult>(result);
         }
         ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str());
     }
-    return PERMISSION_DENIED;
+    return PERMISSION_HARD_DENIED;
 }
 
-} // namespace android
+} // namespace android::permission
diff --git a/libs/permission/include/android/permission/PermissionChecker.h b/libs/permission/include/android/permission/PermissionChecker.h
index 20ab51f..308d794 100644
--- a/libs/permission/include/android/permission/PermissionChecker.h
+++ b/libs/permission/include/android/permission/PermissionChecker.h
@@ -30,6 +30,8 @@
 // ---------------------------------------------------------------------------
 namespace android {
 
+namespace permission {
+
 using android::content::AttributionSourceState;
 using android::permission::IPermissionChecker;
 
@@ -71,7 +73,8 @@
      * Checks whether a given data access chain described by the given attribution source
      * has a given permission and whether the app op that corresponds to this permission
      * is allowed. Call this method if you are the datasource which would not blame you for
-     * access to the data since you are the data. Note that the attribution source chain
+     * access to the data since you are the data.  Use this API if you are the datasource of
+     * the protected state.
      *
      * NOTE: The attribution source should be for yourself with its next attribution
      * source being the app that would receive the data from you.
@@ -82,18 +85,49 @@
      * @param permission The permission to check.
      * @param attributionSource The attribution chain to check.
      * @param message A message describing the reason the permission was checked.
+     * @param attributedOpCode The op code towards which to blame the access. If this
+     *     is a valid app op the op corresponding to the checked permission (if such)
+     *     would only be checked to ensure it is allowed and if that succeeds the
+     *     noting would be against the attributed op.
      * @return The permission check result which is either PERMISSION_GRANTED,
      *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
      */
     PermissionChecker::PermissionResult checkPermissionForDataDeliveryFromDatasource(
-            const String16& permission, AttributionSourceState& attributionSource,
-            const String16& message);
+            const String16& permission, const AttributionSourceState& attributionSource,
+            const String16& message, int32_t attributedOpCode);
+
+   /**
+     * Checks whether a given data access chain described by the given attribution source
+     * has a given permission and whether the app op that corresponds to this permission
+     * is allowed. The app ops are not noted/started.
+     *
+     * NOTE: The attribution source should be for yourself with its next attribution
+     * source being the app that would receive the data from you.
+     *
+     * 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.
+     *
+     * @param permission The permission to check.
+     * @param attributionSource The attribution chain to check.
+     * @param message A message describing the reason the permission was checked.
+     * @param attributedOpCode The op code towards which to blame the access. If this
+     *     is a valid app op the op corresponding to the checked permission (if such)
+     *     would only be checked to ensure it is allowed and if that succeeds the
+     *     starting would be against the attributed op.
+     * @return The permission check result which is either PERMISSION_GRANTED,
+     *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
+     */
+    PermissionResult checkPermissionForPreflightFromDatasource(
+            const String16& permission, const AttributionSourceState& attributionSource,
+            const String16& message, int32_t attributedOpCode);
 
    /**
      * Checks whether a given data access chain described by the given attribution source
      * has a given permission and whether the app op that corresponds to this permission
      * is allowed. The app ops are also marked as started. This is useful for long running
-     * permissions like camera and microphone.
+     * permissions like camera and microphone. Use this API if you are the datasource of
+     * the protected state.
      *
      * NOTE: The attribution source should be for yourself with its next attribution
      * source being the app that would receive the data from you.
@@ -104,32 +138,45 @@
      * @param permission The permission to check.
      * @param attributionSource The attribution chain to check.
      * @param message A message describing the reason the permission was checked.
+     * @param attributedOpCode The op code towards which to blame the access. If this
+     *     is a valid app op the op corresponding to the checked permission (if such)
+     *     would only be checked to ensure it is allowed and if that succeeds the
+     *     starting would be against the attributed op.
      * @return The permission check result which is either PERMISSION_GRANTED,
      *     or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED.
      */
     PermissionResult checkPermissionForStartDataDeliveryFromDatasource(
-            const String16& permission, AttributionSourceState& attributionSource,
-            const String16& message);
+            const String16& permission, const AttributionSourceState& attributionSource,
+            const String16& message, int32_t attributedOpCode);
 
     /**
      * Finishes an ongoing op for data access chain described by the given
-     * attribution source.
+     * attribution source. Use this API if you are the datasource of the protected
+     * state. Use this API if you are the datasource of the protected state.
+     *
+     * NOTE: The attribution source should be for yourself with its next attribution
+     * source being the app that would receive the data from you.
      *
      * @param op The op to finish.
      * @param attributionSource The attribution chain for which to finish data delivery.
+     * @param attributedOpCode The op code towards which to blame the access. If this
+     *     is a valid app op it is the op that would be finished.
      */
-    void finishDataDelivery(const String16& op, AttributionSourceState& attributionSource);
+    void finishDataDeliveryFromDatasource(int32_t op,
+            const AttributionSourceState& attributionSource);
 
 private:
     Mutex mLock;
     sp<IPermissionChecker> mService;
     sp<IPermissionChecker> getService();
 
-    int32_t checkPermission(const String16& permission, AttributionSourceState& attributionSource,
+    PermissionResult checkPermission(const String16& permission,
+            const AttributionSourceState& attributionSource,
             const String16& message, bool forDataDelivery, bool startDataDelivery,
-            bool fromDatasource);
+            bool fromDatasource, int32_t attributedOpCode);
 };
 
+} // namespace permission
 
 } // namespace android