CameraService: intercept Camera module

Wrap camera module returned from HAL so get_camera_info returns
static_camera_characteristics processed by framework, which
generates keys added after HAL3.2 is released.

Change-Id: Ief423a1571cf06c7ef80b98b403a33969baf95f6
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index e184d97..de9551d 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -25,6 +25,7 @@
     CameraDeviceFactory.cpp \
     common/Camera2ClientBase.cpp \
     common/CameraDeviceBase.cpp \
+    common/CameraModule.cpp \
     common/FrameProcessorBase.cpp \
     api1/CameraClient.cpp \
     api1/Camera2Client.cpp \
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 1232c32..485b979 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -113,14 +113,17 @@
 
     BnCameraService::onFirstRef();
 
+    camera_module_t *rawModule;
     if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
-                (const hw_module_t **)&mModule) < 0) {
+                (const hw_module_t **)&rawModule) < 0) {
         ALOGE("Could not load camera HAL module");
         mNumberOfCameras = 0;
     }
     else {
-        ALOGI("Loaded \"%s\" camera module", mModule->common.name);
-        mNumberOfCameras = mModule->get_number_of_cameras();
+        mModule = new CameraModule(rawModule);
+        const hw_module_t *common = mModule->getRawModule();
+        ALOGI("Loaded \"%s\" camera module", common->name);
+        mNumberOfCameras = mModule->getNumberOfCameras();
         if (mNumberOfCameras > MAX_CAMERAS) {
             ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
                     mNumberOfCameras, MAX_CAMERAS);
@@ -130,14 +133,13 @@
             setCameraFree(i);
         }
 
-        if (mModule->common.module_api_version >=
-                CAMERA_MODULE_API_VERSION_2_1) {
-            mModule->set_callbacks(this);
+        if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) {
+            mModule->setCallbacks(this);
         }
 
         VendorTagDescriptor::clearGlobalVendorTagDescriptor();
 
-        if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
+        if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
             setUpVendorTags();
         }
 
@@ -152,6 +154,9 @@
         }
     }
 
+    if (mModule) {
+        delete mModule;
+    }
     VendorTagDescriptor::clearGlobalVendorTagDescriptor();
     gCameraService = NULL;
 }
@@ -236,7 +241,7 @@
 
     struct camera_info info;
     status_t rc = filterGetInfoErrorCode(
-        mModule->get_camera_info(cameraId, &info));
+        mModule->getCameraInfo(cameraId, &info));
     cameraInfo->facing = info.facing;
     cameraInfo->orientation = info.orientation;
     return rc;
@@ -347,7 +352,7 @@
 
     int facing;
     status_t ret = OK;
-    if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
+    if (mModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
             getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
         /**
          * Backwards compatibility mode for old HALs:
@@ -368,7 +373,7 @@
          * Normal HAL 2.1+ codepath.
          */
         struct camera_info info;
-        ret = filterGetInfoErrorCode(mModule->get_camera_info(cameraId, &info));
+        ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
         *cameraInfo = info.static_camera_characteristics;
     }
 
@@ -387,12 +392,12 @@
 
 int CameraService::getDeviceVersion(int cameraId, int* facing) {
     struct camera_info info;
-    if (mModule->get_camera_info(cameraId, &info) != OK) {
+    if (mModule->getCameraInfo(cameraId, &info) != OK) {
         return -1;
     }
 
     int deviceVersion;
-    if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
+    if (mModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
         deviceVersion = info.device_version;
     } else {
         deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
@@ -433,13 +438,13 @@
     vendor_tag_ops_t vOps = vendor_tag_ops_t();
 
     // Check if vendor operations have been implemented
-    if (mModule->get_vendor_tag_ops == NULL) {
+    if (!mModule->isVendorTagDefined()) {
         ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
         return false;
     }
 
     ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
-    mModule->get_vendor_tag_ops(&vOps);
+    mModule->getVendorTagOps(&vOps);
     ATRACE_END();
 
     // Ensure all vendor operations are present
@@ -789,8 +794,9 @@
         /*out*/
         sp<ICamera>& device) {
 
+    int apiVersion = mModule->getRawModule()->module_api_version;
     if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
-            mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_3) {
+            apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
         /*
          * Either the HAL version is unspecified in which case this just creates
          * a camera client selected by the latest device version, or
@@ -798,7 +804,7 @@
          * the open_legacy call
          */
         ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
-                __FUNCTION__, mModule->common.module_api_version);
+                __FUNCTION__, apiVersion);
         return INVALID_OPERATION;
     }
 
@@ -1633,14 +1639,11 @@
             return NO_ERROR;
         }
 
-        result = String8::format("Camera module HAL API version: 0x%x\n",
-                mModule->common.hal_api_version);
-        result.appendFormat("Camera module API version: 0x%x\n",
-                mModule->common.module_api_version);
-        result.appendFormat("Camera module name: %s\n",
-                mModule->common.name);
-        result.appendFormat("Camera module author: %s\n",
-                mModule->common.author);
+        const hw_module_t* common = mModule->getRawModule();
+        result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version);
+        result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version);
+        result.appendFormat("Camera module name: %s\n", common->name);
+        result.appendFormat("Camera module author: %s\n", common->author);
         result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
 
         sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
@@ -1660,7 +1663,7 @@
             result = String8::format("Camera %d static information:\n", i);
             camera_info info;
 
-            status_t rc = mModule->get_camera_info(i, &info);
+            status_t rc = mModule->getCameraInfo(i, &info);
             if (rc != OK) {
                 result.appendFormat("  Error reading static information!\n");
                 write(fd, result.string(), result.size());
@@ -1669,8 +1672,7 @@
                         info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
                 result.appendFormat("  Orientation: %d\n", info.orientation);
                 int deviceVersion;
-                if (mModule->common.module_api_version <
-                        CAMERA_MODULE_API_VERSION_2_0) {
+                if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
                     deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
                 } else {
                     deviceVersion = info.device_version;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 126d8d9..7d0df3a 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -37,6 +37,8 @@
 
 #include <camera/ICameraServiceListener.h>
 
+#include "common/CameraModule.h"
+
 /* This needs to be increased if we can have more cameras */
 #define MAX_CAMERAS 2
 
@@ -153,7 +155,7 @@
 
     class BasicClient : public virtual RefBase {
     public:
-        virtual status_t    initialize(camera_module_t *module) = 0;
+        virtual status_t    initialize(CameraModule *module) = 0;
         virtual void        disconnect();
 
         // because we can't virtually inherit IInterface, which breaks
@@ -385,7 +387,7 @@
     sp<MediaPlayer>     mSoundPlayer[NUM_SOUNDS];
     int                 mSoundRef;  // reference count (release all MediaPlayer when 0)
 
-    camera_module_t *mModule;
+    CameraModule*     mModule;
 
     Vector<sp<ICameraServiceListener> >
                         mListenerList;
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 0ed5586..4ac5166 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -67,7 +67,7 @@
     mLegacyMode = legacyMode;
 }
 
-status_t Camera2Client::initialize(camera_module_t *module)
+status_t Camera2Client::initialize(CameraModule *module)
 {
     ATRACE_CALL();
     ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index d68bb29..5a8241f 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -94,7 +94,7 @@
 
     virtual ~Camera2Client();
 
-    status_t initialize(camera_module_t *module);
+    status_t initialize(CameraModule *module);
 
     virtual status_t dump(int fd, const Vector<String16>& args);
 
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index bbb2fe0..6bea3b6 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -59,7 +59,7 @@
     LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
 }
 
-status_t CameraClient::initialize(camera_module_t *module) {
+status_t CameraClient::initialize(CameraModule *module) {
     int callingPid = getCallingPid();
     status_t res;
 
@@ -75,7 +75,7 @@
     snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
 
     mHardware = new CameraHardwareInterface(camera_device_name);
-    res = mHardware->initialize(&module->common);
+    res = mHardware->initialize(module);
     if (res != OK) {
         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
                 __FUNCTION__, mCameraId, strerror(-res), res);
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 63a9d0f..95616b2 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -68,7 +68,7 @@
             bool legacyMode = false);
     ~CameraClient();
 
-    status_t initialize(camera_module_t *module);
+    status_t initialize(CameraModule *module);
 
     status_t dump(int fd, const Vector<String16>& args);
 
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 6a1ee44..acc092c 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -71,7 +71,7 @@
     ALOGI("CameraDeviceClient %d: Opened", cameraId);
 }
 
-status_t CameraDeviceClient::initialize(camera_module_t *module)
+status_t CameraDeviceClient::initialize(CameraModule *module)
 {
     ATRACE_CALL();
     status_t res;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 84e46b7..e687175 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -119,7 +119,7 @@
             int servicePid);
     virtual ~CameraDeviceClient();
 
-    virtual status_t      initialize(camera_module_t *module);
+    virtual status_t      initialize(CameraModule *module);
 
     virtual status_t      dump(int fd, const Vector<String16>& args);
 
diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp
index 59e5083..30a89c2 100644
--- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp
+++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp
@@ -50,7 +50,7 @@
     mExclusiveLock = false;
 }
 
-status_t ProCamera2Client::initialize(camera_module_t *module)
+status_t ProCamera2Client::initialize(CameraModule *module)
 {
     ATRACE_CALL();
     status_t res;
diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.h b/services/camera/libcameraservice/api_pro/ProCamera2Client.h
index 9d83122..7f5f6ac 100644
--- a/services/camera/libcameraservice/api_pro/ProCamera2Client.h
+++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.h
@@ -85,7 +85,7 @@
             int servicePid);
     virtual ~ProCamera2Client();
 
-    virtual status_t      initialize(camera_module_t *module);
+    virtual status_t      initialize(CameraModule *module);
 
     virtual status_t      dump(int fd, const Vector<String16>& args);
 
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 453c8bd..0415d67 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -78,7 +78,7 @@
 }
 
 template <typename TClientBase>
-status_t Camera2ClientBase<TClientBase>::initialize(camera_module_t *module) {
+status_t Camera2ClientBase<TClientBase>::initialize(CameraModule *module) {
     ATRACE_CALL();
     ALOGV("%s: Initializing client for camera %d", __FUNCTION__,
           TClientBase::mCameraId);
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index e09c1b5..eb21d55 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -18,6 +18,7 @@
 #define ANDROID_SERVERS_CAMERA_CAMERA2CLIENT_BASE_H
 
 #include "common/CameraDeviceBase.h"
+#include "common/CameraModule.h"
 #include "camera/CaptureResult.h"
 
 namespace android {
@@ -55,7 +56,7 @@
                       int servicePid);
     virtual ~Camera2ClientBase();
 
-    virtual status_t      initialize(camera_module_t *module);
+    virtual status_t      initialize(CameraModule *module);
     virtual status_t      dump(int fd, const Vector<String16>& args);
 
     /**
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index d26e20c..06615f6 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -29,6 +29,7 @@
 #include "hardware/camera3.h"
 #include "camera/CameraMetadata.h"
 #include "camera/CaptureResult.h"
+#include "common/CameraModule.h"
 
 namespace android {
 
@@ -45,7 +46,7 @@
      */
     virtual int      getId() const = 0;
 
-    virtual status_t initialize(camera_module_t *module) = 0;
+    virtual status_t initialize(CameraModule *module) = 0;
     virtual status_t disconnect() = 0;
 
     virtual status_t dump(int fd, const Vector<String16> &args) = 0;
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
new file mode 100644
index 0000000..bbf47e8
--- /dev/null
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CameraModule"
+//#define LOG_NDEBUG 0
+
+#include "CameraModule.h"
+
+namespace android {
+
+void CameraModule::deriveCameraCharacteristicsKeys(
+        uint32_t deviceVersion, CameraMetadata &chars) {
+    // HAL1 devices should not reach here
+    if (deviceVersion < CAMERA_DEVICE_API_VERSION_2_0) {
+        ALOGV("%s: Cannot derive keys for HAL version < 2.0");
+        return;
+    }
+
+    // Keys added in HAL3.3
+    if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
+        Vector<uint8_t> controlModes;
+        uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
+        chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1);
+        data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
+        chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/1);
+        controlModes.push(ANDROID_CONTROL_MODE_OFF);
+        controlModes.push(ANDROID_CONTROL_MODE_AUTO);
+        camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
+        if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) {
+            controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE);
+        }
+        chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
+    }
+    return;
+}
+
+CameraModule::CameraModule(camera_module_t *module) {
+    if (module == NULL) {
+        ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
+        assert(0);
+    }
+
+    mModule = module;
+    for (int i = 0; i < MAX_CAMERAS_PER_MODULE; i++) {
+        mCameraInfoCached[i] = false;
+    }
+}
+
+int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) {
+    Mutex::Autolock lock(mCameraInfoLock);
+    if (cameraId < 0 || cameraId >= MAX_CAMERAS_PER_MODULE) {
+        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
+        return -EINVAL;
+    }
+
+    camera_info &wrappedInfo = mCameraInfo[cameraId];
+    if (!mCameraInfoCached[cameraId]) {
+        camera_info rawInfo;
+        int ret = mModule->get_camera_info(cameraId, &rawInfo);
+        if (ret != 0) {
+            return ret;
+        }
+        CameraMetadata &m = mCameraCharacteristics[cameraId];
+        m = rawInfo.static_camera_characteristics;
+        int deviceVersion;
+        int apiVersion = mModule->common.module_api_version;
+        if (apiVersion >= CAMERA_MODULE_API_VERSION_2_0) {
+            deviceVersion = rawInfo.device_version;
+        } else {
+            deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
+        }
+        deriveCameraCharacteristicsKeys(deviceVersion, m);
+        wrappedInfo = rawInfo;
+        wrappedInfo.static_camera_characteristics = m.getAndLock();
+        mCameraInfoCached[cameraId] = true;
+    }
+    *info = wrappedInfo;
+    return 0;
+}
+
+int CameraModule::open(const char* id, struct hw_device_t** device) {
+    return mModule->common.methods->open(&mModule->common, id, device);
+}
+
+int CameraModule::openLegacy(
+        const char* id, uint32_t halVersion, struct hw_device_t** device) {
+    return mModule->open_legacy(&mModule->common, id, halVersion, device);
+}
+
+const hw_module_t* CameraModule::getRawModule() {
+    return &mModule->common;
+}
+
+int CameraModule::getNumberOfCameras() {
+    return mModule->get_number_of_cameras();
+}
+
+int CameraModule::setCallbacks(const camera_module_callbacks_t *callbacks) {
+    return mModule->set_callbacks(callbacks);
+}
+
+bool CameraModule::isVendorTagDefined() {
+    return mModule->get_vendor_tag_ops != NULL;
+}
+
+void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) {
+    if (mModule->get_vendor_tag_ops) {
+        mModule->get_vendor_tag_ops(ops);
+    }
+}
+
+int CameraModule::setTorchMode(const char* camera_id, bool enable) {
+    return mModule->set_torch_mode(camera_id, enable);
+}
+
+}; // namespace android
+
diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h
new file mode 100644
index 0000000..31b9ae2
--- /dev/null
+++ b/services/camera/libcameraservice/common/CameraModule.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERAMODULE_H
+#define ANDROID_SERVERS_CAMERA_CAMERAMODULE_H
+
+#include <hardware/camera.h>
+#include <camera/CameraMetadata.h>
+#include <utils/Mutex.h>
+
+/* This needs to be increased if we can have more cameras */
+#define MAX_CAMERAS_PER_MODULE 2
+
+
+namespace android {
+/**
+ * A wrapper class for HAL camera module.
+ *
+ * This class wraps camera_module_t returned from HAL to provide a wrapped
+ * get_camera_info implementation which CameraService generates some
+ * camera characteristics keys defined in newer HAL version on an older HAL.
+ */
+class CameraModule {
+public:
+    CameraModule(camera_module_t *module);
+
+    const hw_module_t* getRawModule();
+    int getCameraInfo(int cameraId, struct camera_info *info);
+    int getNumberOfCameras(void);
+    int open(const char* id, struct hw_device_t** device);
+    int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device);
+    int setCallbacks(const camera_module_callbacks_t *callbacks);
+    bool isVendorTagDefined();
+    void getVendorTagOps(vendor_tag_ops_t* ops);
+    int setTorchMode(const char* camera_id, bool enable);
+
+private:
+    // Derive camera characteristics keys defined after HAL device version
+    static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
+    camera_module_t *mModule;
+    CameraMetadata mCameraCharacteristics[MAX_CAMERAS_PER_MODULE];
+    camera_info mCameraInfo[MAX_CAMERAS_PER_MODULE];
+    bool mCameraInfoCached[MAX_CAMERAS_PER_MODULE];
+    Mutex mCameraInfoLock;
+};
+
+} // namespace android
+
+#endif
+
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 1935c2b..9e1cdc9 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -89,24 +89,23 @@
         }
     }
 
-    status_t initialize(hw_module_t *module)
+    status_t initialize(CameraModule *module)
     {
         ALOGI("Opening camera %s", mName.string());
-        camera_module_t *cameraModule = reinterpret_cast<camera_module_t *>(module);
         camera_info info;
-        status_t res = cameraModule->get_camera_info(atoi(mName.string()), &info);
+        status_t res = module->getCameraInfo(atoi(mName.string()), &info);
         if (res != OK) return res;
 
         int rc = OK;
-        if (module->module_api_version >= CAMERA_MODULE_API_VERSION_2_3 &&
+        if (module->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_3 &&
             info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
             // Open higher version camera device as HAL1.0 device.
-            rc = cameraModule->open_legacy(module, mName.string(),
-                                               CAMERA_DEVICE_API_VERSION_1_0,
-                                               (hw_device_t **)&mDevice);
+            rc = module->openLegacy(mName.string(),
+                                     CAMERA_DEVICE_API_VERSION_1_0,
+                                     (hw_device_t **)&mDevice);
         } else {
-            rc = CameraService::filterOpenErrorCode(module->methods->open(
-                module, mName.string(), (hw_device_t **)&mDevice));
+            rc = CameraService::filterOpenErrorCode(module->open(
+                    mName.string(), (hw_device_t **)&mDevice));
         }
         if (rc != OK) {
             ALOGE("Could not open camera %s: %d", mName.string(), rc);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index d1158d6..be66c4d 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -53,7 +53,7 @@
     return mId;
 }
 
-status_t Camera2Device::initialize(camera_module_t *module)
+status_t Camera2Device::initialize(CameraModule *module)
 {
     ATRACE_CALL();
     ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
@@ -68,8 +68,8 @@
 
     camera2_device_t *device;
 
-    res = CameraService::filterOpenErrorCode(module->common.methods->open(
-        &module->common, name, reinterpret_cast<hw_device_t**>(&device)));
+    res = CameraService::filterOpenErrorCode(module->open(
+            name, reinterpret_cast<hw_device_t**>(&device)));
 
     if (res != OK) {
         ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
@@ -87,7 +87,7 @@
     }
 
     camera_info info;
-    res = module->get_camera_info(mId, &info);
+    res = module->getCameraInfo(mId, &info);
     if (res != OK ) return res;
 
     if (info.device_version != device->common.version) {
diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h
index 4def8ae..1cc5482 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.h
+++ b/services/camera/libcameraservice/device2/Camera2Device.h
@@ -43,7 +43,7 @@
      * CameraDevice interface
      */
     virtual int      getId() const;
-    virtual status_t initialize(camera_module_t *module);
+    virtual status_t initialize(CameraModule *module);
     virtual status_t disconnect();
     virtual status_t dump(int fd, const Vector<String16>& args);
     virtual const CameraMetadata& info() const;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 53e6fa9..9a4e5ac 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -86,7 +86,7 @@
  * CameraDeviceBase interface
  */
 
-status_t Camera3Device::initialize(camera_module_t *module)
+status_t Camera3Device::initialize(CameraModule *module)
 {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
@@ -106,9 +106,8 @@
     camera3_device_t *device;
 
     ATRACE_BEGIN("camera3->open");
-    res = CameraService::filterOpenErrorCode(module->common.methods->open(
-        &module->common, deviceName.string(),
-        reinterpret_cast<hw_device_t**>(&device)));
+    res = CameraService::filterOpenErrorCode(module->open(
+            deviceName.string(), reinterpret_cast<hw_device_t**>(&device)));
     ATRACE_END();
 
     if (res != OK) {
@@ -127,7 +126,7 @@
     }
 
     camera_info info;
-    res = CameraService::filterGetInfoErrorCode(module->get_camera_info(
+    res = CameraService::filterGetInfoErrorCode(module->getCameraInfo(
         mId, &info));
     if (res != OK) return res;
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index ec8dc10..de10cfe 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -73,7 +73,7 @@
     virtual int      getId() const;
 
     // Transitions to idle state on success.
-    virtual status_t initialize(camera_module_t *module);
+    virtual status_t initialize(CameraModule *module);
     virtual status_t disconnect();
     virtual status_t dump(int fd, const Vector<String16> &args);
     virtual const CameraMetadata& info() const;