Change camera interface to support multiple cameras.

Change-Id: Ie88fe706d2278acf762eca87780de349434778a4
diff --git a/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
index a0d6ee1..87975af 100644
--- a/camera/libcameraservice/Android.mk
+++ b/camera/libcameraservice/Android.mk
@@ -7,15 +7,11 @@
   USE_CAMERA_STUB:=true
 endif
 
-ifeq ($(USE_CAMERA_STUB),true)
-  INCLUDE_CAMERA_STUB:=true
-  INCLUDE_CAMERA_HARDWARE:=false
-else
-  INCLUDE_CAMERA_STUB:=true  # set this to true temporarily for testing
-  INCLUDE_CAMERA_HARDWARE:=true
+ifeq ($(USE_CAMERA_STUB),)
+  USE_CAMERA_STUB:=false
 endif
 
-ifeq ($(INCLUDE_CAMERA_STUB),true)
+ifeq ($(USE_CAMERA_STUB),true)
 #
 # libcamerastub
 #
@@ -35,7 +31,7 @@
 LOCAL_SHARED_LIBRARIES:= libui
 
 include $(BUILD_STATIC_LIBRARY)
-endif # INCLUDE_CAMERA_STUB
+endif # USE_CAMERA_STUB
 
 #
 # libcameraservice
@@ -61,13 +57,9 @@
 LOCAL_CFLAGS += -DSINGLE_PROCESS
 endif
 
-ifeq ($(INCLUDE_CAMERA_STUB), true)
+ifeq ($(USE_CAMERA_STUB), true)
 LOCAL_STATIC_LIBRARIES += libcamerastub
-LOCAL_CFLAGS += -DINCLUDE_CAMERA_STUB
-endif
-
-ifeq ($(INCLUDE_CAMERA_HARDWARE),true)
-LOCAL_CFLAGS += -DINCLUDE_CAMERA_HARDWARE
+else
 LOCAL_SHARED_LIBRARIES += libcamera 
 endif
 
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp
index fda48e8..b3e0ee6 100644
--- a/camera/libcameraservice/CameraHardwareStub.cpp
+++ b/camera/libcameraservice/CameraHardwareStub.cpp
@@ -385,7 +385,24 @@
     return new CameraHardwareStub();
 }
 
-extern "C" sp<CameraHardwareInterface> openCameraHardwareStub()
+static CameraInfo sCameraInfo[] = {
+    {
+        CAMERA_FACING_BACK,
+        90,  /* orientation */
+    }
+};
+
+extern "C" int HAL_getNumberOfCameras()
+{
+    return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
+}
+
+extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
+{
+    memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
+}
+
+extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
 {
     return CameraHardwareStub::createInstance();
 }
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
index d194f3c..d3427ba 100644
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ b/camera/libcameraservice/CameraHardwareStub.h
@@ -128,8 +128,6 @@
     int                 mCurrentPreviewFrame;
 };
 
-extern "C" sp<CameraHardwareInterface> openCameraHardwareStub();
-
 }; // namespace android
 
 #endif
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 690169a..75948a5 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -37,37 +37,9 @@
 #include <utils/String16.h>
 
 #include "CameraService.h"
-#ifdef INCLUDE_CAMERA_STUB
-#include "CameraHardwareStub.h"
-#endif
 
 namespace android {
 
-/* This determines the number of cameras available */
-#if defined(INCLUDE_CAMERA_HARDWARE) && defined(INCLUDE_CAMERA_STUB)
-  #define NUM_CAMERAS 2
-#elif defined(INCLUDE_CAMERA_HARDWARE) || defined(INCLUDE_CAMERA_STUB)
-  #define NUM_CAMERAS 1
-#else
-  #error "Should have at least one camera"
-#endif
-
-/* Make sure we have enough array space allocated */
-#if NUM_CAMERAS > MAX_CAMERAS
-  #error "Need to increase MAX_CAMERAS"
-#endif
-
-/* This defines the "open" function for each camera */
-extern "C" typedef sp<CameraHardwareInterface> (*OpenCameraHardwareFunction)();
-static OpenCameraHardwareFunction sOpenCameraTable[] = {
-#ifdef INCLUDE_CAMERA_HARDWARE
-    &openCameraHardware,
-#endif
-#ifdef INCLUDE_CAMERA_STUB
-    &openCameraHardwareStub,
-#endif
-};
-
 // ----------------------------------------------------------------------------
 // Logging support -- this is for debugging only
 // Use "adb shell dumpsys media.camera -v 1" to change it.
@@ -101,7 +73,14 @@
 {
     LOGI("CameraService started (pid=%d)", getpid());
 
-    for (int i = 0; i < NUM_CAMERAS; i++) {
+    mNumberOfCameras = HAL_getNumberOfCameras();
+    if (mNumberOfCameras > MAX_CAMERAS) {
+        LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
+             mNumberOfCameras, MAX_CAMERAS);
+        mNumberOfCameras = MAX_CAMERAS;
+    }
+
+    for (int i = 0; i < mNumberOfCameras; i++) {
         setCameraFree(i);
     }
 
@@ -109,7 +88,7 @@
 }
 
 CameraService::~CameraService() {
-    for (int i = 0; i < NUM_CAMERAS; i++) {
+    for (int i = 0; i < mNumberOfCameras; i++) {
         if (mBusy[i]) {
             LOGE("camera %d is still in use in destructor!", i);
         }
@@ -119,7 +98,17 @@
 }
 
 int32_t CameraService::getNumberOfCameras() {
-    return NUM_CAMERAS;
+    return mNumberOfCameras;
+}
+
+status_t CameraService::getCameraInfo(int cameraId,
+                                      struct CameraInfo* cameraInfo) {
+    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
+        return BAD_VALUE;
+    }
+
+    HAL_getCameraInfo(cameraId, cameraInfo);
+    return OK;
 }
 
 sp<ICamera> CameraService::connect(
@@ -128,7 +117,7 @@
     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
 
     sp<Client> client;
-    if (cameraId < 0 || cameraId >= NUM_CAMERAS) {
+    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
         LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
             callingPid, cameraId);
         return NULL;
@@ -167,7 +156,7 @@
     int callingPid = getCallingPid();
     LOG1("CameraService::removeClient E (pid %d)", callingPid);
 
-    for (int i = 0; i < NUM_CAMERAS; i++) {
+    for (int i = 0; i < mNumberOfCameras; i++) {
         // Declare this before the lock to make absolutely sure the
         // destructor won't be called with the lock held.
         sp<Client> client;
@@ -199,7 +188,7 @@
 }
 
 sp<CameraService::Client> CameraService::getClientById(int cameraId) {
-    if (cameraId < 0 || cameraId >= NUM_CAMERAS) return NULL;
+    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
     return mClient[cameraId].promote();
 }
 
@@ -311,7 +300,7 @@
     mCameraId = cameraId;
     mClientPid = clientPid;
 
-    mHardware = sOpenCameraTable[cameraId]();
+    mHardware = HAL_openCameraHardware(cameraId);
     mUseOverlay = mHardware->useOverlay();
     mMsgEnabled = 0;
 
@@ -1246,7 +1235,7 @@
         }
 
         bool hasClient = false;
-        for (int i = 0; i < NUM_CAMERAS; i++) {
+        for (int i = 0; i < mNumberOfCameras; i++) {
             sp<Client> client = mClient[i].promote();
             if (client == 0) continue;
             hasClient = true;
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 86986ca..8193e77 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -40,6 +40,8 @@
     virtual             ~CameraService();
 
     virtual int32_t     getNumberOfCameras();
+    virtual status_t    getCameraInfo(int cameraId,
+                                      struct CameraInfo* cameraInfo);
     virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId);
     virtual void        removeClient(const sp<ICameraClient>& cameraClient);
     virtual sp<Client>  getClientById(int cameraId);
@@ -61,6 +63,7 @@
 private:
     Mutex               mServiceLock;
     wp<Client>          mClient[MAX_CAMERAS];  // protected by mServiceLock
+    int                 mNumberOfCameras;
 
     // atomics to record whether the hardware is allocated to some client.
     volatile int32_t    mBusy[MAX_CAMERAS];