blob: 1a1118c59cdf7fae77cf44e829cd7c4677a78351 [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACameraDevice"
19
Yin-Chia Yehead91462016-01-06 16:45:08 -080020#include <vector>
21#include <utility>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080022#include <inttypes.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080023#include <android/hardware/ICameraService.h>
24#include <camera2/SubmitInfo.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080025#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080026#include "ACameraDevice.h"
27#include "ACameraMetadata.h"
28#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080029#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080030
31using namespace android;
32
33namespace android {
34// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080035const char* CameraDevice::kContextKey = "Context";
36const char* CameraDevice::kDeviceKey = "Device";
37const char* CameraDevice::kErrorCodeKey = "ErrorCode";
38const char* CameraDevice::kCallbackFpKey = "Callback";
39const char* CameraDevice::kSessionSpKey = "SessionSp";
40const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
41const char* CameraDevice::kTimeStampKey = "TimeStamp";
42const char* CameraDevice::kCaptureResultKey = "CaptureResult";
43const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
44const char* CameraDevice::kSequenceIdKey = "SequenceId";
45const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080046
47/**
48 * CameraDevice Implementation
49 */
50CameraDevice::CameraDevice(
51 const char* id,
52 ACameraDevice_StateCallbacks* cb,
53 std::unique_ptr<ACameraMetadata> chars,
54 ACameraDevice* wrapper) :
55 mCameraId(id),
56 mAppCallbacks(*cb),
57 mChars(std::move(chars)),
58 mServiceCallback(new ServiceCallback(this)),
59 mWrapper(wrapper),
60 mInError(false),
61 mError(ACAMERA_OK),
62 mIdle(true) {
63 mClosing = false;
64 // Setup looper thread to perfrom device callbacks to app
65 mCbLooper = new ALooper;
66 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080067 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080068 /*runOnCallingThread*/false,
69 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080070 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080071 if (err != OK) {
72 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
73 __FUNCTION__, strerror(-err), err);
74 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
75 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080076 mHandler = new CallbackHandler();
77 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080078
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080079 const CameraMetadata& metadata = mChars->getInternalData();
80 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080081 if (entry.count != 1) {
82 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
83 mPartialResultCount = 1;
84 } else {
85 mPartialResultCount = entry.data.i32[0];
86 }
87
88 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
89 if (entry.count != 2) {
90 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
91 mShadingMapSize[0] = 0;
92 mShadingMapSize[1] = 0;
93 } else {
94 mShadingMapSize[0] = entry.data.i32[0];
95 mShadingMapSize[1] = entry.data.i32[1];
96 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080097}
98
Yin-Chia Yehead91462016-01-06 16:45:08 -080099// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800100CameraDevice::~CameraDevice() {
101 Mutex::Autolock _l(mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800102 if (!isClosed()) {
103 disconnectLocked();
104 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800105 if (mCbLooper != nullptr) {
106 mCbLooper->unregisterHandler(mHandler->id());
107 mCbLooper->stop();
108 }
109 mCbLooper.clear();
110 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800111}
112
113// TODO: cached created request?
114camera_status_t
115CameraDevice::createCaptureRequest(
116 ACameraDevice_request_template templateId,
117 ACaptureRequest** request) const {
118 Mutex::Autolock _l(mDeviceLock);
119 camera_status_t ret = checkCameraClosedOrErrorLocked();
120 if (ret != ACAMERA_OK) {
121 return ret;
122 }
123 if (mRemote == nullptr) {
124 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
125 }
126 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800127 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
128 if (remoteRet.serviceSpecificErrorCode() ==
129 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800130 ALOGW("Create capture request failed! template %d is not supported on this device",
131 templateId);
132 return ACAMERA_ERROR_UNSUPPORTED;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800133 } else if (!remoteRet.isOk()) {
134 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800135 return ACAMERA_ERROR_UNKNOWN;
136 }
137 ACaptureRequest* outReq = new ACaptureRequest();
138 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
139 outReq->targets = new ACameraOutputTargets();
140 *request = outReq;
141 return ACAMERA_OK;
142}
143
Yin-Chia Yehead91462016-01-06 16:45:08 -0800144camera_status_t
145CameraDevice::createCaptureSession(
146 const ACaptureSessionOutputContainer* outputs,
147 const ACameraCaptureSession_stateCallbacks* callbacks,
148 /*out*/ACameraCaptureSession** session) {
149 Mutex::Autolock _l(mDeviceLock);
150 camera_status_t ret = checkCameraClosedOrErrorLocked();
151 if (ret != ACAMERA_OK) {
152 return ret;
153 }
154
155 if (mCurrentSession != nullptr) {
156 mCurrentSession->closeByDevice();
157 stopRepeatingLocked();
158 }
159
160 // Create new session
161 ret = configureStreamsLocked(outputs);
162 if (ret != ACAMERA_OK) {
163 ALOGE("Fail to create new session. cannot configure streams");
164 return ret;
165 }
166
167 ACameraCaptureSession* newSession = new ACameraCaptureSession(
168 mNextSessionId++, outputs, callbacks, this);
169
Yin-Chia Yehead91462016-01-06 16:45:08 -0800170 // set new session as current session
171 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
172 mCurrentSession = newSession;
173 *session = newSession;
174 return ACAMERA_OK;
175}
176
177camera_status_t
178CameraDevice::captureLocked(
179 sp<ACameraCaptureSession> session,
180 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
181 int numRequests, ACaptureRequest** requests,
182 /*optional*/int* captureSequenceId) {
183 return submitRequestsLocked(
184 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
185}
186
187camera_status_t
188CameraDevice::setRepeatingRequestsLocked(
189 sp<ACameraCaptureSession> session,
190 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
191 int numRequests, ACaptureRequest** requests,
192 /*optional*/int* captureSequenceId) {
193 return submitRequestsLocked(
194 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
195}
196
197camera_status_t
198CameraDevice::submitRequestsLocked(
199 sp<ACameraCaptureSession> session,
200 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
201 int numRequests, ACaptureRequest** requests,
202 /*optional*/int* captureSequenceId,
203 bool isRepeating) {
204 camera_status_t ret = checkCameraClosedOrErrorLocked();
205 if (ret != ACAMERA_OK) {
206 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
207 return ret;
208 }
209
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800210 // Form two vectors of capture request, one for internal tracking
211 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800212 Vector<sp<CaptureRequest> > requestsV;
213 requestsV.setCapacity(numRequests);
214 for (int i = 0; i < numRequests; i++) {
215 sp<CaptureRequest> req;
216 ret = allocateCaptureRequest(requests[i], req);
217 if (ret != ACAMERA_OK) {
218 ALOGE("Convert capture request to internal format failure! ret %d", ret);
219 return ret;
220 }
221 if (req->mSurfaceList.empty()) {
222 ALOGE("Capture request without output target cannot be submitted!");
223 return ACAMERA_ERROR_INVALID_PARAMETER;
224 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800225 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800226 requestsV.push_back(req);
227 }
228
229 if (isRepeating) {
230 ret = stopRepeatingLocked();
231 if (ret != ACAMERA_OK) {
232 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
233 return ret;
234 }
235 }
236
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800237 binder::Status remoteRet;
238 hardware::camera2::utils::SubmitInfo info;
239 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
240 int sequenceId = info.mRequestId;
241 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800242 if (sequenceId < 0) {
243 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
244 return ACAMERA_ERROR_UNKNOWN;
245 }
246
247 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
248 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
249
250 if (isRepeating) {
251 // stopRepeating above should have cleanup repeating sequence id
252 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
253 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
254 return ACAMERA_ERROR_CAMERA_DEVICE;
255 }
256 mRepeatingSequenceId = sequenceId;
257 } else {
258 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
259 }
260
261 if (mIdle) {
262 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
263 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
264 msg->setObject(kSessionSpKey, session);
265 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
266 msg->post();
267 }
268 mIdle = false;
269 mBusySession = session;
270
271 if (captureSequenceId) {
272 *captureSequenceId = sequenceId;
273 }
274 return ACAMERA_OK;
275}
276
277camera_status_t
278CameraDevice::allocateCaptureRequest(
279 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
280 camera_status_t ret;
281 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800282 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800283 req->mIsReprocess = false; // NDK does not support reprocessing yet
284
285 for (auto outputTarget : request->targets->mOutputs) {
286 ANativeWindow* anw = outputTarget.mWindow;
287 sp<Surface> surface;
288 ret = getSurfaceFromANativeWindow(anw, surface);
289 if (ret != ACAMERA_OK) {
290 ALOGE("Bad output target in capture request! ret %d", ret);
291 return ret;
292 }
293 req->mSurfaceList.push_back(surface);
294 }
295 outReq = req;
296 return ACAMERA_OK;
297}
298
299ACaptureRequest*
300CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
301 ACaptureRequest* pRequest = new ACaptureRequest();
302 CameraMetadata clone = req->mMetadata;
303 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
304 pRequest->targets = new ACameraOutputTargets();
305 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
306 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
307 ACameraOutputTarget outputTarget(anw);
308 pRequest->targets->mOutputs.insert(outputTarget);
309 }
310 return pRequest;
311}
312
313void
314CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
315 if (req == nullptr) {
316 return;
317 }
318 delete req->settings;
319 delete req->targets;
320 delete req;
321}
322
323void
324CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
325 if (isClosed()) {
326 // Device is closing already. do nothing
327 return;
328 }
329
330 if (session != mCurrentSession) {
331 // Session has been replaced by other seesion or device is closed
332 return;
333 }
334 mCurrentSession = nullptr;
335
336 // Should not happen
337 if (!session->mIsClosed) {
338 ALOGE("Error: unclosed session %p reaches end of life!", session);
339 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
340 return;
341 }
342
343 // No new session, unconfigure now
344 camera_status_t ret = configureStreamsLocked(nullptr);
345 if (ret != ACAMERA_OK) {
346 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
347 }
348}
349
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800350void
351CameraDevice::disconnectLocked() {
352 if (mClosing.exchange(true)) {
353 // Already closing, just return
354 ALOGW("Camera device %s is already closing.", getId());
355 return;
356 }
357
358 if (mRemote != nullptr) {
359 mRemote->disconnect();
360 }
361 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800362
363 if (mCurrentSession != nullptr) {
364 mCurrentSession->closeByDevice();
365 mCurrentSession = nullptr;
366 }
367}
368
369camera_status_t
370CameraDevice::stopRepeatingLocked() {
371 camera_status_t ret = checkCameraClosedOrErrorLocked();
372 if (ret != ACAMERA_OK) {
373 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
374 return ret;
375 }
376 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
377 int repeatingSequenceId = mRepeatingSequenceId;
378 mRepeatingSequenceId = REQUEST_ID_NONE;
379
380 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800381 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
382 if (!remoteRet.isOk()) {
383 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800384 return ACAMERA_ERROR_UNKNOWN;
385 }
386 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
387 }
388 return ACAMERA_OK;
389}
390
391camera_status_t
392CameraDevice::waitUntilIdleLocked() {
393 camera_status_t ret = checkCameraClosedOrErrorLocked();
394 if (ret != ACAMERA_OK) {
395 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
396 return ret;
397 }
398
399 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
400 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
401 return ACAMERA_ERROR_INVALID_OPERATION;
402 }
403
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800404 binder::Status remoteRet = mRemote->waitUntilIdle();
405 if (!remoteRet.isOk()) {
406 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800407 // TODO: define a function to convert status_t -> camera_status_t
408 return ACAMERA_ERROR_UNKNOWN;
409 }
410
411 return ACAMERA_OK;
412}
413
414camera_status_t
415CameraDevice::getIGBPfromSessionOutput(
416 const ACaptureSessionOutput& config,
417 sp<IGraphicBufferProducer>& out) {
418 ANativeWindow* anw = config.mWindow;
419 if (anw == nullptr) {
420 ALOGE("Error: output ANativeWindow is null");
421 return ACAMERA_ERROR_INVALID_PARAMETER;
422 }
423 int value;
424 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800425 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800426 ALOGE("Error: ANativeWindow is not backed by Surface!");
427 return ACAMERA_ERROR_INVALID_PARAMETER;
428 }
429 const sp<Surface> surface(static_cast<Surface*>(anw));
430 out = surface->getIGraphicBufferProducer();
431 return ACAMERA_OK;
432}
433
434camera_status_t
435CameraDevice::getSurfaceFromANativeWindow(
436 ANativeWindow* anw, sp<Surface>& out) {
437 if (anw == nullptr) {
438 ALOGE("Error: output ANativeWindow is null");
439 return ACAMERA_ERROR_INVALID_PARAMETER;
440 }
441 int value;
442 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800443 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800444 ALOGE("Error: ANativeWindow is not backed by Surface!");
445 return ACAMERA_ERROR_INVALID_PARAMETER;
446 }
447 sp<Surface> surface(static_cast<Surface*>(anw));
448 out = surface;
449 return ACAMERA_OK;
450}
451
452camera_status_t
453CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
454 ACaptureSessionOutputContainer emptyOutput;
455 if (outputs == nullptr) {
456 outputs = &emptyOutput;
457 }
458
Yin-Chia Yehead91462016-01-06 16:45:08 -0800459 camera_status_t ret = checkCameraClosedOrErrorLocked();
460 if (ret != ACAMERA_OK) {
461 return ret;
462 }
463
464 std::set<OutputConfiguration> outputSet;
465 for (auto outConfig : outputs->mOutputs) {
466 sp<IGraphicBufferProducer> iGBP(nullptr);
467 ret = getIGBPfromSessionOutput(outConfig, iGBP);
468 if (ret != ACAMERA_OK) {
469 return ret;
470 }
471 outputSet.insert(OutputConfiguration(iGBP, outConfig.mRotation));
472 }
473 std::set<OutputConfiguration> addSet = outputSet;
474 std::vector<int> deleteList;
475
476 // Determine which streams need to be created, which to be deleted
477 for (auto& kvPair : mConfiguredOutputs) {
478 int streamId = kvPair.first;
479 OutputConfiguration& outConfig = kvPair.second;
480 if (outputSet.count(outConfig) == 0) {
481 deleteList.push_back(streamId); // Need to delete a no longer needed stream
482 } else {
483 addSet.erase(outConfig); // No need to add already existing stream
484 }
485 }
486
487 ret = stopRepeatingLocked();
488 if (ret != ACAMERA_OK) {
489 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
490 return ret;
491 }
492
493 ret = waitUntilIdleLocked();
494 if (ret != ACAMERA_OK) {
495 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
496 return ret;
497 }
498
499 // Send onReady to previous session
500 // CurrentSession will be updated after configureStreamLocked, so here
501 // mCurrentSession is the session to be replaced by a new session
502 if (!mIdle && mCurrentSession != nullptr) {
503 if (mBusySession != mCurrentSession) {
504 ALOGE("Current session != busy session");
505 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
506 return ACAMERA_ERROR_CAMERA_DEVICE;
507 }
508 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
509 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
510 msg->setObject(kSessionSpKey, mBusySession);
511 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
512 mBusySession.clear();
513 msg->post();
514 }
515 mIdle = true;
516
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800517 binder::Status remoteRet = mRemote->beginConfigure();
518 if (!remoteRet.isOk()) {
519 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800520 return ACAMERA_ERROR_UNKNOWN;
521 }
522
523 // delete to-be-deleted streams
524 for (auto streamId : deleteList) {
525 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800526 if (!remoteRet.isOk()) {
527 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
528 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800529 return ACAMERA_ERROR_UNKNOWN;
530 }
531 mConfiguredOutputs.erase(streamId);
532 }
533
534 // add new streams
535 for (auto outConfig : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800536 int streamId;
537 remoteRet = mRemote->createStream(outConfig, &streamId);
538 if (!remoteRet.isOk()) {
539 ALOGE("Camera device %s failed to create stream: %s", getId(),
540 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800541 return ACAMERA_ERROR_UNKNOWN;
542 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800543 mConfiguredOutputs.insert(std::make_pair(streamId, outConfig));
544 }
545
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800546 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
547 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
548 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
549 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800550 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800551 } else if (!remoteRet.isOk()) {
552 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800553 return ACAMERA_ERROR_UNKNOWN;
554 }
555
556 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800557}
558
559void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800560CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800561 Mutex::Autolock _l(mDeviceLock);
562 mRemote = remote;
563}
564
565camera_status_t
566CameraDevice::checkCameraClosedOrErrorLocked() const {
567 if (mRemote == nullptr) {
568 ALOGE("%s: camera device already closed", __FUNCTION__);
569 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
570 }
571 if (mInError) {// triggered by onDeviceError
572 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
573 return mError;
574 }
575 return ACAMERA_OK;
576}
577
578void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800579CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
580 mInError = true;
581 mError = error;
582 return;
583}
584
585void
586CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
587 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
588 if (isError) {
589 mFutureErrorSet.insert(frameNumber);
590 } else if (frameNumber <= mCompletedFrameNumber) {
591 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
592 frameNumber, mCompletedFrameNumber);
593 return;
594 } else {
595 if (frameNumber != mCompletedFrameNumber + 1) {
596 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
597 mCompletedFrameNumber + 1, frameNumber);
598 // Do not assert as in java implementation
599 }
600 mCompletedFrameNumber = frameNumber;
601 }
602 update();
603}
604
605void
606CameraDevice::FrameNumberTracker::update() {
607 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
608 int64_t errorFrameNumber = *it;
609 if (errorFrameNumber == mCompletedFrameNumber + 1) {
610 mCompletedFrameNumber++;
611 it = mFutureErrorSet.erase(it);
612 } else if (errorFrameNumber <= mCompletedFrameNumber) {
613 // This should not happen, but deal with it anyway
614 ALOGE("Completd frame number passed through current frame number!");
615 // erase the old error since it's no longer useful
616 it = mFutureErrorSet.erase(it);
617 } else {
618 // Normal requests hasn't catched up error frames, just break
619 break;
620 }
621 }
622 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
623}
624
625void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800626CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800627 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800628 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800629 int sequenceId = resultExtras.requestId;
630 int64_t frameNumber = resultExtras.frameNumber;
631 int32_t burstId = resultExtras.burstId;
632
633 // No way to report buffer error now
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800634 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800635 ALOGE("Camera %s Lost output buffer for frame %" PRId64,
636 getId(), frameNumber);
637 return;
638 }
639 // Fire capture failure callback if there is one registered
640 auto it = mSequenceCallbackMap.find(sequenceId);
641 if (it != mSequenceCallbackMap.end()) {
642 CallbackHolder cbh = (*it).second;
643 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
644 sp<ACameraCaptureSession> session = cbh.mSession;
645 if ((size_t) burstId >= cbh.mRequests.size()) {
646 ALOGE("%s: Error: request index %d out of bound (size %zu)",
647 __FUNCTION__, burstId, cbh.mRequests.size());
648 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
649 return;
650 }
651 sp<CaptureRequest> request = cbh.mRequests[burstId];
652 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
653 failure->frameNumber = frameNumber;
654 // TODO: refine this when implementing flush
655 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
656 failure->sequenceId = sequenceId;
657 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800658 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800659
660 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
661 msg->setPointer(kContextKey, cbh.mCallbacks.context);
662 msg->setObject(kSessionSpKey, session);
663 msg->setPointer(kCallbackFpKey, (void*) onError);
664 msg->setObject(kCaptureRequestKey, request);
665 msg->setObject(kCaptureFailureKey, failure);
666 msg->post();
667 }
668
669 // Update tracker
670 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
671 checkAndFireSequenceCompleteLocked();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800672}
673
674void CameraDevice::CallbackHandler::onMessageReceived(
675 const sp<AMessage> &msg) {
676 switch (msg->what()) {
677 case kWhatOnDisconnected:
678 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800679 case kWhatSessionStateCb:
680 case kWhatCaptureStart:
681 case kWhatCaptureResult:
682 case kWhatCaptureFail:
683 case kWhatCaptureSeqEnd:
684 case kWhatCaptureSeqAbort:
685 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800686 break;
687 default:
688 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
689 return;
690 }
691 // Check the common part of all message
692 void* context;
693 bool found = msg->findPointer(kContextKey, &context);
694 if (!found) {
695 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
696 return;
697 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800698 switch (msg->what()) {
699 case kWhatOnDisconnected:
700 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800701 ACameraDevice* dev;
702 found = msg->findPointer(kDeviceKey, (void**) &dev);
703 if (!found || dev == nullptr) {
704 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
705 return;
706 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800707 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800708 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800709 if (!found) {
710 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
711 return;
712 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800713 if (onDisconnected == nullptr) {
714 return;
715 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800716 (*onDisconnected)(context, dev);
717 break;
718 }
719 case kWhatOnError:
720 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800721 ACameraDevice* dev;
722 found = msg->findPointer(kDeviceKey, (void**) &dev);
723 if (!found || dev == nullptr) {
724 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
725 return;
726 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800727 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800728 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800729 if (!found) {
730 ALOGE("%s: Cannot find onError!", __FUNCTION__);
731 return;
732 }
733 int errorCode;
734 found = msg->findInt32(kErrorCodeKey, &errorCode);
735 if (!found) {
736 ALOGE("%s: Cannot find error code!", __FUNCTION__);
737 return;
738 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800739 if (onError == nullptr) {
740 return;
741 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800742 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800743 break;
744 }
745 case kWhatSessionStateCb:
746 case kWhatCaptureStart:
747 case kWhatCaptureResult:
748 case kWhatCaptureFail:
749 case kWhatCaptureSeqEnd:
750 case kWhatCaptureSeqAbort:
751 {
752 sp<RefBase> obj;
753 found = msg->findObject(kSessionSpKey, &obj);
754 if (!found || obj == nullptr) {
755 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
756 return;
757 }
758 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
759 sp<CaptureRequest> requestSp = nullptr;
760 switch (msg->what()) {
761 case kWhatCaptureStart:
762 case kWhatCaptureResult:
763 case kWhatCaptureFail:
764 found = msg->findObject(kCaptureRequestKey, &obj);
765 if (!found) {
766 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
767 return;
768 }
769 requestSp = static_cast<CaptureRequest*>(obj.get());
770 break;
771 }
772
773 switch (msg->what()) {
774 case kWhatSessionStateCb:
775 {
776 ACameraCaptureSession_stateCallback onState;
777 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
778 if (!found) {
779 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
780 return;
781 }
782 if (onState == nullptr) {
783 return;
784 }
785 (*onState)(context, session.get());
786 break;
787 }
788 case kWhatCaptureStart:
789 {
790 ACameraCaptureSession_captureCallback_start onStart;
791 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
792 if (!found) {
793 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
794 return;
795 }
796 if (onStart == nullptr) {
797 return;
798 }
799 int64_t timestamp;
800 found = msg->findInt64(kTimeStampKey, &timestamp);
801 if (!found) {
802 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
803 return;
804 }
805 ACaptureRequest* request = allocateACaptureRequest(requestSp);
806 (*onStart)(context, session.get(), request, timestamp);
807 freeACaptureRequest(request);
808 break;
809 }
810 case kWhatCaptureResult:
811 {
812 ACameraCaptureSession_captureCallback_result onResult;
813 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
814 if (!found) {
815 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
816 return;
817 }
818 if (onResult == nullptr) {
819 return;
820 }
821
822 found = msg->findObject(kCaptureResultKey, &obj);
823 if (!found) {
824 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
825 return;
826 }
827 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
828 ACaptureRequest* request = allocateACaptureRequest(requestSp);
829 (*onResult)(context, session.get(), request, result.get());
830 freeACaptureRequest(request);
831 break;
832 }
833 case kWhatCaptureFail:
834 {
835 ACameraCaptureSession_captureCallback_failed onFail;
836 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
837 if (!found) {
838 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
839 return;
840 }
841 if (onFail == nullptr) {
842 return;
843 }
844
845 found = msg->findObject(kCaptureFailureKey, &obj);
846 if (!found) {
847 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
848 return;
849 }
850 sp<CameraCaptureFailure> failureSp(
851 static_cast<CameraCaptureFailure*>(obj.get()));
852 ACameraCaptureFailure* failure =
853 static_cast<ACameraCaptureFailure*>(failureSp.get());
854 ACaptureRequest* request = allocateACaptureRequest(requestSp);
855 (*onFail)(context, session.get(), request, failure);
856 freeACaptureRequest(request);
857 delete failure;
858 break;
859 }
860 case kWhatCaptureSeqEnd:
861 {
862 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
863 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
864 if (!found) {
865 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
866 return;
867 }
868 if (onSeqEnd == nullptr) {
869 return;
870 }
871 int seqId;
872 found = msg->findInt32(kSequenceIdKey, &seqId);
873 if (!found) {
874 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
875 return;
876 }
877 int64_t frameNumber;
878 found = msg->findInt64(kFrameNumberKey, &frameNumber);
879 if (!found) {
880 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
881 return;
882 }
883 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
884 break;
885 }
886 case kWhatCaptureSeqAbort:
887 {
888 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
889 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
890 if (!found) {
891 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
892 return;
893 }
894 if (onSeqAbort == nullptr) {
895 return;
896 }
897 int seqId;
898 found = msg->findInt32(kSequenceIdKey, &seqId);
899 if (!found) {
900 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
901 return;
902 }
903 (*onSeqAbort)(context, session.get(), seqId);
904 break;
905 }
906 }
907 break;
908 }
909 }
910}
911
912CameraDevice::CallbackHolder::CallbackHolder(
913 sp<ACameraCaptureSession> session,
914 const Vector<sp<CaptureRequest> >& requests,
915 bool isRepeating,
916 ACameraCaptureSession_captureCallbacks* cbs) :
917 mSession(session), mRequests(requests),
918 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
919
920void
921CameraDevice::checkRepeatingSequenceCompleteLocked(
922 const int sequenceId, const int64_t lastFrameNumber) {
923 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
924 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
925 if (mSequenceCallbackMap.count(sequenceId) == 0) {
926 ALOGW("No callback found for sequenceId %d", sequenceId);
927 return;
928 }
929 // remove callback holder from callback map
930 auto cbIt = mSequenceCallbackMap.find(sequenceId);
931 CallbackHolder cbh = cbIt->second;
932 mSequenceCallbackMap.erase(cbIt);
933 // send seq aborted callback
934 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
935 msg->setPointer(kContextKey, cbh.mCallbacks.context);
936 msg->setObject(kSessionSpKey, cbh.mSession);
937 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
938 msg->setInt32(kSequenceIdKey, sequenceId);
939 msg->post();
940 } else {
941 // Use mSequenceLastFrameNumberMap to track
942 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
943
944 // Last frame might have arrived. Check now
945 checkAndFireSequenceCompleteLocked();
946 }
947}
948
949void
950CameraDevice::checkAndFireSequenceCompleteLocked() {
951 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
952 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
953 auto it = mSequenceLastFrameNumberMap.begin();
954 while (it != mSequenceLastFrameNumberMap.end()) {
955 int sequenceId = it->first;
956 int64_t lastFrameNumber = it->second;
957 bool seqCompleted = false;
958 bool hasCallback = true;
959
960 if (mRemote == nullptr) {
961 ALOGW("Camera %s closed while checking sequence complete", getId());
962 return;
963 }
964
965 // Check if there is callback for this sequence
966 // This should not happen because we always register callback (with nullptr inside)
967 if (mSequenceCallbackMap.count(sequenceId) == 0) {
968 ALOGW("No callback found for sequenceId %d", sequenceId);
969 hasCallback = false;
970 }
971
972 if (lastFrameNumber <= completedFrameNumber) {
973 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
974 sequenceId, lastFrameNumber, completedFrameNumber);
975 seqCompleted = true;
976 }
977
978 if (seqCompleted && hasCallback) {
979 // remove callback holder from callback map
980 auto cbIt = mSequenceCallbackMap.find(sequenceId);
981 CallbackHolder cbh = cbIt->second;
982 mSequenceCallbackMap.erase(cbIt);
983 // send seq complete callback
984 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
985 msg->setPointer(kContextKey, cbh.mCallbacks.context);
986 msg->setObject(kSessionSpKey, cbh.mSession);
987 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
988 msg->setInt32(kSequenceIdKey, sequenceId);
989 msg->setInt64(kFrameNumberKey, lastFrameNumber);
990
991 // Clear the session sp before we send out the message
992 // This will guarantee the rare case where the message is processed
993 // before cbh goes out of scope and causing we call the session
994 // destructor while holding device lock
995 cbh.mSession.clear();
996 msg->post();
997 }
998
999 // No need to track sequence complete if there is no callback registered
1000 if (seqCompleted || !hasCallback) {
1001 it = mSequenceLastFrameNumberMap.erase(it);
1002 } else {
1003 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001004 }
1005 }
1006}
1007
1008/**
1009 * Camera service callback implementation
1010 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001011binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001012CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001013 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001014 const CaptureResultExtras& resultExtras) {
1015 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1016 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001017 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001018 sp<CameraDevice> dev = mDevice.promote();
1019 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001020 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001021 }
1022
1023 Mutex::Autolock _l(dev->mDeviceLock);
1024 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001025 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001026 }
1027 switch (errorCode) {
1028 case ERROR_CAMERA_DISCONNECTED:
1029 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001030 // Camera is disconnected, close the session and expect no more callbacks
1031 if (dev->mCurrentSession != nullptr) {
1032 dev->mCurrentSession->closeByDevice();
1033 dev->mCurrentSession = nullptr;
1034 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001035 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1036 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1037 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001038 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001039 msg->post();
1040 break;
1041 }
1042 default:
1043 ALOGE("Unknown error from camera device: %d", errorCode);
1044 // no break
1045 case ERROR_CAMERA_DEVICE:
1046 case ERROR_CAMERA_SERVICE:
1047 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001048 switch (errorCode) {
1049 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001050 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001051 break;
1052 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001053 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001054 break;
1055 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001056 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001057 break;
1058 }
1059 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1060 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1061 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001062 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001063 msg->setInt32(kErrorCodeKey, errorCode);
1064 msg->post();
1065 break;
1066 }
1067 case ERROR_CAMERA_REQUEST:
1068 case ERROR_CAMERA_RESULT:
1069 case ERROR_CAMERA_BUFFER:
1070 dev->onCaptureErrorLocked(errorCode, resultExtras);
1071 break;
1072 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001073 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001074}
1075
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001076binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001077CameraDevice::ServiceCallback::onDeviceIdle() {
1078 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001079 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001080 sp<CameraDevice> dev = mDevice.promote();
1081 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001082 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001083 }
1084
1085 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001086 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001087 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001088 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001089
1090 if (dev->mIdle) {
1091 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001092 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001093 }
1094
1095 if (dev->mCurrentSession != nullptr) {
1096 ALOGE("onDeviceIdle sending state cb");
1097 if (dev->mBusySession != dev->mCurrentSession) {
1098 ALOGE("Current session != busy session");
1099 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001100 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001101 }
1102 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1103 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1104 msg->setObject(kSessionSpKey, dev->mBusySession);
1105 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1106 // Make sure we clear the sp first so the session destructor can
1107 // only happen on handler thread (where we don't hold device/session lock)
1108 dev->mBusySession.clear();
1109 msg->post();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001110 }
1111 dev->mIdle = true;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001112 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001113}
1114
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001115binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001116CameraDevice::ServiceCallback::onCaptureStarted(
1117 const CaptureResultExtras& resultExtras,
1118 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001119 binder::Status ret = binder::Status::ok();
1120
Yin-Chia Yehead91462016-01-06 16:45:08 -08001121 sp<CameraDevice> dev = mDevice.promote();
1122 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001123 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001124 }
1125 Mutex::Autolock _l(dev->mDeviceLock);
1126 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001127 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001128 }
1129
1130 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001131 int32_t burstId = resultExtras.burstId;
1132
1133 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1134 if (it != dev->mSequenceCallbackMap.end()) {
1135 CallbackHolder cbh = (*it).second;
1136 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1137 sp<ACameraCaptureSession> session = cbh.mSession;
1138 if ((size_t) burstId >= cbh.mRequests.size()) {
1139 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1140 __FUNCTION__, burstId, cbh.mRequests.size());
1141 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1142 }
1143 sp<CaptureRequest> request = cbh.mRequests[burstId];
1144 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1145 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1146 msg->setObject(kSessionSpKey, session);
1147 msg->setPointer(kCallbackFpKey, (void*) onStart);
1148 msg->setObject(kCaptureRequestKey, request);
1149 msg->setInt64(kTimeStampKey, timestamp);
1150 msg->post();
1151 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001152 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001153}
1154
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001155binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001156CameraDevice::ServiceCallback::onResultReceived(
1157 const CameraMetadata& metadata,
1158 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001159 binder::Status ret = binder::Status::ok();
1160
Yin-Chia Yehead91462016-01-06 16:45:08 -08001161 sp<CameraDevice> dev = mDevice.promote();
1162 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001163 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001164 }
1165 int sequenceId = resultExtras.requestId;
1166 int64_t frameNumber = resultExtras.frameNumber;
1167 int32_t burstId = resultExtras.burstId;
1168 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1169
1170 if (!isPartialResult) {
1171 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1172 }
1173
1174 Mutex::Autolock _l(dev->mDeviceLock);
1175 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001176 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001177 }
1178
1179 if (dev->isClosed()) {
1180 if (!isPartialResult) {
1181 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1182 }
1183 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001184 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001185 }
1186
1187 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001188 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001189 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001190
1191 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1192 if (it != dev->mSequenceCallbackMap.end()) {
1193 CallbackHolder cbh = (*it).second;
1194 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1195 cbh.mCallbacks.onCaptureProgressed :
1196 cbh.mCallbacks.onCaptureCompleted;
1197 sp<ACameraCaptureSession> session = cbh.mSession;
1198 if ((size_t) burstId >= cbh.mRequests.size()) {
1199 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1200 __FUNCTION__, burstId, cbh.mRequests.size());
1201 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1202 }
1203 sp<CaptureRequest> request = cbh.mRequests[burstId];
1204 sp<ACameraMetadata> result(new ACameraMetadata(
1205 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1206
1207 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1208 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1209 msg->setObject(kSessionSpKey, session);
1210 msg->setPointer(kCallbackFpKey, (void*) onResult);
1211 msg->setObject(kCaptureRequestKey, request);
1212 msg->setObject(kCaptureResultKey, result);
1213 msg->post();
1214 }
1215
1216 if (!isPartialResult) {
1217 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1218 dev->checkAndFireSequenceCompleteLocked();
1219 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001220
1221 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001222}
1223
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001224binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001225CameraDevice::ServiceCallback::onPrepared(int) {
1226 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001227 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001228}
1229
1230} // namespace android