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