auto import from //branches/cupcake/...@127101
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 33987c3..36c5ada 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -166,22 +166,26 @@
 
 status_t CameraService::Client::checkPid()
 {
-    // zero means the interface is not locked down
-    if (mClientPid == 0) return NO_ERROR;
-    return (int) mClientPid == IPCThreadState::self()->getCallingPid() ? NO_ERROR : -EBUSY;
+    if (mClientPid == IPCThreadState::self()->getCallingPid()) return NO_ERROR;
+    LOGW("Attempt to use locked camera from different process");
+    return -EBUSY;
 }
 
 status_t CameraService::Client::lock()
 {
-    // lock camera to this client
-    status_t result = checkPid();
-    if (result == NO_ERROR) mClientPid = IPCThreadState::self()->getCallingPid();
-    return result;
+    // lock camera to this client if the the camera is unlocked
+    if (mClientPid == 0) {
+        mClientPid = IPCThreadState::self()->getCallingPid();
+        return NO_ERROR;
+    }
+    // returns NO_ERROR if the client already owns the camera, -EBUSY otherwise
+    return checkPid();
 }
 
 status_t CameraService::Client::unlock()
 {
     // allow anyone to use camera
+    LOGV("unlock");
     status_t result = checkPid();
     if (result == NO_ERROR) mClientPid = 0;
     return result;
@@ -189,12 +193,29 @@
 
 status_t CameraService::Client::connect(const sp<ICameraClient>& client)
 {
-    // remove old client
-    LOGV("connect new client to existing camera");
-    Mutex::Autolock _l(mLock);
-    mCameraClient = client;
-    mClientPid = IPCThreadState::self()->getCallingPid();
-    mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+    // connect a new process to the camera
+    LOGV("connect");
+
+    // hold a reference to the old client or we will deadlock if the client is
+    // in the same process and we hold the lock when we remove the reference
+    sp<ICameraClient> oldClient;
+    {
+        Mutex::Autolock _l(mLock);
+        if (mClientPid != 0) {
+            LOGW("Tried to connect to locked camera");
+            return -EBUSY;
+        }
+        oldClient = mCameraClient;
+
+        // did the client actually change?
+        if (client->asBinder() == mCameraClient->asBinder()) return NO_ERROR;
+
+        LOGV("connect new process to existing camera client");
+        mCameraClient = client;
+        mClientPid = IPCThreadState::self()->getCallingPid();
+        mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+    }
+
     return NO_ERROR;
 }
 
@@ -210,7 +231,7 @@
 
 CameraService::Client::~Client()
 {
-    // spin down hardware
+    // tear down client
     LOGD("Client E destructor");
     if (mSurface != 0) {
 #if HAVE_ANDROID_OS
@@ -227,6 +248,8 @@
 #endif
     }
 
+    // make sure we tear down the hardware
+    mClientPid = IPCThreadState::self()->getCallingPid();
     disconnect();
     LOGD("Client X destructor");
 }
@@ -235,7 +258,12 @@
 {
     LOGD("Client E disconnect");
     Mutex::Autolock lock(mLock);
+    if (mClientPid == 0) {
+        LOGV("camera is unlocked, don't tear down hardware");
+        return;
+    }
     if (checkPid() != NO_ERROR) return;
+
     mCameraService->removeClient(mCameraClient);
     if (mHardware != 0) {
         // Before destroying mHardware, we must make sure it's in the
diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h
index 9c7bc47..f8454fd 100644
--- a/include/ui/Overlay.h
+++ b/include/ui/Overlay.h
@@ -40,7 +40,7 @@
 class OverlayRef : public LightRefBase<OverlayRef>
 {
 public:
-    OverlayRef(overlay_handle_t const*, const sp<IOverlay>&,
+    OverlayRef(overlay_handle_t, const sp<IOverlay>&,
             uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs);
 
     static sp<OverlayRef> readFromParcel(const Parcel& data);
@@ -53,7 +53,7 @@
     OverlayRef();
     virtual ~OverlayRef();
 
-    overlay_handle_t const *mOverlayHandle;
+    overlay_handle_t mOverlayHandle;
     sp<IOverlay> mOverlayChannel;
     uint32_t mWidth;
     uint32_t mHeight;
@@ -74,7 +74,7 @@
     void destroy();
     
     /* get the HAL handle for this overlay */
-    overlay_handle_t const* getHandleRef() const;
+    overlay_handle_t getHandleRef() const;
 
     /* blocks until an overlay buffer is available and return that buffer. */
     status_t dequeueBuffer(overlay_buffer_t* buffer);
diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h
index 7c451ab..9087c44 100644
--- a/include/utils/Parcel.h
+++ b/include/utils/Parcel.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_PARCEL_H
 #define ANDROID_PARCEL_H
 
+#include <cutils/native_handle.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/String16.h>
@@ -78,6 +79,9 @@
     status_t            writeString16(const char16_t* str, size_t len);
     status_t            writeStrongBinder(const sp<IBinder>& val);
     status_t            writeWeakBinder(const wp<IBinder>& val);
+
+    // doesn't take ownership of the native_handle
+    status_t            writeNativeHandle(const native_handle& handle);
     
     // Place a file descriptor into the parcel.  The given fd must remain
     // valid for the lifetime of the parcel.
@@ -108,6 +112,15 @@
     const char16_t*     readString16Inplace(size_t* outLen) const;
     sp<IBinder>         readStrongBinder() const;
     wp<IBinder>         readWeakBinder() const;
+
+    
+    // if alloc is NULL, native_handle is allocated with malloc(), otherwise
+    // alloc is used. If the function fails, the effects of alloc() must be
+    // reverted by the caller.
+    native_handle*     readNativeHandle(
+            native_handle* (*alloc)(void* cookie, int numFds, int ints),
+            void* cookie) const;
+
     
     // Retrieve a file descriptor from the parcel.  This returns the raw fd
     // in the parcel, which you do not own -- use dup() to get your own copy.
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index 7242575..c8c8431 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -126,7 +126,7 @@
 // ----------------------------------------------------------------------------
 
 A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
-    mFd(-1), mStandby(false), mStartCount(0), mRetryCount(0), mData(NULL),
+    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
     mInitialized(false)
 {
     // use any address by default
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 3286535..6e3d49f 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -170,7 +170,7 @@
         bool mVisibilityChanged;
 
         overlay_t* mOverlay;        
-        overlay_handle_t const *mOverlayHandle;
+        overlay_handle_t mOverlayHandle;
         overlay_control_device_t* mOverlayDevice;
         uint32_t mWidth;
         uint32_t mHeight;
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 4a325ac..50c6008 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -125,10 +125,9 @@
 status_t Camera::reconnect()
 {
     LOGV("reconnect");
-    if (mCamera != 0) {
-        return mCamera->connect(this);
-    }
-    return NO_INIT;
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->connect(this);
 }
 
 sp<ICamera> Camera::remote()
@@ -138,14 +137,16 @@
 
 status_t Camera::lock()
 {
-    if (mCamera != 0) return mCamera->lock();
-    return NO_INIT;
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->lock();
 }
 
 status_t Camera::unlock()
 {
-    if (mCamera != 0) return mCamera->unlock();
-    return NO_INIT;
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->unlock();
 }
 
 // pass the buffered ISurface to the camera service
@@ -156,7 +157,9 @@
         LOGE("app passed NULL surface");
         return NO_INIT;
     }
-    return mCamera->setPreviewDisplay(surface->getISurface());
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->setPreviewDisplay(surface->getISurface());
 }
 
 status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
@@ -166,7 +169,9 @@
         LOGE("app passed NULL surface");
         return NO_INIT;
     }
-    return mCamera->setPreviewDisplay(surface);
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->setPreviewDisplay(surface);
 }
 
 
@@ -174,48 +179,62 @@
 status_t Camera::startPreview()
 {
     LOGV("startPreview");
-    return mCamera->startPreview();
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->startPreview();
 }
 
 // stop preview mode
 void Camera::stopPreview()
 {
     LOGV("stopPreview");
-    mCamera->stopPreview();
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    c->stopPreview();
 }
 
 // get preview state
 bool Camera::previewEnabled()
 {
     LOGV("previewEnabled");
-    return mCamera->previewEnabled();
+    sp <ICamera> c = mCamera;
+    if (c == 0) return false;
+    return c->previewEnabled();
 }
 
 status_t Camera::autoFocus()
 {
     LOGV("autoFocus");
-    return mCamera->autoFocus();
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->autoFocus();
 }
 
 // take a picture
 status_t Camera::takePicture()
 {
     LOGV("takePicture");
-    return mCamera->takePicture();
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->takePicture();
 }
 
 // set preview/capture parameters - key/value pairs
 status_t Camera::setParameters(const String8& params)
 {
     LOGV("setParameters");
-    return mCamera->setParameters(params);
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->setParameters(params);
 }
 
 // get preview/capture parameters - key/value pairs
 String8 Camera::getParameters() const
 {
     LOGV("getParameters");
-    String8 params = mCamera->getParameters();
+    String8 params;
+    sp <ICamera> c = mCamera;
+    if (c != 0) params = mCamera->getParameters();
     return params;
 }
 
@@ -252,6 +271,8 @@
     LOGV("setFrameCallback");
     mFrameCallback = cb;
     mFrameCallbackCookie = cookie;
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
     mCamera->setFrameCallbackFlag(frame_callback_flag);
 }
 
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index 2745f52..c8e6168 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -74,7 +74,7 @@
     return mStatus;
 }
 
-overlay_handle_t const* Overlay::getHandleRef() const {
+overlay_handle_t Overlay::getHandleRef() const {
     if (mStatus != NO_ERROR) return NULL;
     return mOverlayRef->mOverlayHandle;
 }
@@ -112,7 +112,7 @@
 {    
 }
 
-OverlayRef::OverlayRef(overlay_handle_t const* handle, const sp<IOverlay>& channel,
+OverlayRef::OverlayRef(overlay_handle_t handle, const sp<IOverlay>& channel,
          uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
     : mOverlayHandle(handle), mOverlayChannel(channel),
     mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
@@ -126,7 +126,7 @@
         /* FIXME: handles should be promoted to "real" API and be handled by 
          * the framework */
         for (int i=0 ; i<mOverlayHandle->numFds ; i++) {
-            close(mOverlayHandle->fds[i]);
+            close(mOverlayHandle->data[i]);
         }
         free((void*)mOverlayHandle);
     }
@@ -141,16 +141,8 @@
         uint32_t f = data.readInt32();
         uint32_t ws = data.readInt32();
         uint32_t hs = data.readInt32();
-        /* FIXME: handles should be promoted to "real" API and be handled by 
-         * the framework */
-        int numfd = data.readInt32();
-        int numint = data.readInt32();
-        overlay_handle_t* handle = (overlay_handle_t*)malloc(
-                sizeof(overlay_handle_t) + numint*sizeof(int));
-        for (int i=0 ; i<numfd ; i++)
-            handle->fds[i] = data.readFileDescriptor();
-        for (int i=0 ; i<numint ; i++)
-            handle->data[i] = data.readInt32();
+        native_handle* handle = data.readNativeHandle(NULL, NULL);
+
         result = new OverlayRef();
         result->mOverlayHandle = handle;
         result->mOverlayChannel = overlay;
@@ -171,14 +163,7 @@
         reply->writeInt32(o->mFormat);
         reply->writeInt32(o->mWidthStride);
         reply->writeInt32(o->mHeightStride);
-        /* FIXME: handles should be promoted to "real" API and be handled by 
-         * the framework */
-        reply->writeInt32(o->mOverlayHandle->numFds);
-        reply->writeInt32(o->mOverlayHandle->numInts);
-        for (int i=0 ; i<o->mOverlayHandle->numFds ; i++)
-            reply->writeFileDescriptor(o->mOverlayHandle->fds[i]);
-        for (int i=0 ; i<o->mOverlayHandle->numInts ; i++)
-            reply->writeInt32(o->mOverlayHandle->data[i]);
+        reply->writeNativeHandle(*(o->mOverlayHandle));
     } else {
         reply->writeStrongBinder(NULL);
     }
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index 3eca4b0..0eba0b0 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -650,6 +650,26 @@
     return flatten_binder(ProcessState::self(), val, this);
 }
 
+status_t Parcel::writeNativeHandle(const native_handle& handle)
+{
+    if (handle.version != sizeof(native_handle))
+        return BAD_TYPE;
+
+    status_t err;
+    err = writeInt32(handle.numFds);
+    if (err != NO_ERROR) return err;
+    
+    err = writeInt32(handle.numInts);
+    if (err != NO_ERROR) return err;
+    
+    for (int i=0 ; err==NO_ERROR && i<handle.numFds ; i++)
+        err = writeDupFileDescriptor(handle.data[i]);
+    
+    err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts);
+    
+    return err;
+}
+
 status_t Parcel::writeFileDescriptor(int fd)
 {
     flat_binder_object obj;
@@ -902,6 +922,47 @@
     return val;
 }
 
+
+native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const
+{
+    int numFds, numInts;
+    status_t err;
+    err = readInt32(&numFds);
+    if (err != NO_ERROR) return 0;
+    err = readInt32(&numInts);
+    if (err != NO_ERROR) return 0;
+
+    native_handle* h;
+    if (alloc == 0) {
+        size_t size = sizeof(native_handle) + sizeof(int)*(numFds + numInts);
+        h = (native_handle*)malloc(size); 
+        h->version = sizeof(native_handle);
+        h->numFds = numFds;
+        h->numInts = numInts;
+    } else {
+        h = alloc(cookie, numFds, numInts);
+        if (h->version != sizeof(native_handle)) {
+            return 0;
+        }
+    }
+    
+    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
+        h->data[i] = 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);
+        }
+        h = 0;
+    }
+    return h;
+}
+
+
 int Parcel::readFileDescriptor() const
 {
     const flat_binder_object* flat = readObject(true);
@@ -923,7 +984,7 @@
                 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
         mDataPos = DPOS + sizeof(flat_binder_object);
         if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
-            // When transfering a NULL object, we don't write it into
+            // When transferring a NULL object, we don't write it into
             // the object list, so we don't want to check for it when
             // reading.
             LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);