Camera: Fix passing video native handle for 64-bit app

Add new binder calls to pass video native handle so the video native
handle can be passed between 32-bit and 64-bit processes.

Remove problematic code that used IMemory to pass video native
handle because the sizes of VideoNativeMetadata are different in
32-bit and 64-bit processes.

Bug: 28403412
Change-Id: I3341b1812ecc41d61846bb72ca926ecb1674c9ec
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index d2fedf8..266fb03 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -19,6 +19,7 @@
 
 #include <cutils/properties.h>
 #include <gui/Surface.h>
+#include <media/hardware/HardwareAPI.h>
 
 #include "api1/CameraClient.h"
 #include "device1/CameraHardwareInterface.h"
@@ -488,6 +489,39 @@
     mHardware->releaseRecordingFrame(mem);
 }
 
+void CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
+    if (handle == nullptr) return;
+
+    sp<IMemory> dataPtr;
+    {
+        Mutex::Autolock l(mAvailableCallbackBuffersLock);
+        if (!mAvailableCallbackBuffers.empty()) {
+            dataPtr = mAvailableCallbackBuffers.back();
+            mAvailableCallbackBuffers.pop_back();
+        }
+    }
+
+    if (dataPtr == nullptr) {
+        ALOGE("%s: %d: No callback buffer available. Dropping a native handle.", __FUNCTION__,
+                __LINE__);
+        native_handle_close(handle);
+        native_handle_delete(handle);
+        return;
+    } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
+        ALOGE("%s: %d: Callback buffer size doesn't match VideoNativeHandleMetadata", __FUNCTION__,
+                __LINE__);
+        native_handle_close(handle);
+        native_handle_delete(handle);
+        return;
+    }
+
+    VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
+    metadata->eType = kMetadataBufferTypeNativeHandleSource;
+    metadata->pHandle = handle;
+
+    mHardware->releaseRecordingFrame(dataPtr);
+}
+
 status_t CameraClient::setVideoBufferMode(int32_t videoBufferMode) {
     LOG1("setVideoBufferMode: %d", videoBufferMode);
     bool enableMetadataInBuffers = false;
@@ -929,8 +963,28 @@
     int32_t msgType, const sp<IMemory>& dataPtr) {
     sp<hardware::ICameraClient> c = mRemoteCallback;
     mLock.unlock();
-    if (c != 0) {
-        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+    if (c != 0 && dataPtr != nullptr) {
+        native_handle_t* handle = nullptr;
+
+        // Check if dataPtr contains a VideoNativeHandleMetadata.
+        if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) {
+            VideoNativeHandleMetadata *metadata =
+                (VideoNativeHandleMetadata*)(dataPtr->pointer());
+            if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
+                handle = metadata->pHandle;
+            }
+        }
+
+        // If dataPtr contains a native handle, send it via recordingFrameHandleCallbackTimestamp.
+        if (handle != nullptr) {
+            {
+                Mutex::Autolock l(mAvailableCallbackBuffersLock);
+                mAvailableCallbackBuffers.push_back(dataPtr);
+            }
+            c->recordingFrameHandleCallbackTimestamp(timestamp, handle);
+        } else {
+            c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+        }
     }
 }