Implement Camera Id Remapping in CameraService

0. We reuse the CAMERA_INJECT_EXTERNAL_CAMERA permission to restrict access to the new Camera ID Remapping functionality.
1. Introduce a new binder method remapCameraIds(CameraIdRemapping).
2. The CameraIdRemapping parcelable is just a map of {packageName -> {id0 -> id1}} and is used between CameraManager <-> CameraService.
3. The methods in ICameraService that deal with Camera ID simply call resolveCameraId(id) to find the actual ID to use. Behind the scenes, we also use the UID to lookup the packageName associated with the client to find the associated camera ID.
4. Every time we update the config, we disconnect the clients that are used by the packages that we plan to replace. See the impl in remapCameraIds.
5. For CameraManager listeners for packages which have active ID remapping, we trigger all callbacks (torch, statusUpdates) for both the id0 as well as id1 - meaning, if we get onStatusChanged(id1), and package com.instagram.android has an active remapping of {id0->id1}, we’ll trigger onStatusChanged(id0) as well (to allow the app to receive updates on the camera it thinks it is talking to).
6. Because the CameraDevice in the application layer still only knows about the original (pre-configuration) IDs, the CaptureRequests it sends down also contain that original ID. So, we have to change some logic in CameraDeviceClient to allow it to modify the id while processing the requests. This also means that CameraDeviceClient should know both its remapped ID and the original Id it was created for.
7. To simulate and demonstrate live updates to the id mapping configuration, we add a shell command to invoke remapCameraIds dynamically via `adb shell cmd media.camera remap-camera-id packageName id0 id1`. This will only be allowed via adb root.

Security Bug: b/288901406 (For clearance related to the effort and the permission design)
Bug: b/286287541
Test: Manual testing

Change-Id: I785a70bffad304583cfe557114b003a51cf5ac43
Merged-In: Ie1d726c45032ee8e7b9773640f96465451167dc9
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 38c615d..1720b55 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -98,7 +98,8 @@
         uid_t clientUid,
         int servicePid,
         bool overrideForPerfClass,
-        bool overrideToPortrait) :
+        bool overrideToPortrait,
+        const String8& originalCameraId) :
     Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper, clientPackageName,
             systemNativeClient, clientFeatureId, cameraId, /*API1 camera ID*/ -1, cameraFacing,
             sensorOrientation, clientPid, clientUid, servicePid, overrideForPerfClass,
@@ -106,8 +107,8 @@
     mInputStream(),
     mStreamingRequestId(REQUEST_ID_NONE),
     mRequestIdCounter(0),
-    mOverrideForPerfClass(overrideForPerfClass) {
-
+    mOverrideForPerfClass(overrideForPerfClass),
+    mOriginalCameraId(originalCameraId) {
     ATRACE_CALL();
     ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
 }
@@ -322,7 +323,7 @@
 
         //The first capture settings should always match the logical camera id
         String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
-        if (mDevice->getId() != logicalId) {
+        if (mDevice->getId() != logicalId && mOriginalCameraId != logicalId) {
             ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
                     mCameraIdStr.string());
             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
@@ -437,6 +438,8 @@
 
         CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
         for (const auto& it : request.mPhysicalCameraSettings) {
+            std::string resolvedId = (
+                mOriginalCameraId.string() == it.id) ? mDevice->getId().string() : it.id;
             if (it.settings.isEmpty()) {
                 ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
                         __FUNCTION__, mCameraIdStr.string());
@@ -447,7 +450,7 @@
             // Check whether the physical / logical stream has settings
             // consistent with the sensor pixel mode(s) it was configured with.
             // mCameraIdToStreamSet will only have ids that are high resolution
-            const auto streamIdSetIt = mHighResolutionCameraIdToStreamIdSet.find(it.id);
+            const auto streamIdSetIt = mHighResolutionCameraIdToStreamIdSet.find(resolvedId);
             if (streamIdSetIt != mHighResolutionCameraIdToStreamIdSet.end()) {
                 std::list<int> streamIdsUsedInRequest = getIntersection(streamIdSetIt->second,
                         outputStreamIds);
@@ -455,14 +458,14 @@
                         !isSensorPixelModeConsistent(streamIdsUsedInRequest, it.settings)) {
                      ALOGE("%s: Camera %s: Request settings CONTROL_SENSOR_PIXEL_MODE not "
                             "consistent with configured streams. Rejecting request.",
-                            __FUNCTION__, it.id.c_str());
+                            __FUNCTION__, resolvedId.c_str());
                     return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                         "Request settings CONTROL_SENSOR_PIXEL_MODE are not consistent with "
                         "streams configured");
                 }
             }
 
-            String8 physicalId(it.id.c_str());
+            String8 physicalId(resolvedId.c_str());
             bool hasTestPatternModePhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
                     mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_MODE) !=
                     mSupportedPhysicalRequestKeys.end();
@@ -471,7 +474,7 @@
                     mSupportedPhysicalRequestKeys.end();
             if (physicalId != mDevice->getId()) {
                 auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
-                        it.id);
+                        resolvedId);
                 if (found == requestedPhysicalIds.end()) {
                     ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
                             __FUNCTION__, mCameraIdStr.string(), physicalId.string());
@@ -494,11 +497,11 @@
                         }
                     }
 
-                    physicalSettingsList.push_back({it.id, filteredParams,
+                    physicalSettingsList.push_back({resolvedId, filteredParams,
                             hasTestPatternModePhysicalKey, hasTestPatternDataPhysicalKey});
                 }
             } else {
-                physicalSettingsList.push_back({it.id, it.settings});
+                physicalSettingsList.push_back({resolvedId, it.settings});
             }
         }