Merge
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 36c5ada..b103861 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -158,6 +158,7 @@
     mCameraClient = cameraClient;
     mClientPid = clientPid;
     mHardware = openCameraHardware();
+    mUseOverlay = mHardware->useOverlay();
 
     // Callback is disabled by default
     mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
@@ -233,7 +234,7 @@
 {
     // tear down client
     LOGD("Client E destructor");
-    if (mSurface != 0) {
+    if (mSurface != 0 && !mUseOverlay) {
 #if HAVE_ANDROID_OS
         pthread_t thr;
         // We unregister the buffers in a different thread because binder does
@@ -288,7 +289,7 @@
     Mutex::Autolock surfaceLock(mSurfaceLock);
     // asBinder() is safe on NULL (returns NULL)
     if (surface->asBinder() != mSurface->asBinder()) {
-        if (mSurface != 0) {
+        if (mSurface != 0 && !mUseOverlay) {
             LOGD("clearing old preview surface %p", mSurface.get());
             mSurface->unregisterBuffers();
         }
@@ -341,17 +342,39 @@
 #if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
     debug_frame_cnt = 0;
 #endif
-
-    status_t ret = mHardware->startPreview(previewCallback,
-                                           mCameraService.get());
-    if (ret == NO_ERROR) {
-        mSurface->unregisterBuffers();
-        mSurface->registerBuffers(w,h,w,h,
-                                  PIXEL_FORMAT_YCbCr_420_SP,
-                                  mHardware->getPreviewHeap());
+    status_t ret;
+    if (mUseOverlay) {
+        const char *format = params.getPreviewFormat();
+        int fmt;
+        LOGD("Use Overlays");
+        if (!strcmp(format, "yuv422i"))
+            fmt = OVERLAY_FORMAT_YCbCr_422_I;
+        else if (!strcmp(format, "rgb565"))
+            fmt = OVERLAY_FORMAT_RGB_565;
+        else {
+            LOGE("Invalid preview format for overlays");
+            return -EINVAL;
+        }
+        sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
+        ret = mHardware->setOverlay(new Overlay(ref));
+        if (ret != NO_ERROR) {
+            LOGE("mHardware->setOverlay() failed with status %d\n", ret);
+            return ret;
+        }
+        ret = mHardware->startPreview(NULL, mCameraService.get());
+        if (ret != NO_ERROR)
+            LOGE("mHardware->startPreview() failed with status %d\n", ret);
+    } else {
+        LOGD("Don't use Overlays");
+        ret = mHardware->startPreview(previewCallback,
+                                               mCameraService.get());
+        if (ret == NO_ERROR) {
+            mSurface->unregisterBuffers();
+            mSurface->registerBuffers(w, h, w, h, PIXEL_FORMAT_YCbCr_420_SP,
+                                      mHardware->getPreviewHeap());
+        }
+        else LOGE("mHardware->startPreview() failed with status %d\n", ret);
     }
-    else LOGE("mHardware->startPreview() failed with status %d\n",
-              ret);
 
     return ret;
 }
@@ -372,7 +395,7 @@
     mHardware->stopPreview();
     LOGD("stopPreview(), hardware stopped OK");
 
-    if (mSurface != 0) {
+    if (mSurface != 0 && !mUseOverlay) {
         mSurface->unregisterBuffers();
     }
     mPreviewBuffer.clear();
@@ -520,7 +543,7 @@
         return INVALID_OPERATION;
     }
 
-    if (mSurface != NULL)
+    if (mSurface != NULL && !mUseOverlay)
         mSurface->unregisterBuffers();
 
     return mHardware->takePicture(shutterCallback,
@@ -573,7 +596,7 @@
     params.getPictureSize(&w, &h);
 
 //  Mutex::Autolock clientLock(client->mLock);
-    if (client->mSurface != 0) {
+    if (client->mSurface != 0 && !client->mUseOverlay) {
         client->mSurface->unregisterBuffers();
         client->mSurface->registerBuffers(w,h,w,h,
                                           PIXEL_FORMAT_YCbCr_420_SP, heap);
@@ -880,5 +903,3 @@
 #endif // DEBUG_HEAP_LEAKS
 
 }; // namespace android
-
-
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index cd8c1e9..e5a5d51 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -159,6 +159,7 @@
                     sp<ICameraClient>           mCameraClient;
                     sp<CameraHardwareInterface> mHardware;
                     pid_t                       mClientPid;
+                    bool                        mUseOverlay;
     };
 
 // ----------------------------------------------------------------------------
diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h
index 2bd53dd..3515fb0 100644
--- a/include/ui/CameraHardwareInterface.h
+++ b/include/ui/CameraHardwareInterface.h
@@ -20,6 +20,7 @@
 #include <utils/IMemory.h>
 #include <utils/RefBase.h>
 #include <ui/CameraParameters.h>
+#include <ui/Overlay.h>
 
 namespace android {
 
@@ -89,6 +90,11 @@
      * call back parameter may be null.
      */
     virtual status_t    startPreview(preview_callback cb, void* user) = 0;
+    /**
+     * Only used if overlays are used for camera preview.
+     */
+    virtual bool useOverlay() {return false;}
+    virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;}
 
     /**
      * Stop a previously started preview.
diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h
index f8454fd..66514b4 100644
--- a/include/ui/Overlay.h
+++ b/include/ui/Overlay.h
@@ -91,6 +91,7 @@
     int32_t getFormat() const;
     int32_t getWidthStride() const;
     int32_t getHeightStride() const;
+    int32_t getBufferCount() const;
     status_t getStatus() const;
     
 private:
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index c8e6168..b236edc 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -59,6 +59,12 @@
     return mOverlayData->queueBuffer(mOverlayData, buffer);
 }
 
+int32_t Overlay::getBufferCount() const
+{
+    if (mStatus != NO_ERROR) return mStatus;
+    return mOverlayData->getBufferCount(mOverlayData);
+}
+
 void* Overlay::getBufferAddress(overlay_buffer_t buffer)
 {
     if (mStatus != NO_ERROR) return NULL;
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index 0eba0b0..2962b25 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -945,14 +945,13 @@
             return 0;
         }
     }
-    
     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
-        h->data[i] = readFileDescriptor();
+        h->data[i] = dup(readFileDescriptor());
         if (h->data[i] < 0) err = BAD_VALUE;
     }
-    
+
     err = read(h->data + numFds, sizeof(int)*numInts);
-    
+
     if (err != NO_ERROR) {
         if (alloc == 0) {
             free(h);