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);