diff options
author | Igor Murashkin <iam@google.com> | 2013-02-20 17:15:11 -0800 |
---|---|---|
committer | Igor Murashkin <iam@google.com> | 2013-02-22 10:50:14 -0800 |
commit | 634a51509ee50475f3e9f8ccf897e90fc72ded31 (patch) | |
tree | 5d9fc437299a8b5adc391eb721d55c9df00afc87 /camera/ProCamera.cpp | |
parent | 1d88023e1de6b9f370eb4be944dd9c4480d01f11 (diff) | |
download | frameworks_av-634a51509ee50475f3e9f8ccf897e90fc72ded31.zip frameworks_av-634a51509ee50475f3e9f8ccf897e90fc72ded31.tar.gz frameworks_av-634a51509ee50475f3e9f8ccf897e90fc72ded31.tar.bz2 |
Camera: Add ProCamera private binder interface for an API2-light functionality
Change-Id: I2af7a807c99df75ea659e6e6acc9c4fca6a56274
Diffstat (limited to 'camera/ProCamera.cpp')
-rw-r--r-- | camera/ProCamera.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp new file mode 100644 index 0000000..134a4a3 --- /dev/null +++ b/camera/ProCamera.cpp @@ -0,0 +1,230 @@ +/* +** +** Copyright (C) 2013, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "ProCamera" +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/Mutex.h> + +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <binder/IMemory.h> + +#include <camera/ProCamera.h> +#include <camera/ICameraService.h> +#include <camera/IProCameraUser.h> +#include <camera/IProCameraCallbacks.h> + +#include <gui/IGraphicBufferProducer.h> +#include <gui/Surface.h> + +namespace android { + +// client singleton for camera service binder interface +Mutex ProCamera::mLock; +sp<ICameraService> ProCamera::mCameraService; +sp<ProCamera::DeathNotifier> ProCamera::mDeathNotifier; + +// establish binder interface to camera service +const sp<ICameraService>& ProCamera::getCameraService() +{ + Mutex::Autolock _l(mLock); + if (mCameraService.get() == 0) { + sp<IServiceManager> sm = defaultServiceManager(); + sp<IBinder> binder; + do { + binder = sm->getService(String16("media.camera")); + if (binder != 0) + break; + ALOGW("CameraService not published, waiting..."); + usleep(500000); // 0.5 s + } while(true); + if (mDeathNotifier == NULL) { + mDeathNotifier = new DeathNotifier(); + } + binder->linkToDeath(mDeathNotifier); + mCameraService = interface_cast<ICameraService>(binder); + } + ALOGE_IF(mCameraService==0, "no CameraService!?"); + return mCameraService; +} + +sp<ProCamera> ProCamera::connect(int cameraId) +{ + ALOGV("connect"); + sp<ProCamera> c = new ProCamera(); + sp<IProCameraCallbacks> cl = c; + const sp<ICameraService>& cs = getCameraService(); + if (cs != 0) { + c->mCamera = cs->connect(cl, cameraId); + } + if (c->mCamera != 0) { + c->mCamera->asBinder()->linkToDeath(c); + c->mStatus = NO_ERROR; + } else { + c.clear(); + } + return c; +} + +void ProCamera::disconnect() +{ + ALOGV("disconnect"); + if (mCamera != 0) { + mCamera->disconnect(); + mCamera->asBinder()->unlinkToDeath(this); + mCamera = 0; + } +} + +ProCamera::ProCamera() +{ +} + +ProCamera::~ProCamera() +{ + +} + +sp<IProCameraUser> ProCamera::remote() +{ + return mCamera; +} + +void ProCamera::binderDied(const wp<IBinder>& who) { + ALOGW("IProCameraUser died"); + notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); +} + +void ProCamera::DeathNotifier::binderDied(const wp<IBinder>& who) { + ALOGV("binderDied"); + Mutex::Autolock _l(ProCamera::mLock); + ProCamera::mCameraService.clear(); + ALOGW("Camera service died!"); +} + + +// callback from camera service +void ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) +{ + sp<ProCameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->notify(msgType, ext1, ext2); + } +} + +// callback from camera service when frame or image is ready +void ProCamera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, + camera_frame_metadata_t *metadata) +{ + sp<ProCameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postData(msgType, dataPtr, metadata); + } +} + +// callback from camera service when timestamped frame is ready +void ProCamera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, + const sp<IMemory>& dataPtr) +{ + sp<ProCameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postDataTimestamp(timestamp, msgType, dataPtr); + } else { + ALOGW("No listener was set. Drop a recording frame."); + } +} + +/* IProCameraUser's implementation */ + +status_t ProCamera::exclusiveTryLock() +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->exclusiveTryLock(); +} +status_t ProCamera::exclusiveLock() +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->exclusiveLock(); +} +status_t ProCamera::exclusiveUnlock() +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->exclusiveUnlock(); +} +bool ProCamera::hasExclusiveLock() +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->hasExclusiveLock(); +} + +// Note that the callee gets a copy of the metadata. +int ProCamera::submitRequest(const struct camera_metadata* metadata, + bool streaming) +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->submitRequest(const_cast<struct camera_metadata*>(metadata), + streaming); +} + +status_t ProCamera::cancelRequest(int requestId) +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->cancelRequest(requestId); +} + +status_t ProCamera::requestStream(int streamId) +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->requestStream(streamId); +} +status_t ProCamera::cancelStream(int streamId) +{ + sp <IProCameraUser> c = mCamera; + if (c == 0) return NO_INIT; + + return c->cancelStream(streamId); +} + +}; // namespace android |