Merge "Add comments"
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp
index fec5461..190402e 100644
--- a/camera/ProCamera.cpp
+++ b/camera/ProCamera.cpp
@@ -247,7 +247,8 @@
     sp <IProCameraUser> c = mCamera;
     if (c == 0) return NO_INIT;
 
-    sp<CpuConsumer> cc = new CpuConsumer(heapCount, synchronousMode);
+    sp<BufferQueue> bq = new BufferQueue();
+    sp<CpuConsumer> cc = new CpuConsumer(bq, heapCount, synchronousMode);
     cc->setName(String8("ProCamera::mCpuConsumer"));
 
     sp<Surface> stc = new Surface(
diff --git a/camera/photography/ICameraDeviceUser.cpp b/camera/photography/ICameraDeviceUser.cpp
index 0515bd7..325f94d 100644
--- a/camera/photography/ICameraDeviceUser.cpp
+++ b/camera/photography/ICameraDeviceUser.cpp
@@ -151,21 +151,22 @@
     }
 
 
-    virtual status_t getCameraInfo(int cameraId, camera_metadata** info)
+    virtual status_t getCameraInfo(CameraMetadata* info)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
-        data.writeInt32(cameraId);
         remote()->transact(GET_CAMERA_INFO, data, &reply);
 
-
         reply.readExceptionCode();
         status_t result = reply.readInt32();
 
+        CameraMetadata out;
         if (reply.readInt32() != 0) {
-            CameraMetadata::readFromParcel(reply, /*out*/info);
-        } else if (info) {
-            *info = NULL;
+            out.readFromParcel(&reply);
+        }
+
+        if (info != NULL) {
+            info->swap(out);
         }
 
         return result;
@@ -273,6 +274,7 @@
             reply->writeNoException();
             reply->writeInt32(ret);
 
+            // out-variables are after exception and return value
             reply->writeInt32(1); // to mark presence of metadata object
             request.writeToParcel(const_cast<Parcel*>(reply));
 
@@ -281,19 +283,16 @@
         case GET_CAMERA_INFO: {
             CHECK_INTERFACE(ICameraDeviceUser, data, reply);
 
-            int cameraId = data.readInt32();
-
-            camera_metadata_t* info = NULL;
+            CameraMetadata info;
             status_t ret;
-            ret = getCameraInfo(cameraId, &info);
-
-            reply->writeInt32(1); // to mark presence of metadata object
-            CameraMetadata::writeToParcel(*reply, info);
+            ret = getCameraInfo(&info);
 
             reply->writeNoException();
             reply->writeInt32(ret);
 
-            free_camera_metadata(info);
+            // out-variables are after exception and return value
+            reply->writeInt32(1); // to mark presence of metadata object
+            info.writeToParcel(reply);
 
             return NO_ERROR;
         } break;
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index f8fc8ed..529b96c 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -937,7 +937,8 @@
         } else {
             CHECK(useSurfaceTexAlloc);
 
-            sp<GLConsumer> texture = new GLConsumer(0 /* tex */);
+            sp<BufferQueue> bq = new BufferQueue();
+            sp<GLConsumer> texture = new GLConsumer(bq, 0 /* tex */);
             gSurface = new Surface(texture->getBufferQueue());
         }
 
diff --git a/include/camera/photography/ICameraDeviceUser.h b/include/camera/photography/ICameraDeviceUser.h
index 1b8d666..3ea49f4 100644
--- a/include/camera/photography/ICameraDeviceUser.h
+++ b/include/camera/photography/ICameraDeviceUser.h
@@ -58,9 +58,8 @@
                                                  /*out*/
                                                  CameraMetadata* request) = 0;
     // Get static camera metadata
-    virtual status_t        getCameraInfo(int cameraId,
-                                          /*out*/
-                                          camera_metadata** info) = 0;
+    virtual status_t        getCameraInfo(/*out*/
+                                          CameraMetadata* info) = 0;
 
 };
 
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index b41684a..0592683 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -168,6 +168,7 @@
     const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
     const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
     bool            mIsShutdown;        // latch set to true when shared memory corruption detected
+    size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
 };
 
 // ----------------------------------------------------------------------------
@@ -213,7 +214,7 @@
     //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
     //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
     //  NO_INIT     Shared memory is corrupt.
-    //  BAD_VALUE   On entry buffer == NULL or buffer->mFrameCount == 0.
+    // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
     status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
             struct timespec *elapsed = NULL);
 
@@ -372,7 +373,6 @@
     virtual void        releaseBuffer(Buffer* buffer);
 
 protected:
-    size_t      mUnreleased;    // unreleased frames remaining from most recent obtainBuffer()
     size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
 private:
     int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
diff --git a/libvideoeditor/lvpp/NativeWindowRenderer.cpp b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
index 702900b..84a8e15 100755
--- a/libvideoeditor/lvpp/NativeWindowRenderer.cpp
+++ b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
@@ -568,7 +568,8 @@
 RenderInput::RenderInput(NativeWindowRenderer* renderer, GLuint textureId)
     : mRenderer(renderer)
     , mTextureId(textureId) {
-    mST = new GLConsumer(mTextureId);
+    sp<BufferQueue> bq = new BufferQueue();
+    mST = new GLConsumer(bq, mTextureId);
     mSTC = new Surface(mST->getBufferQueue());
     native_window_connect(mSTC.get(), NATIVE_WINDOW_API_MEDIA);
 }
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 7ceffd3..6b9b3be 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -454,7 +454,7 @@
         } break;
     case OUTPUT_CLOSED: {
         if (gOutputs.indexOfKey(ioHandle) < 0) {
-            ALOGW("ioConfigChanged() closing unknow output! %d", ioHandle);
+            ALOGW("ioConfigChanged() closing unknown output! %d", ioHandle);
             break;
         }
         ALOGV("ioConfigChanged() output %d closed", ioHandle);
@@ -465,7 +465,7 @@
     case OUTPUT_CONFIG_CHANGED: {
         int index = gOutputs.indexOfKey(ioHandle);
         if (index < 0) {
-            ALOGW("ioConfigChanged() modifying unknow output! %d", ioHandle);
+            ALOGW("ioConfigChanged() modifying unknown output! %d", ioHandle);
             break;
         }
         if (param2 == NULL) break;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 3f4cbc2..7b6b38d 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1245,7 +1245,8 @@
         if (tryCounter < 0) {
             ALOGE("did not receive expected priority boost on time");
         }
-        return true;
+        // Run again immediately
+        return 0;
     }
 
     // Can only reference mCblk while locked
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 5f8f292..55bf175 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -38,7 +38,7 @@
         bool isOut, bool clientInServer)
     : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize),
       mFrameCountP2(roundup(frameCount)), mIsOut(isOut), mClientInServer(clientInServer),
-      mIsShutdown(false)
+      mIsShutdown(false), mUnreleased(0)
 {
 }
 
@@ -64,10 +64,7 @@
 status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *requested,
         struct timespec *elapsed)
 {
-    if (buffer == NULL || buffer->mFrameCount == 0) {
-        ALOGE("%s BAD_VALUE", __func__);
-        return BAD_VALUE;
-    }
+    LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0);
     struct timespec total;          // total elapsed time spent waiting
     total.tv_sec = 0;
     total.tv_nsec = 0;
@@ -164,7 +161,7 @@
             buffer->mRaw = part1 > 0 ?
                     &((char *) mBuffers)[(mIsOut ? rear : front) * mFrameSize] : NULL;
             buffer->mNonContig = avail - part1;
-            // mUnreleased = part1;
+            mUnreleased = part1;
             status = NO_ERROR;
             break;
         }
@@ -238,6 +235,7 @@
             case -EWOULDBLOCK:  // benign race condition with server
             case -EINTR:        // wait was interrupted by signal or other spurious wakeup
             case -ETIMEDOUT:    // time-out expired
+                // FIXME these error/non-0 status are being dropped
                 break;
             default:
                 ALOGE("%s unexpected error %d", __func__, ret);
@@ -252,6 +250,7 @@
         buffer->mFrameCount = 0;
         buffer->mRaw = NULL;
         buffer->mNonContig = 0;
+        mUnreleased = 0;
     }
     if (elapsed != NULL) {
         *elapsed = total;
@@ -268,14 +267,17 @@
 
 void ClientProxy::releaseBuffer(Buffer* buffer)
 {
+    LOG_ALWAYS_FATAL_IF(buffer == NULL);
     size_t stepCount = buffer->mFrameCount;
-    // FIXME
-    //  check mUnreleased
-    //  verify that stepCount <= frameCount returned by the last obtainBuffer()
-    //  verify stepCount not > total frame count of pipe
-    if (stepCount == 0) {
+    if (stepCount == 0 || mIsShutdown) {
+        // prevent accidental re-use of buffer
+        buffer->mFrameCount = 0;
+        buffer->mRaw = NULL;
+        buffer->mNonContig = 0;
         return;
     }
+    LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount));
+    mUnreleased -= stepCount;
     audio_track_cblk_t* cblk = mCblk;
     // Both of these barriers are required
     if (mIsOut) {
@@ -362,20 +364,18 @@
 
 ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
         size_t frameSize, bool isOut, bool clientInServer)
-    : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mUnreleased(0),
+    : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
       mAvailToClient(0), mFlush(0), mDeferWake(false)
 {
 }
 
 status_t ServerProxy::obtainBuffer(Buffer* buffer)
 {
+    LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0);
     if (mIsShutdown) {
-        buffer->mFrameCount = 0;
-        buffer->mRaw = NULL;
-        buffer->mNonContig = 0;
-        mUnreleased = 0;
-        return NO_INIT;
+        goto no_init;
     }
+    {
     audio_track_cblk_t* cblk = mCblk;
     // compute number of frames available to write (AudioTrack) or read (AudioRecord),
     // or use previous cached value from framesReady(), with added barrier if it omits.
@@ -388,6 +388,8 @@
         if (flush != mFlush) {
             front = rear;
             mFlush = flush;
+            // effectively obtain then release whatever is in the buffer
+            android_atomic_release_store(rear, &cblk->u.mStreaming.mFront);
         } else {
             front = cblk->u.mStreaming.mFront;
         }
@@ -402,11 +404,7 @@
         mIsShutdown = true;
     }
     if (mIsShutdown) {
-        buffer->mFrameCount = 0;
-        buffer->mRaw = NULL;
-        buffer->mNonContig = 0;
-        mUnreleased = 0;
-        return NO_INIT;
+        goto no_init;
     }
     // don't allow filling pipe beyond the nominal size
     size_t availToServer;
@@ -443,23 +441,27 @@
     // FIXME need to test for recording
     mDeferWake = part1 < ask && availToServer >= ask;
     return part1 > 0 ? NO_ERROR : WOULD_BLOCK;
+    }
+no_init:
+    buffer->mFrameCount = 0;
+    buffer->mRaw = NULL;
+    buffer->mNonContig = 0;
+    mUnreleased = 0;
+    return NO_INIT;
 }
 
 void ServerProxy::releaseBuffer(Buffer* buffer)
 {
-    if (mIsShutdown) {
+    LOG_ALWAYS_FATAL_IF(buffer == NULL);
+    size_t stepCount = buffer->mFrameCount;
+    if (stepCount == 0 || mIsShutdown) {
+        // prevent accidental re-use of buffer
         buffer->mFrameCount = 0;
         buffer->mRaw = NULL;
         buffer->mNonContig = 0;
         return;
     }
-    size_t stepCount = buffer->mFrameCount;
-    LOG_ALWAYS_FATAL_IF(stepCount > mUnreleased);
-    if (stepCount == 0) {
-        buffer->mRaw = NULL;
-        buffer->mNonContig = 0;
-        return;
-    }
+    LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount));
     mUnreleased -= stepCount;
     audio_track_cblk_t* cblk = mCblk;
     if (mIsOut) {
@@ -637,8 +639,9 @@
 void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)
 {
     size_t stepCount = buffer->mFrameCount;
-    LOG_ALWAYS_FATAL_IF(stepCount > mUnreleased);
+    LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased));
     if (stepCount == 0) {
+        // prevent accidental re-use of buffer
         buffer->mRaw = NULL;
         buffer->mNonContig = 0;
         return;
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 71b6569..305e7e0 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -293,7 +293,7 @@
     // wait here till the frames come in from the client side
     while (mStarted) {
 
-        status_t err = mBufferQueue->acquireBuffer(&item);
+        status_t err = mBufferQueue->acquireBuffer(&item, 0);
         if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
             // wait for a buffer to be queued
             mFrameAvailableCondition.wait(mMutex);
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index b3a8463..b3167b5 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -251,7 +251,7 @@
     ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%d",
             mNumFramesAvailable);
     BufferQueue::BufferItem item;
-    status_t err = mBufferQueue->acquireBuffer(&item);
+    status_t err = mBufferQueue->acquireBuffer(&item, 0);
     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
         // shouldn't happen
         ALOGW("fillCodecBuffer_l: frame was not available");
@@ -422,7 +422,7 @@
         ALOGW("onFrameAvailable: EOS is set, ignoring frame");
 
         BufferQueue::BufferItem item;
-        status_t err = mBufferQueue->acquireBuffer(&item);
+        status_t err = mBufferQueue->acquireBuffer(&item, 0);
         if (err == OK) {
             mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 96bde90..203d7c0 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -600,6 +600,7 @@
         case Parameters::STOPPED:
         case Parameters::WAITING_FOR_PREVIEW_WINDOW:
         case Parameters::PREVIEW:
+        case Parameters::STILL_CAPTURE:
             // OK
             break;
         default:
diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
index aae2504..efbbe57 100644
--- a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
@@ -110,7 +110,8 @@
     if (!mCallbackToApp && mCallbackConsumer == 0) {
         // Create CPU buffer queue endpoint, since app hasn't given us one
         // Make it async to avoid disconnect deadlocks
-        mCallbackConsumer = new CpuConsumer(kCallbackHeapCount,
+        sp<BufferQueue> bq = new BufferQueue();
+        mCallbackConsumer = new CpuConsumer(bq, kCallbackHeapCount,
                 /*synchronized*/ false);
         mCallbackConsumer->setFrameAvailableListener(this);
         mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.cpp b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
index f0a13ca..1d739cd 100644
--- a/services/camera/libcameraservice/camera2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
@@ -82,7 +82,8 @@
 
     if (mCaptureConsumer == 0) {
         // Create CPU buffer queue endpoint
-        mCaptureConsumer = new CpuConsumer(1);
+        sp<BufferQueue> bq = new BufferQueue();
+        mCaptureConsumer = new CpuConsumer(bq, 1);
         mCaptureConsumer->setFrameAvailableListener(this);
         mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
         mCaptureWindow = new Surface(
diff --git a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp
index f7a6be7..76fa46c 100644
--- a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp
@@ -319,7 +319,8 @@
         // Create CPU buffer queue endpoint. We need one more buffer here so that we can
         // always acquire and free a buffer when the heap is full; otherwise the consumer
         // will have buffers in flight we'll never clear out.
-        mRecordingConsumer = new BufferItemConsumer(
+        sp<BufferQueue> bq = new BufferQueue();
+        mRecordingConsumer = new BufferItemConsumer(bq,
                 GRALLOC_USAGE_HW_VIDEO_ENCODER,
                 mRecordingHeapCount + 1,
                 true);
@@ -617,7 +618,7 @@
     if (client == 0) {
         // Discard frames during shutdown
         BufferItemConsumer::BufferItem imgBuffer;
-        res = mRecordingConsumer->acquireBuffer(&imgBuffer);
+        res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0);
         if (res != OK) {
             if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
                 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
@@ -635,7 +636,7 @@
         SharedParameters::Lock l(client->getParameters());
         Mutex::Autolock m(mMutex);
         BufferItemConsumer::BufferItem imgBuffer;
-        res = mRecordingConsumer->acquireBuffer(&imgBuffer);
+        res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0);
         if (res != OK) {
             if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
                 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
index 94059cd..3c575f6 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
@@ -128,7 +128,8 @@
 
     if (mZslConsumer == 0) {
         // Create CPU buffer queue endpoint
-        mZslConsumer = new BufferItemConsumer(
+        sp<BufferQueue> bq = new BufferQueue();
+        mZslConsumer = new BufferItemConsumer(bq,
             GRALLOC_USAGE_HW_CAMERA_ZSL,
             kZslBufferDepth,
             true);
@@ -426,7 +427,7 @@
     }
     ALOGVV("Trying to get next buffer");
     BufferItemConsumer::BufferItem item;
-    res = zslConsumer->acquireBuffer(&item);
+    res = zslConsumer->acquireBuffer(&item, 0);
     if (res != OK) {
         if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
             ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
diff --git a/services/camera/libcameraservice/camera3/Camera3InputStream.cpp b/services/camera/libcameraservice/camera3/Camera3InputStream.cpp
index 13e9c83..6d9acc3 100644
--- a/services/camera/libcameraservice/camera3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/camera3/Camera3InputStream.cpp
@@ -211,7 +211,8 @@
     mFrameCount = 0;
 
     if (mConsumer.get() == 0) {
-        mConsumer = new BufferItemConsumer(camera3_stream::usage,
+        sp<BufferQueue> bq = new BufferQueue();
+        mConsumer = new BufferItemConsumer(bq, camera3_stream::usage,
                                            mTotalBufferCount,
                                            /*synchronousMode*/true);
         mConsumer->setName(String8::format("Camera3-InputStream-%d", mId));
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index dfa1066..7625735 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -284,7 +284,7 @@
         /**
          * Acquire new frame
          */
-        err = acquireBufferLocked(&item);
+        err = acquireBufferLocked(&item, 0);
         if (err != OK) {
             if (err != NO_BUFFER_AVAILABLE) {
                 BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
diff --git a/services/camera/libcameraservice/photography/CameraDeviceClient.cpp b/services/camera/libcameraservice/photography/CameraDeviceClient.cpp
index bd6b60a..a6a2dc1 100644
--- a/services/camera/libcameraservice/photography/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/photography/CameraDeviceClient.cpp
@@ -391,28 +391,23 @@
     return res;
 }
 
-status_t CameraDeviceClient::getCameraInfo(int cameraId,
-                                         /*out*/
-                                         camera_metadata** info)
+status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
 {
     ATRACE_CALL();
     ALOGV("%s", __FUNCTION__);
 
     status_t res = OK;
 
-    // TODO: remove cameraId. this should be device-specific info, not static.
-    if (cameraId != mCameraId) {
-        return INVALID_OPERATION;
-    }
-
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
     Mutex::Autolock icl(mBinderSerializationLock);
 
     if (!mDevice.get()) return DEAD_OBJECT;
 
-    CameraMetadata deviceInfo = mDevice->info();
-    *info = deviceInfo.release();
+    if (info != NULL) {
+        *info = mDevice->info(); // static camera metadata
+        // TODO: merge with device-specific camera metadata
+    }
 
     return res;
 }
diff --git a/services/camera/libcameraservice/photography/CameraDeviceClient.h b/services/camera/libcameraservice/photography/CameraDeviceClient.h
index 806aa15..c6c241a 100644
--- a/services/camera/libcameraservice/photography/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/photography/CameraDeviceClient.h
@@ -85,9 +85,7 @@
 
     // Get the static metadata for the camera
     // -- Caller owns the newly allocated metadata
-    virtual status_t      getCameraInfo(int cameraId,
-                                        /*out*/
-                                        camera_metadata** info);
+    virtual status_t      getCameraInfo(/*out*/CameraMetadata* info);
 
     /**
      * Interface used by CameraService