ProCamera.cpp revision 68c80668304fc92db43bbe2e7cbe9753b6d3865a
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 121void ProCamera::setListener(const sp<ProCameraListener>& listener) 122{ 123 Mutex::Autolock _l(mLock); 124 mListener = listener; 125} 126 127 128// callback from camera service 129void ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 130{ 131 sp<ProCameraListener> listener; 132 { 133 Mutex::Autolock _l(mLock); 134 listener = mListener; 135 } 136 if (listener != NULL) { 137 listener->notify(msgType, ext1, ext2); 138 } 139} 140 141// callback from camera service when frame or image is ready 142void ProCamera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 143 camera_frame_metadata_t *metadata) 144{ 145 sp<ProCameraListener> listener; 146 { 147 Mutex::Autolock _l(mLock); 148 listener = mListener; 149 } 150 if (listener != NULL) { 151 listener->postData(msgType, dataPtr, metadata); 152 } 153} 154 155// callback from camera service when timestamped frame is ready 156void ProCamera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, 157 const sp<IMemory>& dataPtr) 158{ 159 sp<ProCameraListener> listener; 160 { 161 Mutex::Autolock _l(mLock); 162 listener = mListener; 163 } 164 if (listener != NULL) { 165 listener->postDataTimestamp(timestamp, msgType, dataPtr); 166 } else { 167 ALOGW("No listener was set. Drop a recording frame."); 168 } 169} 170 171/* IProCameraUser's implementation */ 172 173void ProCamera::onLockStatusChanged( 174 IProCameraCallbacks::LockStatus newLockStatus) 175{ 176 ALOGV("%s: newLockStatus = %d", __FUNCTION__, newLockStatus); 177 178 sp<ProCameraListener> listener; 179 { 180 Mutex::Autolock _l(mLock); 181 listener = mListener; 182 } 183 if (listener != NULL) { 184 switch (newLockStatus) { 185 case IProCameraCallbacks::LOCK_ACQUIRED: 186 listener->onLockAcquired(); 187 break; 188 case IProCameraCallbacks::LOCK_RELEASED: 189 listener->onLockReleased(); 190 break; 191 case IProCameraCallbacks::LOCK_STOLEN: 192 listener->onLockStolen(); 193 break; 194 default: 195 ALOGE("%s: Unknown lock status: %d", 196 __FUNCTION__, newLockStatus); 197 } 198 } 199} 200 201status_t ProCamera::exclusiveTryLock() 202{ 203 sp <IProCameraUser> c = mCamera; 204 if (c == 0) return NO_INIT; 205 206 return c->exclusiveTryLock(); 207} 208status_t ProCamera::exclusiveLock() 209{ 210 sp <IProCameraUser> c = mCamera; 211 if (c == 0) return NO_INIT; 212 213 return c->exclusiveLock(); 214} 215status_t ProCamera::exclusiveUnlock() 216{ 217 sp <IProCameraUser> c = mCamera; 218 if (c == 0) return NO_INIT; 219 220 return c->exclusiveUnlock(); 221} 222bool ProCamera::hasExclusiveLock() 223{ 224 sp <IProCameraUser> c = mCamera; 225 if (c == 0) return NO_INIT; 226 227 return c->hasExclusiveLock(); 228} 229 230// Note that the callee gets a copy of the metadata. 231int ProCamera::submitRequest(const struct camera_metadata* metadata, 232 bool streaming) 233{ 234 sp <IProCameraUser> c = mCamera; 235 if (c == 0) return NO_INIT; 236 237 return c->submitRequest(const_cast<struct camera_metadata*>(metadata), 238 streaming); 239} 240 241status_t ProCamera::cancelRequest(int requestId) 242{ 243 sp <IProCameraUser> c = mCamera; 244 if (c == 0) return NO_INIT; 245 246 return c->cancelRequest(requestId); 247} 248 249status_t ProCamera::requestStream(int streamId) 250{ 251 sp <IProCameraUser> c = mCamera; 252 if (c == 0) return NO_INIT; 253 254 return c->requestStream(streamId); 255} 256status_t ProCamera::cancelStream(int streamId) 257{ 258 sp <IProCameraUser> c = mCamera; 259 if (c == 0) return NO_INIT; 260 261 return c->cancelStream(streamId); 262} 263 264}; // namespace android 265