ProCamera: Add getInfo for getting static metadata (and a test)

Change-Id: I3b87dfbc621d98bf41f37a892a1012baf85b5166
diff --git a/camera/IProCameraUser.cpp b/camera/IProCameraUser.cpp
index e60cfe5..c9d98aa 100644
--- a/camera/IProCameraUser.cpp
+++ b/camera/IProCameraUser.cpp
@@ -44,6 +44,7 @@
     CANCEL_STREAM,
     CREATE_STREAM,
     CREATE_DEFAULT_REQUEST,
+    GET_CAMERA_INFO,
 };
 
 /**
@@ -255,6 +256,17 @@
     }
 
 
+    virtual status_t getCameraInfo(int cameraId, camera_metadata** info)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
+        data.writeInt32(cameraId);
+        remote()->transact(GET_CAMERA_INFO, data, &reply);
+        readMetadata(reply, /*out*/info);
+        return reply.readInt32();
+    }
+
+
 private:
 
 
@@ -367,6 +379,24 @@
             writeMetadata(*reply, request);
             reply->writeInt32(ret);
 
+            free_camera_metadata(request);
+
+            return NO_ERROR;
+        } break;
+        case GET_CAMERA_INFO: {
+            CHECK_INTERFACE(IProCameraUser, data, reply);
+
+            int cameraId = data.readInt32();
+
+            camera_metadata_t* info = NULL;
+            status_t ret;
+            ret = getCameraInfo(cameraId, &info);
+
+            writeMetadata(*reply, info);
+            reply->writeInt32(ret);
+
+            free_camera_metadata(info);
+
             return NO_ERROR;
         } break;
         default:
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp
index 142c03b..c95c4e0 100644
--- a/camera/ProCamera.cpp
+++ b/camera/ProCamera.cpp
@@ -361,15 +361,28 @@
 }
 
 int ProCamera::getNumberOfCameras() {
-    ALOGE("%s: not implemented yet", __FUNCTION__);
-    return 1;
+    const sp<ICameraService> cs = getCameraService();
+
+    if (!cs.get()) {
+        return DEAD_OBJECT;
+    }
+    return cs->getNumberOfCameras();
 }
 
 camera_metadata* ProCamera::getCameraInfo(int cameraId) {
-    ALOGE("%s: not implemented yet", __FUNCTION__);
-
     ALOGV("%s: cameraId = %d", __FUNCTION__, cameraId);
-    return NULL;
+
+    sp <IProCameraUser> c = mCamera;
+    if (c == 0) return NULL;
+
+    camera_metadata* ptr = NULL;
+    status_t status = c->getCameraInfo(cameraId, &ptr);
+
+    if (status != OK) {
+        ALOGE("%s: Failed to get camera info, error = %d", __FUNCTION__, status);
+    }
+
+    return ptr;
 }
 
 status_t ProCamera::createDefaultRequest(int templateId,
diff --git a/camera/tests/ProCameraTests.cpp b/camera/tests/ProCameraTests.cpp
index 021fbae..69b7f3c 100644
--- a/camera/tests/ProCameraTests.cpp
+++ b/camera/tests/ProCameraTests.cpp
@@ -324,10 +324,40 @@
         ASSERT_NE((void*)NULL, surface.get());
     }
 
+    template <typename T>
+    static bool FindItem(T needle, T* array, size_t count) {
+        for (int i = 0; i < count; ++i) {
+            if (array[i] == needle) {
+                return true;
+            }
+        }
+        return false;
+    }
+
 };
 
 sp<Thread> ProCameraTest::mTestThread;
 
+TEST_F(ProCameraTest, AvailableFormats) {
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    camera_metadata_t* info = mCamera->getCameraInfo(CAMERA_ID);
+    ASSERT_NE((void*)NULL, info);
+
+    camera_metadata_entry_t entry;
+    uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
+    EXPECT_EQ(OK, find_camera_metadata_entry(info, tag, &entry));
+
+    EXPECT_TRUE(FindItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
+                                                  entry.data.i32, entry.count));
+    EXPECT_TRUE(FindItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
+                                                  entry.data.i32, entry.count));
+
+    free_camera_metadata(info);
+}
+
 // test around exclusiveTryLock (immediate locking)
 TEST_F(ProCameraTest, LockingImmediate) {
 
diff --git a/include/camera/IProCameraUser.h b/include/camera/IProCameraUser.h
index a141769..7bddb0c 100644
--- a/include/camera/IProCameraUser.h
+++ b/include/camera/IProCameraUser.h
@@ -75,6 +75,11 @@
                                                  camera_metadata** request)
                                                                            = 0;
 
+    // Get static camera metadata
+    virtual status_t        getCameraInfo(int cameraId,
+                                          /*out*/
+                                          camera_metadata** info) = 0;
+
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h
index 7cd9138..11904f9 100644
--- a/include/camera/ProCamera.h
+++ b/include/camera/ProCamera.h
@@ -172,7 +172,7 @@
     static int getNumberOfCameras();
 
     // Get static camera metadata
-    static camera_metadata* getCameraInfo(int cameraId);
+    camera_metadata* getCameraInfo(int cameraId);
 
     sp<IProCameraUser>         remote();
 
diff --git a/services/camera/libcameraservice/ProCamera2Client.cpp b/services/camera/libcameraservice/ProCamera2Client.cpp
index 7611796..c264e2a 100644
--- a/services/camera/libcameraservice/ProCamera2Client.cpp
+++ b/services/camera/libcameraservice/ProCamera2Client.cpp
@@ -309,6 +309,20 @@
     return res;
 }
 
+status_t ProCamera2Client::getCameraInfo(int cameraId,
+                                         /*out*/
+                                         camera_metadata** info)
+{
+    if (cameraId != mCameraId) {
+        return INVALID_OPERATION;
+    }
+
+    CameraMetadata deviceInfo = mDevice->info();
+    *info = deviceInfo.release();
+
+    return OK;
+}
+
 status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) {
     String8 result;
     result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n",
diff --git a/services/camera/libcameraservice/ProCamera2Client.h b/services/camera/libcameraservice/ProCamera2Client.h
index dfea1e1..cd0a2ae 100644
--- a/services/camera/libcameraservice/ProCamera2Client.h
+++ b/services/camera/libcameraservice/ProCamera2Client.h
@@ -65,6 +65,11 @@
                                                /*out*/
                                                camera_metadata** request);
 
+    // Get the static metadata for the camera
+    // -- Caller owns the newly allocated metadata
+    virtual status_t      getCameraInfo(int cameraId,
+                                        /*out*/
+                                        camera_metadata** info);
 
     /**
      * Interface used by CameraService