blob: 4bb82cb3a382330f18cbe0597d8584e6dd8f9e4b [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,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100160 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800161 const ACameraCaptureSession_stateCallbacks* callbacks,
162 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700163 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800164 Mutex::Autolock _l(mDeviceLock);
165 camera_status_t ret = checkCameraClosedOrErrorLocked();
166 if (ret != ACAMERA_OK) {
167 return ret;
168 }
169
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700170 if (currentSession != nullptr) {
171 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800172 stopRepeatingLocked();
173 }
174
175 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100176 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800177 if (ret != ACAMERA_OK) {
178 ALOGE("Fail to create new session. cannot configure streams");
179 return ret;
180 }
181
182 ACameraCaptureSession* newSession = new ACameraCaptureSession(
183 mNextSessionId++, outputs, callbacks, this);
184
Yin-Chia Yehead91462016-01-06 16:45:08 -0800185 // set new session as current session
186 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
187 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700188 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800189 *session = newSession;
190 return ACAMERA_OK;
191}
192
193camera_status_t
194CameraDevice::captureLocked(
195 sp<ACameraCaptureSession> session,
196 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
197 int numRequests, ACaptureRequest** requests,
198 /*optional*/int* captureSequenceId) {
199 return submitRequestsLocked(
200 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
201}
202
203camera_status_t
204CameraDevice::setRepeatingRequestsLocked(
205 sp<ACameraCaptureSession> session,
206 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
207 int numRequests, ACaptureRequest** requests,
208 /*optional*/int* captureSequenceId) {
209 return submitRequestsLocked(
210 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
211}
212
213camera_status_t
214CameraDevice::submitRequestsLocked(
215 sp<ACameraCaptureSession> session,
216 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
217 int numRequests, ACaptureRequest** requests,
218 /*optional*/int* captureSequenceId,
219 bool isRepeating) {
220 camera_status_t ret = checkCameraClosedOrErrorLocked();
221 if (ret != ACAMERA_OK) {
222 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
223 return ret;
224 }
225
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800226 // Form two vectors of capture request, one for internal tracking
227 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800228 Vector<sp<CaptureRequest> > requestsV;
229 requestsV.setCapacity(numRequests);
230 for (int i = 0; i < numRequests; i++) {
231 sp<CaptureRequest> req;
232 ret = allocateCaptureRequest(requests[i], req);
233 if (ret != ACAMERA_OK) {
234 ALOGE("Convert capture request to internal format failure! ret %d", ret);
235 return ret;
236 }
237 if (req->mSurfaceList.empty()) {
238 ALOGE("Capture request without output target cannot be submitted!");
239 return ACAMERA_ERROR_INVALID_PARAMETER;
240 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800241 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800242 requestsV.push_back(req);
243 }
244
245 if (isRepeating) {
246 ret = stopRepeatingLocked();
247 if (ret != ACAMERA_OK) {
248 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
249 return ret;
250 }
251 }
252
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800253 binder::Status remoteRet;
254 hardware::camera2::utils::SubmitInfo info;
255 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
256 int sequenceId = info.mRequestId;
257 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800258 if (sequenceId < 0) {
259 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
260 return ACAMERA_ERROR_UNKNOWN;
261 }
262
263 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
264 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
265
266 if (isRepeating) {
267 // stopRepeating above should have cleanup repeating sequence id
268 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
269 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
270 return ACAMERA_ERROR_CAMERA_DEVICE;
271 }
272 mRepeatingSequenceId = sequenceId;
273 } else {
274 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
275 }
276
277 if (mIdle) {
278 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
279 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
280 msg->setObject(kSessionSpKey, session);
281 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700282 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800283 }
284 mIdle = false;
285 mBusySession = session;
286
287 if (captureSequenceId) {
288 *captureSequenceId = sequenceId;
289 }
290 return ACAMERA_OK;
291}
292
Emilian Peev40ead602017-09-26 15:46:36 +0100293camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *output) {
294 camera_status_t ret = checkCameraClosedOrErrorLocked();
295 if (ret != ACAMERA_OK) {
296 return ret;
297 }
298
299 if (output == nullptr) {
300 return ACAMERA_ERROR_INVALID_PARAMETER;
301 }
302
303 if (!output->mIsShared) {
304 ALOGE("Error output configuration is not shared");
305 return ACAMERA_ERROR_INVALID_OPERATION;
306 }
307
308 int32_t streamId = -1;
309 for (auto& kvPair : mConfiguredOutputs) {
310 if (kvPair.second.first == output->mWindow) {
311 streamId = kvPair.first;
312 break;
313 }
314 }
315 if (streamId < 0) {
316 ALOGE("Error: Invalid output configuration");
317 return ACAMERA_ERROR_INVALID_PARAMETER;
318 }
319
320 sp<IGraphicBufferProducer> iGBP(nullptr);
321 ret = getIGBPfromAnw(output->mWindow, iGBP);
322 if (ret != ACAMERA_OK) {
323 ALOGE("Camera device %s failed to extract graphic producer from native window",
324 getId());
325 return ret;
326 }
327
328 OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
329 true);
330
331 for (auto& anw : output->mSharedWindows) {
332 ret = getIGBPfromAnw(anw, iGBP);
333 if (ret != ACAMERA_OK) {
334 ALOGE("Camera device %s failed to extract graphic producer from native window",
335 getId());
336 return ret;
337 }
338 outConfig.addGraphicProducer(iGBP);
339 }
340
341 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
342 if (!remoteRet.isOk()) {
343 switch (remoteRet.serviceSpecificErrorCode()) {
344 case hardware::ICameraService::ERROR_INVALID_OPERATION:
345 ALOGE("Camera device %s invalid operation: %s", getId(),
346 remoteRet.toString8().string());
347 return ACAMERA_ERROR_INVALID_OPERATION;
348 break;
349 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
350 ALOGE("Camera device %s output surface already exists: %s", getId(),
351 remoteRet.toString8().string());
352 return ACAMERA_ERROR_INVALID_PARAMETER;
353 break;
354 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
355 ALOGE("Camera device %s invalid input argument: %s", getId(),
356 remoteRet.toString8().string());
357 return ACAMERA_ERROR_INVALID_PARAMETER;
358 break;
359 default:
360 ALOGE("Camera device %s failed to add shared output: %s", getId(),
361 remoteRet.toString8().string());
362 return ACAMERA_ERROR_UNKNOWN;
363 }
364 }
365
366 return ACAMERA_OK;
367}
368
Yin-Chia Yehead91462016-01-06 16:45:08 -0800369camera_status_t
370CameraDevice::allocateCaptureRequest(
371 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
372 camera_status_t ret;
373 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800374 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800375 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700376 req->mContext = request->context;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800377
378 for (auto outputTarget : request->targets->mOutputs) {
379 ANativeWindow* anw = outputTarget.mWindow;
380 sp<Surface> surface;
381 ret = getSurfaceFromANativeWindow(anw, surface);
382 if (ret != ACAMERA_OK) {
383 ALOGE("Bad output target in capture request! ret %d", ret);
384 return ret;
385 }
386 req->mSurfaceList.push_back(surface);
387 }
388 outReq = req;
389 return ACAMERA_OK;
390}
391
392ACaptureRequest*
393CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
394 ACaptureRequest* pRequest = new ACaptureRequest();
395 CameraMetadata clone = req->mMetadata;
396 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
397 pRequest->targets = new ACameraOutputTargets();
398 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
399 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
400 ACameraOutputTarget outputTarget(anw);
401 pRequest->targets->mOutputs.insert(outputTarget);
402 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700403 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800404 return pRequest;
405}
406
407void
408CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
409 if (req == nullptr) {
410 return;
411 }
412 delete req->settings;
413 delete req->targets;
414 delete req;
415}
416
417void
418CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
419 if (isClosed()) {
420 // Device is closing already. do nothing
421 return;
422 }
423
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700424 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800425 // Session has been replaced by other seesion or device is closed
426 return;
427 }
428 mCurrentSession = nullptr;
429
430 // Should not happen
431 if (!session->mIsClosed) {
432 ALOGE("Error: unclosed session %p reaches end of life!", session);
433 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
434 return;
435 }
436
437 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100438 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800439 if (ret != ACAMERA_OK) {
440 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
441 }
442}
443
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800444void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700445CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800446 if (mClosing.exchange(true)) {
447 // Already closing, just return
448 ALOGW("Camera device %s is already closing.", getId());
449 return;
450 }
451
452 if (mRemote != nullptr) {
453 mRemote->disconnect();
454 }
455 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800456
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700457 if (session != nullptr) {
458 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800459 }
460}
461
462camera_status_t
463CameraDevice::stopRepeatingLocked() {
464 camera_status_t ret = checkCameraClosedOrErrorLocked();
465 if (ret != ACAMERA_OK) {
466 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
467 return ret;
468 }
469 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
470 int repeatingSequenceId = mRepeatingSequenceId;
471 mRepeatingSequenceId = REQUEST_ID_NONE;
472
473 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800474 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700475 if (remoteRet.serviceSpecificErrorCode() ==
476 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
477 ALOGV("Repeating request is already stopped.");
478 return ACAMERA_OK;
479 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800480 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800481 return ACAMERA_ERROR_UNKNOWN;
482 }
483 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
484 }
485 return ACAMERA_OK;
486}
487
488camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700489CameraDevice::flushLocked(ACameraCaptureSession* session) {
490 camera_status_t ret = checkCameraClosedOrErrorLocked();
491 if (ret != ACAMERA_OK) {
492 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
493 return ret;
494 }
495
496 // This should never happen because creating a new session will close
497 // previous one and thus reject any API call from previous session.
498 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700499 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700500 ALOGE("Camera %s session %p is not current active session!", getId(), session);
501 return ACAMERA_ERROR_INVALID_OPERATION;
502 }
503
504 if (mFlushing) {
505 ALOGW("Camera %s is already aborting captures", getId());
506 return ACAMERA_OK;
507 }
508
509 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700510
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700511 // Send onActive callback to guarantee there is always active->ready transition
512 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
513 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
514 msg->setObject(kSessionSpKey, session);
515 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700516 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700517
518 // If device is already idling, send callback and exit early
519 if (mIdle) {
520 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
521 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
522 msg->setObject(kSessionSpKey, session);
523 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700524 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700525 mFlushing = false;
526 return ACAMERA_OK;
527 }
528
529 int64_t lastFrameNumber;
530 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
531 if (!remoteRet.isOk()) {
532 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
533 return ACAMERA_ERROR_UNKNOWN;
534 }
535 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
536 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
537 }
538 return ACAMERA_OK;
539}
540
541camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800542CameraDevice::waitUntilIdleLocked() {
543 camera_status_t ret = checkCameraClosedOrErrorLocked();
544 if (ret != ACAMERA_OK) {
545 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
546 return ret;
547 }
548
549 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
550 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
551 return ACAMERA_ERROR_INVALID_OPERATION;
552 }
553
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800554 binder::Status remoteRet = mRemote->waitUntilIdle();
555 if (!remoteRet.isOk()) {
556 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800557 // TODO: define a function to convert status_t -> camera_status_t
558 return ACAMERA_ERROR_UNKNOWN;
559 }
560
561 return ACAMERA_OK;
562}
563
564camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700565CameraDevice::getIGBPfromAnw(
566 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800567 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800568 if (anw == nullptr) {
569 ALOGE("Error: output ANativeWindow is null");
570 return ACAMERA_ERROR_INVALID_PARAMETER;
571 }
572 int value;
573 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800574 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800575 ALOGE("Error: ANativeWindow is not backed by Surface!");
576 return ACAMERA_ERROR_INVALID_PARAMETER;
577 }
578 const sp<Surface> surface(static_cast<Surface*>(anw));
579 out = surface->getIGraphicBufferProducer();
580 return ACAMERA_OK;
581}
582
583camera_status_t
584CameraDevice::getSurfaceFromANativeWindow(
585 ANativeWindow* anw, sp<Surface>& out) {
586 if (anw == nullptr) {
587 ALOGE("Error: output ANativeWindow is null");
588 return ACAMERA_ERROR_INVALID_PARAMETER;
589 }
590 int value;
591 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800592 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800593 ALOGE("Error: ANativeWindow is not backed by Surface!");
594 return ACAMERA_ERROR_INVALID_PARAMETER;
595 }
596 sp<Surface> surface(static_cast<Surface*>(anw));
597 out = surface;
598 return ACAMERA_OK;
599}
600
601camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100602CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
603 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800604 ACaptureSessionOutputContainer emptyOutput;
605 if (outputs == nullptr) {
606 outputs = &emptyOutput;
607 }
608
Yin-Chia Yehead91462016-01-06 16:45:08 -0800609 camera_status_t ret = checkCameraClosedOrErrorLocked();
610 if (ret != ACAMERA_OK) {
611 return ret;
612 }
613
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700614 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800615 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700616 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800617 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700618 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800619 if (ret != ACAMERA_OK) {
620 return ret;
621 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700622 outputSet.insert(std::make_pair(
Emilian Peev40ead602017-09-26 15:46:36 +0100623 anw, OutputConfiguration(iGBP, outConfig.mRotation,
624 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800625 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700626 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800627 std::vector<int> deleteList;
628
629 // Determine which streams need to be created, which to be deleted
630 for (auto& kvPair : mConfiguredOutputs) {
631 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700632 auto& outputPair = kvPair.second;
633 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800634 deleteList.push_back(streamId); // Need to delete a no longer needed stream
635 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700636 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800637 }
638 }
639
640 ret = stopRepeatingLocked();
641 if (ret != ACAMERA_OK) {
642 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
643 return ret;
644 }
645
646 ret = waitUntilIdleLocked();
647 if (ret != ACAMERA_OK) {
648 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
649 return ret;
650 }
651
652 // Send onReady to previous session
653 // CurrentSession will be updated after configureStreamLocked, so here
654 // mCurrentSession is the session to be replaced by a new session
655 if (!mIdle && mCurrentSession != nullptr) {
656 if (mBusySession != mCurrentSession) {
657 ALOGE("Current session != busy session");
658 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
659 return ACAMERA_ERROR_CAMERA_DEVICE;
660 }
661 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
662 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
663 msg->setObject(kSessionSpKey, mBusySession);
664 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
665 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700666 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800667 }
668 mIdle = true;
669
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800670 binder::Status remoteRet = mRemote->beginConfigure();
671 if (!remoteRet.isOk()) {
672 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800673 return ACAMERA_ERROR_UNKNOWN;
674 }
675
676 // delete to-be-deleted streams
677 for (auto streamId : deleteList) {
678 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800679 if (!remoteRet.isOk()) {
680 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
681 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800682 return ACAMERA_ERROR_UNKNOWN;
683 }
684 mConfiguredOutputs.erase(streamId);
685 }
686
687 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700688 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800689 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700690 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800691 if (!remoteRet.isOk()) {
692 ALOGE("Camera device %s failed to create stream: %s", getId(),
693 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800694 return ACAMERA_ERROR_UNKNOWN;
695 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700696 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800697 }
698
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100699 CameraMetadata params;
700 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
701 params.append(sessionParameters->settings->getInternalData());
702 }
703 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800704 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
705 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
706 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800707 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800708 } else if (!remoteRet.isOk()) {
709 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800710 return ACAMERA_ERROR_UNKNOWN;
711 }
712
713 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800714}
715
716void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800717CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800718 Mutex::Autolock _l(mDeviceLock);
719 mRemote = remote;
720}
721
722camera_status_t
723CameraDevice::checkCameraClosedOrErrorLocked() const {
724 if (mRemote == nullptr) {
725 ALOGE("%s: camera device already closed", __FUNCTION__);
726 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
727 }
728 if (mInError) {// triggered by onDeviceError
729 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
730 return mError;
731 }
732 return ACAMERA_OK;
733}
734
735void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800736CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
737 mInError = true;
738 mError = error;
739 return;
740}
741
742void
743CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
744 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
745 if (isError) {
746 mFutureErrorSet.insert(frameNumber);
747 } else if (frameNumber <= mCompletedFrameNumber) {
748 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
749 frameNumber, mCompletedFrameNumber);
750 return;
751 } else {
752 if (frameNumber != mCompletedFrameNumber + 1) {
753 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
754 mCompletedFrameNumber + 1, frameNumber);
755 // Do not assert as in java implementation
756 }
757 mCompletedFrameNumber = frameNumber;
758 }
759 update();
760}
761
762void
763CameraDevice::FrameNumberTracker::update() {
764 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
765 int64_t errorFrameNumber = *it;
766 if (errorFrameNumber == mCompletedFrameNumber + 1) {
767 mCompletedFrameNumber++;
768 it = mFutureErrorSet.erase(it);
769 } else if (errorFrameNumber <= mCompletedFrameNumber) {
770 // This should not happen, but deal with it anyway
771 ALOGE("Completd frame number passed through current frame number!");
772 // erase the old error since it's no longer useful
773 it = mFutureErrorSet.erase(it);
774 } else {
775 // Normal requests hasn't catched up error frames, just break
776 break;
777 }
778 }
779 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
780}
781
782void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800783CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800784 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800785 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800786 int sequenceId = resultExtras.requestId;
787 int64_t frameNumber = resultExtras.frameNumber;
788 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700789 auto it = mSequenceCallbackMap.find(sequenceId);
790 if (it == mSequenceCallbackMap.end()) {
791 ALOGE("%s: Error: capture sequence index %d not found!",
792 __FUNCTION__, sequenceId);
793 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800794 return;
795 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700796
797 CallbackHolder cbh = (*it).second;
798 sp<ACameraCaptureSession> session = cbh.mSession;
799 if ((size_t) burstId >= cbh.mRequests.size()) {
800 ALOGE("%s: Error: request index %d out of bound (size %zu)",
801 __FUNCTION__, burstId, cbh.mRequests.size());
802 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
803 return;
804 }
805 sp<CaptureRequest> request = cbh.mRequests[burstId];
806
807 // Handle buffer error
808 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
809 int32_t streamId = resultExtras.errorStreamId;
810 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
811 cbh.mCallbacks.onCaptureBufferLost;
812 auto outputPairIt = mConfiguredOutputs.find(streamId);
813 if (outputPairIt == mConfiguredOutputs.end()) {
814 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800815 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
816 return;
817 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700818 ANativeWindow* anw = outputPairIt->second.first;
819
820 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
821 getId(), anw, frameNumber);
822
823 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
824 msg->setPointer(kContextKey, cbh.mCallbacks.context);
825 msg->setObject(kSessionSpKey, session);
826 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
827 msg->setObject(kCaptureRequestKey, request);
828 msg->setPointer(kAnwKey, (void*) anw);
829 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700830 postSessionMsgAndCleanup(msg);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700831 } else { // Handle other capture failures
832 // Fire capture failure callback if there is one registered
833 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800834 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
835 failure->frameNumber = frameNumber;
836 // TODO: refine this when implementing flush
837 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
838 failure->sequenceId = sequenceId;
839 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800840 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800841
842 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
843 msg->setPointer(kContextKey, cbh.mCallbacks.context);
844 msg->setObject(kSessionSpKey, session);
845 msg->setPointer(kCallbackFpKey, (void*) onError);
846 msg->setObject(kCaptureRequestKey, request);
847 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700848 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800849
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700850 // Update tracker
851 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
852 checkAndFireSequenceCompleteLocked();
853 }
854 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800855}
856
857void CameraDevice::CallbackHandler::onMessageReceived(
858 const sp<AMessage> &msg) {
859 switch (msg->what()) {
860 case kWhatOnDisconnected:
861 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800862 case kWhatSessionStateCb:
863 case kWhatCaptureStart:
864 case kWhatCaptureResult:
865 case kWhatCaptureFail:
866 case kWhatCaptureSeqEnd:
867 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700868 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800869 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800870 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700871 case kWhatCleanUpSessions:
872 mCachedSessions.clear();
873 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800874 default:
875 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
876 return;
877 }
878 // Check the common part of all message
879 void* context;
880 bool found = msg->findPointer(kContextKey, &context);
881 if (!found) {
882 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
883 return;
884 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800885 switch (msg->what()) {
886 case kWhatOnDisconnected:
887 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800888 ACameraDevice* dev;
889 found = msg->findPointer(kDeviceKey, (void**) &dev);
890 if (!found || dev == nullptr) {
891 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
892 return;
893 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800894 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800895 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800896 if (!found) {
897 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
898 return;
899 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800900 if (onDisconnected == nullptr) {
901 return;
902 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800903 (*onDisconnected)(context, dev);
904 break;
905 }
906 case kWhatOnError:
907 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800908 ACameraDevice* dev;
909 found = msg->findPointer(kDeviceKey, (void**) &dev);
910 if (!found || dev == nullptr) {
911 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
912 return;
913 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800914 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800915 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800916 if (!found) {
917 ALOGE("%s: Cannot find onError!", __FUNCTION__);
918 return;
919 }
920 int errorCode;
921 found = msg->findInt32(kErrorCodeKey, &errorCode);
922 if (!found) {
923 ALOGE("%s: Cannot find error code!", __FUNCTION__);
924 return;
925 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800926 if (onError == nullptr) {
927 return;
928 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800929 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800930 break;
931 }
932 case kWhatSessionStateCb:
933 case kWhatCaptureStart:
934 case kWhatCaptureResult:
935 case kWhatCaptureFail:
936 case kWhatCaptureSeqEnd:
937 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700938 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800939 {
940 sp<RefBase> obj;
941 found = msg->findObject(kSessionSpKey, &obj);
942 if (!found || obj == nullptr) {
943 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
944 return;
945 }
946 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700947 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800948 sp<CaptureRequest> requestSp = nullptr;
949 switch (msg->what()) {
950 case kWhatCaptureStart:
951 case kWhatCaptureResult:
952 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700953 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800954 found = msg->findObject(kCaptureRequestKey, &obj);
955 if (!found) {
956 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
957 return;
958 }
959 requestSp = static_cast<CaptureRequest*>(obj.get());
960 break;
961 }
962
963 switch (msg->what()) {
964 case kWhatSessionStateCb:
965 {
966 ACameraCaptureSession_stateCallback onState;
967 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
968 if (!found) {
969 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
970 return;
971 }
972 if (onState == nullptr) {
973 return;
974 }
975 (*onState)(context, session.get());
976 break;
977 }
978 case kWhatCaptureStart:
979 {
980 ACameraCaptureSession_captureCallback_start onStart;
981 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
982 if (!found) {
983 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
984 return;
985 }
986 if (onStart == nullptr) {
987 return;
988 }
989 int64_t timestamp;
990 found = msg->findInt64(kTimeStampKey, &timestamp);
991 if (!found) {
992 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
993 return;
994 }
995 ACaptureRequest* request = allocateACaptureRequest(requestSp);
996 (*onStart)(context, session.get(), request, timestamp);
997 freeACaptureRequest(request);
998 break;
999 }
1000 case kWhatCaptureResult:
1001 {
1002 ACameraCaptureSession_captureCallback_result onResult;
1003 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1004 if (!found) {
1005 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1006 return;
1007 }
1008 if (onResult == nullptr) {
1009 return;
1010 }
1011
1012 found = msg->findObject(kCaptureResultKey, &obj);
1013 if (!found) {
1014 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1015 return;
1016 }
1017 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1018 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1019 (*onResult)(context, session.get(), request, result.get());
1020 freeACaptureRequest(request);
1021 break;
1022 }
1023 case kWhatCaptureFail:
1024 {
1025 ACameraCaptureSession_captureCallback_failed onFail;
1026 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1027 if (!found) {
1028 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1029 return;
1030 }
1031 if (onFail == nullptr) {
1032 return;
1033 }
1034
1035 found = msg->findObject(kCaptureFailureKey, &obj);
1036 if (!found) {
1037 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1038 return;
1039 }
1040 sp<CameraCaptureFailure> failureSp(
1041 static_cast<CameraCaptureFailure*>(obj.get()));
1042 ACameraCaptureFailure* failure =
1043 static_cast<ACameraCaptureFailure*>(failureSp.get());
1044 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1045 (*onFail)(context, session.get(), request, failure);
1046 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001047 break;
1048 }
1049 case kWhatCaptureSeqEnd:
1050 {
1051 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1052 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1053 if (!found) {
1054 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1055 return;
1056 }
1057 if (onSeqEnd == nullptr) {
1058 return;
1059 }
1060 int seqId;
1061 found = msg->findInt32(kSequenceIdKey, &seqId);
1062 if (!found) {
1063 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1064 return;
1065 }
1066 int64_t frameNumber;
1067 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1068 if (!found) {
1069 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1070 return;
1071 }
1072 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1073 break;
1074 }
1075 case kWhatCaptureSeqAbort:
1076 {
1077 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1078 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1079 if (!found) {
1080 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1081 return;
1082 }
1083 if (onSeqAbort == nullptr) {
1084 return;
1085 }
1086 int seqId;
1087 found = msg->findInt32(kSequenceIdKey, &seqId);
1088 if (!found) {
1089 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1090 return;
1091 }
1092 (*onSeqAbort)(context, session.get(), seqId);
1093 break;
1094 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001095 case kWhatCaptureBufferLost:
1096 {
1097 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1098 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1099 if (!found) {
1100 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1101 return;
1102 }
1103 if (onBufferLost == nullptr) {
1104 return;
1105 }
1106
1107 ANativeWindow* anw;
1108 found = msg->findPointer(kAnwKey, (void**) &anw);
1109 if (!found) {
1110 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1111 return;
1112 }
1113
1114 int64_t frameNumber;
1115 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1116 if (!found) {
1117 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1118 return;
1119 }
1120
1121 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1122 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1123 freeACaptureRequest(request);
1124 break;
1125 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001126 }
1127 break;
1128 }
1129 }
1130}
1131
1132CameraDevice::CallbackHolder::CallbackHolder(
1133 sp<ACameraCaptureSession> session,
1134 const Vector<sp<CaptureRequest> >& requests,
1135 bool isRepeating,
1136 ACameraCaptureSession_captureCallbacks* cbs) :
1137 mSession(session), mRequests(requests),
1138 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1139
1140void
1141CameraDevice::checkRepeatingSequenceCompleteLocked(
1142 const int sequenceId, const int64_t lastFrameNumber) {
1143 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1144 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1145 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1146 ALOGW("No callback found for sequenceId %d", sequenceId);
1147 return;
1148 }
1149 // remove callback holder from callback map
1150 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1151 CallbackHolder cbh = cbIt->second;
1152 mSequenceCallbackMap.erase(cbIt);
1153 // send seq aborted callback
1154 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1155 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1156 msg->setObject(kSessionSpKey, cbh.mSession);
1157 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1158 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001159 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001160 } else {
1161 // Use mSequenceLastFrameNumberMap to track
1162 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1163
1164 // Last frame might have arrived. Check now
1165 checkAndFireSequenceCompleteLocked();
1166 }
1167}
1168
1169void
1170CameraDevice::checkAndFireSequenceCompleteLocked() {
1171 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1172 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1173 auto it = mSequenceLastFrameNumberMap.begin();
1174 while (it != mSequenceLastFrameNumberMap.end()) {
1175 int sequenceId = it->first;
1176 int64_t lastFrameNumber = it->second;
1177 bool seqCompleted = false;
1178 bool hasCallback = true;
1179
1180 if (mRemote == nullptr) {
1181 ALOGW("Camera %s closed while checking sequence complete", getId());
1182 return;
1183 }
1184
1185 // Check if there is callback for this sequence
1186 // This should not happen because we always register callback (with nullptr inside)
1187 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1188 ALOGW("No callback found for sequenceId %d", sequenceId);
1189 hasCallback = false;
1190 }
1191
1192 if (lastFrameNumber <= completedFrameNumber) {
1193 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1194 sequenceId, lastFrameNumber, completedFrameNumber);
1195 seqCompleted = true;
1196 }
1197
1198 if (seqCompleted && hasCallback) {
1199 // remove callback holder from callback map
1200 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1201 CallbackHolder cbh = cbIt->second;
1202 mSequenceCallbackMap.erase(cbIt);
1203 // send seq complete callback
1204 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1205 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1206 msg->setObject(kSessionSpKey, cbh.mSession);
1207 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1208 msg->setInt32(kSequenceIdKey, sequenceId);
1209 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1210
1211 // Clear the session sp before we send out the message
1212 // This will guarantee the rare case where the message is processed
1213 // before cbh goes out of scope and causing we call the session
1214 // destructor while holding device lock
1215 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001216 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001217 }
1218
1219 // No need to track sequence complete if there is no callback registered
1220 if (seqCompleted || !hasCallback) {
1221 it = mSequenceLastFrameNumberMap.erase(it);
1222 } else {
1223 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001224 }
1225 }
1226}
1227
1228/**
1229 * Camera service callback implementation
1230 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001231binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001232CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001233 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001234 const CaptureResultExtras& resultExtras) {
1235 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1236 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001237 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001238 sp<CameraDevice> dev = mDevice.promote();
1239 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001240 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001241 }
1242
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001243 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001244 Mutex::Autolock _l(dev->mDeviceLock);
1245 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001246 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001247 }
1248 switch (errorCode) {
1249 case ERROR_CAMERA_DISCONNECTED:
1250 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001251 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001252 if (session != nullptr) {
1253 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001254 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001255 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001256 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1257 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1258 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001259 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001260 msg->post();
1261 break;
1262 }
1263 default:
1264 ALOGE("Unknown error from camera device: %d", errorCode);
1265 // no break
1266 case ERROR_CAMERA_DEVICE:
1267 case ERROR_CAMERA_SERVICE:
1268 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001269 switch (errorCode) {
1270 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001271 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001272 break;
1273 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001274 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001275 break;
1276 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001277 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001278 break;
1279 }
1280 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1281 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1282 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001283 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001284 msg->setInt32(kErrorCodeKey, errorCode);
1285 msg->post();
1286 break;
1287 }
1288 case ERROR_CAMERA_REQUEST:
1289 case ERROR_CAMERA_RESULT:
1290 case ERROR_CAMERA_BUFFER:
1291 dev->onCaptureErrorLocked(errorCode, resultExtras);
1292 break;
1293 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001294 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001295}
1296
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001297binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001298CameraDevice::ServiceCallback::onDeviceIdle() {
1299 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001300 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001301 sp<CameraDevice> dev = mDevice.promote();
1302 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001303 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001304 }
1305
1306 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001307 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001308 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001309 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001310
1311 if (dev->mIdle) {
1312 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001313 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001314 }
1315
1316 if (dev->mCurrentSession != nullptr) {
1317 ALOGE("onDeviceIdle sending state cb");
1318 if (dev->mBusySession != dev->mCurrentSession) {
1319 ALOGE("Current session != busy session");
1320 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001321 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001322 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001323
Yin-Chia Yehead91462016-01-06 16:45:08 -08001324 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1325 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1326 msg->setObject(kSessionSpKey, dev->mBusySession);
1327 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1328 // Make sure we clear the sp first so the session destructor can
1329 // only happen on handler thread (where we don't hold device/session lock)
1330 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001331 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001332 }
1333 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001334 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001335 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001336}
1337
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001338binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001339CameraDevice::ServiceCallback::onCaptureStarted(
1340 const CaptureResultExtras& resultExtras,
1341 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001342 binder::Status ret = binder::Status::ok();
1343
Yin-Chia Yehead91462016-01-06 16:45:08 -08001344 sp<CameraDevice> dev = mDevice.promote();
1345 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001346 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001347 }
1348 Mutex::Autolock _l(dev->mDeviceLock);
1349 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001350 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001351 }
1352
1353 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001354 int32_t burstId = resultExtras.burstId;
1355
1356 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1357 if (it != dev->mSequenceCallbackMap.end()) {
1358 CallbackHolder cbh = (*it).second;
1359 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1360 sp<ACameraCaptureSession> session = cbh.mSession;
1361 if ((size_t) burstId >= cbh.mRequests.size()) {
1362 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1363 __FUNCTION__, burstId, cbh.mRequests.size());
1364 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1365 }
1366 sp<CaptureRequest> request = cbh.mRequests[burstId];
1367 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1368 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1369 msg->setObject(kSessionSpKey, session);
1370 msg->setPointer(kCallbackFpKey, (void*) onStart);
1371 msg->setObject(kCaptureRequestKey, request);
1372 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001373 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001374 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001375 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001376}
1377
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001378binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001379CameraDevice::ServiceCallback::onResultReceived(
1380 const CameraMetadata& metadata,
1381 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001382 binder::Status ret = binder::Status::ok();
1383
Yin-Chia Yehead91462016-01-06 16:45:08 -08001384 sp<CameraDevice> dev = mDevice.promote();
1385 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001386 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001387 }
1388 int sequenceId = resultExtras.requestId;
1389 int64_t frameNumber = resultExtras.frameNumber;
1390 int32_t burstId = resultExtras.burstId;
1391 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1392
1393 if (!isPartialResult) {
1394 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1395 }
1396
1397 Mutex::Autolock _l(dev->mDeviceLock);
1398 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001399 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001400 }
1401
1402 if (dev->isClosed()) {
1403 if (!isPartialResult) {
1404 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1405 }
1406 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001407 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001408 }
1409
1410 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001411 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001412 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001413
1414 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1415 if (it != dev->mSequenceCallbackMap.end()) {
1416 CallbackHolder cbh = (*it).second;
1417 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1418 cbh.mCallbacks.onCaptureProgressed :
1419 cbh.mCallbacks.onCaptureCompleted;
1420 sp<ACameraCaptureSession> session = cbh.mSession;
1421 if ((size_t) burstId >= cbh.mRequests.size()) {
1422 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1423 __FUNCTION__, burstId, cbh.mRequests.size());
1424 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1425 }
1426 sp<CaptureRequest> request = cbh.mRequests[burstId];
1427 sp<ACameraMetadata> result(new ACameraMetadata(
1428 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1429
1430 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1431 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1432 msg->setObject(kSessionSpKey, session);
1433 msg->setPointer(kCallbackFpKey, (void*) onResult);
1434 msg->setObject(kCaptureRequestKey, request);
1435 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001436 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001437 }
1438
1439 if (!isPartialResult) {
1440 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1441 dev->checkAndFireSequenceCompleteLocked();
1442 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001443
1444 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001445}
1446
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001447binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001448CameraDevice::ServiceCallback::onPrepared(int) {
1449 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001450 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001451}
1452
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001453binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001454CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1455 // onRequestQueueEmpty not yet implemented in NDK
1456 return binder::Status::ok();
1457}
1458
1459binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001460CameraDevice::ServiceCallback::onRepeatingRequestError(
1461 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001462 binder::Status ret = binder::Status::ok();
1463
1464 sp<CameraDevice> dev = mDevice.promote();
1465 if (dev == nullptr) {
1466 return ret; // device has been closed
1467 }
1468
1469 Mutex::Autolock _l(dev->mDeviceLock);
1470
1471 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001472 if (stoppedSequenceId == repeatingSequenceId) {
1473 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1474 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001475
1476 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1477
1478 return ret;
1479}
1480
1481
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001482} // namespace android