blob: 45fa28ef9b370a92a67119e3640d525f18653bbd [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACameraDevice"
19
Yin-Chia Yehead91462016-01-06 16:45:08 -080020#include <vector>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080021#include <inttypes.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080022#include <android/hardware/ICameraService.h>
23#include <camera2/SubmitInfo.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080024#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080025#include "ACameraDevice.h"
26#include "ACameraMetadata.h"
27#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080028#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080029
30using namespace android;
31
32namespace android {
33// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080034const char* CameraDevice::kContextKey = "Context";
35const char* CameraDevice::kDeviceKey = "Device";
36const char* CameraDevice::kErrorCodeKey = "ErrorCode";
37const char* CameraDevice::kCallbackFpKey = "Callback";
38const char* CameraDevice::kSessionSpKey = "SessionSp";
39const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
40const char* CameraDevice::kTimeStampKey = "TimeStamp";
41const char* CameraDevice::kCaptureResultKey = "CaptureResult";
42const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
43const char* CameraDevice::kSequenceIdKey = "SequenceId";
44const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070045const char* CameraDevice::kAnwKey = "Anw";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080046
47/**
48 * CameraDevice Implementation
49 */
50CameraDevice::CameraDevice(
51 const char* id,
52 ACameraDevice_StateCallbacks* cb,
53 std::unique_ptr<ACameraMetadata> chars,
54 ACameraDevice* wrapper) :
55 mCameraId(id),
56 mAppCallbacks(*cb),
57 mChars(std::move(chars)),
58 mServiceCallback(new ServiceCallback(this)),
59 mWrapper(wrapper),
60 mInError(false),
61 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070062 mIdle(true),
63 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 mClosing = false;
65 // Setup looper thread to perfrom device callbacks to app
66 mCbLooper = new ALooper;
67 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080068 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080069 /*runOnCallingThread*/false,
70 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080071 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080072 if (err != OK) {
73 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
74 __FUNCTION__, strerror(-err), err);
75 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
76 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080077 mHandler = new CallbackHandler();
78 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080079
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080080 const CameraMetadata& metadata = mChars->getInternalData();
81 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080082 if (entry.count != 1) {
83 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
84 mPartialResultCount = 1;
85 } else {
86 mPartialResultCount = entry.data.i32[0];
87 }
88
89 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
90 if (entry.count != 2) {
91 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
92 mShadingMapSize[0] = 0;
93 mShadingMapSize[1] = 0;
94 } else {
95 mShadingMapSize[0] = entry.data.i32[0];
96 mShadingMapSize[1] = entry.data.i32[1];
97 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080098}
99
Yin-Chia Yehead91462016-01-06 16:45:08 -0800100// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800101CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700102 sp<ACameraCaptureSession> session = mCurrentSession.promote();
103 {
104 Mutex::Autolock _l(mDeviceLock);
105 if (!isClosed()) {
106 disconnectLocked(session);
107 }
108 mCurrentSession = nullptr;
109 if (mCbLooper != nullptr) {
110 mCbLooper->unregisterHandler(mHandler->id());
111 mCbLooper->stop();
112 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800113 }
114 mCbLooper.clear();
115 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116}
117
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700118void
119CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
120 msg->post();
121 msg.clear();
122 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
123 cleanupMsg->post();
124}
125
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126// TODO: cached created request?
127camera_status_t
128CameraDevice::createCaptureRequest(
129 ACameraDevice_request_template templateId,
130 ACaptureRequest** request) const {
131 Mutex::Autolock _l(mDeviceLock);
132 camera_status_t ret = checkCameraClosedOrErrorLocked();
133 if (ret != ACAMERA_OK) {
134 return ret;
135 }
136 if (mRemote == nullptr) {
137 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
138 }
139 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800140 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
141 if (remoteRet.serviceSpecificErrorCode() ==
142 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800143 ALOGW("Create capture request failed! template %d is not supported on this device",
144 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700145 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800146 } else if (!remoteRet.isOk()) {
147 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800148 return ACAMERA_ERROR_UNKNOWN;
149 }
150 ACaptureRequest* outReq = new ACaptureRequest();
151 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
152 outReq->targets = new ACameraOutputTargets();
153 *request = outReq;
154 return ACAMERA_OK;
155}
156
Yin-Chia Yehead91462016-01-06 16:45:08 -0800157camera_status_t
158CameraDevice::createCaptureSession(
159 const ACaptureSessionOutputContainer* outputs,
160 const ACameraCaptureSession_stateCallbacks* callbacks,
161 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700162 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800163 Mutex::Autolock _l(mDeviceLock);
164 camera_status_t ret = checkCameraClosedOrErrorLocked();
165 if (ret != ACAMERA_OK) {
166 return ret;
167 }
168
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700169 if (currentSession != nullptr) {
170 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800171 stopRepeatingLocked();
172 }
173
174 // Create new session
175 ret = configureStreamsLocked(outputs);
176 if (ret != ACAMERA_OK) {
177 ALOGE("Fail to create new session. cannot configure streams");
178 return ret;
179 }
180
181 ACameraCaptureSession* newSession = new ACameraCaptureSession(
182 mNextSessionId++, outputs, callbacks, this);
183
Yin-Chia Yehead91462016-01-06 16:45:08 -0800184 // set new session as current session
185 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
186 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700187 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800188 *session = newSession;
189 return ACAMERA_OK;
190}
191
192camera_status_t
193CameraDevice::captureLocked(
194 sp<ACameraCaptureSession> session,
195 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
196 int numRequests, ACaptureRequest** requests,
197 /*optional*/int* captureSequenceId) {
198 return submitRequestsLocked(
199 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
200}
201
202camera_status_t
203CameraDevice::setRepeatingRequestsLocked(
204 sp<ACameraCaptureSession> session,
205 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
206 int numRequests, ACaptureRequest** requests,
207 /*optional*/int* captureSequenceId) {
208 return submitRequestsLocked(
209 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
210}
211
212camera_status_t
213CameraDevice::submitRequestsLocked(
214 sp<ACameraCaptureSession> session,
215 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
216 int numRequests, ACaptureRequest** requests,
217 /*optional*/int* captureSequenceId,
218 bool isRepeating) {
219 camera_status_t ret = checkCameraClosedOrErrorLocked();
220 if (ret != ACAMERA_OK) {
221 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
222 return ret;
223 }
224
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800225 // Form two vectors of capture request, one for internal tracking
226 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800227 Vector<sp<CaptureRequest> > requestsV;
228 requestsV.setCapacity(numRequests);
229 for (int i = 0; i < numRequests; i++) {
230 sp<CaptureRequest> req;
231 ret = allocateCaptureRequest(requests[i], req);
232 if (ret != ACAMERA_OK) {
233 ALOGE("Convert capture request to internal format failure! ret %d", ret);
234 return ret;
235 }
236 if (req->mSurfaceList.empty()) {
237 ALOGE("Capture request without output target cannot be submitted!");
238 return ACAMERA_ERROR_INVALID_PARAMETER;
239 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800240 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800241 requestsV.push_back(req);
242 }
243
244 if (isRepeating) {
245 ret = stopRepeatingLocked();
246 if (ret != ACAMERA_OK) {
247 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
248 return ret;
249 }
250 }
251
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800252 binder::Status remoteRet;
253 hardware::camera2::utils::SubmitInfo info;
254 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
255 int sequenceId = info.mRequestId;
256 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800257 if (sequenceId < 0) {
258 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
259 return ACAMERA_ERROR_UNKNOWN;
260 }
261
262 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
263 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
264
265 if (isRepeating) {
266 // stopRepeating above should have cleanup repeating sequence id
267 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
268 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
269 return ACAMERA_ERROR_CAMERA_DEVICE;
270 }
271 mRepeatingSequenceId = sequenceId;
272 } else {
273 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
274 }
275
276 if (mIdle) {
277 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
278 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
279 msg->setObject(kSessionSpKey, session);
280 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700281 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800282 }
283 mIdle = false;
284 mBusySession = session;
285
286 if (captureSequenceId) {
287 *captureSequenceId = sequenceId;
288 }
289 return ACAMERA_OK;
290}
291
Emilian Peev40ead602017-09-26 15:46:36 +0100292camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *output) {
293 camera_status_t ret = checkCameraClosedOrErrorLocked();
294 if (ret != ACAMERA_OK) {
295 return ret;
296 }
297
298 if (output == nullptr) {
299 return ACAMERA_ERROR_INVALID_PARAMETER;
300 }
301
302 if (!output->mIsShared) {
303 ALOGE("Error output configuration is not shared");
304 return ACAMERA_ERROR_INVALID_OPERATION;
305 }
306
307 int32_t streamId = -1;
308 for (auto& kvPair : mConfiguredOutputs) {
309 if (kvPair.second.first == output->mWindow) {
310 streamId = kvPair.first;
311 break;
312 }
313 }
314 if (streamId < 0) {
315 ALOGE("Error: Invalid output configuration");
316 return ACAMERA_ERROR_INVALID_PARAMETER;
317 }
318
319 sp<IGraphicBufferProducer> iGBP(nullptr);
320 ret = getIGBPfromAnw(output->mWindow, iGBP);
321 if (ret != ACAMERA_OK) {
322 ALOGE("Camera device %s failed to extract graphic producer from native window",
323 getId());
324 return ret;
325 }
326
327 OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
328 true);
329
330 for (auto& anw : output->mSharedWindows) {
331 ret = getIGBPfromAnw(anw, iGBP);
332 if (ret != ACAMERA_OK) {
333 ALOGE("Camera device %s failed to extract graphic producer from native window",
334 getId());
335 return ret;
336 }
337 outConfig.addGraphicProducer(iGBP);
338 }
339
340 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
341 if (!remoteRet.isOk()) {
342 switch (remoteRet.serviceSpecificErrorCode()) {
343 case hardware::ICameraService::ERROR_INVALID_OPERATION:
344 ALOGE("Camera device %s invalid operation: %s", getId(),
345 remoteRet.toString8().string());
346 return ACAMERA_ERROR_INVALID_OPERATION;
347 break;
348 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
349 ALOGE("Camera device %s output surface already exists: %s", getId(),
350 remoteRet.toString8().string());
351 return ACAMERA_ERROR_INVALID_PARAMETER;
352 break;
353 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
354 ALOGE("Camera device %s invalid input argument: %s", getId(),
355 remoteRet.toString8().string());
356 return ACAMERA_ERROR_INVALID_PARAMETER;
357 break;
358 default:
359 ALOGE("Camera device %s failed to add shared output: %s", getId(),
360 remoteRet.toString8().string());
361 return ACAMERA_ERROR_UNKNOWN;
362 }
363 }
364
365 return ACAMERA_OK;
366}
367
Yin-Chia Yehead91462016-01-06 16:45:08 -0800368camera_status_t
369CameraDevice::allocateCaptureRequest(
370 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
371 camera_status_t ret;
372 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800373 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800374 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700375 req->mContext = request->context;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800376
377 for (auto outputTarget : request->targets->mOutputs) {
378 ANativeWindow* anw = outputTarget.mWindow;
379 sp<Surface> surface;
380 ret = getSurfaceFromANativeWindow(anw, surface);
381 if (ret != ACAMERA_OK) {
382 ALOGE("Bad output target in capture request! ret %d", ret);
383 return ret;
384 }
385 req->mSurfaceList.push_back(surface);
386 }
387 outReq = req;
388 return ACAMERA_OK;
389}
390
391ACaptureRequest*
392CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
393 ACaptureRequest* pRequest = new ACaptureRequest();
394 CameraMetadata clone = req->mMetadata;
395 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
396 pRequest->targets = new ACameraOutputTargets();
397 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
398 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
399 ACameraOutputTarget outputTarget(anw);
400 pRequest->targets->mOutputs.insert(outputTarget);
401 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700402 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800403 return pRequest;
404}
405
406void
407CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
408 if (req == nullptr) {
409 return;
410 }
411 delete req->settings;
412 delete req->targets;
413 delete req;
414}
415
416void
417CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
418 if (isClosed()) {
419 // Device is closing already. do nothing
420 return;
421 }
422
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700423 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800424 // Session has been replaced by other seesion or device is closed
425 return;
426 }
427 mCurrentSession = nullptr;
428
429 // Should not happen
430 if (!session->mIsClosed) {
431 ALOGE("Error: unclosed session %p reaches end of life!", session);
432 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
433 return;
434 }
435
436 // No new session, unconfigure now
437 camera_status_t ret = configureStreamsLocked(nullptr);
438 if (ret != ACAMERA_OK) {
439 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
440 }
441}
442
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800443void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700444CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800445 if (mClosing.exchange(true)) {
446 // Already closing, just return
447 ALOGW("Camera device %s is already closing.", getId());
448 return;
449 }
450
451 if (mRemote != nullptr) {
452 mRemote->disconnect();
453 }
454 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800455
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700456 if (session != nullptr) {
457 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800458 }
459}
460
461camera_status_t
462CameraDevice::stopRepeatingLocked() {
463 camera_status_t ret = checkCameraClosedOrErrorLocked();
464 if (ret != ACAMERA_OK) {
465 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
466 return ret;
467 }
468 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
469 int repeatingSequenceId = mRepeatingSequenceId;
470 mRepeatingSequenceId = REQUEST_ID_NONE;
471
472 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800473 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700474 if (remoteRet.serviceSpecificErrorCode() ==
475 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
476 ALOGV("Repeating request is already stopped.");
477 return ACAMERA_OK;
478 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800479 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800480 return ACAMERA_ERROR_UNKNOWN;
481 }
482 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
483 }
484 return ACAMERA_OK;
485}
486
487camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700488CameraDevice::flushLocked(ACameraCaptureSession* session) {
489 camera_status_t ret = checkCameraClosedOrErrorLocked();
490 if (ret != ACAMERA_OK) {
491 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
492 return ret;
493 }
494
495 // This should never happen because creating a new session will close
496 // previous one and thus reject any API call from previous session.
497 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700498 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700499 ALOGE("Camera %s session %p is not current active session!", getId(), session);
500 return ACAMERA_ERROR_INVALID_OPERATION;
501 }
502
503 if (mFlushing) {
504 ALOGW("Camera %s is already aborting captures", getId());
505 return ACAMERA_OK;
506 }
507
508 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700509
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700510 // Send onActive callback to guarantee there is always active->ready transition
511 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
512 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
513 msg->setObject(kSessionSpKey, session);
514 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700515 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700516
517 // If device is already idling, send callback and exit early
518 if (mIdle) {
519 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
520 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
521 msg->setObject(kSessionSpKey, session);
522 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700523 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700524 mFlushing = false;
525 return ACAMERA_OK;
526 }
527
528 int64_t lastFrameNumber;
529 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
530 if (!remoteRet.isOk()) {
531 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
532 return ACAMERA_ERROR_UNKNOWN;
533 }
534 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
535 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
536 }
537 return ACAMERA_OK;
538}
539
540camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800541CameraDevice::waitUntilIdleLocked() {
542 camera_status_t ret = checkCameraClosedOrErrorLocked();
543 if (ret != ACAMERA_OK) {
544 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
545 return ret;
546 }
547
548 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
549 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
550 return ACAMERA_ERROR_INVALID_OPERATION;
551 }
552
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800553 binder::Status remoteRet = mRemote->waitUntilIdle();
554 if (!remoteRet.isOk()) {
555 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800556 // TODO: define a function to convert status_t -> camera_status_t
557 return ACAMERA_ERROR_UNKNOWN;
558 }
559
560 return ACAMERA_OK;
561}
562
563camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700564CameraDevice::getIGBPfromAnw(
565 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800566 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800567 if (anw == nullptr) {
568 ALOGE("Error: output ANativeWindow is null");
569 return ACAMERA_ERROR_INVALID_PARAMETER;
570 }
571 int value;
572 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800573 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800574 ALOGE("Error: ANativeWindow is not backed by Surface!");
575 return ACAMERA_ERROR_INVALID_PARAMETER;
576 }
577 const sp<Surface> surface(static_cast<Surface*>(anw));
578 out = surface->getIGraphicBufferProducer();
579 return ACAMERA_OK;
580}
581
582camera_status_t
583CameraDevice::getSurfaceFromANativeWindow(
584 ANativeWindow* anw, sp<Surface>& out) {
585 if (anw == nullptr) {
586 ALOGE("Error: output ANativeWindow is null");
587 return ACAMERA_ERROR_INVALID_PARAMETER;
588 }
589 int value;
590 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800591 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800592 ALOGE("Error: ANativeWindow is not backed by Surface!");
593 return ACAMERA_ERROR_INVALID_PARAMETER;
594 }
595 sp<Surface> surface(static_cast<Surface*>(anw));
596 out = surface;
597 return ACAMERA_OK;
598}
599
600camera_status_t
601CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
602 ACaptureSessionOutputContainer emptyOutput;
603 if (outputs == nullptr) {
604 outputs = &emptyOutput;
605 }
606
Yin-Chia Yehead91462016-01-06 16:45:08 -0800607 camera_status_t ret = checkCameraClosedOrErrorLocked();
608 if (ret != ACAMERA_OK) {
609 return ret;
610 }
611
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700612 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800613 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700614 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800615 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700616 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800617 if (ret != ACAMERA_OK) {
618 return ret;
619 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700620 outputSet.insert(std::make_pair(
Emilian Peev40ead602017-09-26 15:46:36 +0100621 anw, OutputConfiguration(iGBP, outConfig.mRotation,
622 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800623 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700624 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800625 std::vector<int> deleteList;
626
627 // Determine which streams need to be created, which to be deleted
628 for (auto& kvPair : mConfiguredOutputs) {
629 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700630 auto& outputPair = kvPair.second;
631 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800632 deleteList.push_back(streamId); // Need to delete a no longer needed stream
633 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700634 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800635 }
636 }
637
638 ret = stopRepeatingLocked();
639 if (ret != ACAMERA_OK) {
640 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
641 return ret;
642 }
643
644 ret = waitUntilIdleLocked();
645 if (ret != ACAMERA_OK) {
646 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
647 return ret;
648 }
649
650 // Send onReady to previous session
651 // CurrentSession will be updated after configureStreamLocked, so here
652 // mCurrentSession is the session to be replaced by a new session
653 if (!mIdle && mCurrentSession != nullptr) {
654 if (mBusySession != mCurrentSession) {
655 ALOGE("Current session != busy session");
656 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
657 return ACAMERA_ERROR_CAMERA_DEVICE;
658 }
659 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
660 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
661 msg->setObject(kSessionSpKey, mBusySession);
662 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
663 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700664 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800665 }
666 mIdle = true;
667
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800668 binder::Status remoteRet = mRemote->beginConfigure();
669 if (!remoteRet.isOk()) {
670 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800671 return ACAMERA_ERROR_UNKNOWN;
672 }
673
674 // delete to-be-deleted streams
675 for (auto streamId : deleteList) {
676 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800677 if (!remoteRet.isOk()) {
678 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
679 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800680 return ACAMERA_ERROR_UNKNOWN;
681 }
682 mConfiguredOutputs.erase(streamId);
683 }
684
685 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700686 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800687 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700688 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800689 if (!remoteRet.isOk()) {
690 ALOGE("Camera device %s failed to create stream: %s", getId(),
691 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800692 return ACAMERA_ERROR_UNKNOWN;
693 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700694 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800695 }
696
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800697 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
698 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
699 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
700 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800701 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800702 } else if (!remoteRet.isOk()) {
703 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800704 return ACAMERA_ERROR_UNKNOWN;
705 }
706
707 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800708}
709
710void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800711CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800712 Mutex::Autolock _l(mDeviceLock);
713 mRemote = remote;
714}
715
716camera_status_t
717CameraDevice::checkCameraClosedOrErrorLocked() const {
718 if (mRemote == nullptr) {
719 ALOGE("%s: camera device already closed", __FUNCTION__);
720 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
721 }
722 if (mInError) {// triggered by onDeviceError
723 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
724 return mError;
725 }
726 return ACAMERA_OK;
727}
728
729void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800730CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
731 mInError = true;
732 mError = error;
733 return;
734}
735
736void
737CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
738 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
739 if (isError) {
740 mFutureErrorSet.insert(frameNumber);
741 } else if (frameNumber <= mCompletedFrameNumber) {
742 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
743 frameNumber, mCompletedFrameNumber);
744 return;
745 } else {
746 if (frameNumber != mCompletedFrameNumber + 1) {
747 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
748 mCompletedFrameNumber + 1, frameNumber);
749 // Do not assert as in java implementation
750 }
751 mCompletedFrameNumber = frameNumber;
752 }
753 update();
754}
755
756void
757CameraDevice::FrameNumberTracker::update() {
758 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
759 int64_t errorFrameNumber = *it;
760 if (errorFrameNumber == mCompletedFrameNumber + 1) {
761 mCompletedFrameNumber++;
762 it = mFutureErrorSet.erase(it);
763 } else if (errorFrameNumber <= mCompletedFrameNumber) {
764 // This should not happen, but deal with it anyway
765 ALOGE("Completd frame number passed through current frame number!");
766 // erase the old error since it's no longer useful
767 it = mFutureErrorSet.erase(it);
768 } else {
769 // Normal requests hasn't catched up error frames, just break
770 break;
771 }
772 }
773 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
774}
775
776void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800777CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800778 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800779 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800780 int sequenceId = resultExtras.requestId;
781 int64_t frameNumber = resultExtras.frameNumber;
782 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700783 auto it = mSequenceCallbackMap.find(sequenceId);
784 if (it == mSequenceCallbackMap.end()) {
785 ALOGE("%s: Error: capture sequence index %d not found!",
786 __FUNCTION__, sequenceId);
787 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800788 return;
789 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700790
791 CallbackHolder cbh = (*it).second;
792 sp<ACameraCaptureSession> session = cbh.mSession;
793 if ((size_t) burstId >= cbh.mRequests.size()) {
794 ALOGE("%s: Error: request index %d out of bound (size %zu)",
795 __FUNCTION__, burstId, cbh.mRequests.size());
796 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
797 return;
798 }
799 sp<CaptureRequest> request = cbh.mRequests[burstId];
800
801 // Handle buffer error
802 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
803 int32_t streamId = resultExtras.errorStreamId;
804 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
805 cbh.mCallbacks.onCaptureBufferLost;
806 auto outputPairIt = mConfiguredOutputs.find(streamId);
807 if (outputPairIt == mConfiguredOutputs.end()) {
808 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800809 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
810 return;
811 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700812 ANativeWindow* anw = outputPairIt->second.first;
813
814 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
815 getId(), anw, frameNumber);
816
817 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
818 msg->setPointer(kContextKey, cbh.mCallbacks.context);
819 msg->setObject(kSessionSpKey, session);
820 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
821 msg->setObject(kCaptureRequestKey, request);
822 msg->setPointer(kAnwKey, (void*) anw);
823 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700824 postSessionMsgAndCleanup(msg);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700825 } else { // Handle other capture failures
826 // Fire capture failure callback if there is one registered
827 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800828 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
829 failure->frameNumber = frameNumber;
830 // TODO: refine this when implementing flush
831 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
832 failure->sequenceId = sequenceId;
833 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800834 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800835
836 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
837 msg->setPointer(kContextKey, cbh.mCallbacks.context);
838 msg->setObject(kSessionSpKey, session);
839 msg->setPointer(kCallbackFpKey, (void*) onError);
840 msg->setObject(kCaptureRequestKey, request);
841 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700842 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800843
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700844 // Update tracker
845 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
846 checkAndFireSequenceCompleteLocked();
847 }
848 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800849}
850
851void CameraDevice::CallbackHandler::onMessageReceived(
852 const sp<AMessage> &msg) {
853 switch (msg->what()) {
854 case kWhatOnDisconnected:
855 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800856 case kWhatSessionStateCb:
857 case kWhatCaptureStart:
858 case kWhatCaptureResult:
859 case kWhatCaptureFail:
860 case kWhatCaptureSeqEnd:
861 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700862 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800864 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700865 case kWhatCleanUpSessions:
866 mCachedSessions.clear();
867 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800868 default:
869 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
870 return;
871 }
872 // Check the common part of all message
873 void* context;
874 bool found = msg->findPointer(kContextKey, &context);
875 if (!found) {
876 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
877 return;
878 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800879 switch (msg->what()) {
880 case kWhatOnDisconnected:
881 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800882 ACameraDevice* dev;
883 found = msg->findPointer(kDeviceKey, (void**) &dev);
884 if (!found || dev == nullptr) {
885 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
886 return;
887 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800888 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800889 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800890 if (!found) {
891 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
892 return;
893 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800894 if (onDisconnected == nullptr) {
895 return;
896 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800897 (*onDisconnected)(context, dev);
898 break;
899 }
900 case kWhatOnError:
901 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800902 ACameraDevice* dev;
903 found = msg->findPointer(kDeviceKey, (void**) &dev);
904 if (!found || dev == nullptr) {
905 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
906 return;
907 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800908 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800909 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800910 if (!found) {
911 ALOGE("%s: Cannot find onError!", __FUNCTION__);
912 return;
913 }
914 int errorCode;
915 found = msg->findInt32(kErrorCodeKey, &errorCode);
916 if (!found) {
917 ALOGE("%s: Cannot find error code!", __FUNCTION__);
918 return;
919 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800920 if (onError == nullptr) {
921 return;
922 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800923 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800924 break;
925 }
926 case kWhatSessionStateCb:
927 case kWhatCaptureStart:
928 case kWhatCaptureResult:
929 case kWhatCaptureFail:
930 case kWhatCaptureSeqEnd:
931 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700932 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800933 {
934 sp<RefBase> obj;
935 found = msg->findObject(kSessionSpKey, &obj);
936 if (!found || obj == nullptr) {
937 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
938 return;
939 }
940 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700941 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800942 sp<CaptureRequest> requestSp = nullptr;
943 switch (msg->what()) {
944 case kWhatCaptureStart:
945 case kWhatCaptureResult:
946 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700947 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800948 found = msg->findObject(kCaptureRequestKey, &obj);
949 if (!found) {
950 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
951 return;
952 }
953 requestSp = static_cast<CaptureRequest*>(obj.get());
954 break;
955 }
956
957 switch (msg->what()) {
958 case kWhatSessionStateCb:
959 {
960 ACameraCaptureSession_stateCallback onState;
961 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
962 if (!found) {
963 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
964 return;
965 }
966 if (onState == nullptr) {
967 return;
968 }
969 (*onState)(context, session.get());
970 break;
971 }
972 case kWhatCaptureStart:
973 {
974 ACameraCaptureSession_captureCallback_start onStart;
975 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
976 if (!found) {
977 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
978 return;
979 }
980 if (onStart == nullptr) {
981 return;
982 }
983 int64_t timestamp;
984 found = msg->findInt64(kTimeStampKey, &timestamp);
985 if (!found) {
986 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
987 return;
988 }
989 ACaptureRequest* request = allocateACaptureRequest(requestSp);
990 (*onStart)(context, session.get(), request, timestamp);
991 freeACaptureRequest(request);
992 break;
993 }
994 case kWhatCaptureResult:
995 {
996 ACameraCaptureSession_captureCallback_result onResult;
997 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
998 if (!found) {
999 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1000 return;
1001 }
1002 if (onResult == nullptr) {
1003 return;
1004 }
1005
1006 found = msg->findObject(kCaptureResultKey, &obj);
1007 if (!found) {
1008 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1009 return;
1010 }
1011 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1012 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1013 (*onResult)(context, session.get(), request, result.get());
1014 freeACaptureRequest(request);
1015 break;
1016 }
1017 case kWhatCaptureFail:
1018 {
1019 ACameraCaptureSession_captureCallback_failed onFail;
1020 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1021 if (!found) {
1022 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1023 return;
1024 }
1025 if (onFail == nullptr) {
1026 return;
1027 }
1028
1029 found = msg->findObject(kCaptureFailureKey, &obj);
1030 if (!found) {
1031 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1032 return;
1033 }
1034 sp<CameraCaptureFailure> failureSp(
1035 static_cast<CameraCaptureFailure*>(obj.get()));
1036 ACameraCaptureFailure* failure =
1037 static_cast<ACameraCaptureFailure*>(failureSp.get());
1038 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1039 (*onFail)(context, session.get(), request, failure);
1040 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001041 break;
1042 }
1043 case kWhatCaptureSeqEnd:
1044 {
1045 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1046 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1047 if (!found) {
1048 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1049 return;
1050 }
1051 if (onSeqEnd == nullptr) {
1052 return;
1053 }
1054 int seqId;
1055 found = msg->findInt32(kSequenceIdKey, &seqId);
1056 if (!found) {
1057 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1058 return;
1059 }
1060 int64_t frameNumber;
1061 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1062 if (!found) {
1063 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1064 return;
1065 }
1066 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1067 break;
1068 }
1069 case kWhatCaptureSeqAbort:
1070 {
1071 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1072 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1073 if (!found) {
1074 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1075 return;
1076 }
1077 if (onSeqAbort == nullptr) {
1078 return;
1079 }
1080 int seqId;
1081 found = msg->findInt32(kSequenceIdKey, &seqId);
1082 if (!found) {
1083 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1084 return;
1085 }
1086 (*onSeqAbort)(context, session.get(), seqId);
1087 break;
1088 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001089 case kWhatCaptureBufferLost:
1090 {
1091 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1092 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1093 if (!found) {
1094 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1095 return;
1096 }
1097 if (onBufferLost == nullptr) {
1098 return;
1099 }
1100
1101 ANativeWindow* anw;
1102 found = msg->findPointer(kAnwKey, (void**) &anw);
1103 if (!found) {
1104 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1105 return;
1106 }
1107
1108 int64_t frameNumber;
1109 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1110 if (!found) {
1111 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1112 return;
1113 }
1114
1115 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1116 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1117 freeACaptureRequest(request);
1118 break;
1119 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001120 }
1121 break;
1122 }
1123 }
1124}
1125
1126CameraDevice::CallbackHolder::CallbackHolder(
1127 sp<ACameraCaptureSession> session,
1128 const Vector<sp<CaptureRequest> >& requests,
1129 bool isRepeating,
1130 ACameraCaptureSession_captureCallbacks* cbs) :
1131 mSession(session), mRequests(requests),
1132 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1133
1134void
1135CameraDevice::checkRepeatingSequenceCompleteLocked(
1136 const int sequenceId, const int64_t lastFrameNumber) {
1137 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1138 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1139 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1140 ALOGW("No callback found for sequenceId %d", sequenceId);
1141 return;
1142 }
1143 // remove callback holder from callback map
1144 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1145 CallbackHolder cbh = cbIt->second;
1146 mSequenceCallbackMap.erase(cbIt);
1147 // send seq aborted callback
1148 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1149 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1150 msg->setObject(kSessionSpKey, cbh.mSession);
1151 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1152 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001153 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001154 } else {
1155 // Use mSequenceLastFrameNumberMap to track
1156 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1157
1158 // Last frame might have arrived. Check now
1159 checkAndFireSequenceCompleteLocked();
1160 }
1161}
1162
1163void
1164CameraDevice::checkAndFireSequenceCompleteLocked() {
1165 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1166 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1167 auto it = mSequenceLastFrameNumberMap.begin();
1168 while (it != mSequenceLastFrameNumberMap.end()) {
1169 int sequenceId = it->first;
1170 int64_t lastFrameNumber = it->second;
1171 bool seqCompleted = false;
1172 bool hasCallback = true;
1173
1174 if (mRemote == nullptr) {
1175 ALOGW("Camera %s closed while checking sequence complete", getId());
1176 return;
1177 }
1178
1179 // Check if there is callback for this sequence
1180 // This should not happen because we always register callback (with nullptr inside)
1181 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1182 ALOGW("No callback found for sequenceId %d", sequenceId);
1183 hasCallback = false;
1184 }
1185
1186 if (lastFrameNumber <= completedFrameNumber) {
1187 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1188 sequenceId, lastFrameNumber, completedFrameNumber);
1189 seqCompleted = true;
1190 }
1191
1192 if (seqCompleted && hasCallback) {
1193 // remove callback holder from callback map
1194 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1195 CallbackHolder cbh = cbIt->second;
1196 mSequenceCallbackMap.erase(cbIt);
1197 // send seq complete callback
1198 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1199 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1200 msg->setObject(kSessionSpKey, cbh.mSession);
1201 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1202 msg->setInt32(kSequenceIdKey, sequenceId);
1203 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1204
1205 // Clear the session sp before we send out the message
1206 // This will guarantee the rare case where the message is processed
1207 // before cbh goes out of scope and causing we call the session
1208 // destructor while holding device lock
1209 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001210 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001211 }
1212
1213 // No need to track sequence complete if there is no callback registered
1214 if (seqCompleted || !hasCallback) {
1215 it = mSequenceLastFrameNumberMap.erase(it);
1216 } else {
1217 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001218 }
1219 }
1220}
1221
1222/**
1223 * Camera service callback implementation
1224 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001225binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001226CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001227 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001228 const CaptureResultExtras& resultExtras) {
1229 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1230 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001231 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001232 sp<CameraDevice> dev = mDevice.promote();
1233 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001234 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001235 }
1236
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001237 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001238 Mutex::Autolock _l(dev->mDeviceLock);
1239 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001240 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001241 }
1242 switch (errorCode) {
1243 case ERROR_CAMERA_DISCONNECTED:
1244 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001245 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001246 if (session != nullptr) {
1247 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001248 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001249 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001250 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1251 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1252 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001253 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001254 msg->post();
1255 break;
1256 }
1257 default:
1258 ALOGE("Unknown error from camera device: %d", errorCode);
1259 // no break
1260 case ERROR_CAMERA_DEVICE:
1261 case ERROR_CAMERA_SERVICE:
1262 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001263 switch (errorCode) {
1264 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001265 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001266 break;
1267 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001268 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001269 break;
1270 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001271 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001272 break;
1273 }
1274 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1275 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1276 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001277 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001278 msg->setInt32(kErrorCodeKey, errorCode);
1279 msg->post();
1280 break;
1281 }
1282 case ERROR_CAMERA_REQUEST:
1283 case ERROR_CAMERA_RESULT:
1284 case ERROR_CAMERA_BUFFER:
1285 dev->onCaptureErrorLocked(errorCode, resultExtras);
1286 break;
1287 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001288 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001289}
1290
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001291binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001292CameraDevice::ServiceCallback::onDeviceIdle() {
1293 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001294 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001295 sp<CameraDevice> dev = mDevice.promote();
1296 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001297 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001298 }
1299
1300 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001301 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001302 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001303 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001304
1305 if (dev->mIdle) {
1306 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001307 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001308 }
1309
1310 if (dev->mCurrentSession != nullptr) {
1311 ALOGE("onDeviceIdle sending state cb");
1312 if (dev->mBusySession != dev->mCurrentSession) {
1313 ALOGE("Current session != busy session");
1314 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001315 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001316 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001317
Yin-Chia Yehead91462016-01-06 16:45:08 -08001318 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1319 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1320 msg->setObject(kSessionSpKey, dev->mBusySession);
1321 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1322 // Make sure we clear the sp first so the session destructor can
1323 // only happen on handler thread (where we don't hold device/session lock)
1324 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001325 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001326 }
1327 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001328 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001329 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001330}
1331
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001332binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001333CameraDevice::ServiceCallback::onCaptureStarted(
1334 const CaptureResultExtras& resultExtras,
1335 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001336 binder::Status ret = binder::Status::ok();
1337
Yin-Chia Yehead91462016-01-06 16:45:08 -08001338 sp<CameraDevice> dev = mDevice.promote();
1339 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001340 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001341 }
1342 Mutex::Autolock _l(dev->mDeviceLock);
1343 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001344 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001345 }
1346
1347 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001348 int32_t burstId = resultExtras.burstId;
1349
1350 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1351 if (it != dev->mSequenceCallbackMap.end()) {
1352 CallbackHolder cbh = (*it).second;
1353 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1354 sp<ACameraCaptureSession> session = cbh.mSession;
1355 if ((size_t) burstId >= cbh.mRequests.size()) {
1356 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1357 __FUNCTION__, burstId, cbh.mRequests.size());
1358 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1359 }
1360 sp<CaptureRequest> request = cbh.mRequests[burstId];
1361 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1362 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1363 msg->setObject(kSessionSpKey, session);
1364 msg->setPointer(kCallbackFpKey, (void*) onStart);
1365 msg->setObject(kCaptureRequestKey, request);
1366 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001367 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001368 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001369 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001370}
1371
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001372binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001373CameraDevice::ServiceCallback::onResultReceived(
1374 const CameraMetadata& metadata,
1375 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001376 binder::Status ret = binder::Status::ok();
1377
Yin-Chia Yehead91462016-01-06 16:45:08 -08001378 sp<CameraDevice> dev = mDevice.promote();
1379 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001380 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001381 }
1382 int sequenceId = resultExtras.requestId;
1383 int64_t frameNumber = resultExtras.frameNumber;
1384 int32_t burstId = resultExtras.burstId;
1385 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1386
1387 if (!isPartialResult) {
1388 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1389 }
1390
1391 Mutex::Autolock _l(dev->mDeviceLock);
1392 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001393 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001394 }
1395
1396 if (dev->isClosed()) {
1397 if (!isPartialResult) {
1398 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1399 }
1400 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001401 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001402 }
1403
1404 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001405 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001406 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001407
1408 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1409 if (it != dev->mSequenceCallbackMap.end()) {
1410 CallbackHolder cbh = (*it).second;
1411 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1412 cbh.mCallbacks.onCaptureProgressed :
1413 cbh.mCallbacks.onCaptureCompleted;
1414 sp<ACameraCaptureSession> session = cbh.mSession;
1415 if ((size_t) burstId >= cbh.mRequests.size()) {
1416 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1417 __FUNCTION__, burstId, cbh.mRequests.size());
1418 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1419 }
1420 sp<CaptureRequest> request = cbh.mRequests[burstId];
1421 sp<ACameraMetadata> result(new ACameraMetadata(
1422 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1423
1424 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1425 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1426 msg->setObject(kSessionSpKey, session);
1427 msg->setPointer(kCallbackFpKey, (void*) onResult);
1428 msg->setObject(kCaptureRequestKey, request);
1429 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001430 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001431 }
1432
1433 if (!isPartialResult) {
1434 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1435 dev->checkAndFireSequenceCompleteLocked();
1436 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001437
1438 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001439}
1440
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001441binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001442CameraDevice::ServiceCallback::onPrepared(int) {
1443 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001444 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001445}
1446
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001447binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001448CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1449 // onRequestQueueEmpty not yet implemented in NDK
1450 return binder::Status::ok();
1451}
1452
1453binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001454CameraDevice::ServiceCallback::onRepeatingRequestError(
1455 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001456 binder::Status ret = binder::Status::ok();
1457
1458 sp<CameraDevice> dev = mDevice.promote();
1459 if (dev == nullptr) {
1460 return ret; // device has been closed
1461 }
1462
1463 Mutex::Autolock _l(dev->mDeviceLock);
1464
1465 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001466 if (stoppedSequenceId == repeatingSequenceId) {
1467 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1468 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001469
1470 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1471
1472 return ret;
1473}
1474
1475
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001476} // namespace android