ACameraDevice.cpp revision 0dea57fd9fc4b2ccaab97d9477359fbd5a626f5c
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "ACameraDevice" 19 20#include <inttypes.h> 21#include "ACameraDevice.h" 22#include "ACameraMetadata.h" 23#include "ACaptureRequest.h" 24 25using namespace android; 26 27namespace android { 28// Static member definitions 29const char* CameraDevice::kContextKey = "Context"; 30const char* CameraDevice::kDeviceKey = "Device"; 31const char* CameraDevice::kErrorCodeKey = "ErrorCode"; 32const char* CameraDevice::kCallbackKey = "Callback"; 33 34/** 35 * CameraDevice Implementation 36 */ 37CameraDevice::CameraDevice( 38 const char* id, 39 ACameraDevice_StateCallbacks* cb, 40 std::unique_ptr<ACameraMetadata> chars, 41 ACameraDevice* wrapper) : 42 mCameraId(id), 43 mAppCallbacks(*cb), 44 mChars(std::move(chars)), 45 mServiceCallback(new ServiceCallback(this)), 46 mWrapper(wrapper), 47 mInError(false), 48 mError(ACAMERA_OK), 49 mIdle(true) { 50 mClosing = false; 51 // Setup looper thread to perfrom device callbacks to app 52 mCbLooper = new ALooper; 53 mCbLooper->setName("C2N-dev-looper"); 54 status_t ret = mCbLooper->start( 55 /*runOnCallingThread*/false, 56 /*canCallJava*/ true, 57 PRIORITY_FOREGROUND); 58 mHandler = new CallbackHandler(); 59 mCbLooper->registerHandler(mHandler); 60} 61 62CameraDevice::~CameraDevice() { 63 Mutex::Autolock _l(mDeviceLock); 64 if (mCbLooper != nullptr) { 65 mCbLooper->unregisterHandler(mHandler->id()); 66 mCbLooper->stop(); 67 } 68 mCbLooper.clear(); 69 mHandler.clear(); 70 if (!isClosed()) { 71 disconnectLocked(); 72 } 73} 74 75// TODO: cached created request? 76camera_status_t 77CameraDevice::createCaptureRequest( 78 ACameraDevice_request_template templateId, 79 ACaptureRequest** request) const { 80 Mutex::Autolock _l(mDeviceLock); 81 camera_status_t ret = checkCameraClosedOrErrorLocked(); 82 if (ret != ACAMERA_OK) { 83 return ret; 84 } 85 if (mRemote == nullptr) { 86 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 87 } 88 CameraMetadata rawRequest; 89 status_t remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest); 90 if (remoteRet == BAD_VALUE) { 91 ALOGW("Create capture request failed! template %d is not supported on this device", 92 templateId); 93 return ACAMERA_ERROR_UNSUPPORTED; 94 } else if (remoteRet != OK) { 95 ALOGE("Create capture request failed! error %d", remoteRet); 96 return ACAMERA_ERROR_UNKNOWN; 97 } 98 ACaptureRequest* outReq = new ACaptureRequest(); 99 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST); 100 outReq->targets = new ACameraOutputTargets(); 101 *request = outReq; 102 return ACAMERA_OK; 103} 104 105void 106CameraDevice::disconnectLocked() { 107 if (mClosing.exchange(true)) { 108 // Already closing, just return 109 ALOGW("Camera device %s is already closing.", getId()); 110 return; 111 } 112 113 if (mRemote != nullptr) { 114 mRemote->disconnect(); 115 } 116 mRemote = nullptr; 117} 118 119void 120CameraDevice::setRemoteDevice(sp<ICameraDeviceUser> remote) { 121 Mutex::Autolock _l(mDeviceLock); 122 mRemote = remote; 123} 124 125camera_status_t 126CameraDevice::checkCameraClosedOrErrorLocked() const { 127 if (mRemote == nullptr) { 128 ALOGE("%s: camera device already closed", __FUNCTION__); 129 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 130 } 131 if (mInError) {// triggered by onDeviceError 132 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__); 133 return mError; 134 } 135 return ACAMERA_OK; 136} 137 138void 139CameraDevice::onCaptureErrorLocked( 140 ICameraDeviceCallbacks::CameraErrorCode errorCode, 141 const CaptureResultExtras& resultExtras) { 142 // TODO: implement! 143} 144 145void CameraDevice::CallbackHandler::onMessageReceived( 146 const sp<AMessage> &msg) { 147 switch (msg->what()) { 148 case kWhatOnDisconnected: 149 case kWhatOnError: 150 break; 151 default: 152 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what()); 153 return; 154 } 155 // Check the common part of all message 156 void* context; 157 bool found = msg->findPointer(kContextKey, &context); 158 if (!found) { 159 ALOGE("%s: Cannot find callback context!", __FUNCTION__); 160 return; 161 } 162 ACameraDevice* dev; 163 found = msg->findPointer(kDeviceKey, (void**) &dev); 164 if (!found) { 165 ALOGE("%s: Cannot find device pointer!", __FUNCTION__); 166 return; 167 } 168 switch (msg->what()) { 169 case kWhatOnDisconnected: 170 { 171 ACameraDevice_StateCallback onDisconnected; 172 found = msg->findPointer(kCallbackKey, (void**) &onDisconnected); 173 if (!found) { 174 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__); 175 return; 176 } 177 (*onDisconnected)(context, dev); 178 break; 179 } 180 case kWhatOnError: 181 { 182 ACameraDevice_ErrorStateCallback onError; 183 found = msg->findPointer(kCallbackKey, (void**) &onError); 184 if (!found) { 185 ALOGE("%s: Cannot find onError!", __FUNCTION__); 186 return; 187 } 188 int errorCode; 189 found = msg->findInt32(kErrorCodeKey, &errorCode); 190 if (!found) { 191 ALOGE("%s: Cannot find error code!", __FUNCTION__); 192 return; 193 } 194 (*onError)(context, dev, errorCode); 195 } 196 } 197} 198 199/** 200 * Camera service callback implementation 201 */ 202void 203CameraDevice::ServiceCallback::onDeviceError( 204 CameraErrorCode errorCode, 205 const CaptureResultExtras& resultExtras) { 206 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d", 207 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId); 208 209 sp<CameraDevice> dev = mDevice.promote(); 210 if (dev == nullptr) { 211 return; // device has been closed 212 } 213 214 Mutex::Autolock _l(dev->mDeviceLock); 215 if (dev->mRemote == nullptr) { 216 return; // device has been disconnected 217 } 218 switch (errorCode) { 219 case ERROR_CAMERA_DISCONNECTED: 220 { 221 // should be clear mRemote here? 222 // TODO: close current session 223 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler); 224 msg->setPointer(kContextKey, dev->mAppCallbacks.context); 225 msg->setPointer(kDeviceKey, (void*) dev->getWrapper()); 226 msg->setPointer(kCallbackKey, (void*) dev->mAppCallbacks.onDisconnected); 227 msg->post(); 228 break; 229 } 230 default: 231 ALOGE("Unknown error from camera device: %d", errorCode); 232 // no break 233 case ERROR_CAMERA_DEVICE: 234 case ERROR_CAMERA_SERVICE: 235 { 236 dev->mInError = true; 237 switch (errorCode) { 238 case ERROR_CAMERA_DEVICE: 239 dev->mError = ACAMERA_ERROR_CAMERA_DEVICE; 240 break; 241 case ERROR_CAMERA_SERVICE: 242 dev->mError = ACAMERA_ERROR_CAMERA_SERVICE; 243 break; 244 default: 245 dev->mError = ACAMERA_ERROR_UNKNOWN; 246 break; 247 } 248 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler); 249 msg->setPointer(kContextKey, dev->mAppCallbacks.context); 250 msg->setPointer(kDeviceKey, (void*) dev->getWrapper()); 251 msg->setPointer(kCallbackKey, (void*) dev->mAppCallbacks.onError); 252 msg->setInt32(kErrorCodeKey, errorCode); 253 msg->post(); 254 break; 255 } 256 case ERROR_CAMERA_REQUEST: 257 case ERROR_CAMERA_RESULT: 258 case ERROR_CAMERA_BUFFER: 259 dev->onCaptureErrorLocked(errorCode, resultExtras); 260 break; 261 } 262} 263 264void 265CameraDevice::ServiceCallback::onDeviceIdle() { 266 ALOGV("Camera is now idle"); 267 sp<CameraDevice> dev = mDevice.promote(); 268 if (dev == nullptr) { 269 return; // device has been closed 270 } 271 272 Mutex::Autolock _l(dev->mDeviceLock); 273 if (dev->mRemote == nullptr) { 274 return; // device has been disconnected 275 } 276 if (!dev->mIdle) { 277 // TODO: send idle callback to current session 278 } 279 dev->mIdle = true; 280} 281 282void 283CameraDevice::ServiceCallback::onCaptureStarted( 284 const CaptureResultExtras& resultExtras, 285 int64_t timestamp) { 286} 287 288void 289CameraDevice::ServiceCallback::onResultReceived( 290 const CameraMetadata& metadata, 291 const CaptureResultExtras& resultExtras) { 292} 293 294void 295CameraDevice::ServiceCallback::onPrepared(int) { 296 // Prepare not yet implemented in NDK 297 return; 298} 299 300} // namespace android 301