cameraservice: cache IPermissionChecker and IPermissionController

CameraService makes frequent calls to PermissionChecker and
PermissionController services while handler application requests.
However it requests a new instance of both from the service manager
for each call. Retrieving an instance from service manager results
in a binder call, which can quickly add up if the application is
making frequent calls to CameraService.

To reduce the latency of fetching the services, this CL caches the
PermissionChecker and IPermissionController objects for the lifetime
of CameraService.

Bug: 326139956
Test: atest CtsCameraTestCases:PerformanceTest#testCameraLaunch
      passes.
Test: Verified by vendors that getCameraCharacteristics calls are
      faster.
Change-Id: I9d7471c00d43bb89135d4026dcb8016be234938b
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 1dc45c3..7e646cf 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -160,3 +160,13 @@
      bug: "297083874"
 }
 
+
+flag {
+     namespace: "camera_platform"
+     name: "cache_permission_services"
+     description: "Cache IPermissionController and IPermissionChecker in CameraService to reduce query latency."
+     bug: "326139956"
+     metadata {
+       purpose: PURPOSE_BUGFIX
+     }
+}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 78c14b2..26208c5 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2309,16 +2309,31 @@
 std::string CameraService::getPackageNameFromUid(int clientUid) {
     std::string packageName("");
 
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(toString16(kPermissionServiceName));
-    if (binder == 0) {
-        ALOGE("Cannot get permission service");
+    sp<IPermissionController> permCtrl;
+    if (flags::cache_permission_services()) {
+        permCtrl = getPermissionController();
+    } else {
+        sp<IServiceManager> sm = defaultServiceManager();
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+        // Using deprecated function to preserve functionality until the
+        // cache_permission_services flag is removed.
+        sp<IBinder> binder = sm->getService(toString16(kPermissionServiceName));
+#pragma clang diagnostic pop
+        if (binder == 0) {
+            ALOGE("Cannot get permission service");
+            permCtrl = nullptr;
+        } else {
+            permCtrl = interface_cast<IPermissionController>(binder);
+        }
+    }
+
+    if (permCtrl == nullptr) {
         // Return empty package name and the further interaction
         // with camera will likely fail
         return packageName;
     }
 
-    sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
     Vector<String16> packages;
 
     permCtrl->getPackagesForUid(clientUid, packages);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 1a887a1..f25cf7d 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -34,6 +34,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/IActivityManager.h>
 #include <binder/IAppOpsCallback.h>
+#include <binder/IPermissionController.h>
 #include <binder/IUidObserver.h>
 #include <hardware/camera.h>
 #include <sensorprivacy/SensorPrivacyManager.h>
@@ -675,7 +676,26 @@
         return activityManager;
     }
 
-   /**
+    static const sp<IPermissionController>& getPermissionController() {
+        static const char* kPermissionControllerService = "permission";
+        static thread_local sp<IPermissionController> sPermissionController = nullptr;
+
+        if (sPermissionController == nullptr ||
+                !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
+            sp<IServiceManager> sm = defaultServiceManager();
+            sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
+            if (binder == nullptr) {
+                ALOGE("%s: Could not get permission service", __FUNCTION__);
+                sPermissionController = nullptr;
+            } else {
+                sPermissionController = interface_cast<IPermissionController>(binder);
+            }
+        }
+
+        return sPermissionController;
+    }
+
+    /**
      * Typesafe version of device status, containing both the HAL-layer and the service interface-
      * layer values.
      */
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
index e63b30b..e8301c1 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -18,6 +18,7 @@
 
 #include <binder/AppOpsManager.h>
 #include <binder/PermissionController.h>
+#include <com_android_internal_camera_flags.h>
 #include <cutils/properties.h>
 #include <private/android_filesystem_config.h>
 
@@ -26,6 +27,8 @@
 
 namespace android {
 
+namespace flags = com::android::internal::camera::flags;
+
 const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
 const std::string AttributionAndPermissionUtils::sManageCameraPermission(
         "android.permission.MANAGE_CAMERA");
@@ -75,9 +78,16 @@
         return true;
     }
 
-    PermissionChecker permissionChecker;
-    return permissionChecker.checkPermissionForPreflight(toString16(permission), attributionSource,
-            toString16(message), attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+    if (!flags::cache_permission_services()) {
+        PermissionChecker permissionChecker;
+        return permissionChecker.checkPermissionForPreflight(
+                       toString16(permission), attributionSource, toString16(message),
+                       attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+    } else {
+        return mPermissionChecker->checkPermissionForPreflight(
+                       toString16(permission), attributionSource, toString16(message),
+                       attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+    }
 }
 
 // Can camera service trust the caller based on the calling UID?
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 7f4a1bd..830a8e8 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -32,7 +32,7 @@
  * caller.
  */
 class AttributionAndPermissionUtils {
-public:
+  public:
     AttributionAndPermissionUtils() { }
     virtual ~AttributionAndPermissionUtils() {}
 
@@ -90,11 +90,15 @@
     static const std::string sCameraOpenCloseListenerPermission;
     static const std::string sCameraInjectExternalCameraPermission;
 
-protected:
+  protected:
     wp<CameraService> mCameraService;
 
     bool checkAutomotivePrivilegedClient(const std::string &cameraId,
             const AttributionSourceState &attributionSource);
+
+  private:
+    std::unique_ptr<permission::PermissionChecker> mPermissionChecker =
+            std::make_unique<permission::PermissionChecker>();
 };
 
 /**