blob: 5f89fa31a47eb18a6934f240fe5d2ad88e875f1b [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
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
Yin-Chia Yehead91462016-01-06 16:45:08 -080020#include <vector>
21#include <utility>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080022#include <inttypes.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080023#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080024#include "ACameraDevice.h"
25#include "ACameraMetadata.h"
26#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080027#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080028
29using namespace android;
30
31namespace android {
32// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080033const char* CameraDevice::kContextKey = "Context";
34const char* CameraDevice::kDeviceKey = "Device";
35const char* CameraDevice::kErrorCodeKey = "ErrorCode";
36const char* CameraDevice::kCallbackFpKey = "Callback";
37const char* CameraDevice::kSessionSpKey = "SessionSp";
38const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
39const char* CameraDevice::kTimeStampKey = "TimeStamp";
40const char* CameraDevice::kCaptureResultKey = "CaptureResult";
41const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
42const char* CameraDevice::kSequenceIdKey = "SequenceId";
43const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080044
45/**
46 * CameraDevice Implementation
47 */
48CameraDevice::CameraDevice(
49 const char* id,
50 ACameraDevice_StateCallbacks* cb,
51 std::unique_ptr<ACameraMetadata> chars,
52 ACameraDevice* wrapper) :
53 mCameraId(id),
54 mAppCallbacks(*cb),
55 mChars(std::move(chars)),
56 mServiceCallback(new ServiceCallback(this)),
57 mWrapper(wrapper),
58 mInError(false),
59 mError(ACAMERA_OK),
60 mIdle(true) {
61 mClosing = false;
62 // Setup looper thread to perfrom device callbacks to app
63 mCbLooper = new ALooper;
64 mCbLooper->setName("C2N-dev-looper");
65 status_t ret = mCbLooper->start(
66 /*runOnCallingThread*/false,
67 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080068 PRIORITY_DEFAULT);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080069 mHandler = new CallbackHandler();
70 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080071
72 CameraMetadata metadata = mChars->mData;
73 camera_metadata_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
74 if (entry.count != 1) {
75 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
76 mPartialResultCount = 1;
77 } else {
78 mPartialResultCount = entry.data.i32[0];
79 }
80
81 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
82 if (entry.count != 2) {
83 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
84 mShadingMapSize[0] = 0;
85 mShadingMapSize[1] = 0;
86 } else {
87 mShadingMapSize[0] = entry.data.i32[0];
88 mShadingMapSize[1] = entry.data.i32[1];
89 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080090}
91
Yin-Chia Yehead91462016-01-06 16:45:08 -080092// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080093CameraDevice::~CameraDevice() {
94 Mutex::Autolock _l(mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -080095 if (!isClosed()) {
96 disconnectLocked();
97 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080098 if (mCbLooper != nullptr) {
99 mCbLooper->unregisterHandler(mHandler->id());
100 mCbLooper->stop();
101 }
102 mCbLooper.clear();
103 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800104}
105
106// TODO: cached created request?
107camera_status_t
108CameraDevice::createCaptureRequest(
109 ACameraDevice_request_template templateId,
110 ACaptureRequest** request) const {
111 Mutex::Autolock _l(mDeviceLock);
112 camera_status_t ret = checkCameraClosedOrErrorLocked();
113 if (ret != ACAMERA_OK) {
114 return ret;
115 }
116 if (mRemote == nullptr) {
117 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
118 }
119 CameraMetadata rawRequest;
120 status_t remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
121 if (remoteRet == BAD_VALUE) {
122 ALOGW("Create capture request failed! template %d is not supported on this device",
123 templateId);
124 return ACAMERA_ERROR_UNSUPPORTED;
125 } else if (remoteRet != OK) {
126 ALOGE("Create capture request failed! error %d", remoteRet);
127 return ACAMERA_ERROR_UNKNOWN;
128 }
129 ACaptureRequest* outReq = new ACaptureRequest();
130 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
131 outReq->targets = new ACameraOutputTargets();
132 *request = outReq;
133 return ACAMERA_OK;
134}
135
Yin-Chia Yehead91462016-01-06 16:45:08 -0800136camera_status_t
137CameraDevice::createCaptureSession(
138 const ACaptureSessionOutputContainer* outputs,
139 const ACameraCaptureSession_stateCallbacks* callbacks,
140 /*out*/ACameraCaptureSession** session) {
141 Mutex::Autolock _l(mDeviceLock);
142 camera_status_t ret = checkCameraClosedOrErrorLocked();
143 if (ret != ACAMERA_OK) {
144 return ret;
145 }
146
147 if (mCurrentSession != nullptr) {
148 mCurrentSession->closeByDevice();
149 stopRepeatingLocked();
150 }
151
152 // Create new session
153 ret = configureStreamsLocked(outputs);
154 if (ret != ACAMERA_OK) {
155 ALOGE("Fail to create new session. cannot configure streams");
156 return ret;
157 }
158
159 ACameraCaptureSession* newSession = new ACameraCaptureSession(
160 mNextSessionId++, outputs, callbacks, this);
161
162 bool configureSucceeded = (ret == ACAMERA_OK);
163
164 // set new session as current session
165 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
166 mCurrentSession = newSession;
167 *session = newSession;
168 return ACAMERA_OK;
169}
170
171camera_status_t
172CameraDevice::captureLocked(
173 sp<ACameraCaptureSession> session,
174 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
175 int numRequests, ACaptureRequest** requests,
176 /*optional*/int* captureSequenceId) {
177 return submitRequestsLocked(
178 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
179}
180
181camera_status_t
182CameraDevice::setRepeatingRequestsLocked(
183 sp<ACameraCaptureSession> session,
184 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
185 int numRequests, ACaptureRequest** requests,
186 /*optional*/int* captureSequenceId) {
187 return submitRequestsLocked(
188 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
189}
190
191camera_status_t
192CameraDevice::submitRequestsLocked(
193 sp<ACameraCaptureSession> session,
194 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
195 int numRequests, ACaptureRequest** requests,
196 /*optional*/int* captureSequenceId,
197 bool isRepeating) {
198 camera_status_t ret = checkCameraClosedOrErrorLocked();
199 if (ret != ACAMERA_OK) {
200 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
201 return ret;
202 }
203
204 // Form List/Vector of capture request
205 List<sp<CaptureRequest> > requestList;
206 Vector<sp<CaptureRequest> > requestsV;
207 requestsV.setCapacity(numRequests);
208 for (int i = 0; i < numRequests; i++) {
209 sp<CaptureRequest> req;
210 ret = allocateCaptureRequest(requests[i], req);
211 if (ret != ACAMERA_OK) {
212 ALOGE("Convert capture request to internal format failure! ret %d", ret);
213 return ret;
214 }
215 if (req->mSurfaceList.empty()) {
216 ALOGE("Capture request without output target cannot be submitted!");
217 return ACAMERA_ERROR_INVALID_PARAMETER;
218 }
219 requestList.push_back(req);
220 requestsV.push_back(req);
221 }
222
223 if (isRepeating) {
224 ret = stopRepeatingLocked();
225 if (ret != ACAMERA_OK) {
226 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
227 return ret;
228 }
229 }
230
231 int sequenceId;
232 int64_t lastFrameNumber;
233
234 sequenceId = mRemote->submitRequestList(requestList, isRepeating, &lastFrameNumber);
235 if (sequenceId < 0) {
236 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
237 return ACAMERA_ERROR_UNKNOWN;
238 }
239
240 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
241 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
242
243 if (isRepeating) {
244 // stopRepeating above should have cleanup repeating sequence id
245 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
246 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
247 return ACAMERA_ERROR_CAMERA_DEVICE;
248 }
249 mRepeatingSequenceId = sequenceId;
250 } else {
251 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
252 }
253
254 if (mIdle) {
255 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
256 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
257 msg->setObject(kSessionSpKey, session);
258 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
259 msg->post();
260 }
261 mIdle = false;
262 mBusySession = session;
263
264 if (captureSequenceId) {
265 *captureSequenceId = sequenceId;
266 }
267 return ACAMERA_OK;
268}
269
270camera_status_t
271CameraDevice::allocateCaptureRequest(
272 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
273 camera_status_t ret;
274 sp<CaptureRequest> req(new CaptureRequest());
275 req->mMetadata = request->settings->mData;
276 req->mIsReprocess = false; // NDK does not support reprocessing yet
277
278 for (auto outputTarget : request->targets->mOutputs) {
279 ANativeWindow* anw = outputTarget.mWindow;
280 sp<Surface> surface;
281 ret = getSurfaceFromANativeWindow(anw, surface);
282 if (ret != ACAMERA_OK) {
283 ALOGE("Bad output target in capture request! ret %d", ret);
284 return ret;
285 }
286 req->mSurfaceList.push_back(surface);
287 }
288 outReq = req;
289 return ACAMERA_OK;
290}
291
292ACaptureRequest*
293CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
294 ACaptureRequest* pRequest = new ACaptureRequest();
295 CameraMetadata clone = req->mMetadata;
296 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
297 pRequest->targets = new ACameraOutputTargets();
298 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
299 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
300 ACameraOutputTarget outputTarget(anw);
301 pRequest->targets->mOutputs.insert(outputTarget);
302 }
303 return pRequest;
304}
305
306void
307CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
308 if (req == nullptr) {
309 return;
310 }
311 delete req->settings;
312 delete req->targets;
313 delete req;
314}
315
316void
317CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
318 if (isClosed()) {
319 // Device is closing already. do nothing
320 return;
321 }
322
323 if (session != mCurrentSession) {
324 // Session has been replaced by other seesion or device is closed
325 return;
326 }
327 mCurrentSession = nullptr;
328
329 // Should not happen
330 if (!session->mIsClosed) {
331 ALOGE("Error: unclosed session %p reaches end of life!", session);
332 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
333 return;
334 }
335
336 // No new session, unconfigure now
337 camera_status_t ret = configureStreamsLocked(nullptr);
338 if (ret != ACAMERA_OK) {
339 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
340 }
341}
342
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800343void
344CameraDevice::disconnectLocked() {
345 if (mClosing.exchange(true)) {
346 // Already closing, just return
347 ALOGW("Camera device %s is already closing.", getId());
348 return;
349 }
350
351 if (mRemote != nullptr) {
352 mRemote->disconnect();
353 }
354 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800355
356 if (mCurrentSession != nullptr) {
357 mCurrentSession->closeByDevice();
358 mCurrentSession = nullptr;
359 }
360}
361
362camera_status_t
363CameraDevice::stopRepeatingLocked() {
364 camera_status_t ret = checkCameraClosedOrErrorLocked();
365 if (ret != ACAMERA_OK) {
366 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
367 return ret;
368 }
369 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
370 int repeatingSequenceId = mRepeatingSequenceId;
371 mRepeatingSequenceId = REQUEST_ID_NONE;
372
373 int64_t lastFrameNumber;
374 status_t remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
375 if (remoteRet != OK) {
376 ALOGE("Stop repeating request fails in remote! ret %d", remoteRet);
377 return ACAMERA_ERROR_UNKNOWN;
378 }
379 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
380 }
381 return ACAMERA_OK;
382}
383
384camera_status_t
385CameraDevice::waitUntilIdleLocked() {
386 camera_status_t ret = checkCameraClosedOrErrorLocked();
387 if (ret != ACAMERA_OK) {
388 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
389 return ret;
390 }
391
392 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
393 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
394 return ACAMERA_ERROR_INVALID_OPERATION;
395 }
396
397 status_t remoteRet = mRemote->waitUntilIdle();
398 if (remoteRet != OK) {
399 ALOGE("Camera device %s waitUntilIdle failed! ret %d", getId(), remoteRet);
400 // TODO: define a function to convert status_t -> camera_status_t
401 return ACAMERA_ERROR_UNKNOWN;
402 }
403
404 return ACAMERA_OK;
405}
406
407camera_status_t
408CameraDevice::getIGBPfromSessionOutput(
409 const ACaptureSessionOutput& config,
410 sp<IGraphicBufferProducer>& out) {
411 ANativeWindow* anw = config.mWindow;
412 if (anw == nullptr) {
413 ALOGE("Error: output ANativeWindow is null");
414 return ACAMERA_ERROR_INVALID_PARAMETER;
415 }
416 int value;
417 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
418 if (value != NATIVE_WINDOW_SURFACE) {
419 ALOGE("Error: ANativeWindow is not backed by Surface!");
420 return ACAMERA_ERROR_INVALID_PARAMETER;
421 }
422 const sp<Surface> surface(static_cast<Surface*>(anw));
423 out = surface->getIGraphicBufferProducer();
424 return ACAMERA_OK;
425}
426
427camera_status_t
428CameraDevice::getSurfaceFromANativeWindow(
429 ANativeWindow* anw, sp<Surface>& out) {
430 if (anw == nullptr) {
431 ALOGE("Error: output ANativeWindow is null");
432 return ACAMERA_ERROR_INVALID_PARAMETER;
433 }
434 int value;
435 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
436 if (value != NATIVE_WINDOW_SURFACE) {
437 ALOGE("Error: ANativeWindow is not backed by Surface!");
438 return ACAMERA_ERROR_INVALID_PARAMETER;
439 }
440 sp<Surface> surface(static_cast<Surface*>(anw));
441 out = surface;
442 return ACAMERA_OK;
443}
444
445camera_status_t
446CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
447 ACaptureSessionOutputContainer emptyOutput;
448 if (outputs == nullptr) {
449 outputs = &emptyOutput;
450 }
451
452 bool success = false;
453 camera_status_t ret = checkCameraClosedOrErrorLocked();
454 if (ret != ACAMERA_OK) {
455 return ret;
456 }
457
458 std::set<OutputConfiguration> outputSet;
459 for (auto outConfig : outputs->mOutputs) {
460 sp<IGraphicBufferProducer> iGBP(nullptr);
461 ret = getIGBPfromSessionOutput(outConfig, iGBP);
462 if (ret != ACAMERA_OK) {
463 return ret;
464 }
465 outputSet.insert(OutputConfiguration(iGBP, outConfig.mRotation));
466 }
467 std::set<OutputConfiguration> addSet = outputSet;
468 std::vector<int> deleteList;
469
470 // Determine which streams need to be created, which to be deleted
471 for (auto& kvPair : mConfiguredOutputs) {
472 int streamId = kvPair.first;
473 OutputConfiguration& outConfig = kvPair.second;
474 if (outputSet.count(outConfig) == 0) {
475 deleteList.push_back(streamId); // Need to delete a no longer needed stream
476 } else {
477 addSet.erase(outConfig); // No need to add already existing stream
478 }
479 }
480
481 ret = stopRepeatingLocked();
482 if (ret != ACAMERA_OK) {
483 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
484 return ret;
485 }
486
487 ret = waitUntilIdleLocked();
488 if (ret != ACAMERA_OK) {
489 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
490 return ret;
491 }
492
493 // Send onReady to previous session
494 // CurrentSession will be updated after configureStreamLocked, so here
495 // mCurrentSession is the session to be replaced by a new session
496 if (!mIdle && mCurrentSession != nullptr) {
497 if (mBusySession != mCurrentSession) {
498 ALOGE("Current session != busy session");
499 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
500 return ACAMERA_ERROR_CAMERA_DEVICE;
501 }
502 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
503 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
504 msg->setObject(kSessionSpKey, mBusySession);
505 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
506 mBusySession.clear();
507 msg->post();
508 }
509 mIdle = true;
510
511 status_t remoteRet = mRemote->beginConfigure();
512 if (remoteRet != ACAMERA_OK) {
513 ALOGE("Camera device %s begin configure failed, ret %d", getId(), remoteRet);
514 return ACAMERA_ERROR_UNKNOWN;
515 }
516
517 // delete to-be-deleted streams
518 for (auto streamId : deleteList) {
519 remoteRet = mRemote->deleteStream(streamId);
520 if (remoteRet != ACAMERA_OK) {
521 ALOGE("Camera device %s fails to remove stream %d", getId(), streamId);
522 return ACAMERA_ERROR_UNKNOWN;
523 }
524 mConfiguredOutputs.erase(streamId);
525 }
526
527 // add new streams
528 for (auto outConfig : addSet) {
529 remoteRet = mRemote->createStream(outConfig);
530 if (remoteRet < 0) {
531 ALOGE("Camera device %s fails to create stream", getId());
532 return ACAMERA_ERROR_UNKNOWN;
533 }
534 int streamId = remoteRet; // Weird, right?
535 mConfiguredOutputs.insert(std::make_pair(streamId, outConfig));
536 }
537
538 remoteRet = mRemote->endConfigure();
539 if (remoteRet == BAD_VALUE) {
540 ALOGE("Camera device %s cannnot support app output configuration", getId());
541 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
542 } else if (remoteRet != ACAMERA_OK) {
543 ALOGE("Camera device %s end configure failed, ret %d", getId(), remoteRet);
544 return ACAMERA_ERROR_UNKNOWN;
545 }
546
547 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800548}
549
550void
551CameraDevice::setRemoteDevice(sp<ICameraDeviceUser> remote) {
552 Mutex::Autolock _l(mDeviceLock);
553 mRemote = remote;
554}
555
556camera_status_t
557CameraDevice::checkCameraClosedOrErrorLocked() const {
558 if (mRemote == nullptr) {
559 ALOGE("%s: camera device already closed", __FUNCTION__);
560 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
561 }
562 if (mInError) {// triggered by onDeviceError
563 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
564 return mError;
565 }
566 return ACAMERA_OK;
567}
568
569void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800570CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
571 mInError = true;
572 mError = error;
573 return;
574}
575
576void
577CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
578 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
579 if (isError) {
580 mFutureErrorSet.insert(frameNumber);
581 } else if (frameNumber <= mCompletedFrameNumber) {
582 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
583 frameNumber, mCompletedFrameNumber);
584 return;
585 } else {
586 if (frameNumber != mCompletedFrameNumber + 1) {
587 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
588 mCompletedFrameNumber + 1, frameNumber);
589 // Do not assert as in java implementation
590 }
591 mCompletedFrameNumber = frameNumber;
592 }
593 update();
594}
595
596void
597CameraDevice::FrameNumberTracker::update() {
598 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
599 int64_t errorFrameNumber = *it;
600 if (errorFrameNumber == mCompletedFrameNumber + 1) {
601 mCompletedFrameNumber++;
602 it = mFutureErrorSet.erase(it);
603 } else if (errorFrameNumber <= mCompletedFrameNumber) {
604 // This should not happen, but deal with it anyway
605 ALOGE("Completd frame number passed through current frame number!");
606 // erase the old error since it's no longer useful
607 it = mFutureErrorSet.erase(it);
608 } else {
609 // Normal requests hasn't catched up error frames, just break
610 break;
611 }
612 }
613 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
614}
615
616void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800617CameraDevice::onCaptureErrorLocked(
618 ICameraDeviceCallbacks::CameraErrorCode errorCode,
619 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800620 int sequenceId = resultExtras.requestId;
621 int64_t frameNumber = resultExtras.frameNumber;
622 int32_t burstId = resultExtras.burstId;
623
624 // No way to report buffer error now
625 if (errorCode == ICameraDeviceCallbacks::CameraErrorCode::ERROR_CAMERA_BUFFER) {
626 ALOGE("Camera %s Lost output buffer for frame %" PRId64,
627 getId(), frameNumber);
628 return;
629 }
630 // Fire capture failure callback if there is one registered
631 auto it = mSequenceCallbackMap.find(sequenceId);
632 if (it != mSequenceCallbackMap.end()) {
633 CallbackHolder cbh = (*it).second;
634 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
635 sp<ACameraCaptureSession> session = cbh.mSession;
636 if ((size_t) burstId >= cbh.mRequests.size()) {
637 ALOGE("%s: Error: request index %d out of bound (size %zu)",
638 __FUNCTION__, burstId, cbh.mRequests.size());
639 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
640 return;
641 }
642 sp<CaptureRequest> request = cbh.mRequests[burstId];
643 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
644 failure->frameNumber = frameNumber;
645 // TODO: refine this when implementing flush
646 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
647 failure->sequenceId = sequenceId;
648 failure->wasImageCaptured = (errorCode ==
649 ICameraDeviceCallbacks::CameraErrorCode::ERROR_CAMERA_RESULT);
650
651 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
652 msg->setPointer(kContextKey, cbh.mCallbacks.context);
653 msg->setObject(kSessionSpKey, session);
654 msg->setPointer(kCallbackFpKey, (void*) onError);
655 msg->setObject(kCaptureRequestKey, request);
656 msg->setObject(kCaptureFailureKey, failure);
657 msg->post();
658 }
659
660 // Update tracker
661 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
662 checkAndFireSequenceCompleteLocked();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800663}
664
665void CameraDevice::CallbackHandler::onMessageReceived(
666 const sp<AMessage> &msg) {
667 switch (msg->what()) {
668 case kWhatOnDisconnected:
669 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800670 case kWhatSessionStateCb:
671 case kWhatCaptureStart:
672 case kWhatCaptureResult:
673 case kWhatCaptureFail:
674 case kWhatCaptureSeqEnd:
675 case kWhatCaptureSeqAbort:
676 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800677 break;
678 default:
679 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
680 return;
681 }
682 // Check the common part of all message
683 void* context;
684 bool found = msg->findPointer(kContextKey, &context);
685 if (!found) {
686 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
687 return;
688 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800689 switch (msg->what()) {
690 case kWhatOnDisconnected:
691 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800692 ACameraDevice* dev;
693 found = msg->findPointer(kDeviceKey, (void**) &dev);
694 if (!found || dev == nullptr) {
695 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
696 return;
697 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800698 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800699 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800700 if (!found) {
701 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
702 return;
703 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800704 if (onDisconnected == nullptr) {
705 return;
706 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800707 (*onDisconnected)(context, dev);
708 break;
709 }
710 case kWhatOnError:
711 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800712 ACameraDevice* dev;
713 found = msg->findPointer(kDeviceKey, (void**) &dev);
714 if (!found || dev == nullptr) {
715 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
716 return;
717 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800718 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800719 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800720 if (!found) {
721 ALOGE("%s: Cannot find onError!", __FUNCTION__);
722 return;
723 }
724 int errorCode;
725 found = msg->findInt32(kErrorCodeKey, &errorCode);
726 if (!found) {
727 ALOGE("%s: Cannot find error code!", __FUNCTION__);
728 return;
729 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800730 if (onError == nullptr) {
731 return;
732 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800733 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800734 break;
735 }
736 case kWhatSessionStateCb:
737 case kWhatCaptureStart:
738 case kWhatCaptureResult:
739 case kWhatCaptureFail:
740 case kWhatCaptureSeqEnd:
741 case kWhatCaptureSeqAbort:
742 {
743 sp<RefBase> obj;
744 found = msg->findObject(kSessionSpKey, &obj);
745 if (!found || obj == nullptr) {
746 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
747 return;
748 }
749 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
750 sp<CaptureRequest> requestSp = nullptr;
751 switch (msg->what()) {
752 case kWhatCaptureStart:
753 case kWhatCaptureResult:
754 case kWhatCaptureFail:
755 found = msg->findObject(kCaptureRequestKey, &obj);
756 if (!found) {
757 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
758 return;
759 }
760 requestSp = static_cast<CaptureRequest*>(obj.get());
761 break;
762 }
763
764 switch (msg->what()) {
765 case kWhatSessionStateCb:
766 {
767 ACameraCaptureSession_stateCallback onState;
768 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
769 if (!found) {
770 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
771 return;
772 }
773 if (onState == nullptr) {
774 return;
775 }
776 (*onState)(context, session.get());
777 break;
778 }
779 case kWhatCaptureStart:
780 {
781 ACameraCaptureSession_captureCallback_start onStart;
782 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
783 if (!found) {
784 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
785 return;
786 }
787 if (onStart == nullptr) {
788 return;
789 }
790 int64_t timestamp;
791 found = msg->findInt64(kTimeStampKey, &timestamp);
792 if (!found) {
793 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
794 return;
795 }
796 ACaptureRequest* request = allocateACaptureRequest(requestSp);
797 (*onStart)(context, session.get(), request, timestamp);
798 freeACaptureRequest(request);
799 break;
800 }
801 case kWhatCaptureResult:
802 {
803 ACameraCaptureSession_captureCallback_result onResult;
804 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
805 if (!found) {
806 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
807 return;
808 }
809 if (onResult == nullptr) {
810 return;
811 }
812
813 found = msg->findObject(kCaptureResultKey, &obj);
814 if (!found) {
815 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
816 return;
817 }
818 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
819 ACaptureRequest* request = allocateACaptureRequest(requestSp);
820 (*onResult)(context, session.get(), request, result.get());
821 freeACaptureRequest(request);
822 break;
823 }
824 case kWhatCaptureFail:
825 {
826 ACameraCaptureSession_captureCallback_failed onFail;
827 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
828 if (!found) {
829 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
830 return;
831 }
832 if (onFail == nullptr) {
833 return;
834 }
835
836 found = msg->findObject(kCaptureFailureKey, &obj);
837 if (!found) {
838 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
839 return;
840 }
841 sp<CameraCaptureFailure> failureSp(
842 static_cast<CameraCaptureFailure*>(obj.get()));
843 ACameraCaptureFailure* failure =
844 static_cast<ACameraCaptureFailure*>(failureSp.get());
845 ACaptureRequest* request = allocateACaptureRequest(requestSp);
846 (*onFail)(context, session.get(), request, failure);
847 freeACaptureRequest(request);
848 delete failure;
849 break;
850 }
851 case kWhatCaptureSeqEnd:
852 {
853 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
854 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
855 if (!found) {
856 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
857 return;
858 }
859 if (onSeqEnd == nullptr) {
860 return;
861 }
862 int seqId;
863 found = msg->findInt32(kSequenceIdKey, &seqId);
864 if (!found) {
865 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
866 return;
867 }
868 int64_t frameNumber;
869 found = msg->findInt64(kFrameNumberKey, &frameNumber);
870 if (!found) {
871 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
872 return;
873 }
874 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
875 break;
876 }
877 case kWhatCaptureSeqAbort:
878 {
879 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
880 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
881 if (!found) {
882 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
883 return;
884 }
885 if (onSeqAbort == nullptr) {
886 return;
887 }
888 int seqId;
889 found = msg->findInt32(kSequenceIdKey, &seqId);
890 if (!found) {
891 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
892 return;
893 }
894 (*onSeqAbort)(context, session.get(), seqId);
895 break;
896 }
897 }
898 break;
899 }
900 }
901}
902
903CameraDevice::CallbackHolder::CallbackHolder(
904 sp<ACameraCaptureSession> session,
905 const Vector<sp<CaptureRequest> >& requests,
906 bool isRepeating,
907 ACameraCaptureSession_captureCallbacks* cbs) :
908 mSession(session), mRequests(requests),
909 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
910
911void
912CameraDevice::checkRepeatingSequenceCompleteLocked(
913 const int sequenceId, const int64_t lastFrameNumber) {
914 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
915 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
916 if (mSequenceCallbackMap.count(sequenceId) == 0) {
917 ALOGW("No callback found for sequenceId %d", sequenceId);
918 return;
919 }
920 // remove callback holder from callback map
921 auto cbIt = mSequenceCallbackMap.find(sequenceId);
922 CallbackHolder cbh = cbIt->second;
923 mSequenceCallbackMap.erase(cbIt);
924 // send seq aborted callback
925 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
926 msg->setPointer(kContextKey, cbh.mCallbacks.context);
927 msg->setObject(kSessionSpKey, cbh.mSession);
928 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
929 msg->setInt32(kSequenceIdKey, sequenceId);
930 msg->post();
931 } else {
932 // Use mSequenceLastFrameNumberMap to track
933 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
934
935 // Last frame might have arrived. Check now
936 checkAndFireSequenceCompleteLocked();
937 }
938}
939
940void
941CameraDevice::checkAndFireSequenceCompleteLocked() {
942 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
943 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
944 auto it = mSequenceLastFrameNumberMap.begin();
945 while (it != mSequenceLastFrameNumberMap.end()) {
946 int sequenceId = it->first;
947 int64_t lastFrameNumber = it->second;
948 bool seqCompleted = false;
949 bool hasCallback = true;
950
951 if (mRemote == nullptr) {
952 ALOGW("Camera %s closed while checking sequence complete", getId());
953 return;
954 }
955
956 // Check if there is callback for this sequence
957 // This should not happen because we always register callback (with nullptr inside)
958 if (mSequenceCallbackMap.count(sequenceId) == 0) {
959 ALOGW("No callback found for sequenceId %d", sequenceId);
960 hasCallback = false;
961 }
962
963 if (lastFrameNumber <= completedFrameNumber) {
964 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
965 sequenceId, lastFrameNumber, completedFrameNumber);
966 seqCompleted = true;
967 }
968
969 if (seqCompleted && hasCallback) {
970 // remove callback holder from callback map
971 auto cbIt = mSequenceCallbackMap.find(sequenceId);
972 CallbackHolder cbh = cbIt->second;
973 mSequenceCallbackMap.erase(cbIt);
974 // send seq complete callback
975 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
976 msg->setPointer(kContextKey, cbh.mCallbacks.context);
977 msg->setObject(kSessionSpKey, cbh.mSession);
978 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
979 msg->setInt32(kSequenceIdKey, sequenceId);
980 msg->setInt64(kFrameNumberKey, lastFrameNumber);
981
982 // Clear the session sp before we send out the message
983 // This will guarantee the rare case where the message is processed
984 // before cbh goes out of scope and causing we call the session
985 // destructor while holding device lock
986 cbh.mSession.clear();
987 msg->post();
988 }
989
990 // No need to track sequence complete if there is no callback registered
991 if (seqCompleted || !hasCallback) {
992 it = mSequenceLastFrameNumberMap.erase(it);
993 } else {
994 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800995 }
996 }
997}
998
999/**
1000 * Camera service callback implementation
1001 */
1002void
1003CameraDevice::ServiceCallback::onDeviceError(
1004 CameraErrorCode errorCode,
1005 const CaptureResultExtras& resultExtras) {
1006 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1007 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
1008
1009 sp<CameraDevice> dev = mDevice.promote();
1010 if (dev == nullptr) {
1011 return; // device has been closed
1012 }
1013
1014 Mutex::Autolock _l(dev->mDeviceLock);
1015 if (dev->mRemote == nullptr) {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001016 return; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001017 }
1018 switch (errorCode) {
1019 case ERROR_CAMERA_DISCONNECTED:
1020 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001021 // Camera is disconnected, close the session and expect no more callbacks
1022 if (dev->mCurrentSession != nullptr) {
1023 dev->mCurrentSession->closeByDevice();
1024 dev->mCurrentSession = nullptr;
1025 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001026 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1027 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1028 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001029 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001030 msg->post();
1031 break;
1032 }
1033 default:
1034 ALOGE("Unknown error from camera device: %d", errorCode);
1035 // no break
1036 case ERROR_CAMERA_DEVICE:
1037 case ERROR_CAMERA_SERVICE:
1038 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001039 switch (errorCode) {
1040 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001041 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001042 break;
1043 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001044 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001045 break;
1046 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001047 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001048 break;
1049 }
1050 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1051 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1052 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001053 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001054 msg->setInt32(kErrorCodeKey, errorCode);
1055 msg->post();
1056 break;
1057 }
1058 case ERROR_CAMERA_REQUEST:
1059 case ERROR_CAMERA_RESULT:
1060 case ERROR_CAMERA_BUFFER:
1061 dev->onCaptureErrorLocked(errorCode, resultExtras);
1062 break;
1063 }
1064}
1065
1066void
1067CameraDevice::ServiceCallback::onDeviceIdle() {
1068 ALOGV("Camera is now idle");
1069 sp<CameraDevice> dev = mDevice.promote();
1070 if (dev == nullptr) {
1071 return; // device has been closed
1072 }
1073
1074 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001075 if (dev->isClosed() || dev->mRemote == nullptr) {
1076 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001077 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001078
1079 if (dev->mIdle) {
1080 // Already in idle state. Possibly other thread did waitUntilIdle
1081 return;
1082 }
1083
1084 if (dev->mCurrentSession != nullptr) {
1085 ALOGE("onDeviceIdle sending state cb");
1086 if (dev->mBusySession != dev->mCurrentSession) {
1087 ALOGE("Current session != busy session");
1088 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
1089 return;
1090 }
1091 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1092 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1093 msg->setObject(kSessionSpKey, dev->mBusySession);
1094 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1095 // Make sure we clear the sp first so the session destructor can
1096 // only happen on handler thread (where we don't hold device/session lock)
1097 dev->mBusySession.clear();
1098 msg->post();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001099 }
1100 dev->mIdle = true;
1101}
1102
1103void
1104CameraDevice::ServiceCallback::onCaptureStarted(
1105 const CaptureResultExtras& resultExtras,
1106 int64_t timestamp) {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001107 sp<CameraDevice> dev = mDevice.promote();
1108 if (dev == nullptr) {
1109 return; // device has been closed
1110 }
1111 Mutex::Autolock _l(dev->mDeviceLock);
1112 if (dev->isClosed() || dev->mRemote == nullptr) {
1113 return;
1114 }
1115
1116 int sequenceId = resultExtras.requestId;
1117 int64_t frameNumber = resultExtras.frameNumber;
1118 int32_t burstId = resultExtras.burstId;
1119
1120 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1121 if (it != dev->mSequenceCallbackMap.end()) {
1122 CallbackHolder cbh = (*it).second;
1123 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1124 sp<ACameraCaptureSession> session = cbh.mSession;
1125 if ((size_t) burstId >= cbh.mRequests.size()) {
1126 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1127 __FUNCTION__, burstId, cbh.mRequests.size());
1128 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1129 }
1130 sp<CaptureRequest> request = cbh.mRequests[burstId];
1131 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1132 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1133 msg->setObject(kSessionSpKey, session);
1134 msg->setPointer(kCallbackFpKey, (void*) onStart);
1135 msg->setObject(kCaptureRequestKey, request);
1136 msg->setInt64(kTimeStampKey, timestamp);
1137 msg->post();
1138 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001139}
1140
1141void
1142CameraDevice::ServiceCallback::onResultReceived(
1143 const CameraMetadata& metadata,
1144 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001145 sp<CameraDevice> dev = mDevice.promote();
1146 if (dev == nullptr) {
1147 return; // device has been closed
1148 }
1149 int sequenceId = resultExtras.requestId;
1150 int64_t frameNumber = resultExtras.frameNumber;
1151 int32_t burstId = resultExtras.burstId;
1152 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1153
1154 if (!isPartialResult) {
1155 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1156 }
1157
1158 Mutex::Autolock _l(dev->mDeviceLock);
1159 if (dev->mRemote == nullptr) {
1160 return; // device has been disconnected
1161 }
1162
1163 if (dev->isClosed()) {
1164 if (!isPartialResult) {
1165 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1166 }
1167 // early return to avoid callback sent to closed devices
1168 return;
1169 }
1170
1171 CameraMetadata metadataCopy = metadata;
1172 // Copied from java implmentation. Why do we need this?
1173 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
1174
1175 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1176 if (it != dev->mSequenceCallbackMap.end()) {
1177 CallbackHolder cbh = (*it).second;
1178 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1179 cbh.mCallbacks.onCaptureProgressed :
1180 cbh.mCallbacks.onCaptureCompleted;
1181 sp<ACameraCaptureSession> session = cbh.mSession;
1182 if ((size_t) burstId >= cbh.mRequests.size()) {
1183 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1184 __FUNCTION__, burstId, cbh.mRequests.size());
1185 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1186 }
1187 sp<CaptureRequest> request = cbh.mRequests[burstId];
1188 sp<ACameraMetadata> result(new ACameraMetadata(
1189 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1190
1191 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1192 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1193 msg->setObject(kSessionSpKey, session);
1194 msg->setPointer(kCallbackFpKey, (void*) onResult);
1195 msg->setObject(kCaptureRequestKey, request);
1196 msg->setObject(kCaptureResultKey, result);
1197 msg->post();
1198 }
1199
1200 if (!isPartialResult) {
1201 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1202 dev->checkAndFireSequenceCompleteLocked();
1203 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001204}
1205
1206void
1207CameraDevice::ServiceCallback::onPrepared(int) {
1208 // Prepare not yet implemented in NDK
1209 return;
1210}
1211
1212} // namespace android