| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2013 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_TAG "ProCamera2Client" | 
 | 18 | #define ATRACE_TAG ATRACE_TAG_CAMERA | 
 | 19 | //#define LOG_NDEBUG 0 | 
 | 20 |  | 
 | 21 | #include <utils/Log.h> | 
 | 22 | #include <utils/Trace.h> | 
 | 23 |  | 
 | 24 | #include <cutils/properties.h> | 
 | 25 | #include <gui/Surface.h> | 
 | 26 | #include <gui/Surface.h> | 
 | 27 | #include "camera2/Parameters.h" | 
 | 28 | #include "ProCamera2Client.h" | 
| Igor Murashkin | a91537e | 2013-02-21 12:02:29 -0800 | [diff] [blame] | 29 | #include "camera2/ProFrameProcessor.h" | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 30 |  | 
 | 31 | namespace android { | 
 | 32 | using namespace camera2; | 
 | 33 |  | 
 | 34 | static int getCallingPid() { | 
 | 35 |     return IPCThreadState::self()->getCallingPid(); | 
 | 36 | } | 
 | 37 |  | 
 | 38 | static int getCallingUid() { | 
 | 39 |     return IPCThreadState::self()->getCallingUid(); | 
 | 40 | } | 
 | 41 |  | 
 | 42 | // Interface used by CameraService | 
 | 43 |  | 
 | 44 | ProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService, | 
 | 45 |         const sp<IProCameraCallbacks>& remoteCallback, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 46 |         const String16& clientPackageName, | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 47 |         int cameraId, | 
 | 48 |         int cameraFacing, | 
 | 49 |         int clientPid, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 50 |         uid_t clientUid, | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 51 |         int servicePid): | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 52 |         ProClient(cameraService, remoteCallback, clientPackageName, | 
 | 53 |                 cameraId, cameraFacing, clientPid, clientUid, servicePid), | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 54 |         mSharedCameraCallbacks(remoteCallback) | 
 | 55 | { | 
 | 56 |     ATRACE_CALL(); | 
 | 57 |     ALOGI("ProCamera %d: Opened", cameraId); | 
 | 58 |  | 
 | 59 |     mDevice = new Camera2Device(cameraId); | 
 | 60 |  | 
 | 61 |     mExclusiveLock = false; | 
 | 62 | } | 
 | 63 |  | 
 | 64 | status_t ProCamera2Client::checkPid(const char* checkLocation) const { | 
 | 65 |     int callingPid = getCallingPid(); | 
 | 66 |     if (callingPid == mClientPid) return NO_ERROR; | 
 | 67 |  | 
 | 68 |     ALOGE("%s: attempt to use a locked camera from a different process" | 
 | 69 |             " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid); | 
 | 70 |     return PERMISSION_DENIED; | 
 | 71 | } | 
 | 72 |  | 
 | 73 | status_t ProCamera2Client::initialize(camera_module_t *module) | 
 | 74 | { | 
 | 75 |     ATRACE_CALL(); | 
 | 76 |     ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId); | 
 | 77 |     status_t res; | 
 | 78 |  | 
 | 79 |     res = mDevice->initialize(module); | 
 | 80 |     if (res != OK) { | 
 | 81 |         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", | 
 | 82 |                 __FUNCTION__, mCameraId, strerror(-res), res); | 
 | 83 |         return NO_INIT; | 
 | 84 |     } | 
 | 85 |  | 
 | 86 |     res = mDevice->setNotifyCallback(this); | 
 | 87 |  | 
| Igor Murashkin | a91537e | 2013-02-21 12:02:29 -0800 | [diff] [blame] | 88 |     String8 threadName; | 
 | 89 |     mFrameProcessor = new ProFrameProcessor(this); | 
 | 90 |     threadName = String8::format("PC2-%d-FrameProc", | 
 | 91 |             mCameraId); | 
 | 92 |     mFrameProcessor->run(threadName.string()); | 
 | 93 |  | 
 | 94 |     mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID, | 
 | 95 |                                       FRAME_PROCESSOR_LISTENER_MAX_ID, | 
 | 96 |                                       /*listener*/this); | 
 | 97 |  | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 98 |     return OK; | 
 | 99 | } | 
 | 100 |  | 
 | 101 | ProCamera2Client::~ProCamera2Client() { | 
 | 102 |     ATRACE_CALL(); | 
 | 103 |  | 
 | 104 |     mDestructionStarted = true; | 
 | 105 |  | 
 | 106 |     disconnect(); | 
 | 107 |  | 
 | 108 |     ALOGI("ProCamera %d: Closed", mCameraId); | 
 | 109 | } | 
 | 110 |  | 
 | 111 | status_t ProCamera2Client::exclusiveTryLock() { | 
 | 112 |     ATRACE_CALL(); | 
 | 113 |     ALOGV("%s", __FUNCTION__); | 
 | 114 |  | 
 | 115 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 116 |     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); | 
 | 117 |  | 
 | 118 |     if (!mExclusiveLock) { | 
 | 119 |         mExclusiveLock = true; | 
 | 120 |  | 
 | 121 |         if (mRemoteCallback != NULL) { | 
 | 122 |             mRemoteCallback->onLockStatusChanged( | 
 | 123 |                               IProCameraCallbacks::LOCK_ACQUIRED); | 
 | 124 |         } | 
 | 125 |  | 
 | 126 |         ALOGV("%s: exclusive lock acquired", __FUNCTION__); | 
 | 127 |  | 
 | 128 |         return OK; | 
 | 129 |     } | 
 | 130 |  | 
 | 131 |     // TODO: have a PERMISSION_DENIED case for when someone else owns the lock | 
 | 132 |  | 
 | 133 |     // don't allow recursive locking | 
 | 134 |     ALOGW("%s: exclusive lock already exists - recursive locking is not" | 
 | 135 |           "allowed", __FUNCTION__); | 
 | 136 |  | 
 | 137 |     return ALREADY_EXISTS; | 
 | 138 | } | 
 | 139 |  | 
 | 140 | status_t ProCamera2Client::exclusiveLock() { | 
 | 141 |     ATRACE_CALL(); | 
 | 142 |     ALOGV("%s", __FUNCTION__); | 
 | 143 |  | 
 | 144 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 145 |     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); | 
 | 146 |  | 
 | 147 |     /** | 
 | 148 |      * TODO: this should asynchronously 'wait' until the lock becomes available | 
 | 149 |      * if another client already has an exclusive lock. | 
 | 150 |      * | 
 | 151 |      * once we have proper sharing support this will need to do | 
 | 152 |      * more than just return immediately | 
 | 153 |      */ | 
 | 154 |     if (!mExclusiveLock) { | 
 | 155 |         mExclusiveLock = true; | 
 | 156 |  | 
 | 157 |         if (mRemoteCallback != NULL) { | 
 | 158 |             mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED); | 
 | 159 |         } | 
 | 160 |  | 
 | 161 |         ALOGV("%s: exclusive lock acquired", __FUNCTION__); | 
 | 162 |  | 
 | 163 |         return OK; | 
 | 164 |     } | 
 | 165 |  | 
 | 166 |     // don't allow recursive locking | 
 | 167 |     ALOGW("%s: exclusive lock already exists - recursive locking is not allowed" | 
 | 168 |                                                                 , __FUNCTION__); | 
 | 169 |     return ALREADY_EXISTS; | 
 | 170 | } | 
 | 171 |  | 
 | 172 | status_t ProCamera2Client::exclusiveUnlock() { | 
 | 173 |     ATRACE_CALL(); | 
 | 174 |     ALOGV("%s", __FUNCTION__); | 
 | 175 |  | 
 | 176 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 177 |     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); | 
 | 178 |  | 
 | 179 |     // don't allow unlocking if we have no lock | 
 | 180 |     if (!mExclusiveLock) { | 
 | 181 |         ALOGW("%s: cannot unlock, no lock was held in the first place", | 
 | 182 |               __FUNCTION__); | 
 | 183 |         return BAD_VALUE; | 
 | 184 |     } | 
 | 185 |  | 
 | 186 |     mExclusiveLock = false; | 
 | 187 |     if (mRemoteCallback != NULL ) { | 
 | 188 |         mRemoteCallback->onLockStatusChanged( | 
 | 189 |                                        IProCameraCallbacks::LOCK_RELEASED); | 
 | 190 |     } | 
 | 191 |     ALOGV("%s: exclusive lock released", __FUNCTION__); | 
 | 192 |  | 
 | 193 |     return OK; | 
 | 194 | } | 
 | 195 |  | 
 | 196 | bool ProCamera2Client::hasExclusiveLock() { | 
 | 197 |     return mExclusiveLock; | 
 | 198 | } | 
 | 199 |  | 
 | 200 | status_t ProCamera2Client::submitRequest(camera_metadata_t* request, | 
 | 201 |                                          bool streaming) { | 
 | 202 |     ATRACE_CALL(); | 
 | 203 |     ALOGV("%s", __FUNCTION__); | 
 | 204 |  | 
 | 205 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 206 |     if (!mExclusiveLock) { | 
 | 207 |         return PERMISSION_DENIED; | 
 | 208 |     } | 
 | 209 |  | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 210 |     CameraMetadata metadata(request); | 
 | 211 |  | 
 | 212 |     if (streaming) { | 
 | 213 |         return mDevice->setStreamingRequest(metadata); | 
 | 214 |     } else { | 
 | 215 |         return mDevice->capture(metadata); | 
 | 216 |     } | 
 | 217 |  | 
 | 218 |     // unreachable. thx gcc for a useless warning | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 219 |     return OK; | 
 | 220 | } | 
 | 221 |  | 
 | 222 | status_t ProCamera2Client::cancelRequest(int requestId) { | 
 | 223 |     ATRACE_CALL(); | 
 | 224 |     ALOGV("%s", __FUNCTION__); | 
 | 225 |  | 
 | 226 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 227 |     if (!mExclusiveLock) { | 
 | 228 |         return PERMISSION_DENIED; | 
 | 229 |     } | 
 | 230 |  | 
 | 231 |     ALOGE("%s: not fully implemented yet", __FUNCTION__); | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 232 |     return INVALID_OPERATION; | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 233 | } | 
 | 234 |  | 
 | 235 | status_t ProCamera2Client::requestStream(int streamId) { | 
 | 236 |     ALOGE("%s: not implemented yet", __FUNCTION__); | 
 | 237 |  | 
 | 238 |     return INVALID_OPERATION; | 
 | 239 | } | 
 | 240 |  | 
 | 241 | status_t ProCamera2Client::cancelStream(int streamId) { | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 242 |     ATRACE_CALL(); | 
 | 243 |     ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 244 |  | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 245 |     status_t res; | 
 | 246 |     if ( (res = checkPid(__FUNCTION__) ) != OK) return res; | 
 | 247 |  | 
 | 248 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 249 |  | 
| Igor Murashkin | 5835cc4 | 2013-02-20 19:29:53 -0800 | [diff] [blame] | 250 |     mDevice->clearStreamingRequest(); | 
 | 251 |  | 
 | 252 |     status_t code; | 
 | 253 |     if ((code = mDevice->waitUntilDrained()) != OK) { | 
 | 254 |         ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code); | 
 | 255 |     } | 
 | 256 |  | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 257 |     return mDevice->deleteStream(streamId); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 258 | } | 
 | 259 |  | 
 | 260 | status_t ProCamera2Client::createStream(int width, int height, int format, | 
| Igor Murashkin | 76f8b43 | 2013-02-20 19:15:15 -0800 | [diff] [blame] | 261 |                       const sp<IGraphicBufferProducer>& bufferProducer, | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 262 |                       /*out*/ | 
 | 263 |                       int* streamId) | 
 | 264 | { | 
 | 265 |     if (streamId) { | 
 | 266 |         *streamId = -1; | 
 | 267 |     } | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 268 |  | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 269 |     ATRACE_CALL(); | 
 | 270 |     ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format); | 
 | 271 |  | 
 | 272 |     status_t res; | 
 | 273 |     if ( (res = checkPid(__FUNCTION__) ) != OK) return res; | 
 | 274 |  | 
 | 275 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 276 |  | 
| Igor Murashkin | 76f8b43 | 2013-02-20 19:15:15 -0800 | [diff] [blame] | 277 |     sp<IBinder> binder; | 
 | 278 |     sp<ANativeWindow> window; | 
 | 279 |     if (bufferProducer != 0) { | 
 | 280 |         binder = bufferProducer->asBinder(); | 
 | 281 |         window = new Surface(bufferProducer); | 
 | 282 |     } | 
 | 283 |  | 
 | 284 |     return mDevice->createStream(window, width, height, format, /*size*/1, | 
 | 285 |                                  streamId); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 286 | } | 
 | 287 |  | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 288 | // Create a request object from a template. | 
 | 289 | // -- Caller owns the newly allocated metadata | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 290 | status_t ProCamera2Client::createDefaultRequest(int templateId, | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 291 |                              /*out*/ | 
 | 292 |                               camera_metadata** request) | 
 | 293 | { | 
 | 294 |     ATRACE_CALL(); | 
 | 295 |     ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 296 |  | 
| Igor Murashkin | 3261fd3 | 2013-02-20 19:02:36 -0800 | [diff] [blame] | 297 |     if (request) { | 
 | 298 |         *request = NULL; | 
 | 299 |     } | 
 | 300 |  | 
 | 301 |     status_t res; | 
 | 302 |     if ( (res = checkPid(__FUNCTION__) ) != OK) return res; | 
 | 303 |  | 
 | 304 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 305 |  | 
 | 306 |     CameraMetadata metadata; | 
 | 307 |     if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) { | 
 | 308 |         *request = metadata.release(); | 
 | 309 |     } | 
 | 310 |  | 
 | 311 |     return res; | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 312 | } | 
 | 313 |  | 
| Igor Murashkin | 7b33a74 | 2013-02-21 13:49:26 -0800 | [diff] [blame] | 314 | status_t ProCamera2Client::getCameraInfo(int cameraId, | 
 | 315 |                                          /*out*/ | 
 | 316 |                                          camera_metadata** info) | 
 | 317 | { | 
 | 318 |     if (cameraId != mCameraId) { | 
 | 319 |         return INVALID_OPERATION; | 
 | 320 |     } | 
 | 321 |  | 
 | 322 |     CameraMetadata deviceInfo = mDevice->info(); | 
 | 323 |     *info = deviceInfo.release(); | 
 | 324 |  | 
 | 325 |     return OK; | 
 | 326 | } | 
 | 327 |  | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 328 | status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) { | 
 | 329 |     String8 result; | 
 | 330 |     result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n", | 
 | 331 |             mCameraId, | 
 | 332 |             getRemoteCallback()->asBinder().get(), | 
 | 333 |             mClientPid); | 
 | 334 |     result.append("  State: "); | 
 | 335 |  | 
 | 336 |     // TODO: print dynamic/request section from most recent requests | 
| Igor Murashkin | a91537e | 2013-02-21 12:02:29 -0800 | [diff] [blame] | 337 |     mFrameProcessor->dump(fd, args); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 338 |  | 
 | 339 | #define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break; | 
 | 340 |  | 
 | 341 |     result = "  Device dump:\n"; | 
 | 342 |     write(fd, result.string(), result.size()); | 
 | 343 |  | 
 | 344 |     status_t res = mDevice->dump(fd, args); | 
 | 345 |     if (res != OK) { | 
 | 346 |         result = String8::format("   Error dumping device: %s (%d)", | 
 | 347 |                 strerror(-res), res); | 
 | 348 |         write(fd, result.string(), result.size()); | 
 | 349 |     } | 
 | 350 |  | 
 | 351 | #undef CASE_APPEND_ENUM | 
 | 352 |     return NO_ERROR; | 
 | 353 | } | 
 | 354 |  | 
 | 355 | // IProCameraUser interface | 
 | 356 |  | 
 | 357 | void ProCamera2Client::disconnect() { | 
 | 358 |     ATRACE_CALL(); | 
 | 359 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 360 |     status_t res; | 
 | 361 |  | 
 | 362 |     // Allow both client and the media server to disconnect at all times | 
 | 363 |     int callingPid = getCallingPid(); | 
 | 364 |     if (callingPid != mClientPid && callingPid != mServicePid) return; | 
 | 365 |  | 
 | 366 |     if (mDevice == 0) return; | 
 | 367 |  | 
 | 368 |     ALOGV("Camera %d: Shutting down", mCameraId); | 
| Igor Murashkin | a91537e | 2013-02-21 12:02:29 -0800 | [diff] [blame] | 369 |     mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID, | 
 | 370 |                                     FRAME_PROCESSOR_LISTENER_MAX_ID, | 
 | 371 |                                     /*listener*/this); | 
 | 372 |     mFrameProcessor->requestExit(); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 373 |     ALOGV("Camera %d: Waiting for threads", mCameraId); | 
| Igor Murashkin | a91537e | 2013-02-21 12:02:29 -0800 | [diff] [blame] | 374 |     mFrameProcessor->join(); | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 375 |     ALOGV("Camera %d: Disconnecting device", mCameraId); | 
 | 376 |  | 
 | 377 |     mDevice->disconnect(); | 
 | 378 |  | 
 | 379 |     mDevice.clear(); | 
 | 380 |  | 
 | 381 |     ProClient::disconnect(); | 
 | 382 | } | 
 | 383 |  | 
 | 384 | status_t ProCamera2Client::connect(const sp<IProCameraCallbacks>& client) { | 
 | 385 |     ATRACE_CALL(); | 
 | 386 |     ALOGV("%s: E", __FUNCTION__); | 
 | 387 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 388 |  | 
 | 389 |     if (mClientPid != 0 && getCallingPid() != mClientPid) { | 
 | 390 |         ALOGE("%s: Camera %d: Connection attempt from pid %d; " | 
 | 391 |                 "current locked to pid %d", __FUNCTION__, | 
 | 392 |                 mCameraId, getCallingPid(), mClientPid); | 
 | 393 |         return BAD_VALUE; | 
 | 394 |     } | 
 | 395 |  | 
 | 396 |     mClientPid = getCallingPid(); | 
 | 397 |  | 
 | 398 |     mRemoteCallback = client; | 
 | 399 |     mSharedCameraCallbacks = client; | 
 | 400 |  | 
 | 401 |     return OK; | 
 | 402 | } | 
 | 403 |  | 
 | 404 | /** Device-related methods */ | 
 | 405 |  | 
 | 406 | void ProCamera2Client::notifyError(int errorCode, int arg1, int arg2) { | 
 | 407 |     ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, | 
 | 408 |                                                                     arg1, arg2); | 
 | 409 | } | 
 | 410 |  | 
 | 411 | void ProCamera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) { | 
 | 412 |     ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__, | 
 | 413 |             frameNumber, timestamp); | 
 | 414 | } | 
 | 415 |  | 
 | 416 | void ProCamera2Client::notifyAutoFocus(uint8_t newState, int triggerId) { | 
 | 417 |     ALOGV("%s: Autofocus state now %d, last trigger %d", | 
 | 418 |             __FUNCTION__, newState, triggerId); | 
 | 419 |  | 
 | 420 |     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); | 
 | 421 |     if (l.mRemoteCallback != 0) { | 
 | 422 |         l.mRemoteCallback->notifyCallback(CAMERA_MSG_FOCUS_MOVE, | 
 | 423 |                 1, 0); | 
 | 424 |     } | 
 | 425 |     if (l.mRemoteCallback != 0) { | 
 | 426 |         l.mRemoteCallback->notifyCallback(CAMERA_MSG_FOCUS, | 
 | 427 |                 1, 0); | 
 | 428 |     } | 
 | 429 | } | 
 | 430 |  | 
 | 431 | void ProCamera2Client::notifyAutoExposure(uint8_t newState, int triggerId) { | 
 | 432 |     ALOGV("%s: Autoexposure state now %d, last trigger %d", | 
 | 433 |             __FUNCTION__, newState, triggerId); | 
 | 434 | } | 
 | 435 |  | 
 | 436 | void ProCamera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) { | 
 | 437 |     ALOGV("%s: Auto-whitebalance state now %d, last trigger %d", | 
 | 438 |             __FUNCTION__, newState, triggerId); | 
 | 439 | } | 
 | 440 |  | 
 | 441 | int ProCamera2Client::getCameraId() const { | 
 | 442 |     return mCameraId; | 
 | 443 | } | 
 | 444 |  | 
 | 445 | const sp<Camera2Device>& ProCamera2Client::getCameraDevice() { | 
 | 446 |     return mDevice; | 
 | 447 | } | 
 | 448 |  | 
 | 449 | const sp<CameraService>& ProCamera2Client::getCameraService() { | 
 | 450 |     return mCameraService; | 
 | 451 | } | 
 | 452 |  | 
 | 453 | ProCamera2Client::SharedCameraCallbacks::Lock::Lock( | 
 | 454 |                                                  SharedCameraCallbacks &client): | 
 | 455 |         mRemoteCallback(client.mRemoteCallback), | 
 | 456 |         mSharedClient(client) { | 
 | 457 |     mSharedClient.mRemoteCallbackLock.lock(); | 
 | 458 | } | 
 | 459 |  | 
 | 460 | ProCamera2Client::SharedCameraCallbacks::Lock::~Lock() { | 
 | 461 |     mSharedClient.mRemoteCallbackLock.unlock(); | 
 | 462 | } | 
 | 463 |  | 
 | 464 | ProCamera2Client::SharedCameraCallbacks::SharedCameraCallbacks | 
 | 465 |                                          (const sp<IProCameraCallbacks>&client): | 
 | 466 |         mRemoteCallback(client) { | 
 | 467 | } | 
 | 468 |  | 
 | 469 | ProCamera2Client::SharedCameraCallbacks& | 
 | 470 |                              ProCamera2Client::SharedCameraCallbacks::operator=( | 
 | 471 |         const sp<IProCameraCallbacks>&client) { | 
 | 472 |     Mutex::Autolock l(mRemoteCallbackLock); | 
 | 473 |     mRemoteCallback = client; | 
 | 474 |     return *this; | 
 | 475 | } | 
 | 476 |  | 
 | 477 | void ProCamera2Client::SharedCameraCallbacks::clear() { | 
 | 478 |     Mutex::Autolock l(mRemoteCallbackLock); | 
 | 479 |     mRemoteCallback.clear(); | 
 | 480 | } | 
 | 481 |  | 
| Igor Murashkin | a91537e | 2013-02-21 12:02:29 -0800 | [diff] [blame] | 482 | void ProCamera2Client::onFrameAvailable(int32_t frameId, | 
 | 483 |                                         const CameraMetadata& frame) { | 
 | 484 |     ATRACE_CALL(); | 
 | 485 |     ALOGV("%s", __FUNCTION__); | 
 | 486 |  | 
 | 487 |     Mutex::Autolock icl(mIProCameraUserLock); | 
 | 488 |     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); | 
 | 489 |  | 
 | 490 |     if (mRemoteCallback != NULL) { | 
 | 491 |         CameraMetadata tmp(frame); | 
 | 492 |         camera_metadata_t* meta = tmp.release(); | 
 | 493 |         ALOGV("%s: meta = %p ", __FUNCTION__, meta); | 
 | 494 |         mRemoteCallback->onResultReceived(frameId, meta); | 
 | 495 |         tmp.acquire(meta); | 
 | 496 |     } | 
 | 497 |  | 
 | 498 | } | 
 | 499 |  | 
| Igor Murashkin | 985fd30 | 2013-02-20 18:24:43 -0800 | [diff] [blame] | 500 | } // namespace android |