ProCamera.cpp revision bfb5d5ef5bae01efac171397260a7152782d92c7
1/* 2** 3** Copyright (C) 2013, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "ProCamera" 20#include <utils/Log.h> 21#include <utils/threads.h> 22#include <utils/Mutex.h> 23 24#include <binder/IPCThreadState.h> 25#include <binder/IServiceManager.h> 26#include <binder/IMemory.h> 27 28#include <camera/ProCamera.h> 29#include <camera/ICameraService.h> 30#include <camera/IProCameraUser.h> 31#include <camera/IProCameraCallbacks.h> 32 33#include <gui/IGraphicBufferProducer.h> 34#include <gui/Surface.h> 35 36namespace android { 37 38// client singleton for camera service binder interface 39Mutex ProCamera::mLock; 40sp<ICameraService> ProCamera::mCameraService; 41sp<ProCamera::DeathNotifier> ProCamera::mDeathNotifier; 42 43// establish binder interface to camera service 44const sp<ICameraService>& ProCamera::getCameraService() 45{ 46 Mutex::Autolock _l(mLock); 47 if (mCameraService.get() == 0) { 48 sp<IServiceManager> sm = defaultServiceManager(); 49 sp<IBinder> binder; 50 do { 51 binder = sm->getService(String16("media.camera")); 52 if (binder != 0) 53 break; 54 ALOGW("CameraService not published, waiting..."); 55 usleep(500000); // 0.5 s 56 } while(true); 57 if (mDeathNotifier == NULL) { 58 mDeathNotifier = new DeathNotifier(); 59 } 60 binder->linkToDeath(mDeathNotifier); 61 mCameraService = interface_cast<ICameraService>(binder); 62 } 63 ALOGE_IF(mCameraService==0, "no CameraService!?"); 64 return mCameraService; 65} 66 67sp<ProCamera> ProCamera::connect(int cameraId) 68{ 69 ALOGV("connect"); 70 sp<ProCamera> c = new ProCamera(); 71 sp<IProCameraCallbacks> cl = c; 72 const sp<ICameraService>& cs = getCameraService(); 73 if (cs != 0) { 74 c->mCamera = cs->connect(cl, cameraId); 75 } 76 if (c->mCamera != 0) { 77 c->mCamera->asBinder()->linkToDeath(c); 78 c->mStatus = NO_ERROR; 79 } else { 80 c.clear(); 81 } 82 return c; 83} 84 85void ProCamera::disconnect() 86{ 87 ALOGV("disconnect"); 88 if (mCamera != 0) { 89 mCamera->disconnect(); 90 mCamera->asBinder()->unlinkToDeath(this); 91 mCamera = 0; 92 } 93} 94 95ProCamera::ProCamera() 96{ 97} 98 99ProCamera::~ProCamera() 100{ 101 102} 103 104sp<IProCameraUser> ProCamera::remote() 105{ 106 return mCamera; 107} 108 109void ProCamera::binderDied(const wp<IBinder>& who) { 110 ALOGW("IProCameraUser died"); 111 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 112} 113 114void ProCamera::DeathNotifier::binderDied(const wp<IBinder>& who) { 115 ALOGV("binderDied"); 116 Mutex::Autolock _l(ProCamera::mLock); 117 ProCamera::mCameraService.clear(); 118 ALOGW("Camera service died!"); 119} 120 121 122// callback from camera service 123void ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 124{ 125 sp<ProCameraListener> listener; 126 { 127 Mutex::Autolock _l(mLock); 128 listener = mListener; 129 } 130 if (listener != NULL) { 131 listener->notify(msgType, ext1, ext2); 132 } 133} 134 135// callback from camera service when frame or image is ready 136void ProCamera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 137 camera_frame_metadata_t *metadata) 138{ 139 sp<ProCameraListener> listener; 140 { 141 Mutex::Autolock _l(mLock); 142 listener = mListener; 143 } 144 if (listener != NULL) { 145 listener->postData(msgType, dataPtr, metadata); 146 } 147} 148 149// callback from camera service when timestamped frame is ready 150void ProCamera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, 151 const sp<IMemory>& dataPtr) 152{ 153 sp<ProCameraListener> listener; 154 { 155 Mutex::Autolock _l(mLock); 156 listener = mListener; 157 } 158 if (listener != NULL) { 159 listener->postDataTimestamp(timestamp, msgType, dataPtr); 160 } else { 161 ALOGW("No listener was set. Drop a recording frame."); 162 } 163} 164 165/* IProCameraUser's implementation */ 166 167status_t ProCamera::exclusiveTryLock() 168{ 169 sp <IProCameraUser> c = mCamera; 170 if (c == 0) return NO_INIT; 171 172 return c->exclusiveTryLock(); 173} 174status_t ProCamera::exclusiveLock() 175{ 176 sp <IProCameraUser> c = mCamera; 177 if (c == 0) return NO_INIT; 178 179 return c->exclusiveLock(); 180} 181status_t ProCamera::exclusiveUnlock() 182{ 183 sp <IProCameraUser> c = mCamera; 184 if (c == 0) return NO_INIT; 185 186 return c->exclusiveUnlock(); 187} 188bool ProCamera::hasExclusiveLock() 189{ 190 sp <IProCameraUser> c = mCamera; 191 if (c == 0) return NO_INIT; 192 193 return c->hasExclusiveLock(); 194} 195 196// Note that the callee gets a copy of the metadata. 197int ProCamera::submitRequest(const struct camera_metadata* metadata, 198 bool streaming) 199{ 200 sp <IProCameraUser> c = mCamera; 201 if (c == 0) return NO_INIT; 202 203 return c->submitRequest(const_cast<struct camera_metadata*>(metadata), 204 streaming); 205} 206 207status_t ProCamera::cancelRequest(int requestId) 208{ 209 sp <IProCameraUser> c = mCamera; 210 if (c == 0) return NO_INIT; 211 212 return c->cancelRequest(requestId); 213} 214 215status_t ProCamera::requestStream(int streamId) 216{ 217 sp <IProCameraUser> c = mCamera; 218 if (c == 0) return NO_INIT; 219 220 return c->requestStream(streamId); 221} 222status_t ProCamera::cancelStream(int streamId) 223{ 224 sp <IProCameraUser> c = mCamera; 225 if (c == 0) return NO_INIT; 226 227 return c->cancelStream(streamId); 228} 229 230}; // namespace android 231