Pass camera frame metadata from camera service to Java.

bug:4460717
Change-Id: I2fae6e1dfca6b8f3a5ee5716fc7817f5417bf657
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 3c00db5..7ac3cc1 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -360,7 +360,8 @@
 }
 
 // callback from camera service when frame or image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
+void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+                          camera_frame_metadata_t *metadata)
 {
     sp<CameraListener> listener;
     {
@@ -368,7 +369,7 @@
         listener = mListener;
     }
     if (listener != NULL) {
-        listener->postData(msgType, dataPtr);
+        listener->postData(msgType, dataPtr, metadata);
     }
 }
 
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index cb3bd0c..183429a 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -51,13 +51,18 @@
     }
 
     // generic data callback from camera service to app with image data
-    void dataCallback(int32_t msgType, const sp<IMemory>& imageData)
+    void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
+                      camera_frame_metadata_t *metadata)
     {
         LOGV("dataCallback");
         Parcel data, reply;
         data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
         data.writeInt32(msgType);
         data.writeStrongBinder(imageData->asBinder());
+        if (metadata) {
+            data.writeInt32(metadata->number_of_faces);
+            data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces);
+        }
         remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -96,7 +101,15 @@
             CHECK_INTERFACE(ICameraClient, data, reply);
             int32_t msgType = data.readInt32();
             sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
-            dataCallback(msgType, imageData);
+            camera_frame_metadata_t *metadata = NULL;
+            if (data.dataAvail() > 0) {
+                metadata = new camera_frame_metadata_t;
+                metadata->number_of_faces = data.readInt32();
+                metadata->faces = (camera_face_t *) data.readInplace(
+                        sizeof(camera_face_t) * metadata->number_of_faces);
+            }
+            dataCallback(msgType, imageData, metadata);
+            if (metadata) delete metadata;
             return NO_ERROR;
         } break;
         case DATA_CALLBACK_TIMESTAMP: {
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index f701280..234e165 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -59,7 +59,8 @@
 {
 public:
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
-    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+                          camera_frame_metadata_t *metadata) = 0;
     virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
 };
 
@@ -138,7 +139,8 @@
 
     // ICameraClient interface
     virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
-    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
+    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+                                     camera_frame_metadata_t *metadata);
     virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
     sp<ICamera>         remote();
diff --git a/include/camera/ICameraClient.h b/include/camera/ICameraClient.h
index 236d0f6..b30aa7a 100644
--- a/include/camera/ICameraClient.h
+++ b/include/camera/ICameraClient.h
@@ -22,6 +22,7 @@
 #include <binder/Parcel.h>
 #include <binder/IMemory.h>
 #include <utils/Timers.h>
+#include <system/camera.h>
 
 namespace android {
 
@@ -31,7 +32,8 @@
     DECLARE_META_INTERFACE(CameraClient);
 
     virtual void            notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
-    virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
+    virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data,
+                                         camera_frame_metadata_t *metadata) = 0;
     virtual void            dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
 };
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index de66d99..ea8eaa4 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -37,7 +37,8 @@
     CameraSourceListener(const sp<CameraSource> &source);
 
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
-    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr);
+    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
+                          camera_frame_metadata_t *metadata);
 
     virtual void postDataTimestamp(
             nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
@@ -63,7 +64,8 @@
     LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
 }
 
-void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) {
+void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
+                                    camera_frame_metadata_t *metadata) {
     LOGV("postData(%d, ptr:%p, size:%d)",
          msgType, dataPtr->pointer(), dataPtr->size());
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index def25d1..e193be0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -350,10 +350,9 @@
                             dataCallbackTimestamp,
                             (void *)cameraId);
 
-    // Enable zoom, error, and focus messages by default
-    enableMsgType(CAMERA_MSG_ERROR |
-                  CAMERA_MSG_ZOOM |
-                  CAMERA_MSG_FOCUS);
+    // Enable zoom, error, focus, and metadata messages by default
+    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
+                  CAMERA_MSG_PREVIEW_METADATA);
 
     // Callback is disabled by default
     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
@@ -995,15 +994,15 @@
     if (client == 0) return;
     if (!client->lockIfMessageWanted(msgType)) return;
 
-    if (dataPtr == 0) {
+    if (dataPtr == 0 && metadata == NULL) {
         LOGE("Null data returned in data callback");
         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
         return;
     }
 
-    switch (msgType) {
+    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
         case CAMERA_MSG_PREVIEW_FRAME:
-            client->handlePreviewData(dataPtr);
+            client->handlePreviewData(msgType, dataPtr, metadata);
             break;
         case CAMERA_MSG_POSTVIEW_FRAME:
             client->handlePostview(dataPtr);
@@ -1015,7 +1014,7 @@
             client->handleCompressedPicture(dataPtr);
             break;
         default:
-            client->handleGenericData(msgType, dataPtr);
+            client->handleGenericData(msgType, dataPtr, metadata);
             break;
     }
 }
@@ -1055,7 +1054,9 @@
 }
 
 // preview callback - frame buffer update
-void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
+void CameraService::Client::handlePreviewData(int32_t msgType,
+                                              const sp<IMemory>& mem,
+                                              camera_frame_metadata_t *metadata) {
     ssize_t offset;
     size_t size;
     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -1087,11 +1088,11 @@
         // Is the received frame copied out or not?
         if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
             LOG2("frame is copied");
-            copyFrameAndPostCopiedFrame(c, heap, offset, size);
+            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
         } else {
             LOG2("frame is forwarded");
             mLock.unlock();
-            c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+            c->dataCallback(msgType, mem, metadata);
         }
     } else {
         mLock.unlock();
@@ -1105,7 +1106,7 @@
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
     }
 }
 
@@ -1120,7 +1121,7 @@
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
     }
 }
 
@@ -1131,7 +1132,7 @@
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
     }
 }
 
@@ -1146,11 +1147,11 @@
 }
 
 void CameraService::Client::handleGenericData(int32_t msgType,
-    const sp<IMemory>& dataPtr) {
+    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(msgType, dataPtr);
+        c->dataCallback(msgType, dataPtr, metadata);
     }
 }
 
@@ -1164,8 +1165,9 @@
 }
 
 void CameraService::Client::copyFrameAndPostCopiedFrame(
-        const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap,
-        size_t offset, size_t size) {
+        int32_t msgType, const sp<ICameraClient>& client,
+        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
+        camera_frame_metadata_t *metadata) {
     LOG2("copyFrameAndPostCopiedFrame");
     // It is necessary to copy out of pmem before sending this to
     // the callback. For efficiency, reuse the same MemoryHeapBase
@@ -1197,7 +1199,7 @@
     }
 
     mLock.unlock();
-    client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+    client->dataCallback(msgType, frame, metadata);
 }
 
 int CameraService::Client::getOrientation(int degrees, bool mirror) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index af7f06e..57abf83 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -147,18 +147,22 @@
         static sp<Client>       getClientFromCookie(void* user);
         // handlers for messages
         void                    handleShutter(void);
-        void                    handlePreviewData(const sp<IMemory>& mem);
+        void                    handlePreviewData(int32_t msgType, const sp<IMemory>& mem,
+                                                  camera_frame_metadata_t *metadata);
         void                    handlePostview(const sp<IMemory>& mem);
         void                    handleRawPicture(const sp<IMemory>& mem);
         void                    handleCompressedPicture(const sp<IMemory>& mem);
         void                    handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
-        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
+        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr,
+                                                  camera_frame_metadata_t *metadata);
         void                    handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
         void                    copyFrameAndPostCopiedFrame(
+                                    int32_t msgType,
                                     const sp<ICameraClient>& client,
                                     const sp<IMemoryHeap>& heap,
-                                    size_t offset, size_t size);
+                                    size_t offset, size_t size,
+                                    camera_frame_metadata_t *metadata);
 
         int                     getOrientation(int orientation, bool mirror);