Camera2: Copy metadata buffers for streaming.

Using the passed-in buffer directly is incorrect; copy them so that
concurrent access can be controlled, and ownership is clear.

Bug: 6243944
Change-Id: Iad22c0dc166b7739e6c5dbfa39aac631b974c95a
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 6a1e9ea..b81d54c 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -302,6 +302,12 @@
         mStreamSlotCount = 0;
         return OK;
     }
+    camera_metadata_t *buf2 = clone_camera_metadata(buf);
+    if (!buf2) {
+        ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
+        return NO_MEMORY;
+    }
+
     if (mStreamSlotCount > 1) {
         List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
         freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
@@ -309,9 +315,9 @@
     }
     if (mStreamSlotCount == 1) {
         free_camera_metadata( *(mStreamSlot.begin()) );
-        *(mStreamSlot.begin()) = buf;
+        *(mStreamSlot.begin()) = buf2;
     } else {
-        mStreamSlot.push_front(buf);
+        mStreamSlot.push_front(buf2);
         mStreamSlotCount = 1;
     }
     return signalConsumerLocked();
@@ -322,11 +328,22 @@
 {
     ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock l(mMutex);
+    status_t res;
+
     if (mStreamSlotCount > 0) {
         freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
     }
-    mStreamSlot = bufs;
-    mStreamSlotCount = mStreamSlot.size();
+    mStreamSlotCount = 0;
+    for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
+         r != bufs.end(); r++) {
+        camera_metadata_t *r2 = clone_camera_metadata(*r);
+        if (!r2) {
+            ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
+            return NO_MEMORY;
+        }
+        mStreamSlot.push_back(r2);
+        mStreamSlotCount++;
+    }
     return signalConsumerLocked();
 }
 
diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h
index e8a68d3..2da3ade 100644
--- a/services/camera/libcameraservice/Camera2Device.h
+++ b/services/camera/libcameraservice/Camera2Device.h
@@ -87,7 +87,8 @@
 
         // Set repeating buffer(s); if the queue is empty on a dequeue call, the
         // queue copies the contents of the stream slot into the queue, and then
-        // dequeues the first new entry.
+        // dequeues the first new entry. The metadata buffers passed in are
+        // copied.
         status_t setStreamSlot(camera_metadata_t *buf);
         status_t setStreamSlot(const List<camera_metadata_t*> &bufs);