diff options
author | 2009-01-20 14:03:58 -0800 | |
---|---|---|
committer | 2009-01-20 14:03:58 -0800 | |
commit | 5f78a48bb8f7714ee231fca67d60fad77bc1cad9 (patch) | |
tree | ac69c2deb25fc345ac453231ed7a8678df497a3e | |
parent | 8a7a67538a9977c892389bfcde76a8372aa0b56c (diff) |
auto import from //branches/cupcake/...@127101
-rw-r--r-- | camera/libcameraservice/CameraService.cpp | 56 | ||||
-rw-r--r-- | include/ui/Overlay.h | 6 | ||||
-rw-r--r-- | include/utils/Parcel.h | 13 | ||||
-rw-r--r-- | libs/audioflinger/A2dpAudioInterface.cpp | 2 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBuffer.h | 2 | ||||
-rw-r--r-- | libs/ui/Camera.cpp | 55 | ||||
-rw-r--r-- | libs/ui/Overlay.cpp | 27 | ||||
-rw-r--r-- | libs/utils/Parcel.cpp | 63 |
8 files changed, 166 insertions, 58 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 33987c3607..36c5ada97a 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -166,22 +166,26 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, 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::unlock() 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 @@ static void *unregister_surface(void *arg) CameraService::Client::~Client() { - // spin down hardware + // tear down client LOGD("Client E destructor"); if (mSurface != 0) { #if HAVE_ANDROID_OS @@ -227,6 +248,8 @@ CameraService::Client::~Client() #endif } + // make sure we tear down the hardware + mClientPid = IPCThreadState::self()->getCallingPid(); disconnect(); LOGD("Client X destructor"); } @@ -235,7 +258,12 @@ void CameraService::Client::disconnect() { 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 9c7bc4764e..f8454fd73a 100644 --- a/include/ui/Overlay.h +++ b/include/ui/Overlay.h @@ -40,7 +40,7 @@ class IMemoryHeap; 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 @@ private: 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 @@ public: 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 7c451ab212..9087c4465b 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 @@ public: 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 @@ public: 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 7242575957..c8c8431096 100644 --- a/libs/audioflinger/A2dpAudioInterface.cpp +++ b/libs/audioflinger/A2dpAudioInterface.cpp @@ -126,7 +126,7 @@ status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args) // ---------------------------------------------------------------------------- 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 3286535d0b..6e3d49f053 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -170,7 +170,7 @@ private: 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 4a325ac2e0..50c60084ad 100644 --- a/libs/ui/Camera.cpp +++ b/libs/ui/Camera.cpp @@ -125,10 +125,9 @@ void Camera::disconnect() 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 @@ sp<ICamera> Camera::remote() 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 @@ status_t Camera::setPreviewDisplay(const sp<Surface>& surface) 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 @@ status_t Camera::setPreviewDisplay(const sp<ISurface>& surface) 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::setPreviewDisplay(const sp<ISurface>& surface) 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 @@ void Camera::setFrameCallback(frame_callback cb, void *cookie, int frame_callbac 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 2745f5214c..c8e61689d5 100644 --- a/libs/ui/Overlay.cpp +++ b/libs/ui/Overlay.cpp @@ -74,7 +74,7 @@ status_t Overlay::getStatus() const { 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() { } -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 @@ OverlayRef::~OverlayRef() /* 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 @@ sp<OverlayRef> OverlayRef::readFromParcel(const Parcel& data) { 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 @@ status_t OverlayRef::writeToParcel(Parcel* reply, const sp<OverlayRef>& o) { 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 3eca4b010e..0eba0b07c8 100644 --- a/libs/utils/Parcel.cpp +++ b/libs/utils/Parcel.cpp @@ -650,6 +650,26 @@ status_t Parcel::writeWeakBinder(const wp<IBinder>& val) 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 @@ wp<IBinder> Parcel::readWeakBinder() const 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 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const = 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); |