Camera: fix FlashLightTest

Fix issues related Treble HAL1 path.

Test: FlashLightTest pass on Angler HAL1/module 1.0
Bug: 35674539
Change-Id: I6bd749464c0e6e437a4743d2d66a0a5f54cdba38
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 07d88f6..0ff9314 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -64,7 +64,13 @@
     status_t res = OK;
 
     if (mCameraModule == nullptr) {
-        mFlashControl = new ProviderFlashControl(mProviderManager);
+        if (mProviderManager->supportSetTorchMode(cameraId.string())) {
+            mFlashControl = new ProviderFlashControl(mProviderManager);
+        } else {
+            // Only HAL1 devices do not support setTorchMode
+            mFlashControl =
+                    new CameraHardwareInterfaceFlashControl(mProviderManager, *mCallbacks);
+        }
     } else if (mCameraModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
         mFlashControl = new ModuleFlashControl(*mCameraModule);
         if (mFlashControl == NULL) {
@@ -99,8 +105,7 @@
             mFlashControl = flashControl;
         } else {
             mFlashControl =
-                    new CameraHardwareInterfaceFlashControl(*mCameraModule,
-                                                            *mCallbacks);
+                    new CameraHardwareInterfaceFlashControl(mCameraModule, *mCallbacks);
         }
     }
 
@@ -164,20 +169,28 @@
     return res;
 }
 
+int CameraFlashlight::getNumberOfCameras() {
+    if (mCameraModule) {
+        return mCameraModule->getNumberOfCameras();
+    } else {
+        return mProviderManager->getStandardCameraCount();
+    }
+}
+
 status_t CameraFlashlight::findFlashUnits() {
     Mutex::Autolock l(mLock);
     status_t res;
 
     std::vector<String8> cameraIds;
+    int numberOfCameras = getNumberOfCameras();
+    cameraIds.resize(numberOfCameras);
     if (mCameraModule) {
-        cameraIds.resize(mCameraModule->getNumberOfCameras());
         for (size_t i = 0; i < cameraIds.size(); i++) {
             cameraIds[i] = String8::format("%zu", i);
         }
     } else {
         // No module, must be provider
-        std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
-        cameraIds.resize(ids.size());
+        std::vector<std::string> ids = mProviderManager->getStandardCameraDeviceIds();
         for (size_t i = 0; i < cameraIds.size(); i++) {
             cameraIds[i] = String8(ids[i].c_str());
         }
@@ -236,6 +249,17 @@
     return mHasFlashlightMap.valueAt(index);
 }
 
+bool CameraFlashlight::isBackwardCompatibleMode(const String8& cameraId) {
+    bool backwardCompatibleMode = false;
+    if (mCameraModule && mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) {
+        backwardCompatibleMode = true;
+    } else if (mProviderManager != nullptr &&
+            !mProviderManager->supportSetTorchMode(cameraId.string())) {
+        backwardCompatibleMode = true;
+    }
+    return backwardCompatibleMode;
+}
+
 status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
     ALOGV("%s: prepare for device open", __FUNCTION__);
 
@@ -246,14 +270,14 @@
         return NO_INIT;
     }
 
-    if (mCameraModule && mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) {
+    if (isBackwardCompatibleMode(cameraId)) {
         // framework is going to open a camera device, all flash light control
         // should be closed for backward compatible support.
         mFlashControl.clear();
 
         if (mOpenedCameraIds.size() == 0) {
             // notify torch unavailable for all cameras with a flash
-            int numCameras = mCameraModule->getNumberOfCameras();
+            int numCameras = getNumberOfCameras();
             for (int i = 0; i < numCameras; i++) {
                 if (hasFlashUnitLocked(String8::format("%d", i))) {
                     mCallbacks->torch_mode_status_change(mCallbacks,
@@ -296,9 +320,9 @@
     if (mOpenedCameraIds.size() != 0)
         return OK;
 
-    if (mCameraModule && mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) {
+    if (isBackwardCompatibleMode(cameraId)) {
         // notify torch available for all cameras with a flash
-        int numCameras = mCameraModule->getNumberOfCameras();
+        int numCameras = getNumberOfCameras();
         for (int i = 0; i < numCameras; i++) {
             if (hasFlashUnitLocked(String8::format("%d", i))) {
                 mCallbacks->torch_mode_status_change(mCallbacks,
@@ -692,12 +716,21 @@
 // Flash control for camera module <= v2.3 and camera HAL v1
 /////////////////////////////////////////////////////////////////////
 CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
-        CameraModule& cameraModule,
+        CameraModule* cameraModule,
         const camera_module_callbacks_t& callbacks) :
-        mCameraModule(&cameraModule),
+        mCameraModule(cameraModule),
+        mProviderManager(nullptr),
         mCallbacks(&callbacks),
         mTorchEnabled(false) {
+}
 
+CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
+        sp<CameraProviderManager> manager,
+        const camera_module_callbacks_t& callbacks) :
+        mCameraModule(nullptr),
+        mProviderManager(manager),
+        mCallbacks(&callbacks),
+        mTorchEnabled(false) {
 }
 
 CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
@@ -898,7 +931,12 @@
     sp<CameraHardwareInterface> device =
             new CameraHardwareInterface(cameraId.string());
 
-    status_t res = device->initialize(mCameraModule);
+    status_t res;
+    if (mCameraModule != nullptr) {
+        res = device->initialize(mCameraModule);
+    } else {
+        res = device->initialize(mProviderManager);
+    }
     if (res) {
         ALOGE("%s: initializing camera %s failed", __FUNCTION__,
                 cameraId.string());
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index b7c7690..98f269a 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -92,6 +92,12 @@
         // mLock should be locked.
         bool hasFlashUnitLocked(const String8& cameraId);
 
+        // Check if flash control is in backward compatible mode (simulated torch API by
+        // opening cameras)
+        bool isBackwardCompatibleMode(const String8& cameraId);
+
+        int getNumberOfCameras();
+
         sp<FlashControlBase> mFlashControl;
 
         CameraModule *mCameraModule;
@@ -202,7 +208,11 @@
  */
 class CameraHardwareInterfaceFlashControl : public FlashControlBase {
     public:
-        CameraHardwareInterfaceFlashControl(CameraModule& cameraModule,
+        CameraHardwareInterfaceFlashControl(
+                CameraModule* cameraModule,
+                const camera_module_callbacks_t& callbacks);
+        CameraHardwareInterfaceFlashControl(
+                sp<CameraProviderManager> manager,
                 const camera_module_callbacks_t& callbacks);
         virtual ~CameraHardwareInterfaceFlashControl();
 
@@ -235,6 +245,7 @@
         status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
 
         CameraModule *mCameraModule;
+        sp<CameraProviderManager> mProviderManager;
         const camera_module_callbacks_t *mCallbacks;
         sp<CameraHardwareInterface> mDevice;
         String8 mCameraId;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 562e6c9..bbeeca6 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -22,7 +22,6 @@
 
 #include <chrono>
 #include <inttypes.h>
-#include <set>
 #include <hidl/ServiceManagement.h>
 
 namespace android {
@@ -96,8 +95,21 @@
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
     std::vector<std::string> deviceIds;
     for (auto& provider : mProviders) {
-        for (auto& deviceInfo : provider->mDevices) {
-            deviceIds.push_back(deviceInfo->mId);
+        for (auto& id : provider->mUniqueCameraIds) {
+            deviceIds.push_back(id);
+        }
+    }
+    return deviceIds;
+}
+
+std::vector<std::string> CameraProviderManager::getStandardCameraDeviceIds() const {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+    std::vector<std::string> deviceIds;
+    for (auto& provider : mProviders) {
+        if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
+            for (auto& id : provider->mUniqueCameraIds) {
+                deviceIds.push_back(id);
+            }
         }
     }
     return deviceIds;
@@ -182,6 +194,23 @@
     return OK;
 }
 
+bool CameraProviderManager::supportSetTorchMode(const std::string &id) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+    bool support = false;
+    for (auto& provider : mProviders) {
+        auto deviceInfo = findDeviceInfoLocked(id);
+        if (deviceInfo != nullptr) {
+            provider->mInterface->isSetTorchModeSupported(
+                [&support](auto status, bool supported) {
+                    if (status == Status::OK) {
+                        support = supported;
+                    }
+                });
+        }
+    }
+    return support;
+}
+
 status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
 
@@ -472,11 +501,10 @@
         }
     }
 
-    std::set<std::string> uniqueCameraIds;
     for (auto& device : mDevices) {
-        uniqueCameraIds.insert(device->mId);
+        mUniqueCameraIds.insert(device->mId);
     }
-    mUniqueDeviceCount = uniqueCameraIds.size();
+    mUniqueDeviceCount = mUniqueCameraIds.size();
 
     ALOGI("Camera provider %s ready with %zu camera devices",
             mProviderName.c_str(), mDevices.size());
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 04b9597..a388db5 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -18,6 +18,7 @@
 #define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H
 
 #include <vector>
+#include <set>
 #include <string>
 #include <mutex>
 
@@ -133,6 +134,8 @@
 
     std::vector<std::string> getCameraDeviceIds() const;
 
+    std::vector<std::string> getStandardCameraDeviceIds() const;
+
     /**
      * Return true if a device with a given ID and major version exists
      */
@@ -170,8 +173,14 @@
             hardware::hidl_version *v);
 
     /**
+     * Check if a given camera device support setTorchMode API.
+     */
+    bool supportSetTorchMode(const std::string &id);
+
+    /**
      * Turn on or off the flashlight on a given camera device.
-     * May fail if the device is in active use, or if the device doesn't exist, etc.
+     * May fail if the device does not support this API, is in active use, or if the device
+     * doesn't exist, etc.
      */
     status_t setTorchMode(const std::string &id, bool enabled);
 
@@ -292,6 +301,7 @@
             static status_t setTorchMode(InterfaceT& interface, bool enabled);
         };
         std::vector<std::unique_ptr<DeviceInfo>> mDevices;
+        std::set<std::string> mUniqueCameraIds;
         int mUniqueDeviceCount;
 
         // HALv1-specific camera fields, including the actual device interface