blob: 907802c8878f53e8fea89e5cc5324f214b4effea [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>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080021#include <inttypes.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080022#include <android/hardware/ICameraService.h>
23#include <camera2/SubmitInfo.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080024#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080025#include "ACameraDevice.h"
26#include "ACameraMetadata.h"
27#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080028#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080029
30using namespace android;
31
32namespace android {
33// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080034const char* CameraDevice::kContextKey = "Context";
35const char* CameraDevice::kDeviceKey = "Device";
36const char* CameraDevice::kErrorCodeKey = "ErrorCode";
37const char* CameraDevice::kCallbackFpKey = "Callback";
38const char* CameraDevice::kSessionSpKey = "SessionSp";
39const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
40const char* CameraDevice::kTimeStampKey = "TimeStamp";
41const char* CameraDevice::kCaptureResultKey = "CaptureResult";
42const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
43const char* CameraDevice::kSequenceIdKey = "SequenceId";
44const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070045const char* CameraDevice::kAnwKey = "Anw";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080046
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),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070062 mIdle(true),
63 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 mClosing = false;
65 // Setup looper thread to perfrom device callbacks to app
66 mCbLooper = new ALooper;
67 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080068 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080069 /*runOnCallingThread*/false,
70 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080071 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080072 if (err != OK) {
73 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
74 __FUNCTION__, strerror(-err), err);
75 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
76 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080077 mHandler = new CallbackHandler();
78 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080079
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080080 const CameraMetadata& metadata = mChars->getInternalData();
81 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080082 if (entry.count != 1) {
83 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
84 mPartialResultCount = 1;
85 } else {
86 mPartialResultCount = entry.data.i32[0];
87 }
88
89 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
90 if (entry.count != 2) {
91 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
92 mShadingMapSize[0] = 0;
93 mShadingMapSize[1] = 0;
94 } else {
95 mShadingMapSize[0] = entry.data.i32[0];
96 mShadingMapSize[1] = entry.data.i32[1];
97 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080098}
99
Yin-Chia Yehead91462016-01-06 16:45:08 -0800100// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800101CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700102 sp<ACameraCaptureSession> session = mCurrentSession.promote();
103 {
104 Mutex::Autolock _l(mDeviceLock);
105 if (!isClosed()) {
106 disconnectLocked(session);
107 }
108 mCurrentSession = nullptr;
109 if (mCbLooper != nullptr) {
110 mCbLooper->unregisterHandler(mHandler->id());
111 mCbLooper->stop();
112 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800113 }
114 mCbLooper.clear();
115 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116}
117
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700118void
119CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
120 msg->post();
121 msg.clear();
122 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
123 cleanupMsg->post();
124}
125
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126// TODO: cached created request?
127camera_status_t
128CameraDevice::createCaptureRequest(
129 ACameraDevice_request_template templateId,
130 ACaptureRequest** request) const {
131 Mutex::Autolock _l(mDeviceLock);
132 camera_status_t ret = checkCameraClosedOrErrorLocked();
133 if (ret != ACAMERA_OK) {
134 return ret;
135 }
136 if (mRemote == nullptr) {
137 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
138 }
139 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800140 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
141 if (remoteRet.serviceSpecificErrorCode() ==
142 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800143 ALOGW("Create capture request failed! template %d is not supported on this device",
144 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700145 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800146 } else if (!remoteRet.isOk()) {
147 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800148 return ACAMERA_ERROR_UNKNOWN;
149 }
150 ACaptureRequest* outReq = new ACaptureRequest();
151 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
152 outReq->targets = new ACameraOutputTargets();
153 *request = outReq;
154 return ACAMERA_OK;
155}
156
Yin-Chia Yehead91462016-01-06 16:45:08 -0800157camera_status_t
158CameraDevice::createCaptureSession(
159 const ACaptureSessionOutputContainer* outputs,
160 const ACameraCaptureSession_stateCallbacks* callbacks,
161 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700162 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800163 Mutex::Autolock _l(mDeviceLock);
164 camera_status_t ret = checkCameraClosedOrErrorLocked();
165 if (ret != ACAMERA_OK) {
166 return ret;
167 }
168
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700169 if (currentSession != nullptr) {
170 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800171 stopRepeatingLocked();
172 }
173
174 // Create new session
175 ret = configureStreamsLocked(outputs);
176 if (ret != ACAMERA_OK) {
177 ALOGE("Fail to create new session. cannot configure streams");
178 return ret;
179 }
180
181 ACameraCaptureSession* newSession = new ACameraCaptureSession(
182 mNextSessionId++, outputs, callbacks, this);
183
Yin-Chia Yehead91462016-01-06 16:45:08 -0800184 // set new session as current session
185 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
186 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700187 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800188 *session = newSession;
189 return ACAMERA_OK;
190}
191
192camera_status_t
193CameraDevice::captureLocked(
194 sp<ACameraCaptureSession> session,
195 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
196 int numRequests, ACaptureRequest** requests,
197 /*optional*/int* captureSequenceId) {
198 return submitRequestsLocked(
199 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
200}
201
202camera_status_t
203CameraDevice::setRepeatingRequestsLocked(
204 sp<ACameraCaptureSession> session,
205 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
206 int numRequests, ACaptureRequest** requests,
207 /*optional*/int* captureSequenceId) {
208 return submitRequestsLocked(
209 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
210}
211
212camera_status_t
213CameraDevice::submitRequestsLocked(
214 sp<ACameraCaptureSession> session,
215 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
216 int numRequests, ACaptureRequest** requests,
217 /*optional*/int* captureSequenceId,
218 bool isRepeating) {
219 camera_status_t ret = checkCameraClosedOrErrorLocked();
220 if (ret != ACAMERA_OK) {
221 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
222 return ret;
223 }
224
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800225 // Form two vectors of capture request, one for internal tracking
226 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800227 Vector<sp<CaptureRequest> > requestsV;
228 requestsV.setCapacity(numRequests);
229 for (int i = 0; i < numRequests; i++) {
230 sp<CaptureRequest> req;
231 ret = allocateCaptureRequest(requests[i], req);
232 if (ret != ACAMERA_OK) {
233 ALOGE("Convert capture request to internal format failure! ret %d", ret);
234 return ret;
235 }
236 if (req->mSurfaceList.empty()) {
237 ALOGE("Capture request without output target cannot be submitted!");
238 return ACAMERA_ERROR_INVALID_PARAMETER;
239 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800240 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800241 requestsV.push_back(req);
242 }
243
244 if (isRepeating) {
245 ret = stopRepeatingLocked();
246 if (ret != ACAMERA_OK) {
247 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
248 return ret;
249 }
250 }
251
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800252 binder::Status remoteRet;
253 hardware::camera2::utils::SubmitInfo info;
254 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
255 int sequenceId = info.mRequestId;
256 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800257 if (sequenceId < 0) {
258 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
259 return ACAMERA_ERROR_UNKNOWN;
260 }
261
262 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
263 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
264
265 if (isRepeating) {
266 // stopRepeating above should have cleanup repeating sequence id
267 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
268 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
269 return ACAMERA_ERROR_CAMERA_DEVICE;
270 }
271 mRepeatingSequenceId = sequenceId;
272 } else {
273 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
274 }
275
276 if (mIdle) {
277 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
278 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
279 msg->setObject(kSessionSpKey, session);
280 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700281 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800282 }
283 mIdle = false;
284 mBusySession = session;
285
286 if (captureSequenceId) {
287 *captureSequenceId = sequenceId;
288 }
289 return ACAMERA_OK;
290}
291
292camera_status_t
293CameraDevice::allocateCaptureRequest(
294 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
295 camera_status_t ret;
296 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800297 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800298 req->mIsReprocess = false; // NDK does not support reprocessing yet
299
300 for (auto outputTarget : request->targets->mOutputs) {
301 ANativeWindow* anw = outputTarget.mWindow;
302 sp<Surface> surface;
303 ret = getSurfaceFromANativeWindow(anw, surface);
304 if (ret != ACAMERA_OK) {
305 ALOGE("Bad output target in capture request! ret %d", ret);
306 return ret;
307 }
308 req->mSurfaceList.push_back(surface);
309 }
310 outReq = req;
311 return ACAMERA_OK;
312}
313
314ACaptureRequest*
315CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
316 ACaptureRequest* pRequest = new ACaptureRequest();
317 CameraMetadata clone = req->mMetadata;
318 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
319 pRequest->targets = new ACameraOutputTargets();
320 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
321 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
322 ACameraOutputTarget outputTarget(anw);
323 pRequest->targets->mOutputs.insert(outputTarget);
324 }
325 return pRequest;
326}
327
328void
329CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
330 if (req == nullptr) {
331 return;
332 }
333 delete req->settings;
334 delete req->targets;
335 delete req;
336}
337
338void
339CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
340 if (isClosed()) {
341 // Device is closing already. do nothing
342 return;
343 }
344
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700345 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800346 // Session has been replaced by other seesion or device is closed
347 return;
348 }
349 mCurrentSession = nullptr;
350
351 // Should not happen
352 if (!session->mIsClosed) {
353 ALOGE("Error: unclosed session %p reaches end of life!", session);
354 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
355 return;
356 }
357
358 // No new session, unconfigure now
359 camera_status_t ret = configureStreamsLocked(nullptr);
360 if (ret != ACAMERA_OK) {
361 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
362 }
363}
364
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800365void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700366CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800367 if (mClosing.exchange(true)) {
368 // Already closing, just return
369 ALOGW("Camera device %s is already closing.", getId());
370 return;
371 }
372
373 if (mRemote != nullptr) {
374 mRemote->disconnect();
375 }
376 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800377
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700378 if (session != nullptr) {
379 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800380 }
381}
382
383camera_status_t
384CameraDevice::stopRepeatingLocked() {
385 camera_status_t ret = checkCameraClosedOrErrorLocked();
386 if (ret != ACAMERA_OK) {
387 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
388 return ret;
389 }
390 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
391 int repeatingSequenceId = mRepeatingSequenceId;
392 mRepeatingSequenceId = REQUEST_ID_NONE;
393
394 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800395 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700396 if (remoteRet.serviceSpecificErrorCode() ==
397 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
398 ALOGV("Repeating request is already stopped.");
399 return ACAMERA_OK;
400 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800401 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800402 return ACAMERA_ERROR_UNKNOWN;
403 }
404 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
405 }
406 return ACAMERA_OK;
407}
408
409camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700410CameraDevice::flushLocked(ACameraCaptureSession* session) {
411 camera_status_t ret = checkCameraClosedOrErrorLocked();
412 if (ret != ACAMERA_OK) {
413 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
414 return ret;
415 }
416
417 // This should never happen because creating a new session will close
418 // previous one and thus reject any API call from previous session.
419 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700420 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700421 ALOGE("Camera %s session %p is not current active session!", getId(), session);
422 return ACAMERA_ERROR_INVALID_OPERATION;
423 }
424
425 if (mFlushing) {
426 ALOGW("Camera %s is already aborting captures", getId());
427 return ACAMERA_OK;
428 }
429
430 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700431
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700432 // Send onActive callback to guarantee there is always active->ready transition
433 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
434 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
435 msg->setObject(kSessionSpKey, session);
436 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700437 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700438
439 // If device is already idling, send callback and exit early
440 if (mIdle) {
441 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
442 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
443 msg->setObject(kSessionSpKey, session);
444 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700445 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700446 mFlushing = false;
447 return ACAMERA_OK;
448 }
449
450 int64_t lastFrameNumber;
451 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
452 if (!remoteRet.isOk()) {
453 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
454 return ACAMERA_ERROR_UNKNOWN;
455 }
456 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
457 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
458 }
459 return ACAMERA_OK;
460}
461
462camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800463CameraDevice::waitUntilIdleLocked() {
464 camera_status_t ret = checkCameraClosedOrErrorLocked();
465 if (ret != ACAMERA_OK) {
466 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
467 return ret;
468 }
469
470 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
471 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
472 return ACAMERA_ERROR_INVALID_OPERATION;
473 }
474
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800475 binder::Status remoteRet = mRemote->waitUntilIdle();
476 if (!remoteRet.isOk()) {
477 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800478 // TODO: define a function to convert status_t -> camera_status_t
479 return ACAMERA_ERROR_UNKNOWN;
480 }
481
482 return ACAMERA_OK;
483}
484
485camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700486CameraDevice::getIGBPfromAnw(
487 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800488 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800489 if (anw == nullptr) {
490 ALOGE("Error: output ANativeWindow is null");
491 return ACAMERA_ERROR_INVALID_PARAMETER;
492 }
493 int value;
494 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800495 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800496 ALOGE("Error: ANativeWindow is not backed by Surface!");
497 return ACAMERA_ERROR_INVALID_PARAMETER;
498 }
499 const sp<Surface> surface(static_cast<Surface*>(anw));
500 out = surface->getIGraphicBufferProducer();
501 return ACAMERA_OK;
502}
503
504camera_status_t
505CameraDevice::getSurfaceFromANativeWindow(
506 ANativeWindow* anw, sp<Surface>& out) {
507 if (anw == nullptr) {
508 ALOGE("Error: output ANativeWindow is null");
509 return ACAMERA_ERROR_INVALID_PARAMETER;
510 }
511 int value;
512 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800513 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800514 ALOGE("Error: ANativeWindow is not backed by Surface!");
515 return ACAMERA_ERROR_INVALID_PARAMETER;
516 }
517 sp<Surface> surface(static_cast<Surface*>(anw));
518 out = surface;
519 return ACAMERA_OK;
520}
521
522camera_status_t
523CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
524 ACaptureSessionOutputContainer emptyOutput;
525 if (outputs == nullptr) {
526 outputs = &emptyOutput;
527 }
528
Yin-Chia Yehead91462016-01-06 16:45:08 -0800529 camera_status_t ret = checkCameraClosedOrErrorLocked();
530 if (ret != ACAMERA_OK) {
531 return ret;
532 }
533
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700534 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800535 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700536 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800537 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700538 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800539 if (ret != ACAMERA_OK) {
540 return ret;
541 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700542 outputSet.insert(std::make_pair(
543 anw, OutputConfiguration(iGBP, outConfig.mRotation)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800544 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700545 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800546 std::vector<int> deleteList;
547
548 // Determine which streams need to be created, which to be deleted
549 for (auto& kvPair : mConfiguredOutputs) {
550 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700551 auto& outputPair = kvPair.second;
552 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800553 deleteList.push_back(streamId); // Need to delete a no longer needed stream
554 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700555 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800556 }
557 }
558
559 ret = stopRepeatingLocked();
560 if (ret != ACAMERA_OK) {
561 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
562 return ret;
563 }
564
565 ret = waitUntilIdleLocked();
566 if (ret != ACAMERA_OK) {
567 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
568 return ret;
569 }
570
571 // Send onReady to previous session
572 // CurrentSession will be updated after configureStreamLocked, so here
573 // mCurrentSession is the session to be replaced by a new session
574 if (!mIdle && mCurrentSession != nullptr) {
575 if (mBusySession != mCurrentSession) {
576 ALOGE("Current session != busy session");
577 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
578 return ACAMERA_ERROR_CAMERA_DEVICE;
579 }
580 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
581 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
582 msg->setObject(kSessionSpKey, mBusySession);
583 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
584 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700585 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800586 }
587 mIdle = true;
588
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800589 binder::Status remoteRet = mRemote->beginConfigure();
590 if (!remoteRet.isOk()) {
591 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800592 return ACAMERA_ERROR_UNKNOWN;
593 }
594
595 // delete to-be-deleted streams
596 for (auto streamId : deleteList) {
597 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800598 if (!remoteRet.isOk()) {
599 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
600 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800601 return ACAMERA_ERROR_UNKNOWN;
602 }
603 mConfiguredOutputs.erase(streamId);
604 }
605
606 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700607 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800608 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700609 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800610 if (!remoteRet.isOk()) {
611 ALOGE("Camera device %s failed to create stream: %s", getId(),
612 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800613 return ACAMERA_ERROR_UNKNOWN;
614 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700615 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800616 }
617
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800618 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
619 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
620 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
621 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800622 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800623 } else if (!remoteRet.isOk()) {
624 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800625 return ACAMERA_ERROR_UNKNOWN;
626 }
627
628 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800629}
630
631void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800632CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800633 Mutex::Autolock _l(mDeviceLock);
634 mRemote = remote;
635}
636
637camera_status_t
638CameraDevice::checkCameraClosedOrErrorLocked() const {
639 if (mRemote == nullptr) {
640 ALOGE("%s: camera device already closed", __FUNCTION__);
641 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
642 }
643 if (mInError) {// triggered by onDeviceError
644 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
645 return mError;
646 }
647 return ACAMERA_OK;
648}
649
650void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800651CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
652 mInError = true;
653 mError = error;
654 return;
655}
656
657void
658CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
659 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
660 if (isError) {
661 mFutureErrorSet.insert(frameNumber);
662 } else if (frameNumber <= mCompletedFrameNumber) {
663 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
664 frameNumber, mCompletedFrameNumber);
665 return;
666 } else {
667 if (frameNumber != mCompletedFrameNumber + 1) {
668 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
669 mCompletedFrameNumber + 1, frameNumber);
670 // Do not assert as in java implementation
671 }
672 mCompletedFrameNumber = frameNumber;
673 }
674 update();
675}
676
677void
678CameraDevice::FrameNumberTracker::update() {
679 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
680 int64_t errorFrameNumber = *it;
681 if (errorFrameNumber == mCompletedFrameNumber + 1) {
682 mCompletedFrameNumber++;
683 it = mFutureErrorSet.erase(it);
684 } else if (errorFrameNumber <= mCompletedFrameNumber) {
685 // This should not happen, but deal with it anyway
686 ALOGE("Completd frame number passed through current frame number!");
687 // erase the old error since it's no longer useful
688 it = mFutureErrorSet.erase(it);
689 } else {
690 // Normal requests hasn't catched up error frames, just break
691 break;
692 }
693 }
694 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
695}
696
697void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800698CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800699 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800700 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800701 int sequenceId = resultExtras.requestId;
702 int64_t frameNumber = resultExtras.frameNumber;
703 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700704 auto it = mSequenceCallbackMap.find(sequenceId);
705 if (it == mSequenceCallbackMap.end()) {
706 ALOGE("%s: Error: capture sequence index %d not found!",
707 __FUNCTION__, sequenceId);
708 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800709 return;
710 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700711
712 CallbackHolder cbh = (*it).second;
713 sp<ACameraCaptureSession> session = cbh.mSession;
714 if ((size_t) burstId >= cbh.mRequests.size()) {
715 ALOGE("%s: Error: request index %d out of bound (size %zu)",
716 __FUNCTION__, burstId, cbh.mRequests.size());
717 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
718 return;
719 }
720 sp<CaptureRequest> request = cbh.mRequests[burstId];
721
722 // Handle buffer error
723 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
724 int32_t streamId = resultExtras.errorStreamId;
725 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
726 cbh.mCallbacks.onCaptureBufferLost;
727 auto outputPairIt = mConfiguredOutputs.find(streamId);
728 if (outputPairIt == mConfiguredOutputs.end()) {
729 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800730 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
731 return;
732 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700733 ANativeWindow* anw = outputPairIt->second.first;
734
735 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
736 getId(), anw, frameNumber);
737
738 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
739 msg->setPointer(kContextKey, cbh.mCallbacks.context);
740 msg->setObject(kSessionSpKey, session);
741 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
742 msg->setObject(kCaptureRequestKey, request);
743 msg->setPointer(kAnwKey, (void*) anw);
744 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700745 postSessionMsgAndCleanup(msg);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700746 } else { // Handle other capture failures
747 // Fire capture failure callback if there is one registered
748 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800749 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
750 failure->frameNumber = frameNumber;
751 // TODO: refine this when implementing flush
752 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
753 failure->sequenceId = sequenceId;
754 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800755 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800756
757 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
758 msg->setPointer(kContextKey, cbh.mCallbacks.context);
759 msg->setObject(kSessionSpKey, session);
760 msg->setPointer(kCallbackFpKey, (void*) onError);
761 msg->setObject(kCaptureRequestKey, request);
762 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700763 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800764
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700765 // Update tracker
766 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
767 checkAndFireSequenceCompleteLocked();
768 }
769 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800770}
771
772void CameraDevice::CallbackHandler::onMessageReceived(
773 const sp<AMessage> &msg) {
774 switch (msg->what()) {
775 case kWhatOnDisconnected:
776 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800777 case kWhatSessionStateCb:
778 case kWhatCaptureStart:
779 case kWhatCaptureResult:
780 case kWhatCaptureFail:
781 case kWhatCaptureSeqEnd:
782 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700783 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800784 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800785 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700786 case kWhatCleanUpSessions:
787 mCachedSessions.clear();
788 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800789 default:
790 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
791 return;
792 }
793 // Check the common part of all message
794 void* context;
795 bool found = msg->findPointer(kContextKey, &context);
796 if (!found) {
797 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
798 return;
799 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800800 switch (msg->what()) {
801 case kWhatOnDisconnected:
802 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800803 ACameraDevice* dev;
804 found = msg->findPointer(kDeviceKey, (void**) &dev);
805 if (!found || dev == nullptr) {
806 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
807 return;
808 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800809 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800810 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800811 if (!found) {
812 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
813 return;
814 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800815 if (onDisconnected == nullptr) {
816 return;
817 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800818 (*onDisconnected)(context, dev);
819 break;
820 }
821 case kWhatOnError:
822 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800823 ACameraDevice* dev;
824 found = msg->findPointer(kDeviceKey, (void**) &dev);
825 if (!found || dev == nullptr) {
826 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
827 return;
828 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800829 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800830 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800831 if (!found) {
832 ALOGE("%s: Cannot find onError!", __FUNCTION__);
833 return;
834 }
835 int errorCode;
836 found = msg->findInt32(kErrorCodeKey, &errorCode);
837 if (!found) {
838 ALOGE("%s: Cannot find error code!", __FUNCTION__);
839 return;
840 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800841 if (onError == nullptr) {
842 return;
843 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800844 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800845 break;
846 }
847 case kWhatSessionStateCb:
848 case kWhatCaptureStart:
849 case kWhatCaptureResult:
850 case kWhatCaptureFail:
851 case kWhatCaptureSeqEnd:
852 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700853 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800854 {
855 sp<RefBase> obj;
856 found = msg->findObject(kSessionSpKey, &obj);
857 if (!found || obj == nullptr) {
858 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
859 return;
860 }
861 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700862 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 sp<CaptureRequest> requestSp = nullptr;
864 switch (msg->what()) {
865 case kWhatCaptureStart:
866 case kWhatCaptureResult:
867 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700868 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800869 found = msg->findObject(kCaptureRequestKey, &obj);
870 if (!found) {
871 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
872 return;
873 }
874 requestSp = static_cast<CaptureRequest*>(obj.get());
875 break;
876 }
877
878 switch (msg->what()) {
879 case kWhatSessionStateCb:
880 {
881 ACameraCaptureSession_stateCallback onState;
882 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
883 if (!found) {
884 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
885 return;
886 }
887 if (onState == nullptr) {
888 return;
889 }
890 (*onState)(context, session.get());
891 break;
892 }
893 case kWhatCaptureStart:
894 {
895 ACameraCaptureSession_captureCallback_start onStart;
896 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
897 if (!found) {
898 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
899 return;
900 }
901 if (onStart == nullptr) {
902 return;
903 }
904 int64_t timestamp;
905 found = msg->findInt64(kTimeStampKey, &timestamp);
906 if (!found) {
907 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
908 return;
909 }
910 ACaptureRequest* request = allocateACaptureRequest(requestSp);
911 (*onStart)(context, session.get(), request, timestamp);
912 freeACaptureRequest(request);
913 break;
914 }
915 case kWhatCaptureResult:
916 {
917 ACameraCaptureSession_captureCallback_result onResult;
918 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
919 if (!found) {
920 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
921 return;
922 }
923 if (onResult == nullptr) {
924 return;
925 }
926
927 found = msg->findObject(kCaptureResultKey, &obj);
928 if (!found) {
929 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
930 return;
931 }
932 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
933 ACaptureRequest* request = allocateACaptureRequest(requestSp);
934 (*onResult)(context, session.get(), request, result.get());
935 freeACaptureRequest(request);
936 break;
937 }
938 case kWhatCaptureFail:
939 {
940 ACameraCaptureSession_captureCallback_failed onFail;
941 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
942 if (!found) {
943 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
944 return;
945 }
946 if (onFail == nullptr) {
947 return;
948 }
949
950 found = msg->findObject(kCaptureFailureKey, &obj);
951 if (!found) {
952 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
953 return;
954 }
955 sp<CameraCaptureFailure> failureSp(
956 static_cast<CameraCaptureFailure*>(obj.get()));
957 ACameraCaptureFailure* failure =
958 static_cast<ACameraCaptureFailure*>(failureSp.get());
959 ACaptureRequest* request = allocateACaptureRequest(requestSp);
960 (*onFail)(context, session.get(), request, failure);
961 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800962 break;
963 }
964 case kWhatCaptureSeqEnd:
965 {
966 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
967 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
968 if (!found) {
969 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
970 return;
971 }
972 if (onSeqEnd == nullptr) {
973 return;
974 }
975 int seqId;
976 found = msg->findInt32(kSequenceIdKey, &seqId);
977 if (!found) {
978 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
979 return;
980 }
981 int64_t frameNumber;
982 found = msg->findInt64(kFrameNumberKey, &frameNumber);
983 if (!found) {
984 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
985 return;
986 }
987 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
988 break;
989 }
990 case kWhatCaptureSeqAbort:
991 {
992 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
993 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
994 if (!found) {
995 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
996 return;
997 }
998 if (onSeqAbort == nullptr) {
999 return;
1000 }
1001 int seqId;
1002 found = msg->findInt32(kSequenceIdKey, &seqId);
1003 if (!found) {
1004 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1005 return;
1006 }
1007 (*onSeqAbort)(context, session.get(), seqId);
1008 break;
1009 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001010 case kWhatCaptureBufferLost:
1011 {
1012 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1013 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1014 if (!found) {
1015 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1016 return;
1017 }
1018 if (onBufferLost == nullptr) {
1019 return;
1020 }
1021
1022 ANativeWindow* anw;
1023 found = msg->findPointer(kAnwKey, (void**) &anw);
1024 if (!found) {
1025 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1026 return;
1027 }
1028
1029 int64_t frameNumber;
1030 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1031 if (!found) {
1032 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1033 return;
1034 }
1035
1036 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1037 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1038 freeACaptureRequest(request);
1039 break;
1040 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001041 }
1042 break;
1043 }
1044 }
1045}
1046
1047CameraDevice::CallbackHolder::CallbackHolder(
1048 sp<ACameraCaptureSession> session,
1049 const Vector<sp<CaptureRequest> >& requests,
1050 bool isRepeating,
1051 ACameraCaptureSession_captureCallbacks* cbs) :
1052 mSession(session), mRequests(requests),
1053 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1054
1055void
1056CameraDevice::checkRepeatingSequenceCompleteLocked(
1057 const int sequenceId, const int64_t lastFrameNumber) {
1058 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1059 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1060 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1061 ALOGW("No callback found for sequenceId %d", sequenceId);
1062 return;
1063 }
1064 // remove callback holder from callback map
1065 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1066 CallbackHolder cbh = cbIt->second;
1067 mSequenceCallbackMap.erase(cbIt);
1068 // send seq aborted callback
1069 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1070 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1071 msg->setObject(kSessionSpKey, cbh.mSession);
1072 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1073 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001074 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001075 } else {
1076 // Use mSequenceLastFrameNumberMap to track
1077 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1078
1079 // Last frame might have arrived. Check now
1080 checkAndFireSequenceCompleteLocked();
1081 }
1082}
1083
1084void
1085CameraDevice::checkAndFireSequenceCompleteLocked() {
1086 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1087 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1088 auto it = mSequenceLastFrameNumberMap.begin();
1089 while (it != mSequenceLastFrameNumberMap.end()) {
1090 int sequenceId = it->first;
1091 int64_t lastFrameNumber = it->second;
1092 bool seqCompleted = false;
1093 bool hasCallback = true;
1094
1095 if (mRemote == nullptr) {
1096 ALOGW("Camera %s closed while checking sequence complete", getId());
1097 return;
1098 }
1099
1100 // Check if there is callback for this sequence
1101 // This should not happen because we always register callback (with nullptr inside)
1102 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1103 ALOGW("No callback found for sequenceId %d", sequenceId);
1104 hasCallback = false;
1105 }
1106
1107 if (lastFrameNumber <= completedFrameNumber) {
1108 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1109 sequenceId, lastFrameNumber, completedFrameNumber);
1110 seqCompleted = true;
1111 }
1112
1113 if (seqCompleted && hasCallback) {
1114 // remove callback holder from callback map
1115 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1116 CallbackHolder cbh = cbIt->second;
1117 mSequenceCallbackMap.erase(cbIt);
1118 // send seq complete callback
1119 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1120 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1121 msg->setObject(kSessionSpKey, cbh.mSession);
1122 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1123 msg->setInt32(kSequenceIdKey, sequenceId);
1124 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1125
1126 // Clear the session sp before we send out the message
1127 // This will guarantee the rare case where the message is processed
1128 // before cbh goes out of scope and causing we call the session
1129 // destructor while holding device lock
1130 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001131 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001132 }
1133
1134 // No need to track sequence complete if there is no callback registered
1135 if (seqCompleted || !hasCallback) {
1136 it = mSequenceLastFrameNumberMap.erase(it);
1137 } else {
1138 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001139 }
1140 }
1141}
1142
1143/**
1144 * Camera service callback implementation
1145 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001146binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001147CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001148 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001149 const CaptureResultExtras& resultExtras) {
1150 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1151 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001152 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001153 sp<CameraDevice> dev = mDevice.promote();
1154 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001155 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001156 }
1157
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001158 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001159 Mutex::Autolock _l(dev->mDeviceLock);
1160 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001161 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001162 }
1163 switch (errorCode) {
1164 case ERROR_CAMERA_DISCONNECTED:
1165 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001166 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001167 if (session != nullptr) {
1168 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001169 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001170 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001171 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1172 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1173 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001174 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001175 msg->post();
1176 break;
1177 }
1178 default:
1179 ALOGE("Unknown error from camera device: %d", errorCode);
1180 // no break
1181 case ERROR_CAMERA_DEVICE:
1182 case ERROR_CAMERA_SERVICE:
1183 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001184 switch (errorCode) {
1185 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001186 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001187 break;
1188 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001189 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001190 break;
1191 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001192 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001193 break;
1194 }
1195 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1196 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1197 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001198 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001199 msg->setInt32(kErrorCodeKey, errorCode);
1200 msg->post();
1201 break;
1202 }
1203 case ERROR_CAMERA_REQUEST:
1204 case ERROR_CAMERA_RESULT:
1205 case ERROR_CAMERA_BUFFER:
1206 dev->onCaptureErrorLocked(errorCode, resultExtras);
1207 break;
1208 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001209 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001210}
1211
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001212binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001213CameraDevice::ServiceCallback::onDeviceIdle() {
1214 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001215 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001216 sp<CameraDevice> dev = mDevice.promote();
1217 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001218 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001219 }
1220
1221 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001222 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001223 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001224 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001225
1226 if (dev->mIdle) {
1227 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001228 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001229 }
1230
1231 if (dev->mCurrentSession != nullptr) {
1232 ALOGE("onDeviceIdle sending state cb");
1233 if (dev->mBusySession != dev->mCurrentSession) {
1234 ALOGE("Current session != busy session");
1235 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001236 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001237 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001238
Yin-Chia Yehead91462016-01-06 16:45:08 -08001239 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1240 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1241 msg->setObject(kSessionSpKey, dev->mBusySession);
1242 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1243 // Make sure we clear the sp first so the session destructor can
1244 // only happen on handler thread (where we don't hold device/session lock)
1245 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001246 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001247 }
1248 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001249 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001250 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001251}
1252
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001253binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001254CameraDevice::ServiceCallback::onCaptureStarted(
1255 const CaptureResultExtras& resultExtras,
1256 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001257 binder::Status ret = binder::Status::ok();
1258
Yin-Chia Yehead91462016-01-06 16:45:08 -08001259 sp<CameraDevice> dev = mDevice.promote();
1260 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001261 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001262 }
1263 Mutex::Autolock _l(dev->mDeviceLock);
1264 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001265 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001266 }
1267
1268 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001269 int32_t burstId = resultExtras.burstId;
1270
1271 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1272 if (it != dev->mSequenceCallbackMap.end()) {
1273 CallbackHolder cbh = (*it).second;
1274 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1275 sp<ACameraCaptureSession> session = cbh.mSession;
1276 if ((size_t) burstId >= cbh.mRequests.size()) {
1277 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1278 __FUNCTION__, burstId, cbh.mRequests.size());
1279 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1280 }
1281 sp<CaptureRequest> request = cbh.mRequests[burstId];
1282 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1283 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1284 msg->setObject(kSessionSpKey, session);
1285 msg->setPointer(kCallbackFpKey, (void*) onStart);
1286 msg->setObject(kCaptureRequestKey, request);
1287 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001288 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001289 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001290 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001291}
1292
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001293binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001294CameraDevice::ServiceCallback::onResultReceived(
1295 const CameraMetadata& metadata,
1296 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001297 binder::Status ret = binder::Status::ok();
1298
Yin-Chia Yehead91462016-01-06 16:45:08 -08001299 sp<CameraDevice> dev = mDevice.promote();
1300 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001301 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001302 }
1303 int sequenceId = resultExtras.requestId;
1304 int64_t frameNumber = resultExtras.frameNumber;
1305 int32_t burstId = resultExtras.burstId;
1306 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1307
1308 if (!isPartialResult) {
1309 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1310 }
1311
1312 Mutex::Autolock _l(dev->mDeviceLock);
1313 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001314 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001315 }
1316
1317 if (dev->isClosed()) {
1318 if (!isPartialResult) {
1319 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1320 }
1321 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001322 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001323 }
1324
1325 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001326 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001327 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001328
1329 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1330 if (it != dev->mSequenceCallbackMap.end()) {
1331 CallbackHolder cbh = (*it).second;
1332 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1333 cbh.mCallbacks.onCaptureProgressed :
1334 cbh.mCallbacks.onCaptureCompleted;
1335 sp<ACameraCaptureSession> session = cbh.mSession;
1336 if ((size_t) burstId >= cbh.mRequests.size()) {
1337 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1338 __FUNCTION__, burstId, cbh.mRequests.size());
1339 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1340 }
1341 sp<CaptureRequest> request = cbh.mRequests[burstId];
1342 sp<ACameraMetadata> result(new ACameraMetadata(
1343 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1344
1345 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1346 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1347 msg->setObject(kSessionSpKey, session);
1348 msg->setPointer(kCallbackFpKey, (void*) onResult);
1349 msg->setObject(kCaptureRequestKey, request);
1350 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001351 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001352 }
1353
1354 if (!isPartialResult) {
1355 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1356 dev->checkAndFireSequenceCompleteLocked();
1357 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001358
1359 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001360}
1361
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001362binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001363CameraDevice::ServiceCallback::onPrepared(int) {
1364 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001365 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001366}
1367
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001368binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001369CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1370 // onRequestQueueEmpty not yet implemented in NDK
1371 return binder::Status::ok();
1372}
1373
1374binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001375CameraDevice::ServiceCallback::onRepeatingRequestError(
1376 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001377 binder::Status ret = binder::Status::ok();
1378
1379 sp<CameraDevice> dev = mDevice.promote();
1380 if (dev == nullptr) {
1381 return ret; // device has been closed
1382 }
1383
1384 Mutex::Autolock _l(dev->mDeviceLock);
1385
1386 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001387 if (stoppedSequenceId == repeatingSequenceId) {
1388 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1389 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001390
1391 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1392
1393 return ret;
1394}
1395
1396
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001397} // namespace android