blob: 1ab6af802defc24d1512d15b237befa7b0241444 [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");
67 status_t ret = mCbLooper->start(
68 /*runOnCallingThread*/false,
69 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080070 PRIORITY_DEFAULT);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080071 mHandler = new CallbackHandler();
72 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080073
74 CameraMetadata metadata = mChars->mData;
75 camera_metadata_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
76 if (entry.count != 1) {
77 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
78 mPartialResultCount = 1;
79 } else {
80 mPartialResultCount = entry.data.i32[0];
81 }
82
83 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
84 if (entry.count != 2) {
85 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
86 mShadingMapSize[0] = 0;
87 mShadingMapSize[1] = 0;
88 } else {
89 mShadingMapSize[0] = entry.data.i32[0];
90 mShadingMapSize[1] = entry.data.i32[1];
91 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080092}
93
Yin-Chia Yehead91462016-01-06 16:45:08 -080094// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080095CameraDevice::~CameraDevice() {
96 Mutex::Autolock _l(mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -080097 if (!isClosed()) {
98 disconnectLocked();
99 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800100 if (mCbLooper != nullptr) {
101 mCbLooper->unregisterHandler(mHandler->id());
102 mCbLooper->stop();
103 }
104 mCbLooper.clear();
105 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800106}
107
108// TODO: cached created request?
109camera_status_t
110CameraDevice::createCaptureRequest(
111 ACameraDevice_request_template templateId,
112 ACaptureRequest** request) const {
113 Mutex::Autolock _l(mDeviceLock);
114 camera_status_t ret = checkCameraClosedOrErrorLocked();
115 if (ret != ACAMERA_OK) {
116 return ret;
117 }
118 if (mRemote == nullptr) {
119 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
120 }
121 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800122 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
123 if (remoteRet.serviceSpecificErrorCode() ==
124 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800125 ALOGW("Create capture request failed! template %d is not supported on this device",
126 templateId);
127 return ACAMERA_ERROR_UNSUPPORTED;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800128 } else if (!remoteRet.isOk()) {
129 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800130 return ACAMERA_ERROR_UNKNOWN;
131 }
132 ACaptureRequest* outReq = new ACaptureRequest();
133 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
134 outReq->targets = new ACameraOutputTargets();
135 *request = outReq;
136 return ACAMERA_OK;
137}
138
Yin-Chia Yehead91462016-01-06 16:45:08 -0800139camera_status_t
140CameraDevice::createCaptureSession(
141 const ACaptureSessionOutputContainer* outputs,
142 const ACameraCaptureSession_stateCallbacks* callbacks,
143 /*out*/ACameraCaptureSession** session) {
144 Mutex::Autolock _l(mDeviceLock);
145 camera_status_t ret = checkCameraClosedOrErrorLocked();
146 if (ret != ACAMERA_OK) {
147 return ret;
148 }
149
150 if (mCurrentSession != nullptr) {
151 mCurrentSession->closeByDevice();
152 stopRepeatingLocked();
153 }
154
155 // Create new session
156 ret = configureStreamsLocked(outputs);
157 if (ret != ACAMERA_OK) {
158 ALOGE("Fail to create new session. cannot configure streams");
159 return ret;
160 }
161
162 ACameraCaptureSession* newSession = new ACameraCaptureSession(
163 mNextSessionId++, outputs, callbacks, this);
164
165 bool configureSucceeded = (ret == ACAMERA_OK);
166
167 // set new session as current session
168 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
169 mCurrentSession = newSession;
170 *session = newSession;
171 return ACAMERA_OK;
172}
173
174camera_status_t
175CameraDevice::captureLocked(
176 sp<ACameraCaptureSession> session,
177 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
178 int numRequests, ACaptureRequest** requests,
179 /*optional*/int* captureSequenceId) {
180 return submitRequestsLocked(
181 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
182}
183
184camera_status_t
185CameraDevice::setRepeatingRequestsLocked(
186 sp<ACameraCaptureSession> session,
187 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
188 int numRequests, ACaptureRequest** requests,
189 /*optional*/int* captureSequenceId) {
190 return submitRequestsLocked(
191 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
192}
193
194camera_status_t
195CameraDevice::submitRequestsLocked(
196 sp<ACameraCaptureSession> session,
197 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
198 int numRequests, ACaptureRequest** requests,
199 /*optional*/int* captureSequenceId,
200 bool isRepeating) {
201 camera_status_t ret = checkCameraClosedOrErrorLocked();
202 if (ret != ACAMERA_OK) {
203 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
204 return ret;
205 }
206
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800207 // Form two vectors of capture request, one for internal tracking
208 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800209 Vector<sp<CaptureRequest> > requestsV;
210 requestsV.setCapacity(numRequests);
211 for (int i = 0; i < numRequests; i++) {
212 sp<CaptureRequest> req;
213 ret = allocateCaptureRequest(requests[i], req);
214 if (ret != ACAMERA_OK) {
215 ALOGE("Convert capture request to internal format failure! ret %d", ret);
216 return ret;
217 }
218 if (req->mSurfaceList.empty()) {
219 ALOGE("Capture request without output target cannot be submitted!");
220 return ACAMERA_ERROR_INVALID_PARAMETER;
221 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800222 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800223 requestsV.push_back(req);
224 }
225
226 if (isRepeating) {
227 ret = stopRepeatingLocked();
228 if (ret != ACAMERA_OK) {
229 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
230 return ret;
231 }
232 }
233
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800234 binder::Status remoteRet;
235 hardware::camera2::utils::SubmitInfo info;
236 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
237 int sequenceId = info.mRequestId;
238 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800239 if (sequenceId < 0) {
240 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
241 return ACAMERA_ERROR_UNKNOWN;
242 }
243
244 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
245 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
246
247 if (isRepeating) {
248 // stopRepeating above should have cleanup repeating sequence id
249 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
250 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
251 return ACAMERA_ERROR_CAMERA_DEVICE;
252 }
253 mRepeatingSequenceId = sequenceId;
254 } else {
255 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
256 }
257
258 if (mIdle) {
259 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
260 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
261 msg->setObject(kSessionSpKey, session);
262 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
263 msg->post();
264 }
265 mIdle = false;
266 mBusySession = session;
267
268 if (captureSequenceId) {
269 *captureSequenceId = sequenceId;
270 }
271 return ACAMERA_OK;
272}
273
274camera_status_t
275CameraDevice::allocateCaptureRequest(
276 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
277 camera_status_t ret;
278 sp<CaptureRequest> req(new CaptureRequest());
279 req->mMetadata = request->settings->mData;
280 req->mIsReprocess = false; // NDK does not support reprocessing yet
281
282 for (auto outputTarget : request->targets->mOutputs) {
283 ANativeWindow* anw = outputTarget.mWindow;
284 sp<Surface> surface;
285 ret = getSurfaceFromANativeWindow(anw, surface);
286 if (ret != ACAMERA_OK) {
287 ALOGE("Bad output target in capture request! ret %d", ret);
288 return ret;
289 }
290 req->mSurfaceList.push_back(surface);
291 }
292 outReq = req;
293 return ACAMERA_OK;
294}
295
296ACaptureRequest*
297CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
298 ACaptureRequest* pRequest = new ACaptureRequest();
299 CameraMetadata clone = req->mMetadata;
300 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
301 pRequest->targets = new ACameraOutputTargets();
302 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
303 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
304 ACameraOutputTarget outputTarget(anw);
305 pRequest->targets->mOutputs.insert(outputTarget);
306 }
307 return pRequest;
308}
309
310void
311CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
312 if (req == nullptr) {
313 return;
314 }
315 delete req->settings;
316 delete req->targets;
317 delete req;
318}
319
320void
321CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
322 if (isClosed()) {
323 // Device is closing already. do nothing
324 return;
325 }
326
327 if (session != mCurrentSession) {
328 // Session has been replaced by other seesion or device is closed
329 return;
330 }
331 mCurrentSession = nullptr;
332
333 // Should not happen
334 if (!session->mIsClosed) {
335 ALOGE("Error: unclosed session %p reaches end of life!", session);
336 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
337 return;
338 }
339
340 // No new session, unconfigure now
341 camera_status_t ret = configureStreamsLocked(nullptr);
342 if (ret != ACAMERA_OK) {
343 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
344 }
345}
346
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800347void
348CameraDevice::disconnectLocked() {
349 if (mClosing.exchange(true)) {
350 // Already closing, just return
351 ALOGW("Camera device %s is already closing.", getId());
352 return;
353 }
354
355 if (mRemote != nullptr) {
356 mRemote->disconnect();
357 }
358 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800359
360 if (mCurrentSession != nullptr) {
361 mCurrentSession->closeByDevice();
362 mCurrentSession = nullptr;
363 }
364}
365
366camera_status_t
367CameraDevice::stopRepeatingLocked() {
368 camera_status_t ret = checkCameraClosedOrErrorLocked();
369 if (ret != ACAMERA_OK) {
370 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
371 return ret;
372 }
373 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
374 int repeatingSequenceId = mRepeatingSequenceId;
375 mRepeatingSequenceId = REQUEST_ID_NONE;
376
377 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800378 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
379 if (!remoteRet.isOk()) {
380 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800381 return ACAMERA_ERROR_UNKNOWN;
382 }
383 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
384 }
385 return ACAMERA_OK;
386}
387
388camera_status_t
389CameraDevice::waitUntilIdleLocked() {
390 camera_status_t ret = checkCameraClosedOrErrorLocked();
391 if (ret != ACAMERA_OK) {
392 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
393 return ret;
394 }
395
396 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
397 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
398 return ACAMERA_ERROR_INVALID_OPERATION;
399 }
400
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800401 binder::Status remoteRet = mRemote->waitUntilIdle();
402 if (!remoteRet.isOk()) {
403 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800404 // TODO: define a function to convert status_t -> camera_status_t
405 return ACAMERA_ERROR_UNKNOWN;
406 }
407
408 return ACAMERA_OK;
409}
410
411camera_status_t
412CameraDevice::getIGBPfromSessionOutput(
413 const ACaptureSessionOutput& config,
414 sp<IGraphicBufferProducer>& out) {
415 ANativeWindow* anw = config.mWindow;
416 if (anw == nullptr) {
417 ALOGE("Error: output ANativeWindow is null");
418 return ACAMERA_ERROR_INVALID_PARAMETER;
419 }
420 int value;
421 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
422 if (value != NATIVE_WINDOW_SURFACE) {
423 ALOGE("Error: ANativeWindow is not backed by Surface!");
424 return ACAMERA_ERROR_INVALID_PARAMETER;
425 }
426 const sp<Surface> surface(static_cast<Surface*>(anw));
427 out = surface->getIGraphicBufferProducer();
428 return ACAMERA_OK;
429}
430
431camera_status_t
432CameraDevice::getSurfaceFromANativeWindow(
433 ANativeWindow* anw, sp<Surface>& out) {
434 if (anw == nullptr) {
435 ALOGE("Error: output ANativeWindow is null");
436 return ACAMERA_ERROR_INVALID_PARAMETER;
437 }
438 int value;
439 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
440 if (value != NATIVE_WINDOW_SURFACE) {
441 ALOGE("Error: ANativeWindow is not backed by Surface!");
442 return ACAMERA_ERROR_INVALID_PARAMETER;
443 }
444 sp<Surface> surface(static_cast<Surface*>(anw));
445 out = surface;
446 return ACAMERA_OK;
447}
448
449camera_status_t
450CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
451 ACaptureSessionOutputContainer emptyOutput;
452 if (outputs == nullptr) {
453 outputs = &emptyOutput;
454 }
455
456 bool success = false;
457 camera_status_t ret = checkCameraClosedOrErrorLocked();
458 if (ret != ACAMERA_OK) {
459 return ret;
460 }
461
462 std::set<OutputConfiguration> outputSet;
463 for (auto outConfig : outputs->mOutputs) {
464 sp<IGraphicBufferProducer> iGBP(nullptr);
465 ret = getIGBPfromSessionOutput(outConfig, iGBP);
466 if (ret != ACAMERA_OK) {
467 return ret;
468 }
469 outputSet.insert(OutputConfiguration(iGBP, outConfig.mRotation));
470 }
471 std::set<OutputConfiguration> addSet = outputSet;
472 std::vector<int> deleteList;
473
474 // Determine which streams need to be created, which to be deleted
475 for (auto& kvPair : mConfiguredOutputs) {
476 int streamId = kvPair.first;
477 OutputConfiguration& outConfig = kvPair.second;
478 if (outputSet.count(outConfig) == 0) {
479 deleteList.push_back(streamId); // Need to delete a no longer needed stream
480 } else {
481 addSet.erase(outConfig); // No need to add already existing stream
482 }
483 }
484
485 ret = stopRepeatingLocked();
486 if (ret != ACAMERA_OK) {
487 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
488 return ret;
489 }
490
491 ret = waitUntilIdleLocked();
492 if (ret != ACAMERA_OK) {
493 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
494 return ret;
495 }
496
497 // Send onReady to previous session
498 // CurrentSession will be updated after configureStreamLocked, so here
499 // mCurrentSession is the session to be replaced by a new session
500 if (!mIdle && mCurrentSession != nullptr) {
501 if (mBusySession != mCurrentSession) {
502 ALOGE("Current session != busy session");
503 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
504 return ACAMERA_ERROR_CAMERA_DEVICE;
505 }
506 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
507 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
508 msg->setObject(kSessionSpKey, mBusySession);
509 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
510 mBusySession.clear();
511 msg->post();
512 }
513 mIdle = true;
514
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800515 binder::Status remoteRet = mRemote->beginConfigure();
516 if (!remoteRet.isOk()) {
517 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800518 return ACAMERA_ERROR_UNKNOWN;
519 }
520
521 // delete to-be-deleted streams
522 for (auto streamId : deleteList) {
523 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800524 if (!remoteRet.isOk()) {
525 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
526 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800527 return ACAMERA_ERROR_UNKNOWN;
528 }
529 mConfiguredOutputs.erase(streamId);
530 }
531
532 // add new streams
533 for (auto outConfig : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800534 int streamId;
535 remoteRet = mRemote->createStream(outConfig, &streamId);
536 if (!remoteRet.isOk()) {
537 ALOGE("Camera device %s failed to create stream: %s", getId(),
538 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800539 return ACAMERA_ERROR_UNKNOWN;
540 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800541 mConfiguredOutputs.insert(std::make_pair(streamId, outConfig));
542 }
543
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800544 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
545 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
546 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
547 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800548 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800549 } else if (!remoteRet.isOk()) {
550 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800551 return ACAMERA_ERROR_UNKNOWN;
552 }
553
554 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800555}
556
557void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800558CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800559 Mutex::Autolock _l(mDeviceLock);
560 mRemote = remote;
561}
562
563camera_status_t
564CameraDevice::checkCameraClosedOrErrorLocked() const {
565 if (mRemote == nullptr) {
566 ALOGE("%s: camera device already closed", __FUNCTION__);
567 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
568 }
569 if (mInError) {// triggered by onDeviceError
570 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
571 return mError;
572 }
573 return ACAMERA_OK;
574}
575
576void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800577CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
578 mInError = true;
579 mError = error;
580 return;
581}
582
583void
584CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
585 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
586 if (isError) {
587 mFutureErrorSet.insert(frameNumber);
588 } else if (frameNumber <= mCompletedFrameNumber) {
589 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
590 frameNumber, mCompletedFrameNumber);
591 return;
592 } else {
593 if (frameNumber != mCompletedFrameNumber + 1) {
594 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
595 mCompletedFrameNumber + 1, frameNumber);
596 // Do not assert as in java implementation
597 }
598 mCompletedFrameNumber = frameNumber;
599 }
600 update();
601}
602
603void
604CameraDevice::FrameNumberTracker::update() {
605 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
606 int64_t errorFrameNumber = *it;
607 if (errorFrameNumber == mCompletedFrameNumber + 1) {
608 mCompletedFrameNumber++;
609 it = mFutureErrorSet.erase(it);
610 } else if (errorFrameNumber <= mCompletedFrameNumber) {
611 // This should not happen, but deal with it anyway
612 ALOGE("Completd frame number passed through current frame number!");
613 // erase the old error since it's no longer useful
614 it = mFutureErrorSet.erase(it);
615 } else {
616 // Normal requests hasn't catched up error frames, just break
617 break;
618 }
619 }
620 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
621}
622
623void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800624CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800625 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800626 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800627 int sequenceId = resultExtras.requestId;
628 int64_t frameNumber = resultExtras.frameNumber;
629 int32_t burstId = resultExtras.burstId;
630
631 // No way to report buffer error now
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800632 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800633 ALOGE("Camera %s Lost output buffer for frame %" PRId64,
634 getId(), frameNumber);
635 return;
636 }
637 // Fire capture failure callback if there is one registered
638 auto it = mSequenceCallbackMap.find(sequenceId);
639 if (it != mSequenceCallbackMap.end()) {
640 CallbackHolder cbh = (*it).second;
641 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
642 sp<ACameraCaptureSession> session = cbh.mSession;
643 if ((size_t) burstId >= cbh.mRequests.size()) {
644 ALOGE("%s: Error: request index %d out of bound (size %zu)",
645 __FUNCTION__, burstId, cbh.mRequests.size());
646 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
647 return;
648 }
649 sp<CaptureRequest> request = cbh.mRequests[burstId];
650 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
651 failure->frameNumber = frameNumber;
652 // TODO: refine this when implementing flush
653 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
654 failure->sequenceId = sequenceId;
655 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800656 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800657
658 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
659 msg->setPointer(kContextKey, cbh.mCallbacks.context);
660 msg->setObject(kSessionSpKey, session);
661 msg->setPointer(kCallbackFpKey, (void*) onError);
662 msg->setObject(kCaptureRequestKey, request);
663 msg->setObject(kCaptureFailureKey, failure);
664 msg->post();
665 }
666
667 // Update tracker
668 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
669 checkAndFireSequenceCompleteLocked();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800670}
671
672void CameraDevice::CallbackHandler::onMessageReceived(
673 const sp<AMessage> &msg) {
674 switch (msg->what()) {
675 case kWhatOnDisconnected:
676 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800677 case kWhatSessionStateCb:
678 case kWhatCaptureStart:
679 case kWhatCaptureResult:
680 case kWhatCaptureFail:
681 case kWhatCaptureSeqEnd:
682 case kWhatCaptureSeqAbort:
683 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800684 break;
685 default:
686 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
687 return;
688 }
689 // Check the common part of all message
690 void* context;
691 bool found = msg->findPointer(kContextKey, &context);
692 if (!found) {
693 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
694 return;
695 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800696 switch (msg->what()) {
697 case kWhatOnDisconnected:
698 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800699 ACameraDevice* dev;
700 found = msg->findPointer(kDeviceKey, (void**) &dev);
701 if (!found || dev == nullptr) {
702 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
703 return;
704 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800705 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800706 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800707 if (!found) {
708 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
709 return;
710 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800711 if (onDisconnected == nullptr) {
712 return;
713 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800714 (*onDisconnected)(context, dev);
715 break;
716 }
717 case kWhatOnError:
718 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800719 ACameraDevice* dev;
720 found = msg->findPointer(kDeviceKey, (void**) &dev);
721 if (!found || dev == nullptr) {
722 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
723 return;
724 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800725 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800726 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800727 if (!found) {
728 ALOGE("%s: Cannot find onError!", __FUNCTION__);
729 return;
730 }
731 int errorCode;
732 found = msg->findInt32(kErrorCodeKey, &errorCode);
733 if (!found) {
734 ALOGE("%s: Cannot find error code!", __FUNCTION__);
735 return;
736 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800737 if (onError == nullptr) {
738 return;
739 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800740 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800741 break;
742 }
743 case kWhatSessionStateCb:
744 case kWhatCaptureStart:
745 case kWhatCaptureResult:
746 case kWhatCaptureFail:
747 case kWhatCaptureSeqEnd:
748 case kWhatCaptureSeqAbort:
749 {
750 sp<RefBase> obj;
751 found = msg->findObject(kSessionSpKey, &obj);
752 if (!found || obj == nullptr) {
753 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
754 return;
755 }
756 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
757 sp<CaptureRequest> requestSp = nullptr;
758 switch (msg->what()) {
759 case kWhatCaptureStart:
760 case kWhatCaptureResult:
761 case kWhatCaptureFail:
762 found = msg->findObject(kCaptureRequestKey, &obj);
763 if (!found) {
764 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
765 return;
766 }
767 requestSp = static_cast<CaptureRequest*>(obj.get());
768 break;
769 }
770
771 switch (msg->what()) {
772 case kWhatSessionStateCb:
773 {
774 ACameraCaptureSession_stateCallback onState;
775 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
776 if (!found) {
777 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
778 return;
779 }
780 if (onState == nullptr) {
781 return;
782 }
783 (*onState)(context, session.get());
784 break;
785 }
786 case kWhatCaptureStart:
787 {
788 ACameraCaptureSession_captureCallback_start onStart;
789 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
790 if (!found) {
791 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
792 return;
793 }
794 if (onStart == nullptr) {
795 return;
796 }
797 int64_t timestamp;
798 found = msg->findInt64(kTimeStampKey, &timestamp);
799 if (!found) {
800 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
801 return;
802 }
803 ACaptureRequest* request = allocateACaptureRequest(requestSp);
804 (*onStart)(context, session.get(), request, timestamp);
805 freeACaptureRequest(request);
806 break;
807 }
808 case kWhatCaptureResult:
809 {
810 ACameraCaptureSession_captureCallback_result onResult;
811 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
812 if (!found) {
813 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
814 return;
815 }
816 if (onResult == nullptr) {
817 return;
818 }
819
820 found = msg->findObject(kCaptureResultKey, &obj);
821 if (!found) {
822 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
823 return;
824 }
825 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
826 ACaptureRequest* request = allocateACaptureRequest(requestSp);
827 (*onResult)(context, session.get(), request, result.get());
828 freeACaptureRequest(request);
829 break;
830 }
831 case kWhatCaptureFail:
832 {
833 ACameraCaptureSession_captureCallback_failed onFail;
834 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
835 if (!found) {
836 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
837 return;
838 }
839 if (onFail == nullptr) {
840 return;
841 }
842
843 found = msg->findObject(kCaptureFailureKey, &obj);
844 if (!found) {
845 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
846 return;
847 }
848 sp<CameraCaptureFailure> failureSp(
849 static_cast<CameraCaptureFailure*>(obj.get()));
850 ACameraCaptureFailure* failure =
851 static_cast<ACameraCaptureFailure*>(failureSp.get());
852 ACaptureRequest* request = allocateACaptureRequest(requestSp);
853 (*onFail)(context, session.get(), request, failure);
854 freeACaptureRequest(request);
855 delete failure;
856 break;
857 }
858 case kWhatCaptureSeqEnd:
859 {
860 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
861 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
862 if (!found) {
863 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
864 return;
865 }
866 if (onSeqEnd == nullptr) {
867 return;
868 }
869 int seqId;
870 found = msg->findInt32(kSequenceIdKey, &seqId);
871 if (!found) {
872 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
873 return;
874 }
875 int64_t frameNumber;
876 found = msg->findInt64(kFrameNumberKey, &frameNumber);
877 if (!found) {
878 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
879 return;
880 }
881 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
882 break;
883 }
884 case kWhatCaptureSeqAbort:
885 {
886 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
887 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
888 if (!found) {
889 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
890 return;
891 }
892 if (onSeqAbort == nullptr) {
893 return;
894 }
895 int seqId;
896 found = msg->findInt32(kSequenceIdKey, &seqId);
897 if (!found) {
898 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
899 return;
900 }
901 (*onSeqAbort)(context, session.get(), seqId);
902 break;
903 }
904 }
905 break;
906 }
907 }
908}
909
910CameraDevice::CallbackHolder::CallbackHolder(
911 sp<ACameraCaptureSession> session,
912 const Vector<sp<CaptureRequest> >& requests,
913 bool isRepeating,
914 ACameraCaptureSession_captureCallbacks* cbs) :
915 mSession(session), mRequests(requests),
916 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
917
918void
919CameraDevice::checkRepeatingSequenceCompleteLocked(
920 const int sequenceId, const int64_t lastFrameNumber) {
921 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
922 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
923 if (mSequenceCallbackMap.count(sequenceId) == 0) {
924 ALOGW("No callback found for sequenceId %d", sequenceId);
925 return;
926 }
927 // remove callback holder from callback map
928 auto cbIt = mSequenceCallbackMap.find(sequenceId);
929 CallbackHolder cbh = cbIt->second;
930 mSequenceCallbackMap.erase(cbIt);
931 // send seq aborted callback
932 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
933 msg->setPointer(kContextKey, cbh.mCallbacks.context);
934 msg->setObject(kSessionSpKey, cbh.mSession);
935 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
936 msg->setInt32(kSequenceIdKey, sequenceId);
937 msg->post();
938 } else {
939 // Use mSequenceLastFrameNumberMap to track
940 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
941
942 // Last frame might have arrived. Check now
943 checkAndFireSequenceCompleteLocked();
944 }
945}
946
947void
948CameraDevice::checkAndFireSequenceCompleteLocked() {
949 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
950 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
951 auto it = mSequenceLastFrameNumberMap.begin();
952 while (it != mSequenceLastFrameNumberMap.end()) {
953 int sequenceId = it->first;
954 int64_t lastFrameNumber = it->second;
955 bool seqCompleted = false;
956 bool hasCallback = true;
957
958 if (mRemote == nullptr) {
959 ALOGW("Camera %s closed while checking sequence complete", getId());
960 return;
961 }
962
963 // Check if there is callback for this sequence
964 // This should not happen because we always register callback (with nullptr inside)
965 if (mSequenceCallbackMap.count(sequenceId) == 0) {
966 ALOGW("No callback found for sequenceId %d", sequenceId);
967 hasCallback = false;
968 }
969
970 if (lastFrameNumber <= completedFrameNumber) {
971 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
972 sequenceId, lastFrameNumber, completedFrameNumber);
973 seqCompleted = true;
974 }
975
976 if (seqCompleted && hasCallback) {
977 // remove callback holder from callback map
978 auto cbIt = mSequenceCallbackMap.find(sequenceId);
979 CallbackHolder cbh = cbIt->second;
980 mSequenceCallbackMap.erase(cbIt);
981 // send seq complete callback
982 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
983 msg->setPointer(kContextKey, cbh.mCallbacks.context);
984 msg->setObject(kSessionSpKey, cbh.mSession);
985 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
986 msg->setInt32(kSequenceIdKey, sequenceId);
987 msg->setInt64(kFrameNumberKey, lastFrameNumber);
988
989 // Clear the session sp before we send out the message
990 // This will guarantee the rare case where the message is processed
991 // before cbh goes out of scope and causing we call the session
992 // destructor while holding device lock
993 cbh.mSession.clear();
994 msg->post();
995 }
996
997 // No need to track sequence complete if there is no callback registered
998 if (seqCompleted || !hasCallback) {
999 it = mSequenceLastFrameNumberMap.erase(it);
1000 } else {
1001 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001002 }
1003 }
1004}
1005
1006/**
1007 * Camera service callback implementation
1008 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001009binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001010CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001011 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001012 const CaptureResultExtras& resultExtras) {
1013 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1014 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001015 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001016 sp<CameraDevice> dev = mDevice.promote();
1017 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001018 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001019 }
1020
1021 Mutex::Autolock _l(dev->mDeviceLock);
1022 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001023 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001024 }
1025 switch (errorCode) {
1026 case ERROR_CAMERA_DISCONNECTED:
1027 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001028 // Camera is disconnected, close the session and expect no more callbacks
1029 if (dev->mCurrentSession != nullptr) {
1030 dev->mCurrentSession->closeByDevice();
1031 dev->mCurrentSession = nullptr;
1032 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001033 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1034 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1035 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001036 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001037 msg->post();
1038 break;
1039 }
1040 default:
1041 ALOGE("Unknown error from camera device: %d", errorCode);
1042 // no break
1043 case ERROR_CAMERA_DEVICE:
1044 case ERROR_CAMERA_SERVICE:
1045 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001046 switch (errorCode) {
1047 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001048 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001049 break;
1050 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001051 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001052 break;
1053 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001054 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001055 break;
1056 }
1057 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1058 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1059 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001060 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001061 msg->setInt32(kErrorCodeKey, errorCode);
1062 msg->post();
1063 break;
1064 }
1065 case ERROR_CAMERA_REQUEST:
1066 case ERROR_CAMERA_RESULT:
1067 case ERROR_CAMERA_BUFFER:
1068 dev->onCaptureErrorLocked(errorCode, resultExtras);
1069 break;
1070 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001071 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001072}
1073
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001074binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001075CameraDevice::ServiceCallback::onDeviceIdle() {
1076 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001077 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001078 sp<CameraDevice> dev = mDevice.promote();
1079 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001080 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001081 }
1082
1083 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001084 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001085 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001086 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001087
1088 if (dev->mIdle) {
1089 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001090 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001091 }
1092
1093 if (dev->mCurrentSession != nullptr) {
1094 ALOGE("onDeviceIdle sending state cb");
1095 if (dev->mBusySession != dev->mCurrentSession) {
1096 ALOGE("Current session != busy session");
1097 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001098 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001099 }
1100 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1101 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1102 msg->setObject(kSessionSpKey, dev->mBusySession);
1103 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1104 // Make sure we clear the sp first so the session destructor can
1105 // only happen on handler thread (where we don't hold device/session lock)
1106 dev->mBusySession.clear();
1107 msg->post();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001108 }
1109 dev->mIdle = true;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001110 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001111}
1112
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001113binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001114CameraDevice::ServiceCallback::onCaptureStarted(
1115 const CaptureResultExtras& resultExtras,
1116 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001117 binder::Status ret = binder::Status::ok();
1118
Yin-Chia Yehead91462016-01-06 16:45:08 -08001119 sp<CameraDevice> dev = mDevice.promote();
1120 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001121 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001122 }
1123 Mutex::Autolock _l(dev->mDeviceLock);
1124 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001125 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001126 }
1127
1128 int sequenceId = resultExtras.requestId;
1129 int64_t frameNumber = resultExtras.frameNumber;
1130 int32_t burstId = resultExtras.burstId;
1131
1132 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1133 if (it != dev->mSequenceCallbackMap.end()) {
1134 CallbackHolder cbh = (*it).second;
1135 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1136 sp<ACameraCaptureSession> session = cbh.mSession;
1137 if ((size_t) burstId >= cbh.mRequests.size()) {
1138 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1139 __FUNCTION__, burstId, cbh.mRequests.size());
1140 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1141 }
1142 sp<CaptureRequest> request = cbh.mRequests[burstId];
1143 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1144 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1145 msg->setObject(kSessionSpKey, session);
1146 msg->setPointer(kCallbackFpKey, (void*) onStart);
1147 msg->setObject(kCaptureRequestKey, request);
1148 msg->setInt64(kTimeStampKey, timestamp);
1149 msg->post();
1150 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001151 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001152}
1153
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001154binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001155CameraDevice::ServiceCallback::onResultReceived(
1156 const CameraMetadata& metadata,
1157 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001158 binder::Status ret = binder::Status::ok();
1159
Yin-Chia Yehead91462016-01-06 16:45:08 -08001160 sp<CameraDevice> dev = mDevice.promote();
1161 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001162 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001163 }
1164 int sequenceId = resultExtras.requestId;
1165 int64_t frameNumber = resultExtras.frameNumber;
1166 int32_t burstId = resultExtras.burstId;
1167 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1168
1169 if (!isPartialResult) {
1170 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1171 }
1172
1173 Mutex::Autolock _l(dev->mDeviceLock);
1174 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001175 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001176 }
1177
1178 if (dev->isClosed()) {
1179 if (!isPartialResult) {
1180 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1181 }
1182 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001183 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001184 }
1185
1186 CameraMetadata metadataCopy = metadata;
1187 // Copied from java implmentation. Why do we need this?
1188 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
1189
1190 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1191 if (it != dev->mSequenceCallbackMap.end()) {
1192 CallbackHolder cbh = (*it).second;
1193 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1194 cbh.mCallbacks.onCaptureProgressed :
1195 cbh.mCallbacks.onCaptureCompleted;
1196 sp<ACameraCaptureSession> session = cbh.mSession;
1197 if ((size_t) burstId >= cbh.mRequests.size()) {
1198 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1199 __FUNCTION__, burstId, cbh.mRequests.size());
1200 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1201 }
1202 sp<CaptureRequest> request = cbh.mRequests[burstId];
1203 sp<ACameraMetadata> result(new ACameraMetadata(
1204 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1205
1206 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1207 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1208 msg->setObject(kSessionSpKey, session);
1209 msg->setPointer(kCallbackFpKey, (void*) onResult);
1210 msg->setObject(kCaptureRequestKey, request);
1211 msg->setObject(kCaptureResultKey, result);
1212 msg->post();
1213 }
1214
1215 if (!isPartialResult) {
1216 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1217 dev->checkAndFireSequenceCompleteLocked();
1218 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001219
1220 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001221}
1222
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001223binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001224CameraDevice::ServiceCallback::onPrepared(int) {
1225 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001226 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001227}
1228
1229} // namespace android