cameraserver: Modified rules for different kinds of system cameras.

Since we now have AIDL HALs as well, just depending on whether a binder
call is being made from a hwbinder thread is not enough to determine
whether a system camera / hidden secure camera should be accessible to the
client. The same goes for modifying oom scores / process state for
vendor clients. Instead we now allow privileged clients (uid <
AID_APP_START) to access system and hidden secure cameras. This will
include vendor clients as well. Oom score and process state re-mapping is now done for native
privileged clients.

Bug: 196432585

Test: Make Camera2 app privileged; make all cameras on device system only cameras
      See that other 3P apps / GCA can't access cameras; Camera2 can.

Test: CTS with cuttlefish depth camera made system camera

Test: Manually check that privileged native camera clients have their
      oom score and process state modified to let 3P apps evict them.

Test: atest Camera2PermissionTest.java

Change-Id: I1e81a554491f3d84f28d82a22bd0683a3407d46f
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 5740038..271cfec 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -132,8 +132,9 @@
 static const String16
         sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
 const char *sFileName = "lastOpenSessionDumpFile";
-static constexpr int32_t kVendorClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
-static constexpr int32_t kVendorClientState = ActivityManager::PROCESS_STATE_PERSISTENT_UI;
+static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
+static constexpr int32_t kSystemNativeClientState =
+        ActivityManager::PROCESS_STATE_PERSISTENT_UI;
 
 const String8 CameraService::kOfflineDevice("offline-");
 const String16 CameraService::kWatchAllClientsFlag("all");
@@ -155,6 +156,12 @@
     }
 }
 
+// The word 'System' here does not refer to clients only on the system
+// partition. They just need to have a android system uid.
+static bool doesClientHaveSystemUid() {
+    return (CameraThreadState::getCallingUid() < AID_APP_START);
+}
+
 void CameraService::onFirstRef()
 {
 
@@ -923,7 +930,7 @@
 }
 
 Status CameraService::makeClient(const sp<CameraService>& cameraService,
-        const sp<IInterface>& cameraCb, const String16& packageName,
+        const sp<IInterface>& cameraCb, const String16& packageName, bool systemNativeClient,
         const std::optional<String16>& featureId,  const String8& cameraId,
         int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid,
         int servicePid, int deviceVersion, apiLevel effectiveApiLevel, bool overrideForPerfClass,
@@ -949,15 +956,14 @@
             if (effectiveApiLevel == API_1) { // Camera1 API route
                 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                 *client = new Camera2Client(cameraService, tmp, packageName, featureId,
-                        cameraId, api1CameraId,
-                        facing, sensorOrientation, clientPid, clientUid,
+                        cameraId, api1CameraId, facing, sensorOrientation, clientPid, clientUid,
                         servicePid, overrideForPerfClass);
             } else { // Camera2 API route
                 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                         static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
-                *client = new CameraDeviceClient(cameraService, tmp, packageName, featureId,
-                        cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
-                        overrideForPerfClass);
+                *client = new CameraDeviceClient(cameraService, tmp, packageName,
+                        systemNativeClient, featureId, cameraId, facing, sensorOrientation,
+                        clientPid, clientUid, servicePid, overrideForPerfClass);
             }
             break;
         default:
@@ -1053,7 +1059,7 @@
     sp<Client> tmp = nullptr;
     if (!(ret = connectHelper<ICameraClient,Client>(
             sp<ICameraClient>{nullptr}, id, cameraId,
-            internalPackageName, {}, uid, USE_CALLING_PID,
+            internalPackageName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
             API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
             /*targetSdkVersion*/ __ANDROID_API_FUTURE__, /*out*/ tmp)
             ).isOk()) {
@@ -1288,9 +1294,9 @@
 
     userid_t clientUserId = multiuser_get_user_id(clientUid);
 
-    // Only allow clients who are being used by the current foreground device user, unless calling
-    // from our own process OR the caller is using the cameraserver's HIDL interface.
-    if (getCurrentServingCall() != BinderCallType::HWBINDER && callingPid != getpid() &&
+    // For non-system clients : Only allow clients who are being used by the current foreground
+    // device user, unless calling from our own process.
+    if (!doesClientHaveSystemUid() && callingPid != getpid() &&
             (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
         ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
                 "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
@@ -1327,12 +1333,12 @@
 }
 
 void CameraService::finishConnectLocked(const sp<BasicClient>& client,
-        const CameraService::DescriptorPtr& desc, int oomScoreOffset) {
+        const CameraService::DescriptorPtr& desc, int oomScoreOffset, bool systemNativeClient) {
 
     // Make a descriptor for the incoming client
     auto clientDescriptor =
             CameraService::CameraClientManager::makeClientDescriptor(client, desc,
-                    oomScoreOffset);
+                    oomScoreOffset, systemNativeClient);
     auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
 
     logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
@@ -1362,7 +1368,7 @@
 
 status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
         apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
-        int oomScoreOffset,
+        int oomScoreOffset, bool systemNativeClient,
         /*out*/
         sp<BasicClient>* client,
         std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
@@ -1437,7 +1443,7 @@
         clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
                 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
                 state->getConflicting(), actualScore, clientPid, actualState,
-                oomScoreOffset);
+                oomScoreOffset, systemNativeClient);
 
         resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
 
@@ -1580,7 +1586,7 @@
     String8 id = cameraIdIntToStr(api1CameraId);
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
-            clientPackageName, {}, clientUid, clientPid, API_1,
+            clientPackageName,/*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
             /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion, /*out*/client);
 
     if(!ret.isOk()) {
@@ -1612,14 +1618,14 @@
     // 1) If cameraserver tries to access this camera device, accept the
     //    connection.
     // 2) The camera device is a publicly hidden secure camera device AND some
-    //    component is trying to access it on a non-hwbinder thread (generally a non HAL client),
-    //    reject it.
+    //    non system component is trying to access it.
     // 3) if the camera device is advertised by the camera HAL as SYSTEM_ONLY
     //    and the serving thread is a non hwbinder thread, the client must have
     //    android.permission.SYSTEM_CAMERA permissions to connect.
 
     int cPid = CameraThreadState::getCallingPid();
     int cUid = CameraThreadState::getCallingUid();
+    bool systemClient = doesClientHaveSystemUid();
     SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
     if (getSystemCameraKind(cameraId, &systemCameraKind) != OK) {
         // This isn't a known camera ID, so it's not a system camera
@@ -1632,8 +1638,7 @@
         return false;
     }
     // (2)
-    if (getCurrentServingCall() != BinderCallType::HWBINDER &&
-            systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA) {
+    if (!systemClient && systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA) {
         ALOGW("Rejecting access to secure hidden camera %s", cameraId.c_str());
         return true;
     }
@@ -1641,8 +1646,7 @@
     //     getCameraCharacteristics() allows for calls to succeed (albeit after hiding some
     //     characteristics) even if clients don't have android.permission.CAMERA. We do not want the
     //     same behavior for system camera devices.
-    if (getCurrentServingCall() != BinderCallType::HWBINDER &&
-            systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
+    if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
             !hasPermissionsForSystemCamera(cPid, cUid, /*logPermissionFailure*/true)) {
         ALOGW("Rejecting access to system only camera %s, inadequete permissions",
                 cameraId.c_str());
@@ -1667,11 +1671,12 @@
     sp<CameraDeviceClient> client = nullptr;
     String16 clientPackageNameAdj = clientPackageName;
     int callingPid = CameraThreadState::getCallingPid();
-
-    if (getCurrentServingCall() == BinderCallType::HWBINDER) {
-        std::string vendorClient =
-                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
-        clientPackageNameAdj = String16(vendorClient.c_str());
+    bool systemNativeClient = false;
+    if (doesClientHaveSystemUid() && (clientPackageNameAdj.size() == 0)) {
+        std::string systemClient =
+                StringPrintf("client.pid<%d>", CameraThreadState::getCallingPid());
+        clientPackageNameAdj = String16(systemClient.c_str());
+        systemNativeClient = true;
     }
 
     if (oomScoreOffset < 0) {
@@ -1695,7 +1700,7 @@
     }
 
     ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
-            /*api1CameraId*/-1, clientPackageNameAdj, clientFeatureId,
+            /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient,clientFeatureId,
             clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
             targetSdkVersion, /*out*/client);
 
@@ -1726,7 +1731,7 @@
 
 template<class CALLBACK, class CLIENT>
 Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
-        int api1CameraId, const String16& clientPackageName,
+        int api1CameraId, const String16& clientPackageName, bool systemNativeClient,
         const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
         apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
         /*out*/sp<CLIENT>& device) {
@@ -1745,7 +1750,7 @@
     sp<CLIENT> client = nullptr;
     int facing = -1;
     int orientation = 0;
-    bool isNdk = (clientPackageName.size() == 0);
+    bool isNonSystemNdk = (clientPackageName.size() == 0);
     {
         // Acquire mServiceLock and prevent other clients from connecting
         std::unique_ptr<AutoConditionLock> lock =
@@ -1779,8 +1784,8 @@
         sp<BasicClient> clientTmp = nullptr;
         std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
         if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
-                IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, /*out*/&clientTmp,
-                /*out*/&partial)) != NO_ERROR) {
+                IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, systemNativeClient,
+                /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
             switch (err) {
                 case -ENODEV:
                     return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
@@ -1820,8 +1825,8 @@
         sp<BasicClient> tmp = nullptr;
         bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
                 mPerfClassPrimaryCameraIds, cameraId.string(), targetSdkVersion);
-        if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,
-                cameraId, api1CameraId, facing, orientation,
+        if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
+                clientFeatureId, cameraId, api1CameraId, facing, orientation,
                 clientPid, clientUid, getpid(),
                 deviceVersion, effectiveApiLevel, overrideForPerfClass,
                 /*out*/&tmp)).isOk()) {
@@ -1923,7 +1928,7 @@
             mServiceLock.lock();
         } else {
             // Otherwise, add client to active clients list
-            finishConnectLocked(client, partial, oomScoreOffset);
+            finishConnectLocked(client, partial, oomScoreOffset, systemNativeClient);
         }
 
         client->setImageDumpMask(mImageDumpMask);
@@ -1935,7 +1940,7 @@
 
     int32_t openLatencyMs = ns2ms(systemTime() - openTimeNs);
     CameraServiceProxyWrapper::logOpen(cameraId, facing, clientPackageName,
-            effectiveApiLevel, isNdk, openLatencyMs);
+            effectiveApiLevel, isNonSystemNdk, openLatencyMs);
 
     {
         Mutex::Autolock lock(mInjectionParametersLock);
@@ -1998,7 +2003,8 @@
                 kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
                 /*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
                 onlineClientDesc->getOwnerId(), onlinePriority.getState(),
-                /*ommScoreOffset*/ 0);
+                // native clients don't have offline processing support.
+                /*ommScoreOffset*/ 0, /*systemNativeClient*/false);
 
         // Allow only one offline device per camera
         auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc);
@@ -3169,7 +3175,7 @@
 
 CameraService::Client::Client(const sp<CameraService>& cameraService,
         const sp<ICameraClient>& cameraClient,
-        const String16& clientPackageName,
+        const String16& clientPackageName, bool systemNativeClient,
         const std::optional<String16>& clientFeatureId,
         const String8& cameraIdStr,
         int api1CameraId, int cameraFacing, int sensorOrientation,
@@ -3177,7 +3183,7 @@
         int servicePid) :
         CameraService::BasicClient(cameraService,
                 IInterface::asBinder(cameraClient),
-                clientPackageName, clientFeatureId,
+                clientPackageName, systemNativeClient, clientFeatureId,
                 cameraIdStr, cameraFacing, sensorOrientation,
                 clientPid, clientUid,
                 servicePid),
@@ -3207,13 +3213,14 @@
 
 CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
         const sp<IBinder>& remoteCallback,
-        const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
-        const String8& cameraIdStr, int cameraFacing, int sensorOrientation,
-        int clientPid, uid_t clientUid,
+        const String16& clientPackageName, bool nativeClient,
+        const std::optional<String16>& clientFeatureId, const String8& cameraIdStr,
+        int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid,
         int servicePid):
         mDestructionStarted(false),
         mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation),
-        mClientPackageName(clientPackageName), mClientFeatureId(clientFeatureId),
+        mClientPackageName(clientPackageName), mSystemNativeClient(nativeClient),
+        mClientFeatureId(clientFeatureId),
         mClientPid(clientPid), mClientUid(clientUid),
         mServicePid(servicePid),
         mDisconnected(false), mUidIsTrusted(false),
@@ -3256,7 +3263,19 @@
         }
         mClientPackageName = packages[0];
     }
-    if (getCurrentServingCall() != BinderCallType::HWBINDER) {
+
+    // There are 2 scenarios in which a client won't have AppOps operations
+    // (both scenarios : native clients)
+    //    1) It's an system native client*, the package name will be empty
+    //       and it will return from this function in the previous if condition
+    //       (This is the same as the previously existing behavior).
+    //    2) It is a system native client, but its package name has been
+    //       modified for debugging, however it still must not use AppOps since
+    //       the package name is not a real one.
+    //
+    //       * system native client - native client with UID < AID_APP_START. It
+    //         doesn't exclude clients not on the system partition.
+    if (!mSystemNativeClient) {
         mAppOpsManager = std::make_unique<AppOpsManager>();
     }
 
@@ -4078,23 +4097,23 @@
 CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
         const String8& key, const sp<BasicClient>& value, int32_t cost,
         const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
-        int32_t state, int32_t oomScoreOffset) {
+        int32_t state, int32_t oomScoreOffset, bool systemNativeClient) {
 
-    bool isVendorClient = getCurrentServingCall() == BinderCallType::HWBINDER;
-    int32_t score_adj = isVendorClient ? kVendorClientScore : score;
-    int32_t state_adj = isVendorClient ? kVendorClientState: state;
+    int32_t score_adj = systemNativeClient ? kSystemNativeClientScore : score;
+    int32_t state_adj = systemNativeClient ? kSystemNativeClientState: state;
 
     return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
-            key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient,
-            oomScoreOffset);
+            key, value, cost, conflictingKeys, score_adj, ownerId, state_adj,
+            systemNativeClient, oomScoreOffset);
 }
 
 CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
         const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial,
-        int32_t oomScoreOffset) {
+        int32_t oomScoreOffset, bool systemNativeClient) {
     return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
             partial->getConflicting(), partial->getPriority().getScore(),
-            partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset);
+            partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset,
+            systemNativeClient);
 }
 
 // ----------------------------------------------------------------------------