blob: 3ae208aa14eadd29ad7307092f24791f4a58ef76 [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);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700132 return ACAMERA_ERROR_INVALID_PARAMETER;
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);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700383 if (remoteRet.serviceSpecificErrorCode() ==
384 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
385 ALOGV("Repeating request is already stopped.");
386 return ACAMERA_OK;
387 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800388 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800389 return ACAMERA_ERROR_UNKNOWN;
390 }
391 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
392 }
393 return ACAMERA_OK;
394}
395
396camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700397CameraDevice::flushLocked(ACameraCaptureSession* session) {
398 camera_status_t ret = checkCameraClosedOrErrorLocked();
399 if (ret != ACAMERA_OK) {
400 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
401 return ret;
402 }
403
404 // This should never happen because creating a new session will close
405 // previous one and thus reject any API call from previous session.
406 // But still good to check here in case something unexpected happen.
407 if (session != mCurrentSession) {
408 ALOGE("Camera %s session %p is not current active session!", getId(), session);
409 return ACAMERA_ERROR_INVALID_OPERATION;
410 }
411
412 if (mFlushing) {
413 ALOGW("Camera %s is already aborting captures", getId());
414 return ACAMERA_OK;
415 }
416
417 mFlushing = true;
418 // Send onActive callback to guarantee there is always active->ready transition
419 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
420 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
421 msg->setObject(kSessionSpKey, session);
422 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
423 msg->post();
424
425 // If device is already idling, send callback and exit early
426 if (mIdle) {
427 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
428 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
429 msg->setObject(kSessionSpKey, session);
430 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
431 msg->post();
432 mFlushing = false;
433 return ACAMERA_OK;
434 }
435
436 int64_t lastFrameNumber;
437 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
438 if (!remoteRet.isOk()) {
439 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
440 return ACAMERA_ERROR_UNKNOWN;
441 }
442 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
443 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
444 }
445 return ACAMERA_OK;
446}
447
448camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800449CameraDevice::waitUntilIdleLocked() {
450 camera_status_t ret = checkCameraClosedOrErrorLocked();
451 if (ret != ACAMERA_OK) {
452 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
453 return ret;
454 }
455
456 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
457 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
458 return ACAMERA_ERROR_INVALID_OPERATION;
459 }
460
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800461 binder::Status remoteRet = mRemote->waitUntilIdle();
462 if (!remoteRet.isOk()) {
463 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800464 // TODO: define a function to convert status_t -> camera_status_t
465 return ACAMERA_ERROR_UNKNOWN;
466 }
467
468 return ACAMERA_OK;
469}
470
471camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700472CameraDevice::getIGBPfromAnw(
473 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800474 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800475 if (anw == nullptr) {
476 ALOGE("Error: output ANativeWindow is null");
477 return ACAMERA_ERROR_INVALID_PARAMETER;
478 }
479 int value;
480 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800481 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800482 ALOGE("Error: ANativeWindow is not backed by Surface!");
483 return ACAMERA_ERROR_INVALID_PARAMETER;
484 }
485 const sp<Surface> surface(static_cast<Surface*>(anw));
486 out = surface->getIGraphicBufferProducer();
487 return ACAMERA_OK;
488}
489
490camera_status_t
491CameraDevice::getSurfaceFromANativeWindow(
492 ANativeWindow* anw, sp<Surface>& out) {
493 if (anw == nullptr) {
494 ALOGE("Error: output ANativeWindow is null");
495 return ACAMERA_ERROR_INVALID_PARAMETER;
496 }
497 int value;
498 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800499 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800500 ALOGE("Error: ANativeWindow is not backed by Surface!");
501 return ACAMERA_ERROR_INVALID_PARAMETER;
502 }
503 sp<Surface> surface(static_cast<Surface*>(anw));
504 out = surface;
505 return ACAMERA_OK;
506}
507
508camera_status_t
509CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
510 ACaptureSessionOutputContainer emptyOutput;
511 if (outputs == nullptr) {
512 outputs = &emptyOutput;
513 }
514
Yin-Chia Yehead91462016-01-06 16:45:08 -0800515 camera_status_t ret = checkCameraClosedOrErrorLocked();
516 if (ret != ACAMERA_OK) {
517 return ret;
518 }
519
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700520 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800521 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700522 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800523 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700524 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800525 if (ret != ACAMERA_OK) {
526 return ret;
527 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700528 outputSet.insert(std::make_pair(
529 anw, OutputConfiguration(iGBP, outConfig.mRotation)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800530 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700531 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800532 std::vector<int> deleteList;
533
534 // Determine which streams need to be created, which to be deleted
535 for (auto& kvPair : mConfiguredOutputs) {
536 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700537 auto& outputPair = kvPair.second;
538 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800539 deleteList.push_back(streamId); // Need to delete a no longer needed stream
540 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700541 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800542 }
543 }
544
545 ret = stopRepeatingLocked();
546 if (ret != ACAMERA_OK) {
547 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
548 return ret;
549 }
550
551 ret = waitUntilIdleLocked();
552 if (ret != ACAMERA_OK) {
553 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
554 return ret;
555 }
556
557 // Send onReady to previous session
558 // CurrentSession will be updated after configureStreamLocked, so here
559 // mCurrentSession is the session to be replaced by a new session
560 if (!mIdle && mCurrentSession != nullptr) {
561 if (mBusySession != mCurrentSession) {
562 ALOGE("Current session != busy session");
563 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
564 return ACAMERA_ERROR_CAMERA_DEVICE;
565 }
566 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
567 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
568 msg->setObject(kSessionSpKey, mBusySession);
569 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
570 mBusySession.clear();
571 msg->post();
572 }
573 mIdle = true;
574
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800575 binder::Status remoteRet = mRemote->beginConfigure();
576 if (!remoteRet.isOk()) {
577 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800578 return ACAMERA_ERROR_UNKNOWN;
579 }
580
581 // delete to-be-deleted streams
582 for (auto streamId : deleteList) {
583 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800584 if (!remoteRet.isOk()) {
585 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
586 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800587 return ACAMERA_ERROR_UNKNOWN;
588 }
589 mConfiguredOutputs.erase(streamId);
590 }
591
592 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700593 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800594 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700595 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800596 if (!remoteRet.isOk()) {
597 ALOGE("Camera device %s failed to create stream: %s", getId(),
598 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800599 return ACAMERA_ERROR_UNKNOWN;
600 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700601 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800602 }
603
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800604 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
605 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
606 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
607 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800608 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800609 } else if (!remoteRet.isOk()) {
610 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800611 return ACAMERA_ERROR_UNKNOWN;
612 }
613
614 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800615}
616
617void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800618CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800619 Mutex::Autolock _l(mDeviceLock);
620 mRemote = remote;
621}
622
623camera_status_t
624CameraDevice::checkCameraClosedOrErrorLocked() const {
625 if (mRemote == nullptr) {
626 ALOGE("%s: camera device already closed", __FUNCTION__);
627 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
628 }
629 if (mInError) {// triggered by onDeviceError
630 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
631 return mError;
632 }
633 return ACAMERA_OK;
634}
635
636void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800637CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
638 mInError = true;
639 mError = error;
640 return;
641}
642
643void
644CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
645 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
646 if (isError) {
647 mFutureErrorSet.insert(frameNumber);
648 } else if (frameNumber <= mCompletedFrameNumber) {
649 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
650 frameNumber, mCompletedFrameNumber);
651 return;
652 } else {
653 if (frameNumber != mCompletedFrameNumber + 1) {
654 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
655 mCompletedFrameNumber + 1, frameNumber);
656 // Do not assert as in java implementation
657 }
658 mCompletedFrameNumber = frameNumber;
659 }
660 update();
661}
662
663void
664CameraDevice::FrameNumberTracker::update() {
665 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
666 int64_t errorFrameNumber = *it;
667 if (errorFrameNumber == mCompletedFrameNumber + 1) {
668 mCompletedFrameNumber++;
669 it = mFutureErrorSet.erase(it);
670 } else if (errorFrameNumber <= mCompletedFrameNumber) {
671 // This should not happen, but deal with it anyway
672 ALOGE("Completd frame number passed through current frame number!");
673 // erase the old error since it's no longer useful
674 it = mFutureErrorSet.erase(it);
675 } else {
676 // Normal requests hasn't catched up error frames, just break
677 break;
678 }
679 }
680 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
681}
682
683void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800684CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800685 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800686 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800687 int sequenceId = resultExtras.requestId;
688 int64_t frameNumber = resultExtras.frameNumber;
689 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700690 auto it = mSequenceCallbackMap.find(sequenceId);
691 if (it == mSequenceCallbackMap.end()) {
692 ALOGE("%s: Error: capture sequence index %d not found!",
693 __FUNCTION__, sequenceId);
694 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800695 return;
696 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700697
698 CallbackHolder cbh = (*it).second;
699 sp<ACameraCaptureSession> session = cbh.mSession;
700 if ((size_t) burstId >= cbh.mRequests.size()) {
701 ALOGE("%s: Error: request index %d out of bound (size %zu)",
702 __FUNCTION__, burstId, cbh.mRequests.size());
703 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
704 return;
705 }
706 sp<CaptureRequest> request = cbh.mRequests[burstId];
707
708 // Handle buffer error
709 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
710 int32_t streamId = resultExtras.errorStreamId;
711 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
712 cbh.mCallbacks.onCaptureBufferLost;
713 auto outputPairIt = mConfiguredOutputs.find(streamId);
714 if (outputPairIt == mConfiguredOutputs.end()) {
715 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800716 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
717 return;
718 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700719 ANativeWindow* anw = outputPairIt->second.first;
720
721 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
722 getId(), anw, frameNumber);
723
724 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
725 msg->setPointer(kContextKey, cbh.mCallbacks.context);
726 msg->setObject(kSessionSpKey, session);
727 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
728 msg->setObject(kCaptureRequestKey, request);
729 msg->setPointer(kAnwKey, (void*) anw);
730 msg->setInt64(kFrameNumberKey, frameNumber);
731 msg->post();
732 } else { // Handle other capture failures
733 // Fire capture failure callback if there is one registered
734 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800735 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
736 failure->frameNumber = frameNumber;
737 // TODO: refine this when implementing flush
738 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
739 failure->sequenceId = sequenceId;
740 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800741 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800742
743 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
744 msg->setPointer(kContextKey, cbh.mCallbacks.context);
745 msg->setObject(kSessionSpKey, session);
746 msg->setPointer(kCallbackFpKey, (void*) onError);
747 msg->setObject(kCaptureRequestKey, request);
748 msg->setObject(kCaptureFailureKey, failure);
749 msg->post();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800750
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700751 // Update tracker
752 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
753 checkAndFireSequenceCompleteLocked();
754 }
755 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800756}
757
758void CameraDevice::CallbackHandler::onMessageReceived(
759 const sp<AMessage> &msg) {
760 switch (msg->what()) {
761 case kWhatOnDisconnected:
762 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800763 case kWhatSessionStateCb:
764 case kWhatCaptureStart:
765 case kWhatCaptureResult:
766 case kWhatCaptureFail:
767 case kWhatCaptureSeqEnd:
768 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700769 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800770 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800771 break;
772 default:
773 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
774 return;
775 }
776 // Check the common part of all message
777 void* context;
778 bool found = msg->findPointer(kContextKey, &context);
779 if (!found) {
780 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
781 return;
782 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800783 switch (msg->what()) {
784 case kWhatOnDisconnected:
785 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800786 ACameraDevice* dev;
787 found = msg->findPointer(kDeviceKey, (void**) &dev);
788 if (!found || dev == nullptr) {
789 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
790 return;
791 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800792 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800793 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800794 if (!found) {
795 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
796 return;
797 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800798 if (onDisconnected == nullptr) {
799 return;
800 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800801 (*onDisconnected)(context, dev);
802 break;
803 }
804 case kWhatOnError:
805 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800806 ACameraDevice* dev;
807 found = msg->findPointer(kDeviceKey, (void**) &dev);
808 if (!found || dev == nullptr) {
809 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
810 return;
811 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800812 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800813 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800814 if (!found) {
815 ALOGE("%s: Cannot find onError!", __FUNCTION__);
816 return;
817 }
818 int errorCode;
819 found = msg->findInt32(kErrorCodeKey, &errorCode);
820 if (!found) {
821 ALOGE("%s: Cannot find error code!", __FUNCTION__);
822 return;
823 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800824 if (onError == nullptr) {
825 return;
826 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800827 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800828 break;
829 }
830 case kWhatSessionStateCb:
831 case kWhatCaptureStart:
832 case kWhatCaptureResult:
833 case kWhatCaptureFail:
834 case kWhatCaptureSeqEnd:
835 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700836 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800837 {
838 sp<RefBase> obj;
839 found = msg->findObject(kSessionSpKey, &obj);
840 if (!found || obj == nullptr) {
841 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
842 return;
843 }
844 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
845 sp<CaptureRequest> requestSp = nullptr;
846 switch (msg->what()) {
847 case kWhatCaptureStart:
848 case kWhatCaptureResult:
849 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700850 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800851 found = msg->findObject(kCaptureRequestKey, &obj);
852 if (!found) {
853 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
854 return;
855 }
856 requestSp = static_cast<CaptureRequest*>(obj.get());
857 break;
858 }
859
860 switch (msg->what()) {
861 case kWhatSessionStateCb:
862 {
863 ACameraCaptureSession_stateCallback onState;
864 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
865 if (!found) {
866 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
867 return;
868 }
869 if (onState == nullptr) {
870 return;
871 }
872 (*onState)(context, session.get());
873 break;
874 }
875 case kWhatCaptureStart:
876 {
877 ACameraCaptureSession_captureCallback_start onStart;
878 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
879 if (!found) {
880 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
881 return;
882 }
883 if (onStart == nullptr) {
884 return;
885 }
886 int64_t timestamp;
887 found = msg->findInt64(kTimeStampKey, &timestamp);
888 if (!found) {
889 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
890 return;
891 }
892 ACaptureRequest* request = allocateACaptureRequest(requestSp);
893 (*onStart)(context, session.get(), request, timestamp);
894 freeACaptureRequest(request);
895 break;
896 }
897 case kWhatCaptureResult:
898 {
899 ACameraCaptureSession_captureCallback_result onResult;
900 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
901 if (!found) {
902 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
903 return;
904 }
905 if (onResult == nullptr) {
906 return;
907 }
908
909 found = msg->findObject(kCaptureResultKey, &obj);
910 if (!found) {
911 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
912 return;
913 }
914 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
915 ACaptureRequest* request = allocateACaptureRequest(requestSp);
916 (*onResult)(context, session.get(), request, result.get());
917 freeACaptureRequest(request);
918 break;
919 }
920 case kWhatCaptureFail:
921 {
922 ACameraCaptureSession_captureCallback_failed onFail;
923 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
924 if (!found) {
925 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
926 return;
927 }
928 if (onFail == nullptr) {
929 return;
930 }
931
932 found = msg->findObject(kCaptureFailureKey, &obj);
933 if (!found) {
934 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
935 return;
936 }
937 sp<CameraCaptureFailure> failureSp(
938 static_cast<CameraCaptureFailure*>(obj.get()));
939 ACameraCaptureFailure* failure =
940 static_cast<ACameraCaptureFailure*>(failureSp.get());
941 ACaptureRequest* request = allocateACaptureRequest(requestSp);
942 (*onFail)(context, session.get(), request, failure);
943 freeACaptureRequest(request);
944 delete failure;
945 break;
946 }
947 case kWhatCaptureSeqEnd:
948 {
949 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
950 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
951 if (!found) {
952 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
953 return;
954 }
955 if (onSeqEnd == nullptr) {
956 return;
957 }
958 int seqId;
959 found = msg->findInt32(kSequenceIdKey, &seqId);
960 if (!found) {
961 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
962 return;
963 }
964 int64_t frameNumber;
965 found = msg->findInt64(kFrameNumberKey, &frameNumber);
966 if (!found) {
967 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
968 return;
969 }
970 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
971 break;
972 }
973 case kWhatCaptureSeqAbort:
974 {
975 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
976 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
977 if (!found) {
978 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
979 return;
980 }
981 if (onSeqAbort == nullptr) {
982 return;
983 }
984 int seqId;
985 found = msg->findInt32(kSequenceIdKey, &seqId);
986 if (!found) {
987 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
988 return;
989 }
990 (*onSeqAbort)(context, session.get(), seqId);
991 break;
992 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700993 case kWhatCaptureBufferLost:
994 {
995 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
996 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
997 if (!found) {
998 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
999 return;
1000 }
1001 if (onBufferLost == nullptr) {
1002 return;
1003 }
1004
1005 ANativeWindow* anw;
1006 found = msg->findPointer(kAnwKey, (void**) &anw);
1007 if (!found) {
1008 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1009 return;
1010 }
1011
1012 int64_t frameNumber;
1013 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1014 if (!found) {
1015 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1016 return;
1017 }
1018
1019 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1020 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1021 freeACaptureRequest(request);
1022 break;
1023 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001024 }
1025 break;
1026 }
1027 }
1028}
1029
1030CameraDevice::CallbackHolder::CallbackHolder(
1031 sp<ACameraCaptureSession> session,
1032 const Vector<sp<CaptureRequest> >& requests,
1033 bool isRepeating,
1034 ACameraCaptureSession_captureCallbacks* cbs) :
1035 mSession(session), mRequests(requests),
1036 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1037
1038void
1039CameraDevice::checkRepeatingSequenceCompleteLocked(
1040 const int sequenceId, const int64_t lastFrameNumber) {
1041 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1042 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1043 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1044 ALOGW("No callback found for sequenceId %d", sequenceId);
1045 return;
1046 }
1047 // remove callback holder from callback map
1048 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1049 CallbackHolder cbh = cbIt->second;
1050 mSequenceCallbackMap.erase(cbIt);
1051 // send seq aborted callback
1052 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1053 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1054 msg->setObject(kSessionSpKey, cbh.mSession);
1055 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1056 msg->setInt32(kSequenceIdKey, sequenceId);
1057 msg->post();
1058 } else {
1059 // Use mSequenceLastFrameNumberMap to track
1060 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1061
1062 // Last frame might have arrived. Check now
1063 checkAndFireSequenceCompleteLocked();
1064 }
1065}
1066
1067void
1068CameraDevice::checkAndFireSequenceCompleteLocked() {
1069 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1070 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1071 auto it = mSequenceLastFrameNumberMap.begin();
1072 while (it != mSequenceLastFrameNumberMap.end()) {
1073 int sequenceId = it->first;
1074 int64_t lastFrameNumber = it->second;
1075 bool seqCompleted = false;
1076 bool hasCallback = true;
1077
1078 if (mRemote == nullptr) {
1079 ALOGW("Camera %s closed while checking sequence complete", getId());
1080 return;
1081 }
1082
1083 // Check if there is callback for this sequence
1084 // This should not happen because we always register callback (with nullptr inside)
1085 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1086 ALOGW("No callback found for sequenceId %d", sequenceId);
1087 hasCallback = false;
1088 }
1089
1090 if (lastFrameNumber <= completedFrameNumber) {
1091 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1092 sequenceId, lastFrameNumber, completedFrameNumber);
1093 seqCompleted = true;
1094 }
1095
1096 if (seqCompleted && hasCallback) {
1097 // remove callback holder from callback map
1098 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1099 CallbackHolder cbh = cbIt->second;
1100 mSequenceCallbackMap.erase(cbIt);
1101 // send seq complete callback
1102 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1103 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1104 msg->setObject(kSessionSpKey, cbh.mSession);
1105 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1106 msg->setInt32(kSequenceIdKey, sequenceId);
1107 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1108
1109 // Clear the session sp before we send out the message
1110 // This will guarantee the rare case where the message is processed
1111 // before cbh goes out of scope and causing we call the session
1112 // destructor while holding device lock
1113 cbh.mSession.clear();
1114 msg->post();
1115 }
1116
1117 // No need to track sequence complete if there is no callback registered
1118 if (seqCompleted || !hasCallback) {
1119 it = mSequenceLastFrameNumberMap.erase(it);
1120 } else {
1121 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001122 }
1123 }
1124}
1125
1126/**
1127 * Camera service callback implementation
1128 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001129binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001130CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001131 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001132 const CaptureResultExtras& resultExtras) {
1133 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1134 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001135 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001136 sp<CameraDevice> dev = mDevice.promote();
1137 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001138 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001139 }
1140
1141 Mutex::Autolock _l(dev->mDeviceLock);
1142 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001143 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001144 }
1145 switch (errorCode) {
1146 case ERROR_CAMERA_DISCONNECTED:
1147 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001148 // Camera is disconnected, close the session and expect no more callbacks
1149 if (dev->mCurrentSession != nullptr) {
1150 dev->mCurrentSession->closeByDevice();
1151 dev->mCurrentSession = nullptr;
1152 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001153 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1154 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1155 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001156 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001157 msg->post();
1158 break;
1159 }
1160 default:
1161 ALOGE("Unknown error from camera device: %d", errorCode);
1162 // no break
1163 case ERROR_CAMERA_DEVICE:
1164 case ERROR_CAMERA_SERVICE:
1165 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001166 switch (errorCode) {
1167 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001168 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001169 break;
1170 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001171 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001172 break;
1173 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001174 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001175 break;
1176 }
1177 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1178 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1179 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001180 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001181 msg->setInt32(kErrorCodeKey, errorCode);
1182 msg->post();
1183 break;
1184 }
1185 case ERROR_CAMERA_REQUEST:
1186 case ERROR_CAMERA_RESULT:
1187 case ERROR_CAMERA_BUFFER:
1188 dev->onCaptureErrorLocked(errorCode, resultExtras);
1189 break;
1190 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001191 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001192}
1193
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001194binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001195CameraDevice::ServiceCallback::onDeviceIdle() {
1196 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001197 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001198 sp<CameraDevice> dev = mDevice.promote();
1199 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001200 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001201 }
1202
1203 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001204 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001205 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001206 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001207
1208 if (dev->mIdle) {
1209 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001210 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001211 }
1212
1213 if (dev->mCurrentSession != nullptr) {
1214 ALOGE("onDeviceIdle sending state cb");
1215 if (dev->mBusySession != dev->mCurrentSession) {
1216 ALOGE("Current session != busy session");
1217 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001218 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001219 }
1220 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1221 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1222 msg->setObject(kSessionSpKey, dev->mBusySession);
1223 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1224 // Make sure we clear the sp first so the session destructor can
1225 // only happen on handler thread (where we don't hold device/session lock)
1226 dev->mBusySession.clear();
1227 msg->post();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001228 }
1229 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001230 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001231 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001232}
1233
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001234binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001235CameraDevice::ServiceCallback::onCaptureStarted(
1236 const CaptureResultExtras& resultExtras,
1237 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001238 binder::Status ret = binder::Status::ok();
1239
Yin-Chia Yehead91462016-01-06 16:45:08 -08001240 sp<CameraDevice> dev = mDevice.promote();
1241 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001242 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001243 }
1244 Mutex::Autolock _l(dev->mDeviceLock);
1245 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001246 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001247 }
1248
1249 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001250 int32_t burstId = resultExtras.burstId;
1251
1252 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1253 if (it != dev->mSequenceCallbackMap.end()) {
1254 CallbackHolder cbh = (*it).second;
1255 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1256 sp<ACameraCaptureSession> session = cbh.mSession;
1257 if ((size_t) burstId >= cbh.mRequests.size()) {
1258 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1259 __FUNCTION__, burstId, cbh.mRequests.size());
1260 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1261 }
1262 sp<CaptureRequest> request = cbh.mRequests[burstId];
1263 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1264 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1265 msg->setObject(kSessionSpKey, session);
1266 msg->setPointer(kCallbackFpKey, (void*) onStart);
1267 msg->setObject(kCaptureRequestKey, request);
1268 msg->setInt64(kTimeStampKey, timestamp);
1269 msg->post();
1270 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001271 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001272}
1273
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001274binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001275CameraDevice::ServiceCallback::onResultReceived(
1276 const CameraMetadata& metadata,
1277 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001278 binder::Status ret = binder::Status::ok();
1279
Yin-Chia Yehead91462016-01-06 16:45:08 -08001280 sp<CameraDevice> dev = mDevice.promote();
1281 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001282 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001283 }
1284 int sequenceId = resultExtras.requestId;
1285 int64_t frameNumber = resultExtras.frameNumber;
1286 int32_t burstId = resultExtras.burstId;
1287 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1288
1289 if (!isPartialResult) {
1290 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1291 }
1292
1293 Mutex::Autolock _l(dev->mDeviceLock);
1294 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001295 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001296 }
1297
1298 if (dev->isClosed()) {
1299 if (!isPartialResult) {
1300 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1301 }
1302 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001303 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001304 }
1305
1306 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001307 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001308 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001309
1310 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1311 if (it != dev->mSequenceCallbackMap.end()) {
1312 CallbackHolder cbh = (*it).second;
1313 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1314 cbh.mCallbacks.onCaptureProgressed :
1315 cbh.mCallbacks.onCaptureCompleted;
1316 sp<ACameraCaptureSession> session = cbh.mSession;
1317 if ((size_t) burstId >= cbh.mRequests.size()) {
1318 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1319 __FUNCTION__, burstId, cbh.mRequests.size());
1320 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1321 }
1322 sp<CaptureRequest> request = cbh.mRequests[burstId];
1323 sp<ACameraMetadata> result(new ACameraMetadata(
1324 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1325
1326 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1327 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1328 msg->setObject(kSessionSpKey, session);
1329 msg->setPointer(kCallbackFpKey, (void*) onResult);
1330 msg->setObject(kCaptureRequestKey, request);
1331 msg->setObject(kCaptureResultKey, result);
1332 msg->post();
1333 }
1334
1335 if (!isPartialResult) {
1336 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1337 dev->checkAndFireSequenceCompleteLocked();
1338 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001339
1340 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001341}
1342
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001343binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001344CameraDevice::ServiceCallback::onPrepared(int) {
1345 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001346 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001347}
1348
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001349binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001350CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1351 // onRequestQueueEmpty not yet implemented in NDK
1352 return binder::Status::ok();
1353}
1354
1355binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001356CameraDevice::ServiceCallback::onRepeatingRequestError(
1357 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001358 binder::Status ret = binder::Status::ok();
1359
1360 sp<CameraDevice> dev = mDevice.promote();
1361 if (dev == nullptr) {
1362 return ret; // device has been closed
1363 }
1364
1365 Mutex::Autolock _l(dev->mDeviceLock);
1366
1367 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001368 if (stoppedSequenceId == repeatingSequenceId) {
1369 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1370 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001371
1372 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1373
1374 return ret;
1375}
1376
1377
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001378} // namespace android