blob: 8f1115a0dc70f81d91326ff340b173b3126dec14 [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>
21#include <utility>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080022#include <inttypes.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080023#include <android/hardware/ICameraService.h>
24#include <camera2/SubmitInfo.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080025#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080026#include "ACameraDevice.h"
27#include "ACameraMetadata.h"
28#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080029#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080030
31using namespace android;
32
33namespace android {
34// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080035const char* CameraDevice::kContextKey = "Context";
36const char* CameraDevice::kDeviceKey = "Device";
37const char* CameraDevice::kErrorCodeKey = "ErrorCode";
38const char* CameraDevice::kCallbackFpKey = "Callback";
39const char* CameraDevice::kSessionSpKey = "SessionSp";
40const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
41const char* CameraDevice::kTimeStampKey = "TimeStamp";
42const char* CameraDevice::kCaptureResultKey = "CaptureResult";
43const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
44const char* CameraDevice::kSequenceIdKey = "SequenceId";
45const char* CameraDevice::kFrameNumberKey = "FrameNumber";
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
468CameraDevice::getIGBPfromSessionOutput(
469 const ACaptureSessionOutput& config,
470 sp<IGraphicBufferProducer>& out) {
471 ANativeWindow* anw = config.mWindow;
472 if (anw == nullptr) {
473 ALOGE("Error: output ANativeWindow is null");
474 return ACAMERA_ERROR_INVALID_PARAMETER;
475 }
476 int value;
477 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800478 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800479 ALOGE("Error: ANativeWindow is not backed by Surface!");
480 return ACAMERA_ERROR_INVALID_PARAMETER;
481 }
482 const sp<Surface> surface(static_cast<Surface*>(anw));
483 out = surface->getIGraphicBufferProducer();
484 return ACAMERA_OK;
485}
486
487camera_status_t
488CameraDevice::getSurfaceFromANativeWindow(
489 ANativeWindow* anw, sp<Surface>& out) {
490 if (anw == nullptr) {
491 ALOGE("Error: output ANativeWindow is null");
492 return ACAMERA_ERROR_INVALID_PARAMETER;
493 }
494 int value;
495 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800496 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800497 ALOGE("Error: ANativeWindow is not backed by Surface!");
498 return ACAMERA_ERROR_INVALID_PARAMETER;
499 }
500 sp<Surface> surface(static_cast<Surface*>(anw));
501 out = surface;
502 return ACAMERA_OK;
503}
504
505camera_status_t
506CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
507 ACaptureSessionOutputContainer emptyOutput;
508 if (outputs == nullptr) {
509 outputs = &emptyOutput;
510 }
511
Yin-Chia Yehead91462016-01-06 16:45:08 -0800512 camera_status_t ret = checkCameraClosedOrErrorLocked();
513 if (ret != ACAMERA_OK) {
514 return ret;
515 }
516
517 std::set<OutputConfiguration> outputSet;
518 for (auto outConfig : outputs->mOutputs) {
519 sp<IGraphicBufferProducer> iGBP(nullptr);
520 ret = getIGBPfromSessionOutput(outConfig, iGBP);
521 if (ret != ACAMERA_OK) {
522 return ret;
523 }
524 outputSet.insert(OutputConfiguration(iGBP, outConfig.mRotation));
525 }
526 std::set<OutputConfiguration> addSet = outputSet;
527 std::vector<int> deleteList;
528
529 // Determine which streams need to be created, which to be deleted
530 for (auto& kvPair : mConfiguredOutputs) {
531 int streamId = kvPair.first;
532 OutputConfiguration& outConfig = kvPair.second;
533 if (outputSet.count(outConfig) == 0) {
534 deleteList.push_back(streamId); // Need to delete a no longer needed stream
535 } else {
536 addSet.erase(outConfig); // No need to add already existing stream
537 }
538 }
539
540 ret = stopRepeatingLocked();
541 if (ret != ACAMERA_OK) {
542 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
543 return ret;
544 }
545
546 ret = waitUntilIdleLocked();
547 if (ret != ACAMERA_OK) {
548 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
549 return ret;
550 }
551
552 // Send onReady to previous session
553 // CurrentSession will be updated after configureStreamLocked, so here
554 // mCurrentSession is the session to be replaced by a new session
555 if (!mIdle && mCurrentSession != nullptr) {
556 if (mBusySession != mCurrentSession) {
557 ALOGE("Current session != busy session");
558 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
559 return ACAMERA_ERROR_CAMERA_DEVICE;
560 }
561 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
562 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
563 msg->setObject(kSessionSpKey, mBusySession);
564 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
565 mBusySession.clear();
566 msg->post();
567 }
568 mIdle = true;
569
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800570 binder::Status remoteRet = mRemote->beginConfigure();
571 if (!remoteRet.isOk()) {
572 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800573 return ACAMERA_ERROR_UNKNOWN;
574 }
575
576 // delete to-be-deleted streams
577 for (auto streamId : deleteList) {
578 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800579 if (!remoteRet.isOk()) {
580 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
581 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800582 return ACAMERA_ERROR_UNKNOWN;
583 }
584 mConfiguredOutputs.erase(streamId);
585 }
586
587 // add new streams
588 for (auto outConfig : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800589 int streamId;
590 remoteRet = mRemote->createStream(outConfig, &streamId);
591 if (!remoteRet.isOk()) {
592 ALOGE("Camera device %s failed to create stream: %s", getId(),
593 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800594 return ACAMERA_ERROR_UNKNOWN;
595 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800596 mConfiguredOutputs.insert(std::make_pair(streamId, outConfig));
597 }
598
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800599 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
600 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
601 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
602 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800603 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800604 } else if (!remoteRet.isOk()) {
605 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800606 return ACAMERA_ERROR_UNKNOWN;
607 }
608
609 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800610}
611
612void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800613CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800614 Mutex::Autolock _l(mDeviceLock);
615 mRemote = remote;
616}
617
618camera_status_t
619CameraDevice::checkCameraClosedOrErrorLocked() const {
620 if (mRemote == nullptr) {
621 ALOGE("%s: camera device already closed", __FUNCTION__);
622 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
623 }
624 if (mInError) {// triggered by onDeviceError
625 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
626 return mError;
627 }
628 return ACAMERA_OK;
629}
630
631void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800632CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
633 mInError = true;
634 mError = error;
635 return;
636}
637
638void
639CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
640 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
641 if (isError) {
642 mFutureErrorSet.insert(frameNumber);
643 } else if (frameNumber <= mCompletedFrameNumber) {
644 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
645 frameNumber, mCompletedFrameNumber);
646 return;
647 } else {
648 if (frameNumber != mCompletedFrameNumber + 1) {
649 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
650 mCompletedFrameNumber + 1, frameNumber);
651 // Do not assert as in java implementation
652 }
653 mCompletedFrameNumber = frameNumber;
654 }
655 update();
656}
657
658void
659CameraDevice::FrameNumberTracker::update() {
660 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
661 int64_t errorFrameNumber = *it;
662 if (errorFrameNumber == mCompletedFrameNumber + 1) {
663 mCompletedFrameNumber++;
664 it = mFutureErrorSet.erase(it);
665 } else if (errorFrameNumber <= mCompletedFrameNumber) {
666 // This should not happen, but deal with it anyway
667 ALOGE("Completd frame number passed through current frame number!");
668 // erase the old error since it's no longer useful
669 it = mFutureErrorSet.erase(it);
670 } else {
671 // Normal requests hasn't catched up error frames, just break
672 break;
673 }
674 }
675 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
676}
677
678void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800679CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800680 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800681 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800682 int sequenceId = resultExtras.requestId;
683 int64_t frameNumber = resultExtras.frameNumber;
684 int32_t burstId = resultExtras.burstId;
685
686 // No way to report buffer error now
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800687 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800688 ALOGE("Camera %s Lost output buffer for frame %" PRId64,
689 getId(), frameNumber);
690 return;
691 }
692 // Fire capture failure callback if there is one registered
693 auto it = mSequenceCallbackMap.find(sequenceId);
694 if (it != mSequenceCallbackMap.end()) {
695 CallbackHolder cbh = (*it).second;
696 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
697 sp<ACameraCaptureSession> session = cbh.mSession;
698 if ((size_t) burstId >= cbh.mRequests.size()) {
699 ALOGE("%s: Error: request index %d out of bound (size %zu)",
700 __FUNCTION__, burstId, cbh.mRequests.size());
701 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
702 return;
703 }
704 sp<CaptureRequest> request = cbh.mRequests[burstId];
705 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
706 failure->frameNumber = frameNumber;
707 // TODO: refine this when implementing flush
708 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
709 failure->sequenceId = sequenceId;
710 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800711 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800712
713 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
714 msg->setPointer(kContextKey, cbh.mCallbacks.context);
715 msg->setObject(kSessionSpKey, session);
716 msg->setPointer(kCallbackFpKey, (void*) onError);
717 msg->setObject(kCaptureRequestKey, request);
718 msg->setObject(kCaptureFailureKey, failure);
719 msg->post();
720 }
721
722 // Update tracker
723 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
724 checkAndFireSequenceCompleteLocked();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800725}
726
727void CameraDevice::CallbackHandler::onMessageReceived(
728 const sp<AMessage> &msg) {
729 switch (msg->what()) {
730 case kWhatOnDisconnected:
731 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800732 case kWhatSessionStateCb:
733 case kWhatCaptureStart:
734 case kWhatCaptureResult:
735 case kWhatCaptureFail:
736 case kWhatCaptureSeqEnd:
737 case kWhatCaptureSeqAbort:
738 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800739 break;
740 default:
741 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
742 return;
743 }
744 // Check the common part of all message
745 void* context;
746 bool found = msg->findPointer(kContextKey, &context);
747 if (!found) {
748 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
749 return;
750 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800751 switch (msg->what()) {
752 case kWhatOnDisconnected:
753 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800754 ACameraDevice* dev;
755 found = msg->findPointer(kDeviceKey, (void**) &dev);
756 if (!found || dev == nullptr) {
757 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
758 return;
759 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800760 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800761 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800762 if (!found) {
763 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
764 return;
765 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800766 if (onDisconnected == nullptr) {
767 return;
768 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800769 (*onDisconnected)(context, dev);
770 break;
771 }
772 case kWhatOnError:
773 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800774 ACameraDevice* dev;
775 found = msg->findPointer(kDeviceKey, (void**) &dev);
776 if (!found || dev == nullptr) {
777 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
778 return;
779 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800780 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800781 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800782 if (!found) {
783 ALOGE("%s: Cannot find onError!", __FUNCTION__);
784 return;
785 }
786 int errorCode;
787 found = msg->findInt32(kErrorCodeKey, &errorCode);
788 if (!found) {
789 ALOGE("%s: Cannot find error code!", __FUNCTION__);
790 return;
791 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800792 if (onError == nullptr) {
793 return;
794 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800795 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800796 break;
797 }
798 case kWhatSessionStateCb:
799 case kWhatCaptureStart:
800 case kWhatCaptureResult:
801 case kWhatCaptureFail:
802 case kWhatCaptureSeqEnd:
803 case kWhatCaptureSeqAbort:
804 {
805 sp<RefBase> obj;
806 found = msg->findObject(kSessionSpKey, &obj);
807 if (!found || obj == nullptr) {
808 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
809 return;
810 }
811 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
812 sp<CaptureRequest> requestSp = nullptr;
813 switch (msg->what()) {
814 case kWhatCaptureStart:
815 case kWhatCaptureResult:
816 case kWhatCaptureFail:
817 found = msg->findObject(kCaptureRequestKey, &obj);
818 if (!found) {
819 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
820 return;
821 }
822 requestSp = static_cast<CaptureRequest*>(obj.get());
823 break;
824 }
825
826 switch (msg->what()) {
827 case kWhatSessionStateCb:
828 {
829 ACameraCaptureSession_stateCallback onState;
830 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
831 if (!found) {
832 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
833 return;
834 }
835 if (onState == nullptr) {
836 return;
837 }
838 (*onState)(context, session.get());
839 break;
840 }
841 case kWhatCaptureStart:
842 {
843 ACameraCaptureSession_captureCallback_start onStart;
844 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
845 if (!found) {
846 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
847 return;
848 }
849 if (onStart == nullptr) {
850 return;
851 }
852 int64_t timestamp;
853 found = msg->findInt64(kTimeStampKey, &timestamp);
854 if (!found) {
855 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
856 return;
857 }
858 ACaptureRequest* request = allocateACaptureRequest(requestSp);
859 (*onStart)(context, session.get(), request, timestamp);
860 freeACaptureRequest(request);
861 break;
862 }
863 case kWhatCaptureResult:
864 {
865 ACameraCaptureSession_captureCallback_result onResult;
866 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
867 if (!found) {
868 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
869 return;
870 }
871 if (onResult == nullptr) {
872 return;
873 }
874
875 found = msg->findObject(kCaptureResultKey, &obj);
876 if (!found) {
877 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
878 return;
879 }
880 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
881 ACaptureRequest* request = allocateACaptureRequest(requestSp);
882 (*onResult)(context, session.get(), request, result.get());
883 freeACaptureRequest(request);
884 break;
885 }
886 case kWhatCaptureFail:
887 {
888 ACameraCaptureSession_captureCallback_failed onFail;
889 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
890 if (!found) {
891 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
892 return;
893 }
894 if (onFail == nullptr) {
895 return;
896 }
897
898 found = msg->findObject(kCaptureFailureKey, &obj);
899 if (!found) {
900 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
901 return;
902 }
903 sp<CameraCaptureFailure> failureSp(
904 static_cast<CameraCaptureFailure*>(obj.get()));
905 ACameraCaptureFailure* failure =
906 static_cast<ACameraCaptureFailure*>(failureSp.get());
907 ACaptureRequest* request = allocateACaptureRequest(requestSp);
908 (*onFail)(context, session.get(), request, failure);
909 freeACaptureRequest(request);
910 delete failure;
911 break;
912 }
913 case kWhatCaptureSeqEnd:
914 {
915 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
916 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
917 if (!found) {
918 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
919 return;
920 }
921 if (onSeqEnd == nullptr) {
922 return;
923 }
924 int seqId;
925 found = msg->findInt32(kSequenceIdKey, &seqId);
926 if (!found) {
927 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
928 return;
929 }
930 int64_t frameNumber;
931 found = msg->findInt64(kFrameNumberKey, &frameNumber);
932 if (!found) {
933 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
934 return;
935 }
936 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
937 break;
938 }
939 case kWhatCaptureSeqAbort:
940 {
941 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
942 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
943 if (!found) {
944 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
945 return;
946 }
947 if (onSeqAbort == nullptr) {
948 return;
949 }
950 int seqId;
951 found = msg->findInt32(kSequenceIdKey, &seqId);
952 if (!found) {
953 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
954 return;
955 }
956 (*onSeqAbort)(context, session.get(), seqId);
957 break;
958 }
959 }
960 break;
961 }
962 }
963}
964
965CameraDevice::CallbackHolder::CallbackHolder(
966 sp<ACameraCaptureSession> session,
967 const Vector<sp<CaptureRequest> >& requests,
968 bool isRepeating,
969 ACameraCaptureSession_captureCallbacks* cbs) :
970 mSession(session), mRequests(requests),
971 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
972
973void
974CameraDevice::checkRepeatingSequenceCompleteLocked(
975 const int sequenceId, const int64_t lastFrameNumber) {
976 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
977 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
978 if (mSequenceCallbackMap.count(sequenceId) == 0) {
979 ALOGW("No callback found for sequenceId %d", sequenceId);
980 return;
981 }
982 // remove callback holder from callback map
983 auto cbIt = mSequenceCallbackMap.find(sequenceId);
984 CallbackHolder cbh = cbIt->second;
985 mSequenceCallbackMap.erase(cbIt);
986 // send seq aborted callback
987 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
988 msg->setPointer(kContextKey, cbh.mCallbacks.context);
989 msg->setObject(kSessionSpKey, cbh.mSession);
990 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
991 msg->setInt32(kSequenceIdKey, sequenceId);
992 msg->post();
993 } else {
994 // Use mSequenceLastFrameNumberMap to track
995 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
996
997 // Last frame might have arrived. Check now
998 checkAndFireSequenceCompleteLocked();
999 }
1000}
1001
1002void
1003CameraDevice::checkAndFireSequenceCompleteLocked() {
1004 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1005 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1006 auto it = mSequenceLastFrameNumberMap.begin();
1007 while (it != mSequenceLastFrameNumberMap.end()) {
1008 int sequenceId = it->first;
1009 int64_t lastFrameNumber = it->second;
1010 bool seqCompleted = false;
1011 bool hasCallback = true;
1012
1013 if (mRemote == nullptr) {
1014 ALOGW("Camera %s closed while checking sequence complete", getId());
1015 return;
1016 }
1017
1018 // Check if there is callback for this sequence
1019 // This should not happen because we always register callback (with nullptr inside)
1020 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1021 ALOGW("No callback found for sequenceId %d", sequenceId);
1022 hasCallback = false;
1023 }
1024
1025 if (lastFrameNumber <= completedFrameNumber) {
1026 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1027 sequenceId, lastFrameNumber, completedFrameNumber);
1028 seqCompleted = true;
1029 }
1030
1031 if (seqCompleted && hasCallback) {
1032 // remove callback holder from callback map
1033 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1034 CallbackHolder cbh = cbIt->second;
1035 mSequenceCallbackMap.erase(cbIt);
1036 // send seq complete callback
1037 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1038 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1039 msg->setObject(kSessionSpKey, cbh.mSession);
1040 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1041 msg->setInt32(kSequenceIdKey, sequenceId);
1042 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1043
1044 // Clear the session sp before we send out the message
1045 // This will guarantee the rare case where the message is processed
1046 // before cbh goes out of scope and causing we call the session
1047 // destructor while holding device lock
1048 cbh.mSession.clear();
1049 msg->post();
1050 }
1051
1052 // No need to track sequence complete if there is no callback registered
1053 if (seqCompleted || !hasCallback) {
1054 it = mSequenceLastFrameNumberMap.erase(it);
1055 } else {
1056 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001057 }
1058 }
1059}
1060
1061/**
1062 * Camera service callback implementation
1063 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001064binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001065CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001066 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001067 const CaptureResultExtras& resultExtras) {
1068 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1069 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001070 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001071 sp<CameraDevice> dev = mDevice.promote();
1072 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001073 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001074 }
1075
1076 Mutex::Autolock _l(dev->mDeviceLock);
1077 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001078 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001079 }
1080 switch (errorCode) {
1081 case ERROR_CAMERA_DISCONNECTED:
1082 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001083 // Camera is disconnected, close the session and expect no more callbacks
1084 if (dev->mCurrentSession != nullptr) {
1085 dev->mCurrentSession->closeByDevice();
1086 dev->mCurrentSession = nullptr;
1087 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001088 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1089 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1090 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001091 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001092 msg->post();
1093 break;
1094 }
1095 default:
1096 ALOGE("Unknown error from camera device: %d", errorCode);
1097 // no break
1098 case ERROR_CAMERA_DEVICE:
1099 case ERROR_CAMERA_SERVICE:
1100 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001101 switch (errorCode) {
1102 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001103 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001104 break;
1105 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001106 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001107 break;
1108 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001109 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001110 break;
1111 }
1112 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1113 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1114 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001115 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001116 msg->setInt32(kErrorCodeKey, errorCode);
1117 msg->post();
1118 break;
1119 }
1120 case ERROR_CAMERA_REQUEST:
1121 case ERROR_CAMERA_RESULT:
1122 case ERROR_CAMERA_BUFFER:
1123 dev->onCaptureErrorLocked(errorCode, resultExtras);
1124 break;
1125 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001126 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001127}
1128
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001129binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001130CameraDevice::ServiceCallback::onDeviceIdle() {
1131 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001132 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001133 sp<CameraDevice> dev = mDevice.promote();
1134 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001135 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001136 }
1137
1138 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001139 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001140 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001141 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001142
1143 if (dev->mIdle) {
1144 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001145 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001146 }
1147
1148 if (dev->mCurrentSession != nullptr) {
1149 ALOGE("onDeviceIdle sending state cb");
1150 if (dev->mBusySession != dev->mCurrentSession) {
1151 ALOGE("Current session != busy session");
1152 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001153 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001154 }
1155 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1156 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1157 msg->setObject(kSessionSpKey, dev->mBusySession);
1158 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1159 // Make sure we clear the sp first so the session destructor can
1160 // only happen on handler thread (where we don't hold device/session lock)
1161 dev->mBusySession.clear();
1162 msg->post();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001163 }
1164 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001165 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001166 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001167}
1168
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001169binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001170CameraDevice::ServiceCallback::onCaptureStarted(
1171 const CaptureResultExtras& resultExtras,
1172 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001173 binder::Status ret = binder::Status::ok();
1174
Yin-Chia Yehead91462016-01-06 16:45:08 -08001175 sp<CameraDevice> dev = mDevice.promote();
1176 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001177 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001178 }
1179 Mutex::Autolock _l(dev->mDeviceLock);
1180 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001181 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001182 }
1183
1184 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001185 int32_t burstId = resultExtras.burstId;
1186
1187 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1188 if (it != dev->mSequenceCallbackMap.end()) {
1189 CallbackHolder cbh = (*it).second;
1190 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1191 sp<ACameraCaptureSession> session = cbh.mSession;
1192 if ((size_t) burstId >= cbh.mRequests.size()) {
1193 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1194 __FUNCTION__, burstId, cbh.mRequests.size());
1195 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1196 }
1197 sp<CaptureRequest> request = cbh.mRequests[burstId];
1198 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1199 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1200 msg->setObject(kSessionSpKey, session);
1201 msg->setPointer(kCallbackFpKey, (void*) onStart);
1202 msg->setObject(kCaptureRequestKey, request);
1203 msg->setInt64(kTimeStampKey, timestamp);
1204 msg->post();
1205 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001206 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001207}
1208
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001209binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001210CameraDevice::ServiceCallback::onResultReceived(
1211 const CameraMetadata& metadata,
1212 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001213 binder::Status ret = binder::Status::ok();
1214
Yin-Chia Yehead91462016-01-06 16:45:08 -08001215 sp<CameraDevice> dev = mDevice.promote();
1216 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001217 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001218 }
1219 int sequenceId = resultExtras.requestId;
1220 int64_t frameNumber = resultExtras.frameNumber;
1221 int32_t burstId = resultExtras.burstId;
1222 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1223
1224 if (!isPartialResult) {
1225 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1226 }
1227
1228 Mutex::Autolock _l(dev->mDeviceLock);
1229 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001230 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001231 }
1232
1233 if (dev->isClosed()) {
1234 if (!isPartialResult) {
1235 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1236 }
1237 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001238 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001239 }
1240
1241 CameraMetadata metadataCopy = metadata;
1242 // Copied from java implmentation. Why do we need this?
1243 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
1244
1245 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1246 if (it != dev->mSequenceCallbackMap.end()) {
1247 CallbackHolder cbh = (*it).second;
1248 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1249 cbh.mCallbacks.onCaptureProgressed :
1250 cbh.mCallbacks.onCaptureCompleted;
1251 sp<ACameraCaptureSession> session = cbh.mSession;
1252 if ((size_t) burstId >= cbh.mRequests.size()) {
1253 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1254 __FUNCTION__, burstId, cbh.mRequests.size());
1255 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1256 }
1257 sp<CaptureRequest> request = cbh.mRequests[burstId];
1258 sp<ACameraMetadata> result(new ACameraMetadata(
1259 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1260
1261 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1262 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1263 msg->setObject(kSessionSpKey, session);
1264 msg->setPointer(kCallbackFpKey, (void*) onResult);
1265 msg->setObject(kCaptureRequestKey, request);
1266 msg->setObject(kCaptureResultKey, result);
1267 msg->post();
1268 }
1269
1270 if (!isPartialResult) {
1271 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1272 dev->checkAndFireSequenceCompleteLocked();
1273 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001274
1275 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001276}
1277
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001278binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001279CameraDevice::ServiceCallback::onPrepared(int) {
1280 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001281 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001282}
1283
1284} // namespace android