blob: 0b758b6cdc097dbfadc857178418fb1459428118 [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),
62 mIdle(true) {
63 mClosing = false;
64 // Setup looper thread to perfrom device callbacks to app
65 mCbLooper = new ALooper;
66 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080067 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080068 /*runOnCallingThread*/false,
69 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080070 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080071 if (err != OK) {
72 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
73 __FUNCTION__, strerror(-err), err);
74 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
75 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080076 mHandler = new CallbackHandler();
77 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080078
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080079 const CameraMetadata& metadata = mChars->getInternalData();
80 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080081 if (entry.count != 1) {
82 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
83 mPartialResultCount = 1;
84 } else {
85 mPartialResultCount = entry.data.i32[0];
86 }
87
88 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
89 if (entry.count != 2) {
90 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
91 mShadingMapSize[0] = 0;
92 mShadingMapSize[1] = 0;
93 } else {
94 mShadingMapSize[0] = entry.data.i32[0];
95 mShadingMapSize[1] = entry.data.i32[1];
96 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080097}
98
Yin-Chia Yehead91462016-01-06 16:45:08 -080099// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800100CameraDevice::~CameraDevice() {
101 Mutex::Autolock _l(mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800102 if (!isClosed()) {
103 disconnectLocked();
104 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800105 if (mCbLooper != nullptr) {
106 mCbLooper->unregisterHandler(mHandler->id());
107 mCbLooper->stop();
108 }
109 mCbLooper.clear();
110 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800111}
112
113// TODO: cached created request?
114camera_status_t
115CameraDevice::createCaptureRequest(
116 ACameraDevice_request_template templateId,
117 ACaptureRequest** request) const {
118 Mutex::Autolock _l(mDeviceLock);
119 camera_status_t ret = checkCameraClosedOrErrorLocked();
120 if (ret != ACAMERA_OK) {
121 return ret;
122 }
123 if (mRemote == nullptr) {
124 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
125 }
126 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800127 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
128 if (remoteRet.serviceSpecificErrorCode() ==
129 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800130 ALOGW("Create capture request failed! template %d is not supported on this device",
131 templateId);
132 return ACAMERA_ERROR_UNSUPPORTED;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800133 } else if (!remoteRet.isOk()) {
134 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800135 return ACAMERA_ERROR_UNKNOWN;
136 }
137 ACaptureRequest* outReq = new ACaptureRequest();
138 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
139 outReq->targets = new ACameraOutputTargets();
140 *request = outReq;
141 return ACAMERA_OK;
142}
143
Yin-Chia Yehead91462016-01-06 16:45:08 -0800144camera_status_t
145CameraDevice::createCaptureSession(
146 const ACaptureSessionOutputContainer* outputs,
147 const ACameraCaptureSession_stateCallbacks* callbacks,
148 /*out*/ACameraCaptureSession** session) {
149 Mutex::Autolock _l(mDeviceLock);
150 camera_status_t ret = checkCameraClosedOrErrorLocked();
151 if (ret != ACAMERA_OK) {
152 return ret;
153 }
154
155 if (mCurrentSession != nullptr) {
156 mCurrentSession->closeByDevice();
157 stopRepeatingLocked();
158 }
159
160 // Create new session
161 ret = configureStreamsLocked(outputs);
162 if (ret != ACAMERA_OK) {
163 ALOGE("Fail to create new session. cannot configure streams");
164 return ret;
165 }
166
167 ACameraCaptureSession* newSession = new ACameraCaptureSession(
168 mNextSessionId++, outputs, callbacks, this);
169
Yin-Chia Yehead91462016-01-06 16:45:08 -0800170 // set new session as current session
171 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
172 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700173 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800174 *session = newSession;
175 return ACAMERA_OK;
176}
177
178camera_status_t
179CameraDevice::captureLocked(
180 sp<ACameraCaptureSession> session,
181 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
182 int numRequests, ACaptureRequest** requests,
183 /*optional*/int* captureSequenceId) {
184 return submitRequestsLocked(
185 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
186}
187
188camera_status_t
189CameraDevice::setRepeatingRequestsLocked(
190 sp<ACameraCaptureSession> session,
191 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
192 int numRequests, ACaptureRequest** requests,
193 /*optional*/int* captureSequenceId) {
194 return submitRequestsLocked(
195 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
196}
197
198camera_status_t
199CameraDevice::submitRequestsLocked(
200 sp<ACameraCaptureSession> session,
201 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
202 int numRequests, ACaptureRequest** requests,
203 /*optional*/int* captureSequenceId,
204 bool isRepeating) {
205 camera_status_t ret = checkCameraClosedOrErrorLocked();
206 if (ret != ACAMERA_OK) {
207 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
208 return ret;
209 }
210
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800211 // Form two vectors of capture request, one for internal tracking
212 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800213 Vector<sp<CaptureRequest> > requestsV;
214 requestsV.setCapacity(numRequests);
215 for (int i = 0; i < numRequests; i++) {
216 sp<CaptureRequest> req;
217 ret = allocateCaptureRequest(requests[i], req);
218 if (ret != ACAMERA_OK) {
219 ALOGE("Convert capture request to internal format failure! ret %d", ret);
220 return ret;
221 }
222 if (req->mSurfaceList.empty()) {
223 ALOGE("Capture request without output target cannot be submitted!");
224 return ACAMERA_ERROR_INVALID_PARAMETER;
225 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800226 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800227 requestsV.push_back(req);
228 }
229
230 if (isRepeating) {
231 ret = stopRepeatingLocked();
232 if (ret != ACAMERA_OK) {
233 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
234 return ret;
235 }
236 }
237
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800238 binder::Status remoteRet;
239 hardware::camera2::utils::SubmitInfo info;
240 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
241 int sequenceId = info.mRequestId;
242 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800243 if (sequenceId < 0) {
244 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
245 return ACAMERA_ERROR_UNKNOWN;
246 }
247
248 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
249 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
250
251 if (isRepeating) {
252 // stopRepeating above should have cleanup repeating sequence id
253 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
254 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
255 return ACAMERA_ERROR_CAMERA_DEVICE;
256 }
257 mRepeatingSequenceId = sequenceId;
258 } else {
259 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
260 }
261
262 if (mIdle) {
263 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
264 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
265 msg->setObject(kSessionSpKey, session);
266 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
267 msg->post();
268 }
269 mIdle = false;
270 mBusySession = session;
271
272 if (captureSequenceId) {
273 *captureSequenceId = sequenceId;
274 }
275 return ACAMERA_OK;
276}
277
278camera_status_t
279CameraDevice::allocateCaptureRequest(
280 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
281 camera_status_t ret;
282 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800283 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800284 req->mIsReprocess = false; // NDK does not support reprocessing yet
285
286 for (auto outputTarget : request->targets->mOutputs) {
287 ANativeWindow* anw = outputTarget.mWindow;
288 sp<Surface> surface;
289 ret = getSurfaceFromANativeWindow(anw, surface);
290 if (ret != ACAMERA_OK) {
291 ALOGE("Bad output target in capture request! ret %d", ret);
292 return ret;
293 }
294 req->mSurfaceList.push_back(surface);
295 }
296 outReq = req;
297 return ACAMERA_OK;
298}
299
300ACaptureRequest*
301CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
302 ACaptureRequest* pRequest = new ACaptureRequest();
303 CameraMetadata clone = req->mMetadata;
304 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
305 pRequest->targets = new ACameraOutputTargets();
306 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
307 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
308 ACameraOutputTarget outputTarget(anw);
309 pRequest->targets->mOutputs.insert(outputTarget);
310 }
311 return pRequest;
312}
313
314void
315CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
316 if (req == nullptr) {
317 return;
318 }
319 delete req->settings;
320 delete req->targets;
321 delete req;
322}
323
324void
325CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
326 if (isClosed()) {
327 // Device is closing already. do nothing
328 return;
329 }
330
331 if (session != mCurrentSession) {
332 // Session has been replaced by other seesion or device is closed
333 return;
334 }
335 mCurrentSession = nullptr;
336
337 // Should not happen
338 if (!session->mIsClosed) {
339 ALOGE("Error: unclosed session %p reaches end of life!", session);
340 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
341 return;
342 }
343
344 // No new session, unconfigure now
345 camera_status_t ret = configureStreamsLocked(nullptr);
346 if (ret != ACAMERA_OK) {
347 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
348 }
349}
350
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800351void
352CameraDevice::disconnectLocked() {
353 if (mClosing.exchange(true)) {
354 // Already closing, just return
355 ALOGW("Camera device %s is already closing.", getId());
356 return;
357 }
358
359 if (mRemote != nullptr) {
360 mRemote->disconnect();
361 }
362 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800363
364 if (mCurrentSession != nullptr) {
365 mCurrentSession->closeByDevice();
366 mCurrentSession = nullptr;
367 }
368}
369
370camera_status_t
371CameraDevice::stopRepeatingLocked() {
372 camera_status_t ret = checkCameraClosedOrErrorLocked();
373 if (ret != ACAMERA_OK) {
374 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
375 return ret;
376 }
377 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
378 int repeatingSequenceId = mRepeatingSequenceId;
379 mRepeatingSequenceId = REQUEST_ID_NONE;
380
381 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800382 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
383 if (!remoteRet.isOk()) {
384 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800385 return ACAMERA_ERROR_UNKNOWN;
386 }
387 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
388 }
389 return ACAMERA_OK;
390}
391
392camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700393CameraDevice::flushLocked(ACameraCaptureSession* session) {
394 camera_status_t ret = checkCameraClosedOrErrorLocked();
395 if (ret != ACAMERA_OK) {
396 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
397 return ret;
398 }
399
400 // This should never happen because creating a new session will close
401 // previous one and thus reject any API call from previous session.
402 // But still good to check here in case something unexpected happen.
403 if (session != mCurrentSession) {
404 ALOGE("Camera %s session %p is not current active session!", getId(), session);
405 return ACAMERA_ERROR_INVALID_OPERATION;
406 }
407
408 if (mFlushing) {
409 ALOGW("Camera %s is already aborting captures", getId());
410 return ACAMERA_OK;
411 }
412
413 mFlushing = true;
414 // Send onActive callback to guarantee there is always active->ready transition
415 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
416 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
417 msg->setObject(kSessionSpKey, session);
418 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
419 msg->post();
420
421 // If device is already idling, send callback and exit early
422 if (mIdle) {
423 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
424 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
425 msg->setObject(kSessionSpKey, session);
426 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
427 msg->post();
428 mFlushing = false;
429 return ACAMERA_OK;
430 }
431
432 int64_t lastFrameNumber;
433 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
434 if (!remoteRet.isOk()) {
435 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
436 return ACAMERA_ERROR_UNKNOWN;
437 }
438 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
439 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
440 }
441 return ACAMERA_OK;
442}
443
444camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800445CameraDevice::waitUntilIdleLocked() {
446 camera_status_t ret = checkCameraClosedOrErrorLocked();
447 if (ret != ACAMERA_OK) {
448 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
449 return ret;
450 }
451
452 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
453 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
454 return ACAMERA_ERROR_INVALID_OPERATION;
455 }
456
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800457 binder::Status remoteRet = mRemote->waitUntilIdle();
458 if (!remoteRet.isOk()) {
459 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800460 // TODO: define a function to convert status_t -> camera_status_t
461 return ACAMERA_ERROR_UNKNOWN;
462 }
463
464 return ACAMERA_OK;
465}
466
467camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700468CameraDevice::getIGBPfromAnw(
469 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800470 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800471 if (anw == nullptr) {
472 ALOGE("Error: output ANativeWindow is null");
473 return ACAMERA_ERROR_INVALID_PARAMETER;
474 }
475 int value;
476 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800477 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800478 ALOGE("Error: ANativeWindow is not backed by Surface!");
479 return ACAMERA_ERROR_INVALID_PARAMETER;
480 }
481 const sp<Surface> surface(static_cast<Surface*>(anw));
482 out = surface->getIGraphicBufferProducer();
483 return ACAMERA_OK;
484}
485
486camera_status_t
487CameraDevice::getSurfaceFromANativeWindow(
488 ANativeWindow* anw, sp<Surface>& out) {
489 if (anw == nullptr) {
490 ALOGE("Error: output ANativeWindow is null");
491 return ACAMERA_ERROR_INVALID_PARAMETER;
492 }
493 int value;
494 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800495 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800496 ALOGE("Error: ANativeWindow is not backed by Surface!");
497 return ACAMERA_ERROR_INVALID_PARAMETER;
498 }
499 sp<Surface> surface(static_cast<Surface*>(anw));
500 out = surface;
501 return ACAMERA_OK;
502}
503
504camera_status_t
505CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
506 ACaptureSessionOutputContainer emptyOutput;
507 if (outputs == nullptr) {
508 outputs = &emptyOutput;
509 }
510
Yin-Chia Yehead91462016-01-06 16:45:08 -0800511 camera_status_t ret = checkCameraClosedOrErrorLocked();
512 if (ret != ACAMERA_OK) {
513 return ret;
514 }
515
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700516 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800517 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700518 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800519 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700520 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800521 if (ret != ACAMERA_OK) {
522 return ret;
523 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700524 outputSet.insert(std::make_pair(
525 anw, OutputConfiguration(iGBP, outConfig.mRotation)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800526 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700527 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800528 std::vector<int> deleteList;
529
530 // Determine which streams need to be created, which to be deleted
531 for (auto& kvPair : mConfiguredOutputs) {
532 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700533 auto& outputPair = kvPair.second;
534 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800535 deleteList.push_back(streamId); // Need to delete a no longer needed stream
536 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700537 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800538 }
539 }
540
541 ret = stopRepeatingLocked();
542 if (ret != ACAMERA_OK) {
543 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
544 return ret;
545 }
546
547 ret = waitUntilIdleLocked();
548 if (ret != ACAMERA_OK) {
549 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
550 return ret;
551 }
552
553 // Send onReady to previous session
554 // CurrentSession will be updated after configureStreamLocked, so here
555 // mCurrentSession is the session to be replaced by a new session
556 if (!mIdle && mCurrentSession != nullptr) {
557 if (mBusySession != mCurrentSession) {
558 ALOGE("Current session != busy session");
559 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
560 return ACAMERA_ERROR_CAMERA_DEVICE;
561 }
562 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
563 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
564 msg->setObject(kSessionSpKey, mBusySession);
565 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
566 mBusySession.clear();
567 msg->post();
568 }
569 mIdle = true;
570
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800571 binder::Status remoteRet = mRemote->beginConfigure();
572 if (!remoteRet.isOk()) {
573 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800574 return ACAMERA_ERROR_UNKNOWN;
575 }
576
577 // delete to-be-deleted streams
578 for (auto streamId : deleteList) {
579 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800580 if (!remoteRet.isOk()) {
581 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
582 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800583 return ACAMERA_ERROR_UNKNOWN;
584 }
585 mConfiguredOutputs.erase(streamId);
586 }
587
588 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700589 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800590 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700591 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800592 if (!remoteRet.isOk()) {
593 ALOGE("Camera device %s failed to create stream: %s", getId(),
594 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800595 return ACAMERA_ERROR_UNKNOWN;
596 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700597 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800598 }
599
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800600 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
601 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
602 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
603 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800604 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800605 } else if (!remoteRet.isOk()) {
606 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800607 return ACAMERA_ERROR_UNKNOWN;
608 }
609
610 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800611}
612
613void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800614CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800615 Mutex::Autolock _l(mDeviceLock);
616 mRemote = remote;
617}
618
619camera_status_t
620CameraDevice::checkCameraClosedOrErrorLocked() const {
621 if (mRemote == nullptr) {
622 ALOGE("%s: camera device already closed", __FUNCTION__);
623 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
624 }
625 if (mInError) {// triggered by onDeviceError
626 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
627 return mError;
628 }
629 return ACAMERA_OK;
630}
631
632void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800633CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
634 mInError = true;
635 mError = error;
636 return;
637}
638
639void
640CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
641 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
642 if (isError) {
643 mFutureErrorSet.insert(frameNumber);
644 } else if (frameNumber <= mCompletedFrameNumber) {
645 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
646 frameNumber, mCompletedFrameNumber);
647 return;
648 } else {
649 if (frameNumber != mCompletedFrameNumber + 1) {
650 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
651 mCompletedFrameNumber + 1, frameNumber);
652 // Do not assert as in java implementation
653 }
654 mCompletedFrameNumber = frameNumber;
655 }
656 update();
657}
658
659void
660CameraDevice::FrameNumberTracker::update() {
661 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
662 int64_t errorFrameNumber = *it;
663 if (errorFrameNumber == mCompletedFrameNumber + 1) {
664 mCompletedFrameNumber++;
665 it = mFutureErrorSet.erase(it);
666 } else if (errorFrameNumber <= mCompletedFrameNumber) {
667 // This should not happen, but deal with it anyway
668 ALOGE("Completd frame number passed through current frame number!");
669 // erase the old error since it's no longer useful
670 it = mFutureErrorSet.erase(it);
671 } else {
672 // Normal requests hasn't catched up error frames, just break
673 break;
674 }
675 }
676 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
677}
678
679void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800680CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800681 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800682 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800683 int sequenceId = resultExtras.requestId;
684 int64_t frameNumber = resultExtras.frameNumber;
685 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700686 auto it = mSequenceCallbackMap.find(sequenceId);
687 if (it == mSequenceCallbackMap.end()) {
688 ALOGE("%s: Error: capture sequence index %d not found!",
689 __FUNCTION__, sequenceId);
690 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800691 return;
692 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700693
694 CallbackHolder cbh = (*it).second;
695 sp<ACameraCaptureSession> session = cbh.mSession;
696 if ((size_t) burstId >= cbh.mRequests.size()) {
697 ALOGE("%s: Error: request index %d out of bound (size %zu)",
698 __FUNCTION__, burstId, cbh.mRequests.size());
699 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
700 return;
701 }
702 sp<CaptureRequest> request = cbh.mRequests[burstId];
703
704 // Handle buffer error
705 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
706 int32_t streamId = resultExtras.errorStreamId;
707 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
708 cbh.mCallbacks.onCaptureBufferLost;
709 auto outputPairIt = mConfiguredOutputs.find(streamId);
710 if (outputPairIt == mConfiguredOutputs.end()) {
711 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800712 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
713 return;
714 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700715 ANativeWindow* anw = outputPairIt->second.first;
716
717 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
718 getId(), anw, frameNumber);
719
720 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
721 msg->setPointer(kContextKey, cbh.mCallbacks.context);
722 msg->setObject(kSessionSpKey, session);
723 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
724 msg->setObject(kCaptureRequestKey, request);
725 msg->setPointer(kAnwKey, (void*) anw);
726 msg->setInt64(kFrameNumberKey, frameNumber);
727 msg->post();
728 } else { // Handle other capture failures
729 // Fire capture failure callback if there is one registered
730 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800731 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
732 failure->frameNumber = frameNumber;
733 // TODO: refine this when implementing flush
734 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
735 failure->sequenceId = sequenceId;
736 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800737 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800738
739 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
740 msg->setPointer(kContextKey, cbh.mCallbacks.context);
741 msg->setObject(kSessionSpKey, session);
742 msg->setPointer(kCallbackFpKey, (void*) onError);
743 msg->setObject(kCaptureRequestKey, request);
744 msg->setObject(kCaptureFailureKey, failure);
745 msg->post();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800746
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700747 // Update tracker
748 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
749 checkAndFireSequenceCompleteLocked();
750 }
751 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800752}
753
754void CameraDevice::CallbackHandler::onMessageReceived(
755 const sp<AMessage> &msg) {
756 switch (msg->what()) {
757 case kWhatOnDisconnected:
758 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800759 case kWhatSessionStateCb:
760 case kWhatCaptureStart:
761 case kWhatCaptureResult:
762 case kWhatCaptureFail:
763 case kWhatCaptureSeqEnd:
764 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700765 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800766 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800767 break;
768 default:
769 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
770 return;
771 }
772 // Check the common part of all message
773 void* context;
774 bool found = msg->findPointer(kContextKey, &context);
775 if (!found) {
776 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
777 return;
778 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800779 switch (msg->what()) {
780 case kWhatOnDisconnected:
781 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800782 ACameraDevice* dev;
783 found = msg->findPointer(kDeviceKey, (void**) &dev);
784 if (!found || dev == nullptr) {
785 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
786 return;
787 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800788 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800789 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800790 if (!found) {
791 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
792 return;
793 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800794 if (onDisconnected == nullptr) {
795 return;
796 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800797 (*onDisconnected)(context, dev);
798 break;
799 }
800 case kWhatOnError:
801 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800802 ACameraDevice* dev;
803 found = msg->findPointer(kDeviceKey, (void**) &dev);
804 if (!found || dev == nullptr) {
805 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
806 return;
807 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800808 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800809 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800810 if (!found) {
811 ALOGE("%s: Cannot find onError!", __FUNCTION__);
812 return;
813 }
814 int errorCode;
815 found = msg->findInt32(kErrorCodeKey, &errorCode);
816 if (!found) {
817 ALOGE("%s: Cannot find error code!", __FUNCTION__);
818 return;
819 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800820 if (onError == nullptr) {
821 return;
822 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800823 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800824 break;
825 }
826 case kWhatSessionStateCb:
827 case kWhatCaptureStart:
828 case kWhatCaptureResult:
829 case kWhatCaptureFail:
830 case kWhatCaptureSeqEnd:
831 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700832 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800833 {
834 sp<RefBase> obj;
835 found = msg->findObject(kSessionSpKey, &obj);
836 if (!found || obj == nullptr) {
837 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
838 return;
839 }
840 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
841 sp<CaptureRequest> requestSp = nullptr;
842 switch (msg->what()) {
843 case kWhatCaptureStart:
844 case kWhatCaptureResult:
845 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700846 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800847 found = msg->findObject(kCaptureRequestKey, &obj);
848 if (!found) {
849 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
850 return;
851 }
852 requestSp = static_cast<CaptureRequest*>(obj.get());
853 break;
854 }
855
856 switch (msg->what()) {
857 case kWhatSessionStateCb:
858 {
859 ACameraCaptureSession_stateCallback onState;
860 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
861 if (!found) {
862 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
863 return;
864 }
865 if (onState == nullptr) {
866 return;
867 }
868 (*onState)(context, session.get());
869 break;
870 }
871 case kWhatCaptureStart:
872 {
873 ACameraCaptureSession_captureCallback_start onStart;
874 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
875 if (!found) {
876 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
877 return;
878 }
879 if (onStart == nullptr) {
880 return;
881 }
882 int64_t timestamp;
883 found = msg->findInt64(kTimeStampKey, &timestamp);
884 if (!found) {
885 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
886 return;
887 }
888 ACaptureRequest* request = allocateACaptureRequest(requestSp);
889 (*onStart)(context, session.get(), request, timestamp);
890 freeACaptureRequest(request);
891 break;
892 }
893 case kWhatCaptureResult:
894 {
895 ACameraCaptureSession_captureCallback_result onResult;
896 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
897 if (!found) {
898 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
899 return;
900 }
901 if (onResult == nullptr) {
902 return;
903 }
904
905 found = msg->findObject(kCaptureResultKey, &obj);
906 if (!found) {
907 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
908 return;
909 }
910 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
911 ACaptureRequest* request = allocateACaptureRequest(requestSp);
912 (*onResult)(context, session.get(), request, result.get());
913 freeACaptureRequest(request);
914 break;
915 }
916 case kWhatCaptureFail:
917 {
918 ACameraCaptureSession_captureCallback_failed onFail;
919 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
920 if (!found) {
921 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
922 return;
923 }
924 if (onFail == nullptr) {
925 return;
926 }
927
928 found = msg->findObject(kCaptureFailureKey, &obj);
929 if (!found) {
930 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
931 return;
932 }
933 sp<CameraCaptureFailure> failureSp(
934 static_cast<CameraCaptureFailure*>(obj.get()));
935 ACameraCaptureFailure* failure =
936 static_cast<ACameraCaptureFailure*>(failureSp.get());
937 ACaptureRequest* request = allocateACaptureRequest(requestSp);
938 (*onFail)(context, session.get(), request, failure);
939 freeACaptureRequest(request);
940 delete failure;
941 break;
942 }
943 case kWhatCaptureSeqEnd:
944 {
945 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
946 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
947 if (!found) {
948 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
949 return;
950 }
951 if (onSeqEnd == nullptr) {
952 return;
953 }
954 int seqId;
955 found = msg->findInt32(kSequenceIdKey, &seqId);
956 if (!found) {
957 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
958 return;
959 }
960 int64_t frameNumber;
961 found = msg->findInt64(kFrameNumberKey, &frameNumber);
962 if (!found) {
963 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
964 return;
965 }
966 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
967 break;
968 }
969 case kWhatCaptureSeqAbort:
970 {
971 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
972 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
973 if (!found) {
974 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
975 return;
976 }
977 if (onSeqAbort == nullptr) {
978 return;
979 }
980 int seqId;
981 found = msg->findInt32(kSequenceIdKey, &seqId);
982 if (!found) {
983 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
984 return;
985 }
986 (*onSeqAbort)(context, session.get(), seqId);
987 break;
988 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700989 case kWhatCaptureBufferLost:
990 {
991 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
992 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
993 if (!found) {
994 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
995 return;
996 }
997 if (onBufferLost == nullptr) {
998 return;
999 }
1000
1001 ANativeWindow* anw;
1002 found = msg->findPointer(kAnwKey, (void**) &anw);
1003 if (!found) {
1004 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1005 return;
1006 }
1007
1008 int64_t frameNumber;
1009 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1010 if (!found) {
1011 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1012 return;
1013 }
1014
1015 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1016 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1017 freeACaptureRequest(request);
1018 break;
1019 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001020 }
1021 break;
1022 }
1023 }
1024}
1025
1026CameraDevice::CallbackHolder::CallbackHolder(
1027 sp<ACameraCaptureSession> session,
1028 const Vector<sp<CaptureRequest> >& requests,
1029 bool isRepeating,
1030 ACameraCaptureSession_captureCallbacks* cbs) :
1031 mSession(session), mRequests(requests),
1032 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1033
1034void
1035CameraDevice::checkRepeatingSequenceCompleteLocked(
1036 const int sequenceId, const int64_t lastFrameNumber) {
1037 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1038 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1039 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1040 ALOGW("No callback found for sequenceId %d", sequenceId);
1041 return;
1042 }
1043 // remove callback holder from callback map
1044 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1045 CallbackHolder cbh = cbIt->second;
1046 mSequenceCallbackMap.erase(cbIt);
1047 // send seq aborted callback
1048 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1049 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1050 msg->setObject(kSessionSpKey, cbh.mSession);
1051 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1052 msg->setInt32(kSequenceIdKey, sequenceId);
1053 msg->post();
1054 } else {
1055 // Use mSequenceLastFrameNumberMap to track
1056 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1057
1058 // Last frame might have arrived. Check now
1059 checkAndFireSequenceCompleteLocked();
1060 }
1061}
1062
1063void
1064CameraDevice::checkAndFireSequenceCompleteLocked() {
1065 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1066 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1067 auto it = mSequenceLastFrameNumberMap.begin();
1068 while (it != mSequenceLastFrameNumberMap.end()) {
1069 int sequenceId = it->first;
1070 int64_t lastFrameNumber = it->second;
1071 bool seqCompleted = false;
1072 bool hasCallback = true;
1073
1074 if (mRemote == nullptr) {
1075 ALOGW("Camera %s closed while checking sequence complete", getId());
1076 return;
1077 }
1078
1079 // Check if there is callback for this sequence
1080 // This should not happen because we always register callback (with nullptr inside)
1081 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1082 ALOGW("No callback found for sequenceId %d", sequenceId);
1083 hasCallback = false;
1084 }
1085
1086 if (lastFrameNumber <= completedFrameNumber) {
1087 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1088 sequenceId, lastFrameNumber, completedFrameNumber);
1089 seqCompleted = true;
1090 }
1091
1092 if (seqCompleted && hasCallback) {
1093 // remove callback holder from callback map
1094 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1095 CallbackHolder cbh = cbIt->second;
1096 mSequenceCallbackMap.erase(cbIt);
1097 // send seq complete callback
1098 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1099 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1100 msg->setObject(kSessionSpKey, cbh.mSession);
1101 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1102 msg->setInt32(kSequenceIdKey, sequenceId);
1103 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1104
1105 // Clear the session sp before we send out the message
1106 // This will guarantee the rare case where the message is processed
1107 // before cbh goes out of scope and causing we call the session
1108 // destructor while holding device lock
1109 cbh.mSession.clear();
1110 msg->post();
1111 }
1112
1113 // No need to track sequence complete if there is no callback registered
1114 if (seqCompleted || !hasCallback) {
1115 it = mSequenceLastFrameNumberMap.erase(it);
1116 } else {
1117 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001118 }
1119 }
1120}
1121
1122/**
1123 * Camera service callback implementation
1124 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001125binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001126CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001127 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001128 const CaptureResultExtras& resultExtras) {
1129 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1130 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001131 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001132 sp<CameraDevice> dev = mDevice.promote();
1133 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001134 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001135 }
1136
1137 Mutex::Autolock _l(dev->mDeviceLock);
1138 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001139 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001140 }
1141 switch (errorCode) {
1142 case ERROR_CAMERA_DISCONNECTED:
1143 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001144 // Camera is disconnected, close the session and expect no more callbacks
1145 if (dev->mCurrentSession != nullptr) {
1146 dev->mCurrentSession->closeByDevice();
1147 dev->mCurrentSession = nullptr;
1148 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001149 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1150 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1151 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001152 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001153 msg->post();
1154 break;
1155 }
1156 default:
1157 ALOGE("Unknown error from camera device: %d", errorCode);
1158 // no break
1159 case ERROR_CAMERA_DEVICE:
1160 case ERROR_CAMERA_SERVICE:
1161 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001162 switch (errorCode) {
1163 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001164 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001165 break;
1166 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001167 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001168 break;
1169 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001170 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001171 break;
1172 }
1173 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1174 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1175 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001176 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001177 msg->setInt32(kErrorCodeKey, errorCode);
1178 msg->post();
1179 break;
1180 }
1181 case ERROR_CAMERA_REQUEST:
1182 case ERROR_CAMERA_RESULT:
1183 case ERROR_CAMERA_BUFFER:
1184 dev->onCaptureErrorLocked(errorCode, resultExtras);
1185 break;
1186 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001187 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001188}
1189
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001190binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001191CameraDevice::ServiceCallback::onDeviceIdle() {
1192 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001193 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001194 sp<CameraDevice> dev = mDevice.promote();
1195 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001196 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001197 }
1198
1199 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001200 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001201 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001202 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001203
1204 if (dev->mIdle) {
1205 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001206 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001207 }
1208
1209 if (dev->mCurrentSession != nullptr) {
1210 ALOGE("onDeviceIdle sending state cb");
1211 if (dev->mBusySession != dev->mCurrentSession) {
1212 ALOGE("Current session != busy session");
1213 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001214 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001215 }
1216 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1217 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1218 msg->setObject(kSessionSpKey, dev->mBusySession);
1219 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1220 // Make sure we clear the sp first so the session destructor can
1221 // only happen on handler thread (where we don't hold device/session lock)
1222 dev->mBusySession.clear();
1223 msg->post();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001224 }
1225 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001226 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001227 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001228}
1229
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001230binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001231CameraDevice::ServiceCallback::onCaptureStarted(
1232 const CaptureResultExtras& resultExtras,
1233 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001234 binder::Status ret = binder::Status::ok();
1235
Yin-Chia Yehead91462016-01-06 16:45:08 -08001236 sp<CameraDevice> dev = mDevice.promote();
1237 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001238 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001239 }
1240 Mutex::Autolock _l(dev->mDeviceLock);
1241 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001242 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001243 }
1244
1245 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001246 int32_t burstId = resultExtras.burstId;
1247
1248 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1249 if (it != dev->mSequenceCallbackMap.end()) {
1250 CallbackHolder cbh = (*it).second;
1251 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1252 sp<ACameraCaptureSession> session = cbh.mSession;
1253 if ((size_t) burstId >= cbh.mRequests.size()) {
1254 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1255 __FUNCTION__, burstId, cbh.mRequests.size());
1256 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1257 }
1258 sp<CaptureRequest> request = cbh.mRequests[burstId];
1259 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1260 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1261 msg->setObject(kSessionSpKey, session);
1262 msg->setPointer(kCallbackFpKey, (void*) onStart);
1263 msg->setObject(kCaptureRequestKey, request);
1264 msg->setInt64(kTimeStampKey, timestamp);
1265 msg->post();
1266 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001267 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001268}
1269
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001270binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001271CameraDevice::ServiceCallback::onResultReceived(
1272 const CameraMetadata& metadata,
1273 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001274 binder::Status ret = binder::Status::ok();
1275
Yin-Chia Yehead91462016-01-06 16:45:08 -08001276 sp<CameraDevice> dev = mDevice.promote();
1277 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001278 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001279 }
1280 int sequenceId = resultExtras.requestId;
1281 int64_t frameNumber = resultExtras.frameNumber;
1282 int32_t burstId = resultExtras.burstId;
1283 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1284
1285 if (!isPartialResult) {
1286 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1287 }
1288
1289 Mutex::Autolock _l(dev->mDeviceLock);
1290 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001291 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001292 }
1293
1294 if (dev->isClosed()) {
1295 if (!isPartialResult) {
1296 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1297 }
1298 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001299 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001300 }
1301
1302 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001303 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001304 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001305
1306 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1307 if (it != dev->mSequenceCallbackMap.end()) {
1308 CallbackHolder cbh = (*it).second;
1309 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1310 cbh.mCallbacks.onCaptureProgressed :
1311 cbh.mCallbacks.onCaptureCompleted;
1312 sp<ACameraCaptureSession> session = cbh.mSession;
1313 if ((size_t) burstId >= cbh.mRequests.size()) {
1314 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1315 __FUNCTION__, burstId, cbh.mRequests.size());
1316 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1317 }
1318 sp<CaptureRequest> request = cbh.mRequests[burstId];
1319 sp<ACameraMetadata> result(new ACameraMetadata(
1320 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1321
1322 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1323 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1324 msg->setObject(kSessionSpKey, session);
1325 msg->setPointer(kCallbackFpKey, (void*) onResult);
1326 msg->setObject(kCaptureRequestKey, request);
1327 msg->setObject(kCaptureResultKey, result);
1328 msg->post();
1329 }
1330
1331 if (!isPartialResult) {
1332 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1333 dev->checkAndFireSequenceCompleteLocked();
1334 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001335
1336 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001337}
1338
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001339binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001340CameraDevice::ServiceCallback::onPrepared(int) {
1341 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001342 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001343}
1344
1345} // namespace android