From 634a51509ee50475f3e9f8ccf897e90fc72ded31 Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Wed, 20 Feb 2013 17:15:11 -0800 Subject: Camera: Add ProCamera private binder interface for an API2-light functionality Change-Id: I2af7a807c99df75ea659e6e6acc9c4fca6a56274 --- camera/ProCamera.cpp | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 camera/ProCamera.cpp (limited to 'camera/ProCamera.cpp') 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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace android { + +// client singleton for camera service binder interface +Mutex ProCamera::mLock; +sp ProCamera::mCameraService; +sp ProCamera::mDeathNotifier; + +// establish binder interface to camera service +const sp& ProCamera::getCameraService() +{ + Mutex::Autolock _l(mLock); + if (mCameraService.get() == 0) { + sp sm = defaultServiceManager(); + sp 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(binder); + } + ALOGE_IF(mCameraService==0, "no CameraService!?"); + return mCameraService; +} + +sp ProCamera::connect(int cameraId) +{ + ALOGV("connect"); + sp c = new ProCamera(); + sp cl = c; + const sp& 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 ProCamera::remote() +{ + return mCamera; +} + +void ProCamera::binderDied(const wp& who) { + ALOGW("IProCameraUser died"); + notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); +} + +void ProCamera::DeathNotifier::binderDied(const wp& 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 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& dataPtr, + camera_frame_metadata_t *metadata) +{ + sp 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& dataPtr) +{ + sp 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 c = mCamera; + if (c == 0) return NO_INIT; + + return c->exclusiveTryLock(); +} +status_t ProCamera::exclusiveLock() +{ + sp c = mCamera; + if (c == 0) return NO_INIT; + + return c->exclusiveLock(); +} +status_t ProCamera::exclusiveUnlock() +{ + sp c = mCamera; + if (c == 0) return NO_INIT; + + return c->exclusiveUnlock(); +} +bool ProCamera::hasExclusiveLock() +{ + sp 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 c = mCamera; + if (c == 0) return NO_INIT; + + return c->submitRequest(const_cast(metadata), + streaming); +} + +status_t ProCamera::cancelRequest(int requestId) +{ + sp c = mCamera; + if (c == 0) return NO_INIT; + + return c->cancelRequest(requestId); +} + +status_t ProCamera::requestStream(int streamId) +{ + sp c = mCamera; + if (c == 0) return NO_INIT; + + return c->requestStream(streamId); +} +status_t ProCamera::cancelStream(int streamId) +{ + sp c = mCamera; + if (c == 0) return NO_INIT; + + return c->cancelStream(streamId); +} + +}; // namespace android -- cgit v1.1