blob: 9ce0ac884f6423ed03bb223840d4b65995ec2d1f [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
Emilian Peev40ead602017-09-26 15:46:36 +0100292camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *output) {
293 camera_status_t ret = checkCameraClosedOrErrorLocked();
294 if (ret != ACAMERA_OK) {
295 return ret;
296 }
297
298 if (output == nullptr) {
299 return ACAMERA_ERROR_INVALID_PARAMETER;
300 }
301
302 if (!output->mIsShared) {
303 ALOGE("Error output configuration is not shared");
304 return ACAMERA_ERROR_INVALID_OPERATION;
305 }
306
307 int32_t streamId = -1;
308 for (auto& kvPair : mConfiguredOutputs) {
309 if (kvPair.second.first == output->mWindow) {
310 streamId = kvPair.first;
311 break;
312 }
313 }
314 if (streamId < 0) {
315 ALOGE("Error: Invalid output configuration");
316 return ACAMERA_ERROR_INVALID_PARAMETER;
317 }
318
319 sp<IGraphicBufferProducer> iGBP(nullptr);
320 ret = getIGBPfromAnw(output->mWindow, iGBP);
321 if (ret != ACAMERA_OK) {
322 ALOGE("Camera device %s failed to extract graphic producer from native window",
323 getId());
324 return ret;
325 }
326
327 OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
328 true);
329
330 for (auto& anw : output->mSharedWindows) {
331 ret = getIGBPfromAnw(anw, iGBP);
332 if (ret != ACAMERA_OK) {
333 ALOGE("Camera device %s failed to extract graphic producer from native window",
334 getId());
335 return ret;
336 }
337 outConfig.addGraphicProducer(iGBP);
338 }
339
340 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
341 if (!remoteRet.isOk()) {
342 switch (remoteRet.serviceSpecificErrorCode()) {
343 case hardware::ICameraService::ERROR_INVALID_OPERATION:
344 ALOGE("Camera device %s invalid operation: %s", getId(),
345 remoteRet.toString8().string());
346 return ACAMERA_ERROR_INVALID_OPERATION;
347 break;
348 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
349 ALOGE("Camera device %s output surface already exists: %s", getId(),
350 remoteRet.toString8().string());
351 return ACAMERA_ERROR_INVALID_PARAMETER;
352 break;
353 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
354 ALOGE("Camera device %s invalid input argument: %s", getId(),
355 remoteRet.toString8().string());
356 return ACAMERA_ERROR_INVALID_PARAMETER;
357 break;
358 default:
359 ALOGE("Camera device %s failed to add shared output: %s", getId(),
360 remoteRet.toString8().string());
361 return ACAMERA_ERROR_UNKNOWN;
362 }
363 }
364
365 return ACAMERA_OK;
366}
367
Yin-Chia Yehead91462016-01-06 16:45:08 -0800368camera_status_t
369CameraDevice::allocateCaptureRequest(
370 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
371 camera_status_t ret;
372 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800373 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800374 req->mIsReprocess = false; // NDK does not support reprocessing yet
375
376 for (auto outputTarget : request->targets->mOutputs) {
377 ANativeWindow* anw = outputTarget.mWindow;
378 sp<Surface> surface;
379 ret = getSurfaceFromANativeWindow(anw, surface);
380 if (ret != ACAMERA_OK) {
381 ALOGE("Bad output target in capture request! ret %d", ret);
382 return ret;
383 }
384 req->mSurfaceList.push_back(surface);
385 }
386 outReq = req;
387 return ACAMERA_OK;
388}
389
390ACaptureRequest*
391CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
392 ACaptureRequest* pRequest = new ACaptureRequest();
393 CameraMetadata clone = req->mMetadata;
394 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
395 pRequest->targets = new ACameraOutputTargets();
396 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
397 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
398 ACameraOutputTarget outputTarget(anw);
399 pRequest->targets->mOutputs.insert(outputTarget);
400 }
401 return pRequest;
402}
403
404void
405CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
406 if (req == nullptr) {
407 return;
408 }
409 delete req->settings;
410 delete req->targets;
411 delete req;
412}
413
414void
415CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
416 if (isClosed()) {
417 // Device is closing already. do nothing
418 return;
419 }
420
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700421 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800422 // Session has been replaced by other seesion or device is closed
423 return;
424 }
425 mCurrentSession = nullptr;
426
427 // Should not happen
428 if (!session->mIsClosed) {
429 ALOGE("Error: unclosed session %p reaches end of life!", session);
430 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
431 return;
432 }
433
434 // No new session, unconfigure now
435 camera_status_t ret = configureStreamsLocked(nullptr);
436 if (ret != ACAMERA_OK) {
437 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
438 }
439}
440
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800441void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700442CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800443 if (mClosing.exchange(true)) {
444 // Already closing, just return
445 ALOGW("Camera device %s is already closing.", getId());
446 return;
447 }
448
449 if (mRemote != nullptr) {
450 mRemote->disconnect();
451 }
452 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800453
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700454 if (session != nullptr) {
455 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800456 }
457}
458
459camera_status_t
460CameraDevice::stopRepeatingLocked() {
461 camera_status_t ret = checkCameraClosedOrErrorLocked();
462 if (ret != ACAMERA_OK) {
463 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
464 return ret;
465 }
466 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
467 int repeatingSequenceId = mRepeatingSequenceId;
468 mRepeatingSequenceId = REQUEST_ID_NONE;
469
470 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800471 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700472 if (remoteRet.serviceSpecificErrorCode() ==
473 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
474 ALOGV("Repeating request is already stopped.");
475 return ACAMERA_OK;
476 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800477 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800478 return ACAMERA_ERROR_UNKNOWN;
479 }
480 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
481 }
482 return ACAMERA_OK;
483}
484
485camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700486CameraDevice::flushLocked(ACameraCaptureSession* session) {
487 camera_status_t ret = checkCameraClosedOrErrorLocked();
488 if (ret != ACAMERA_OK) {
489 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
490 return ret;
491 }
492
493 // This should never happen because creating a new session will close
494 // previous one and thus reject any API call from previous session.
495 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700496 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700497 ALOGE("Camera %s session %p is not current active session!", getId(), session);
498 return ACAMERA_ERROR_INVALID_OPERATION;
499 }
500
501 if (mFlushing) {
502 ALOGW("Camera %s is already aborting captures", getId());
503 return ACAMERA_OK;
504 }
505
506 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700507
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700508 // Send onActive callback to guarantee there is always active->ready transition
509 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
510 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
511 msg->setObject(kSessionSpKey, session);
512 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700513 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700514
515 // If device is already idling, send callback and exit early
516 if (mIdle) {
517 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
518 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
519 msg->setObject(kSessionSpKey, session);
520 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700521 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700522 mFlushing = false;
523 return ACAMERA_OK;
524 }
525
526 int64_t lastFrameNumber;
527 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
528 if (!remoteRet.isOk()) {
529 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
530 return ACAMERA_ERROR_UNKNOWN;
531 }
532 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
533 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
534 }
535 return ACAMERA_OK;
536}
537
538camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800539CameraDevice::waitUntilIdleLocked() {
540 camera_status_t ret = checkCameraClosedOrErrorLocked();
541 if (ret != ACAMERA_OK) {
542 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
543 return ret;
544 }
545
546 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
547 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
548 return ACAMERA_ERROR_INVALID_OPERATION;
549 }
550
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800551 binder::Status remoteRet = mRemote->waitUntilIdle();
552 if (!remoteRet.isOk()) {
553 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800554 // TODO: define a function to convert status_t -> camera_status_t
555 return ACAMERA_ERROR_UNKNOWN;
556 }
557
558 return ACAMERA_OK;
559}
560
561camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700562CameraDevice::getIGBPfromAnw(
563 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800564 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800565 if (anw == nullptr) {
566 ALOGE("Error: output ANativeWindow is null");
567 return ACAMERA_ERROR_INVALID_PARAMETER;
568 }
569 int value;
570 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800571 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800572 ALOGE("Error: ANativeWindow is not backed by Surface!");
573 return ACAMERA_ERROR_INVALID_PARAMETER;
574 }
575 const sp<Surface> surface(static_cast<Surface*>(anw));
576 out = surface->getIGraphicBufferProducer();
577 return ACAMERA_OK;
578}
579
580camera_status_t
581CameraDevice::getSurfaceFromANativeWindow(
582 ANativeWindow* anw, sp<Surface>& out) {
583 if (anw == nullptr) {
584 ALOGE("Error: output ANativeWindow is null");
585 return ACAMERA_ERROR_INVALID_PARAMETER;
586 }
587 int value;
588 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800589 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800590 ALOGE("Error: ANativeWindow is not backed by Surface!");
591 return ACAMERA_ERROR_INVALID_PARAMETER;
592 }
593 sp<Surface> surface(static_cast<Surface*>(anw));
594 out = surface;
595 return ACAMERA_OK;
596}
597
598camera_status_t
599CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
600 ACaptureSessionOutputContainer emptyOutput;
601 if (outputs == nullptr) {
602 outputs = &emptyOutput;
603 }
604
Yin-Chia Yehead91462016-01-06 16:45:08 -0800605 camera_status_t ret = checkCameraClosedOrErrorLocked();
606 if (ret != ACAMERA_OK) {
607 return ret;
608 }
609
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700610 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800611 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700612 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800613 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700614 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800615 if (ret != ACAMERA_OK) {
616 return ret;
617 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700618 outputSet.insert(std::make_pair(
Emilian Peev40ead602017-09-26 15:46:36 +0100619 anw, OutputConfiguration(iGBP, outConfig.mRotation,
620 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800621 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700622 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800623 std::vector<int> deleteList;
624
625 // Determine which streams need to be created, which to be deleted
626 for (auto& kvPair : mConfiguredOutputs) {
627 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700628 auto& outputPair = kvPair.second;
629 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800630 deleteList.push_back(streamId); // Need to delete a no longer needed stream
631 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700632 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800633 }
634 }
635
636 ret = stopRepeatingLocked();
637 if (ret != ACAMERA_OK) {
638 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
639 return ret;
640 }
641
642 ret = waitUntilIdleLocked();
643 if (ret != ACAMERA_OK) {
644 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
645 return ret;
646 }
647
648 // Send onReady to previous session
649 // CurrentSession will be updated after configureStreamLocked, so here
650 // mCurrentSession is the session to be replaced by a new session
651 if (!mIdle && mCurrentSession != nullptr) {
652 if (mBusySession != mCurrentSession) {
653 ALOGE("Current session != busy session");
654 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
655 return ACAMERA_ERROR_CAMERA_DEVICE;
656 }
657 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
658 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
659 msg->setObject(kSessionSpKey, mBusySession);
660 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
661 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700662 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800663 }
664 mIdle = true;
665
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800666 binder::Status remoteRet = mRemote->beginConfigure();
667 if (!remoteRet.isOk()) {
668 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800669 return ACAMERA_ERROR_UNKNOWN;
670 }
671
672 // delete to-be-deleted streams
673 for (auto streamId : deleteList) {
674 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800675 if (!remoteRet.isOk()) {
676 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
677 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800678 return ACAMERA_ERROR_UNKNOWN;
679 }
680 mConfiguredOutputs.erase(streamId);
681 }
682
683 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700684 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800685 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700686 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800687 if (!remoteRet.isOk()) {
688 ALOGE("Camera device %s failed to create stream: %s", getId(),
689 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800690 return ACAMERA_ERROR_UNKNOWN;
691 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700692 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800693 }
694
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800695 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
696 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
697 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
698 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800699 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800700 } else if (!remoteRet.isOk()) {
701 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800702 return ACAMERA_ERROR_UNKNOWN;
703 }
704
705 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800706}
707
708void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800709CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800710 Mutex::Autolock _l(mDeviceLock);
711 mRemote = remote;
712}
713
714camera_status_t
715CameraDevice::checkCameraClosedOrErrorLocked() const {
716 if (mRemote == nullptr) {
717 ALOGE("%s: camera device already closed", __FUNCTION__);
718 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
719 }
720 if (mInError) {// triggered by onDeviceError
721 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
722 return mError;
723 }
724 return ACAMERA_OK;
725}
726
727void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800728CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
729 mInError = true;
730 mError = error;
731 return;
732}
733
734void
735CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
736 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
737 if (isError) {
738 mFutureErrorSet.insert(frameNumber);
739 } else if (frameNumber <= mCompletedFrameNumber) {
740 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
741 frameNumber, mCompletedFrameNumber);
742 return;
743 } else {
744 if (frameNumber != mCompletedFrameNumber + 1) {
745 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
746 mCompletedFrameNumber + 1, frameNumber);
747 // Do not assert as in java implementation
748 }
749 mCompletedFrameNumber = frameNumber;
750 }
751 update();
752}
753
754void
755CameraDevice::FrameNumberTracker::update() {
756 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
757 int64_t errorFrameNumber = *it;
758 if (errorFrameNumber == mCompletedFrameNumber + 1) {
759 mCompletedFrameNumber++;
760 it = mFutureErrorSet.erase(it);
761 } else if (errorFrameNumber <= mCompletedFrameNumber) {
762 // This should not happen, but deal with it anyway
763 ALOGE("Completd frame number passed through current frame number!");
764 // erase the old error since it's no longer useful
765 it = mFutureErrorSet.erase(it);
766 } else {
767 // Normal requests hasn't catched up error frames, just break
768 break;
769 }
770 }
771 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
772}
773
774void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800775CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800776 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800777 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800778 int sequenceId = resultExtras.requestId;
779 int64_t frameNumber = resultExtras.frameNumber;
780 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700781 auto it = mSequenceCallbackMap.find(sequenceId);
782 if (it == mSequenceCallbackMap.end()) {
783 ALOGE("%s: Error: capture sequence index %d not found!",
784 __FUNCTION__, sequenceId);
785 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800786 return;
787 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700788
789 CallbackHolder cbh = (*it).second;
790 sp<ACameraCaptureSession> session = cbh.mSession;
791 if ((size_t) burstId >= cbh.mRequests.size()) {
792 ALOGE("%s: Error: request index %d out of bound (size %zu)",
793 __FUNCTION__, burstId, cbh.mRequests.size());
794 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
795 return;
796 }
797 sp<CaptureRequest> request = cbh.mRequests[burstId];
798
799 // Handle buffer error
800 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
801 int32_t streamId = resultExtras.errorStreamId;
802 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
803 cbh.mCallbacks.onCaptureBufferLost;
804 auto outputPairIt = mConfiguredOutputs.find(streamId);
805 if (outputPairIt == mConfiguredOutputs.end()) {
806 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800807 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
808 return;
809 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700810 ANativeWindow* anw = outputPairIt->second.first;
811
812 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
813 getId(), anw, frameNumber);
814
815 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
816 msg->setPointer(kContextKey, cbh.mCallbacks.context);
817 msg->setObject(kSessionSpKey, session);
818 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
819 msg->setObject(kCaptureRequestKey, request);
820 msg->setPointer(kAnwKey, (void*) anw);
821 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700822 postSessionMsgAndCleanup(msg);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700823 } else { // Handle other capture failures
824 // Fire capture failure callback if there is one registered
825 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800826 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
827 failure->frameNumber = frameNumber;
828 // TODO: refine this when implementing flush
829 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
830 failure->sequenceId = sequenceId;
831 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800832 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800833
834 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
835 msg->setPointer(kContextKey, cbh.mCallbacks.context);
836 msg->setObject(kSessionSpKey, session);
837 msg->setPointer(kCallbackFpKey, (void*) onError);
838 msg->setObject(kCaptureRequestKey, request);
839 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700840 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800841
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700842 // Update tracker
843 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
844 checkAndFireSequenceCompleteLocked();
845 }
846 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800847}
848
849void CameraDevice::CallbackHandler::onMessageReceived(
850 const sp<AMessage> &msg) {
851 switch (msg->what()) {
852 case kWhatOnDisconnected:
853 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800854 case kWhatSessionStateCb:
855 case kWhatCaptureStart:
856 case kWhatCaptureResult:
857 case kWhatCaptureFail:
858 case kWhatCaptureSeqEnd:
859 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700860 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800861 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800862 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700863 case kWhatCleanUpSessions:
864 mCachedSessions.clear();
865 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800866 default:
867 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
868 return;
869 }
870 // Check the common part of all message
871 void* context;
872 bool found = msg->findPointer(kContextKey, &context);
873 if (!found) {
874 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
875 return;
876 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800877 switch (msg->what()) {
878 case kWhatOnDisconnected:
879 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800880 ACameraDevice* dev;
881 found = msg->findPointer(kDeviceKey, (void**) &dev);
882 if (!found || dev == nullptr) {
883 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
884 return;
885 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800886 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800887 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800888 if (!found) {
889 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
890 return;
891 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800892 if (onDisconnected == nullptr) {
893 return;
894 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800895 (*onDisconnected)(context, dev);
896 break;
897 }
898 case kWhatOnError:
899 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800900 ACameraDevice* dev;
901 found = msg->findPointer(kDeviceKey, (void**) &dev);
902 if (!found || dev == nullptr) {
903 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
904 return;
905 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800906 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800907 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800908 if (!found) {
909 ALOGE("%s: Cannot find onError!", __FUNCTION__);
910 return;
911 }
912 int errorCode;
913 found = msg->findInt32(kErrorCodeKey, &errorCode);
914 if (!found) {
915 ALOGE("%s: Cannot find error code!", __FUNCTION__);
916 return;
917 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800918 if (onError == nullptr) {
919 return;
920 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800921 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800922 break;
923 }
924 case kWhatSessionStateCb:
925 case kWhatCaptureStart:
926 case kWhatCaptureResult:
927 case kWhatCaptureFail:
928 case kWhatCaptureSeqEnd:
929 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700930 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800931 {
932 sp<RefBase> obj;
933 found = msg->findObject(kSessionSpKey, &obj);
934 if (!found || obj == nullptr) {
935 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
936 return;
937 }
938 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700939 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800940 sp<CaptureRequest> requestSp = nullptr;
941 switch (msg->what()) {
942 case kWhatCaptureStart:
943 case kWhatCaptureResult:
944 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700945 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800946 found = msg->findObject(kCaptureRequestKey, &obj);
947 if (!found) {
948 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
949 return;
950 }
951 requestSp = static_cast<CaptureRequest*>(obj.get());
952 break;
953 }
954
955 switch (msg->what()) {
956 case kWhatSessionStateCb:
957 {
958 ACameraCaptureSession_stateCallback onState;
959 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
960 if (!found) {
961 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
962 return;
963 }
964 if (onState == nullptr) {
965 return;
966 }
967 (*onState)(context, session.get());
968 break;
969 }
970 case kWhatCaptureStart:
971 {
972 ACameraCaptureSession_captureCallback_start onStart;
973 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
974 if (!found) {
975 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
976 return;
977 }
978 if (onStart == nullptr) {
979 return;
980 }
981 int64_t timestamp;
982 found = msg->findInt64(kTimeStampKey, &timestamp);
983 if (!found) {
984 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
985 return;
986 }
987 ACaptureRequest* request = allocateACaptureRequest(requestSp);
988 (*onStart)(context, session.get(), request, timestamp);
989 freeACaptureRequest(request);
990 break;
991 }
992 case kWhatCaptureResult:
993 {
994 ACameraCaptureSession_captureCallback_result onResult;
995 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
996 if (!found) {
997 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
998 return;
999 }
1000 if (onResult == nullptr) {
1001 return;
1002 }
1003
1004 found = msg->findObject(kCaptureResultKey, &obj);
1005 if (!found) {
1006 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1007 return;
1008 }
1009 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1010 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1011 (*onResult)(context, session.get(), request, result.get());
1012 freeACaptureRequest(request);
1013 break;
1014 }
1015 case kWhatCaptureFail:
1016 {
1017 ACameraCaptureSession_captureCallback_failed onFail;
1018 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1019 if (!found) {
1020 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1021 return;
1022 }
1023 if (onFail == nullptr) {
1024 return;
1025 }
1026
1027 found = msg->findObject(kCaptureFailureKey, &obj);
1028 if (!found) {
1029 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1030 return;
1031 }
1032 sp<CameraCaptureFailure> failureSp(
1033 static_cast<CameraCaptureFailure*>(obj.get()));
1034 ACameraCaptureFailure* failure =
1035 static_cast<ACameraCaptureFailure*>(failureSp.get());
1036 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1037 (*onFail)(context, session.get(), request, failure);
1038 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001039 break;
1040 }
1041 case kWhatCaptureSeqEnd:
1042 {
1043 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1044 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1045 if (!found) {
1046 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1047 return;
1048 }
1049 if (onSeqEnd == nullptr) {
1050 return;
1051 }
1052 int seqId;
1053 found = msg->findInt32(kSequenceIdKey, &seqId);
1054 if (!found) {
1055 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1056 return;
1057 }
1058 int64_t frameNumber;
1059 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1060 if (!found) {
1061 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1062 return;
1063 }
1064 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1065 break;
1066 }
1067 case kWhatCaptureSeqAbort:
1068 {
1069 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1070 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1071 if (!found) {
1072 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1073 return;
1074 }
1075 if (onSeqAbort == nullptr) {
1076 return;
1077 }
1078 int seqId;
1079 found = msg->findInt32(kSequenceIdKey, &seqId);
1080 if (!found) {
1081 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1082 return;
1083 }
1084 (*onSeqAbort)(context, session.get(), seqId);
1085 break;
1086 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001087 case kWhatCaptureBufferLost:
1088 {
1089 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1090 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1091 if (!found) {
1092 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1093 return;
1094 }
1095 if (onBufferLost == nullptr) {
1096 return;
1097 }
1098
1099 ANativeWindow* anw;
1100 found = msg->findPointer(kAnwKey, (void**) &anw);
1101 if (!found) {
1102 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1103 return;
1104 }
1105
1106 int64_t frameNumber;
1107 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1108 if (!found) {
1109 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1110 return;
1111 }
1112
1113 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1114 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1115 freeACaptureRequest(request);
1116 break;
1117 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001118 }
1119 break;
1120 }
1121 }
1122}
1123
1124CameraDevice::CallbackHolder::CallbackHolder(
1125 sp<ACameraCaptureSession> session,
1126 const Vector<sp<CaptureRequest> >& requests,
1127 bool isRepeating,
1128 ACameraCaptureSession_captureCallbacks* cbs) :
1129 mSession(session), mRequests(requests),
1130 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1131
1132void
1133CameraDevice::checkRepeatingSequenceCompleteLocked(
1134 const int sequenceId, const int64_t lastFrameNumber) {
1135 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1136 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1137 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1138 ALOGW("No callback found for sequenceId %d", sequenceId);
1139 return;
1140 }
1141 // remove callback holder from callback map
1142 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1143 CallbackHolder cbh = cbIt->second;
1144 mSequenceCallbackMap.erase(cbIt);
1145 // send seq aborted callback
1146 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1147 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1148 msg->setObject(kSessionSpKey, cbh.mSession);
1149 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1150 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001151 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001152 } else {
1153 // Use mSequenceLastFrameNumberMap to track
1154 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1155
1156 // Last frame might have arrived. Check now
1157 checkAndFireSequenceCompleteLocked();
1158 }
1159}
1160
1161void
1162CameraDevice::checkAndFireSequenceCompleteLocked() {
1163 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1164 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1165 auto it = mSequenceLastFrameNumberMap.begin();
1166 while (it != mSequenceLastFrameNumberMap.end()) {
1167 int sequenceId = it->first;
1168 int64_t lastFrameNumber = it->second;
1169 bool seqCompleted = false;
1170 bool hasCallback = true;
1171
1172 if (mRemote == nullptr) {
1173 ALOGW("Camera %s closed while checking sequence complete", getId());
1174 return;
1175 }
1176
1177 // Check if there is callback for this sequence
1178 // This should not happen because we always register callback (with nullptr inside)
1179 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1180 ALOGW("No callback found for sequenceId %d", sequenceId);
1181 hasCallback = false;
1182 }
1183
1184 if (lastFrameNumber <= completedFrameNumber) {
1185 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1186 sequenceId, lastFrameNumber, completedFrameNumber);
1187 seqCompleted = true;
1188 }
1189
1190 if (seqCompleted && hasCallback) {
1191 // remove callback holder from callback map
1192 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1193 CallbackHolder cbh = cbIt->second;
1194 mSequenceCallbackMap.erase(cbIt);
1195 // send seq complete callback
1196 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1197 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1198 msg->setObject(kSessionSpKey, cbh.mSession);
1199 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1200 msg->setInt32(kSequenceIdKey, sequenceId);
1201 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1202
1203 // Clear the session sp before we send out the message
1204 // This will guarantee the rare case where the message is processed
1205 // before cbh goes out of scope and causing we call the session
1206 // destructor while holding device lock
1207 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001208 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001209 }
1210
1211 // No need to track sequence complete if there is no callback registered
1212 if (seqCompleted || !hasCallback) {
1213 it = mSequenceLastFrameNumberMap.erase(it);
1214 } else {
1215 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001216 }
1217 }
1218}
1219
1220/**
1221 * Camera service callback implementation
1222 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001223binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001224CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001225 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001226 const CaptureResultExtras& resultExtras) {
1227 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1228 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001229 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001230 sp<CameraDevice> dev = mDevice.promote();
1231 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001232 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001233 }
1234
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001235 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001236 Mutex::Autolock _l(dev->mDeviceLock);
1237 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001238 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001239 }
1240 switch (errorCode) {
1241 case ERROR_CAMERA_DISCONNECTED:
1242 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001243 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001244 if (session != nullptr) {
1245 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001246 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001247 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001248 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1249 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1250 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001251 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001252 msg->post();
1253 break;
1254 }
1255 default:
1256 ALOGE("Unknown error from camera device: %d", errorCode);
1257 // no break
1258 case ERROR_CAMERA_DEVICE:
1259 case ERROR_CAMERA_SERVICE:
1260 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001261 switch (errorCode) {
1262 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001263 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001264 break;
1265 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001266 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001267 break;
1268 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001269 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001270 break;
1271 }
1272 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1273 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1274 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001275 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001276 msg->setInt32(kErrorCodeKey, errorCode);
1277 msg->post();
1278 break;
1279 }
1280 case ERROR_CAMERA_REQUEST:
1281 case ERROR_CAMERA_RESULT:
1282 case ERROR_CAMERA_BUFFER:
1283 dev->onCaptureErrorLocked(errorCode, resultExtras);
1284 break;
1285 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001286 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001287}
1288
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001289binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001290CameraDevice::ServiceCallback::onDeviceIdle() {
1291 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001292 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001293 sp<CameraDevice> dev = mDevice.promote();
1294 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001295 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001296 }
1297
1298 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001299 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001300 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001301 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001302
1303 if (dev->mIdle) {
1304 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001305 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001306 }
1307
1308 if (dev->mCurrentSession != nullptr) {
1309 ALOGE("onDeviceIdle sending state cb");
1310 if (dev->mBusySession != dev->mCurrentSession) {
1311 ALOGE("Current session != busy session");
1312 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001313 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001314 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001315
Yin-Chia Yehead91462016-01-06 16:45:08 -08001316 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1317 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1318 msg->setObject(kSessionSpKey, dev->mBusySession);
1319 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1320 // Make sure we clear the sp first so the session destructor can
1321 // only happen on handler thread (where we don't hold device/session lock)
1322 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001323 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001324 }
1325 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001326 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001327 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001328}
1329
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001330binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001331CameraDevice::ServiceCallback::onCaptureStarted(
1332 const CaptureResultExtras& resultExtras,
1333 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001334 binder::Status ret = binder::Status::ok();
1335
Yin-Chia Yehead91462016-01-06 16:45:08 -08001336 sp<CameraDevice> dev = mDevice.promote();
1337 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001338 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001339 }
1340 Mutex::Autolock _l(dev->mDeviceLock);
1341 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001342 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001343 }
1344
1345 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001346 int32_t burstId = resultExtras.burstId;
1347
1348 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1349 if (it != dev->mSequenceCallbackMap.end()) {
1350 CallbackHolder cbh = (*it).second;
1351 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1352 sp<ACameraCaptureSession> session = cbh.mSession;
1353 if ((size_t) burstId >= cbh.mRequests.size()) {
1354 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1355 __FUNCTION__, burstId, cbh.mRequests.size());
1356 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1357 }
1358 sp<CaptureRequest> request = cbh.mRequests[burstId];
1359 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1360 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1361 msg->setObject(kSessionSpKey, session);
1362 msg->setPointer(kCallbackFpKey, (void*) onStart);
1363 msg->setObject(kCaptureRequestKey, request);
1364 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001365 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001366 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001367 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001368}
1369
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001370binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001371CameraDevice::ServiceCallback::onResultReceived(
1372 const CameraMetadata& metadata,
1373 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001374 binder::Status ret = binder::Status::ok();
1375
Yin-Chia Yehead91462016-01-06 16:45:08 -08001376 sp<CameraDevice> dev = mDevice.promote();
1377 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001378 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001379 }
1380 int sequenceId = resultExtras.requestId;
1381 int64_t frameNumber = resultExtras.frameNumber;
1382 int32_t burstId = resultExtras.burstId;
1383 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1384
1385 if (!isPartialResult) {
1386 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1387 }
1388
1389 Mutex::Autolock _l(dev->mDeviceLock);
1390 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001391 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001392 }
1393
1394 if (dev->isClosed()) {
1395 if (!isPartialResult) {
1396 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1397 }
1398 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001399 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001400 }
1401
1402 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001403 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001404 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001405
1406 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1407 if (it != dev->mSequenceCallbackMap.end()) {
1408 CallbackHolder cbh = (*it).second;
1409 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1410 cbh.mCallbacks.onCaptureProgressed :
1411 cbh.mCallbacks.onCaptureCompleted;
1412 sp<ACameraCaptureSession> session = cbh.mSession;
1413 if ((size_t) burstId >= cbh.mRequests.size()) {
1414 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1415 __FUNCTION__, burstId, cbh.mRequests.size());
1416 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1417 }
1418 sp<CaptureRequest> request = cbh.mRequests[burstId];
1419 sp<ACameraMetadata> result(new ACameraMetadata(
1420 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1421
1422 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1423 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1424 msg->setObject(kSessionSpKey, session);
1425 msg->setPointer(kCallbackFpKey, (void*) onResult);
1426 msg->setObject(kCaptureRequestKey, request);
1427 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001428 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001429 }
1430
1431 if (!isPartialResult) {
1432 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1433 dev->checkAndFireSequenceCompleteLocked();
1434 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001435
1436 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001437}
1438
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001439binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001440CameraDevice::ServiceCallback::onPrepared(int) {
1441 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001442 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001443}
1444
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001445binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001446CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1447 // onRequestQueueEmpty not yet implemented in NDK
1448 return binder::Status::ok();
1449}
1450
1451binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001452CameraDevice::ServiceCallback::onRepeatingRequestError(
1453 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001454 binder::Status ret = binder::Status::ok();
1455
1456 sp<CameraDevice> dev = mDevice.promote();
1457 if (dev == nullptr) {
1458 return ret; // device has been closed
1459 }
1460
1461 Mutex::Autolock _l(dev->mDeviceLock);
1462
1463 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001464 if (stoppedSequenceId == repeatingSequenceId) {
1465 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1466 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001467
1468 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1469
1470 return ret;
1471}
1472
1473
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001474} // namespace android