blob: f7cea4f737a7e712cba76260d0b0d2a87848438f [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,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100160 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800161 const ACameraCaptureSession_stateCallbacks* callbacks,
162 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700163 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800164 Mutex::Autolock _l(mDeviceLock);
165 camera_status_t ret = checkCameraClosedOrErrorLocked();
166 if (ret != ACAMERA_OK) {
167 return ret;
168 }
169
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700170 if (currentSession != nullptr) {
171 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800172 stopRepeatingLocked();
173 }
174
175 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100176 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800177 if (ret != ACAMERA_OK) {
178 ALOGE("Fail to create new session. cannot configure streams");
179 return ret;
180 }
181
182 ACameraCaptureSession* newSession = new ACameraCaptureSession(
183 mNextSessionId++, outputs, callbacks, this);
184
Yin-Chia Yehead91462016-01-06 16:45:08 -0800185 // set new session as current session
186 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
187 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700188 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800189 *session = newSession;
190 return ACAMERA_OK;
191}
192
193camera_status_t
194CameraDevice::captureLocked(
195 sp<ACameraCaptureSession> session,
196 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
197 int numRequests, ACaptureRequest** requests,
198 /*optional*/int* captureSequenceId) {
199 return submitRequestsLocked(
200 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
201}
202
203camera_status_t
204CameraDevice::setRepeatingRequestsLocked(
205 sp<ACameraCaptureSession> session,
206 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
207 int numRequests, ACaptureRequest** requests,
208 /*optional*/int* captureSequenceId) {
209 return submitRequestsLocked(
210 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
211}
212
213camera_status_t
214CameraDevice::submitRequestsLocked(
215 sp<ACameraCaptureSession> session,
216 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
217 int numRequests, ACaptureRequest** requests,
218 /*optional*/int* captureSequenceId,
219 bool isRepeating) {
220 camera_status_t ret = checkCameraClosedOrErrorLocked();
221 if (ret != ACAMERA_OK) {
222 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
223 return ret;
224 }
225
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800226 // Form two vectors of capture request, one for internal tracking
227 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800228 Vector<sp<CaptureRequest> > requestsV;
229 requestsV.setCapacity(numRequests);
230 for (int i = 0; i < numRequests; i++) {
231 sp<CaptureRequest> req;
232 ret = allocateCaptureRequest(requests[i], req);
233 if (ret != ACAMERA_OK) {
234 ALOGE("Convert capture request to internal format failure! ret %d", ret);
235 return ret;
236 }
237 if (req->mSurfaceList.empty()) {
238 ALOGE("Capture request without output target cannot be submitted!");
239 return ACAMERA_ERROR_INVALID_PARAMETER;
240 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800241 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800242 requestsV.push_back(req);
243 }
244
245 if (isRepeating) {
246 ret = stopRepeatingLocked();
247 if (ret != ACAMERA_OK) {
248 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
249 return ret;
250 }
251 }
252
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800253 binder::Status remoteRet;
254 hardware::camera2::utils::SubmitInfo info;
255 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
256 int sequenceId = info.mRequestId;
257 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800258 if (sequenceId < 0) {
259 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
260 return ACAMERA_ERROR_UNKNOWN;
261 }
262
263 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
264 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
265
266 if (isRepeating) {
267 // stopRepeating above should have cleanup repeating sequence id
268 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
269 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
270 return ACAMERA_ERROR_CAMERA_DEVICE;
271 }
272 mRepeatingSequenceId = sequenceId;
273 } else {
274 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
275 }
276
277 if (mIdle) {
278 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
279 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
280 msg->setObject(kSessionSpKey, session);
281 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700282 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800283 }
284 mIdle = false;
285 mBusySession = session;
286
287 if (captureSequenceId) {
288 *captureSequenceId = sequenceId;
289 }
290 return ACAMERA_OK;
291}
292
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800293camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100294 camera_status_t ret = checkCameraClosedOrErrorLocked();
295 if (ret != ACAMERA_OK) {
296 return ret;
297 }
298
299 if (output == nullptr) {
300 return ACAMERA_ERROR_INVALID_PARAMETER;
301 }
302
303 if (!output->mIsShared) {
304 ALOGE("Error output configuration is not shared");
305 return ACAMERA_ERROR_INVALID_OPERATION;
306 }
307
308 int32_t streamId = -1;
309 for (auto& kvPair : mConfiguredOutputs) {
310 if (kvPair.second.first == output->mWindow) {
311 streamId = kvPair.first;
312 break;
313 }
314 }
315 if (streamId < 0) {
316 ALOGE("Error: Invalid output configuration");
317 return ACAMERA_ERROR_INVALID_PARAMETER;
318 }
319
320 sp<IGraphicBufferProducer> iGBP(nullptr);
321 ret = getIGBPfromAnw(output->mWindow, iGBP);
322 if (ret != ACAMERA_OK) {
323 ALOGE("Camera device %s failed to extract graphic producer from native window",
324 getId());
325 return ret;
326 }
327
328 OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
329 true);
330
331 for (auto& anw : output->mSharedWindows) {
332 ret = getIGBPfromAnw(anw, iGBP);
333 if (ret != ACAMERA_OK) {
334 ALOGE("Camera device %s failed to extract graphic producer from native window",
335 getId());
336 return ret;
337 }
338 outConfig.addGraphicProducer(iGBP);
339 }
340
341 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
342 if (!remoteRet.isOk()) {
343 switch (remoteRet.serviceSpecificErrorCode()) {
344 case hardware::ICameraService::ERROR_INVALID_OPERATION:
345 ALOGE("Camera device %s invalid operation: %s", getId(),
346 remoteRet.toString8().string());
347 return ACAMERA_ERROR_INVALID_OPERATION;
348 break;
349 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
350 ALOGE("Camera device %s output surface already exists: %s", getId(),
351 remoteRet.toString8().string());
352 return ACAMERA_ERROR_INVALID_PARAMETER;
353 break;
354 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
355 ALOGE("Camera device %s invalid input argument: %s", getId(),
356 remoteRet.toString8().string());
357 return ACAMERA_ERROR_INVALID_PARAMETER;
358 break;
359 default:
360 ALOGE("Camera device %s failed to add shared output: %s", getId(),
361 remoteRet.toString8().string());
362 return ACAMERA_ERROR_UNKNOWN;
363 }
364 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800365 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100366
367 return ACAMERA_OK;
368}
369
Yin-Chia Yehead91462016-01-06 16:45:08 -0800370camera_status_t
371CameraDevice::allocateCaptureRequest(
372 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
373 camera_status_t ret;
374 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800375 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800376 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700377 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800378 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800379
380 for (auto outputTarget : request->targets->mOutputs) {
381 ANativeWindow* anw = outputTarget.mWindow;
382 sp<Surface> surface;
383 ret = getSurfaceFromANativeWindow(anw, surface);
384 if (ret != ACAMERA_OK) {
385 ALOGE("Bad output target in capture request! ret %d", ret);
386 return ret;
387 }
388 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800389
390 bool found = false;
391 // lookup stream/surface ID
392 for (const auto& kvPair : mConfiguredOutputs) {
393 int streamId = kvPair.first;
394 const OutputConfiguration& outConfig = kvPair.second.second;
395 const auto& gbps = outConfig.getGraphicBufferProducers();
396 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
397 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
398 found = true;
399 req->mStreamIdxList.push_back(streamId);
400 req->mSurfaceIdxList.push_back(surfaceId);
401 break;
402 }
403 }
404 if (found) {
405 break;
406 }
407 }
408 if (!found) {
409 ALOGE("Unconfigured output target %p in capture request!", anw);
410 return ret;
411 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800412 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800413
Yin-Chia Yehead91462016-01-06 16:45:08 -0800414 outReq = req;
415 return ACAMERA_OK;
416}
417
418ACaptureRequest*
419CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
420 ACaptureRequest* pRequest = new ACaptureRequest();
421 CameraMetadata clone = req->mMetadata;
422 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
423 pRequest->targets = new ACameraOutputTargets();
424 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
425 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
426 ACameraOutputTarget outputTarget(anw);
427 pRequest->targets->mOutputs.insert(outputTarget);
428 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700429 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800430 return pRequest;
431}
432
433void
434CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
435 if (req == nullptr) {
436 return;
437 }
438 delete req->settings;
439 delete req->targets;
440 delete req;
441}
442
443void
444CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
445 if (isClosed()) {
446 // Device is closing already. do nothing
447 return;
448 }
449
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700450 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800451 // Session has been replaced by other seesion or device is closed
452 return;
453 }
454 mCurrentSession = nullptr;
455
456 // Should not happen
457 if (!session->mIsClosed) {
458 ALOGE("Error: unclosed session %p reaches end of life!", session);
459 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
460 return;
461 }
462
463 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100464 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800465 if (ret != ACAMERA_OK) {
466 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
467 }
468}
469
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700471CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800472 if (mClosing.exchange(true)) {
473 // Already closing, just return
474 ALOGW("Camera device %s is already closing.", getId());
475 return;
476 }
477
478 if (mRemote != nullptr) {
479 mRemote->disconnect();
480 }
481 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800482
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700483 if (session != nullptr) {
484 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800485 }
486}
487
488camera_status_t
489CameraDevice::stopRepeatingLocked() {
490 camera_status_t ret = checkCameraClosedOrErrorLocked();
491 if (ret != ACAMERA_OK) {
492 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
493 return ret;
494 }
495 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
496 int repeatingSequenceId = mRepeatingSequenceId;
497 mRepeatingSequenceId = REQUEST_ID_NONE;
498
499 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800500 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700501 if (remoteRet.serviceSpecificErrorCode() ==
502 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
503 ALOGV("Repeating request is already stopped.");
504 return ACAMERA_OK;
505 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800506 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800507 return ACAMERA_ERROR_UNKNOWN;
508 }
509 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
510 }
511 return ACAMERA_OK;
512}
513
514camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700515CameraDevice::flushLocked(ACameraCaptureSession* session) {
516 camera_status_t ret = checkCameraClosedOrErrorLocked();
517 if (ret != ACAMERA_OK) {
518 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
519 return ret;
520 }
521
522 // This should never happen because creating a new session will close
523 // previous one and thus reject any API call from previous session.
524 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700525 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700526 ALOGE("Camera %s session %p is not current active session!", getId(), session);
527 return ACAMERA_ERROR_INVALID_OPERATION;
528 }
529
530 if (mFlushing) {
531 ALOGW("Camera %s is already aborting captures", getId());
532 return ACAMERA_OK;
533 }
534
535 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700536
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700537 // Send onActive callback to guarantee there is always active->ready transition
538 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
539 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
540 msg->setObject(kSessionSpKey, session);
541 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700542 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700543
544 // If device is already idling, send callback and exit early
545 if (mIdle) {
546 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
547 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
548 msg->setObject(kSessionSpKey, session);
549 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700550 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700551 mFlushing = false;
552 return ACAMERA_OK;
553 }
554
555 int64_t lastFrameNumber;
556 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
557 if (!remoteRet.isOk()) {
558 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
559 return ACAMERA_ERROR_UNKNOWN;
560 }
561 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
562 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
563 }
564 return ACAMERA_OK;
565}
566
567camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800568CameraDevice::waitUntilIdleLocked() {
569 camera_status_t ret = checkCameraClosedOrErrorLocked();
570 if (ret != ACAMERA_OK) {
571 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
572 return ret;
573 }
574
575 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
576 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
577 return ACAMERA_ERROR_INVALID_OPERATION;
578 }
579
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800580 binder::Status remoteRet = mRemote->waitUntilIdle();
581 if (!remoteRet.isOk()) {
582 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800583 // TODO: define a function to convert status_t -> camera_status_t
584 return ACAMERA_ERROR_UNKNOWN;
585 }
586
587 return ACAMERA_OK;
588}
589
590camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700591CameraDevice::getIGBPfromAnw(
592 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800593 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800594 sp<Surface> surface;
595 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
596 if (ret != ACAMERA_OK) {
597 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800598 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800599 out = surface->getIGraphicBufferProducer();
600 return ACAMERA_OK;
601}
602
603camera_status_t
604CameraDevice::getSurfaceFromANativeWindow(
605 ANativeWindow* anw, sp<Surface>& out) {
606 if (anw == nullptr) {
607 ALOGE("Error: output ANativeWindow is null");
608 return ACAMERA_ERROR_INVALID_PARAMETER;
609 }
610 int value;
611 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800612 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800613 ALOGE("Error: ANativeWindow is not backed by Surface!");
614 return ACAMERA_ERROR_INVALID_PARAMETER;
615 }
616 sp<Surface> surface(static_cast<Surface*>(anw));
617 out = surface;
618 return ACAMERA_OK;
619}
620
621camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100622CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
623 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800624 ACaptureSessionOutputContainer emptyOutput;
625 if (outputs == nullptr) {
626 outputs = &emptyOutput;
627 }
628
Yin-Chia Yehead91462016-01-06 16:45:08 -0800629 camera_status_t ret = checkCameraClosedOrErrorLocked();
630 if (ret != ACAMERA_OK) {
631 return ret;
632 }
633
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700634 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800635 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700636 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800637 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700638 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800639 if (ret != ACAMERA_OK) {
640 return ret;
641 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700642 outputSet.insert(std::make_pair(
Emilian Peev40ead602017-09-26 15:46:36 +0100643 anw, OutputConfiguration(iGBP, outConfig.mRotation,
644 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800645 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700646 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800647 std::vector<int> deleteList;
648
649 // Determine which streams need to be created, which to be deleted
650 for (auto& kvPair : mConfiguredOutputs) {
651 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700652 auto& outputPair = kvPair.second;
653 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800654 deleteList.push_back(streamId); // Need to delete a no longer needed stream
655 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700656 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800657 }
658 }
659
660 ret = stopRepeatingLocked();
661 if (ret != ACAMERA_OK) {
662 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
663 return ret;
664 }
665
666 ret = waitUntilIdleLocked();
667 if (ret != ACAMERA_OK) {
668 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
669 return ret;
670 }
671
672 // Send onReady to previous session
673 // CurrentSession will be updated after configureStreamLocked, so here
674 // mCurrentSession is the session to be replaced by a new session
675 if (!mIdle && mCurrentSession != nullptr) {
676 if (mBusySession != mCurrentSession) {
677 ALOGE("Current session != busy session");
678 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
679 return ACAMERA_ERROR_CAMERA_DEVICE;
680 }
681 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
682 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
683 msg->setObject(kSessionSpKey, mBusySession);
684 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
685 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700686 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800687 }
688 mIdle = true;
689
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800690 binder::Status remoteRet = mRemote->beginConfigure();
691 if (!remoteRet.isOk()) {
692 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800693 return ACAMERA_ERROR_UNKNOWN;
694 }
695
696 // delete to-be-deleted streams
697 for (auto streamId : deleteList) {
698 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800699 if (!remoteRet.isOk()) {
700 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
701 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800702 return ACAMERA_ERROR_UNKNOWN;
703 }
704 mConfiguredOutputs.erase(streamId);
705 }
706
707 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700708 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800709 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700710 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800711 if (!remoteRet.isOk()) {
712 ALOGE("Camera device %s failed to create stream: %s", getId(),
713 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800714 return ACAMERA_ERROR_UNKNOWN;
715 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700716 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800717 }
718
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100719 CameraMetadata params;
720 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
721 params.append(sessionParameters->settings->getInternalData());
722 }
723 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800724 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
725 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
726 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800727 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800728 } else if (!remoteRet.isOk()) {
729 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800730 return ACAMERA_ERROR_UNKNOWN;
731 }
732
733 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800734}
735
736void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800737CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800738 Mutex::Autolock _l(mDeviceLock);
739 mRemote = remote;
740}
741
742camera_status_t
743CameraDevice::checkCameraClosedOrErrorLocked() const {
744 if (mRemote == nullptr) {
745 ALOGE("%s: camera device already closed", __FUNCTION__);
746 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
747 }
748 if (mInError) {// triggered by onDeviceError
749 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
750 return mError;
751 }
752 return ACAMERA_OK;
753}
754
755void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800756CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
757 mInError = true;
758 mError = error;
759 return;
760}
761
762void
763CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
764 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
765 if (isError) {
766 mFutureErrorSet.insert(frameNumber);
767 } else if (frameNumber <= mCompletedFrameNumber) {
768 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
769 frameNumber, mCompletedFrameNumber);
770 return;
771 } else {
772 if (frameNumber != mCompletedFrameNumber + 1) {
773 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
774 mCompletedFrameNumber + 1, frameNumber);
775 // Do not assert as in java implementation
776 }
777 mCompletedFrameNumber = frameNumber;
778 }
779 update();
780}
781
782void
783CameraDevice::FrameNumberTracker::update() {
784 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
785 int64_t errorFrameNumber = *it;
786 if (errorFrameNumber == mCompletedFrameNumber + 1) {
787 mCompletedFrameNumber++;
788 it = mFutureErrorSet.erase(it);
789 } else if (errorFrameNumber <= mCompletedFrameNumber) {
790 // This should not happen, but deal with it anyway
791 ALOGE("Completd frame number passed through current frame number!");
792 // erase the old error since it's no longer useful
793 it = mFutureErrorSet.erase(it);
794 } else {
795 // Normal requests hasn't catched up error frames, just break
796 break;
797 }
798 }
799 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
800}
801
802void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800803CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800804 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800805 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800806 int sequenceId = resultExtras.requestId;
807 int64_t frameNumber = resultExtras.frameNumber;
808 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700809 auto it = mSequenceCallbackMap.find(sequenceId);
810 if (it == mSequenceCallbackMap.end()) {
811 ALOGE("%s: Error: capture sequence index %d not found!",
812 __FUNCTION__, sequenceId);
813 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800814 return;
815 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700816
817 CallbackHolder cbh = (*it).second;
818 sp<ACameraCaptureSession> session = cbh.mSession;
819 if ((size_t) burstId >= cbh.mRequests.size()) {
820 ALOGE("%s: Error: request index %d out of bound (size %zu)",
821 __FUNCTION__, burstId, cbh.mRequests.size());
822 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
823 return;
824 }
825 sp<CaptureRequest> request = cbh.mRequests[burstId];
826
827 // Handle buffer error
828 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
829 int32_t streamId = resultExtras.errorStreamId;
830 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
831 cbh.mCallbacks.onCaptureBufferLost;
832 auto outputPairIt = mConfiguredOutputs.find(streamId);
833 if (outputPairIt == mConfiguredOutputs.end()) {
834 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800835 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
836 return;
837 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700838
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800839 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
840 for (const auto& outGbp : gbps) {
841 for (auto surface : request->mSurfaceList) {
842 if (surface->getIGraphicBufferProducer() == outGbp) {
843 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
844 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
845 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700846
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800847 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
848 msg->setPointer(kContextKey, cbh.mCallbacks.context);
849 msg->setObject(kSessionSpKey, session);
850 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
851 msg->setObject(kCaptureRequestKey, request);
852 msg->setPointer(kAnwKey, (void*) anw);
853 msg->setInt64(kFrameNumberKey, frameNumber);
854 postSessionMsgAndCleanup(msg);
855 }
856 }
857 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700858 } else { // Handle other capture failures
859 // Fire capture failure callback if there is one registered
860 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800861 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
862 failure->frameNumber = frameNumber;
863 // TODO: refine this when implementing flush
864 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
865 failure->sequenceId = sequenceId;
866 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800867 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800868
869 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
870 msg->setPointer(kContextKey, cbh.mCallbacks.context);
871 msg->setObject(kSessionSpKey, session);
872 msg->setPointer(kCallbackFpKey, (void*) onError);
873 msg->setObject(kCaptureRequestKey, request);
874 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700875 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800876
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700877 // Update tracker
878 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
879 checkAndFireSequenceCompleteLocked();
880 }
881 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800882}
883
884void CameraDevice::CallbackHandler::onMessageReceived(
885 const sp<AMessage> &msg) {
886 switch (msg->what()) {
887 case kWhatOnDisconnected:
888 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800889 case kWhatSessionStateCb:
890 case kWhatCaptureStart:
891 case kWhatCaptureResult:
892 case kWhatCaptureFail:
893 case kWhatCaptureSeqEnd:
894 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700895 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800896 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800897 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700898 case kWhatCleanUpSessions:
899 mCachedSessions.clear();
900 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800901 default:
902 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
903 return;
904 }
905 // Check the common part of all message
906 void* context;
907 bool found = msg->findPointer(kContextKey, &context);
908 if (!found) {
909 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
910 return;
911 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800912 switch (msg->what()) {
913 case kWhatOnDisconnected:
914 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800915 ACameraDevice* dev;
916 found = msg->findPointer(kDeviceKey, (void**) &dev);
917 if (!found || dev == nullptr) {
918 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
919 return;
920 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800921 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800922 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800923 if (!found) {
924 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
925 return;
926 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800927 if (onDisconnected == nullptr) {
928 return;
929 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800930 (*onDisconnected)(context, dev);
931 break;
932 }
933 case kWhatOnError:
934 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800935 ACameraDevice* dev;
936 found = msg->findPointer(kDeviceKey, (void**) &dev);
937 if (!found || dev == nullptr) {
938 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
939 return;
940 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800941 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800942 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800943 if (!found) {
944 ALOGE("%s: Cannot find onError!", __FUNCTION__);
945 return;
946 }
947 int errorCode;
948 found = msg->findInt32(kErrorCodeKey, &errorCode);
949 if (!found) {
950 ALOGE("%s: Cannot find error code!", __FUNCTION__);
951 return;
952 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800953 if (onError == nullptr) {
954 return;
955 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800956 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800957 break;
958 }
959 case kWhatSessionStateCb:
960 case kWhatCaptureStart:
961 case kWhatCaptureResult:
962 case kWhatCaptureFail:
963 case kWhatCaptureSeqEnd:
964 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700965 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800966 {
967 sp<RefBase> obj;
968 found = msg->findObject(kSessionSpKey, &obj);
969 if (!found || obj == nullptr) {
970 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
971 return;
972 }
973 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700974 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800975 sp<CaptureRequest> requestSp = nullptr;
976 switch (msg->what()) {
977 case kWhatCaptureStart:
978 case kWhatCaptureResult:
979 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700980 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800981 found = msg->findObject(kCaptureRequestKey, &obj);
982 if (!found) {
983 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
984 return;
985 }
986 requestSp = static_cast<CaptureRequest*>(obj.get());
987 break;
988 }
989
990 switch (msg->what()) {
991 case kWhatSessionStateCb:
992 {
993 ACameraCaptureSession_stateCallback onState;
994 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
995 if (!found) {
996 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
997 return;
998 }
999 if (onState == nullptr) {
1000 return;
1001 }
1002 (*onState)(context, session.get());
1003 break;
1004 }
1005 case kWhatCaptureStart:
1006 {
1007 ACameraCaptureSession_captureCallback_start onStart;
1008 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1009 if (!found) {
1010 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1011 return;
1012 }
1013 if (onStart == nullptr) {
1014 return;
1015 }
1016 int64_t timestamp;
1017 found = msg->findInt64(kTimeStampKey, &timestamp);
1018 if (!found) {
1019 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1020 return;
1021 }
1022 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1023 (*onStart)(context, session.get(), request, timestamp);
1024 freeACaptureRequest(request);
1025 break;
1026 }
1027 case kWhatCaptureResult:
1028 {
1029 ACameraCaptureSession_captureCallback_result onResult;
1030 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1031 if (!found) {
1032 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1033 return;
1034 }
1035 if (onResult == nullptr) {
1036 return;
1037 }
1038
1039 found = msg->findObject(kCaptureResultKey, &obj);
1040 if (!found) {
1041 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1042 return;
1043 }
1044 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1045 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1046 (*onResult)(context, session.get(), request, result.get());
1047 freeACaptureRequest(request);
1048 break;
1049 }
1050 case kWhatCaptureFail:
1051 {
1052 ACameraCaptureSession_captureCallback_failed onFail;
1053 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1054 if (!found) {
1055 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1056 return;
1057 }
1058 if (onFail == nullptr) {
1059 return;
1060 }
1061
1062 found = msg->findObject(kCaptureFailureKey, &obj);
1063 if (!found) {
1064 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1065 return;
1066 }
1067 sp<CameraCaptureFailure> failureSp(
1068 static_cast<CameraCaptureFailure*>(obj.get()));
1069 ACameraCaptureFailure* failure =
1070 static_cast<ACameraCaptureFailure*>(failureSp.get());
1071 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1072 (*onFail)(context, session.get(), request, failure);
1073 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001074 break;
1075 }
1076 case kWhatCaptureSeqEnd:
1077 {
1078 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1079 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1080 if (!found) {
1081 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1082 return;
1083 }
1084 if (onSeqEnd == nullptr) {
1085 return;
1086 }
1087 int seqId;
1088 found = msg->findInt32(kSequenceIdKey, &seqId);
1089 if (!found) {
1090 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1091 return;
1092 }
1093 int64_t frameNumber;
1094 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1095 if (!found) {
1096 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1097 return;
1098 }
1099 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1100 break;
1101 }
1102 case kWhatCaptureSeqAbort:
1103 {
1104 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1105 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1106 if (!found) {
1107 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1108 return;
1109 }
1110 if (onSeqAbort == nullptr) {
1111 return;
1112 }
1113 int seqId;
1114 found = msg->findInt32(kSequenceIdKey, &seqId);
1115 if (!found) {
1116 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1117 return;
1118 }
1119 (*onSeqAbort)(context, session.get(), seqId);
1120 break;
1121 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001122 case kWhatCaptureBufferLost:
1123 {
1124 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1125 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1126 if (!found) {
1127 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1128 return;
1129 }
1130 if (onBufferLost == nullptr) {
1131 return;
1132 }
1133
1134 ANativeWindow* anw;
1135 found = msg->findPointer(kAnwKey, (void**) &anw);
1136 if (!found) {
1137 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1138 return;
1139 }
1140
1141 int64_t frameNumber;
1142 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1143 if (!found) {
1144 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1145 return;
1146 }
1147
1148 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1149 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1150 freeACaptureRequest(request);
1151 break;
1152 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001153 }
1154 break;
1155 }
1156 }
1157}
1158
1159CameraDevice::CallbackHolder::CallbackHolder(
1160 sp<ACameraCaptureSession> session,
1161 const Vector<sp<CaptureRequest> >& requests,
1162 bool isRepeating,
1163 ACameraCaptureSession_captureCallbacks* cbs) :
1164 mSession(session), mRequests(requests),
1165 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1166
1167void
1168CameraDevice::checkRepeatingSequenceCompleteLocked(
1169 const int sequenceId, const int64_t lastFrameNumber) {
1170 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1171 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1172 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1173 ALOGW("No callback found for sequenceId %d", sequenceId);
1174 return;
1175 }
1176 // remove callback holder from callback map
1177 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1178 CallbackHolder cbh = cbIt->second;
1179 mSequenceCallbackMap.erase(cbIt);
1180 // send seq aborted callback
1181 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1182 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1183 msg->setObject(kSessionSpKey, cbh.mSession);
1184 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1185 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001186 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001187 } else {
1188 // Use mSequenceLastFrameNumberMap to track
1189 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1190
1191 // Last frame might have arrived. Check now
1192 checkAndFireSequenceCompleteLocked();
1193 }
1194}
1195
1196void
1197CameraDevice::checkAndFireSequenceCompleteLocked() {
1198 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1199 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1200 auto it = mSequenceLastFrameNumberMap.begin();
1201 while (it != mSequenceLastFrameNumberMap.end()) {
1202 int sequenceId = it->first;
1203 int64_t lastFrameNumber = it->second;
1204 bool seqCompleted = false;
1205 bool hasCallback = true;
1206
1207 if (mRemote == nullptr) {
1208 ALOGW("Camera %s closed while checking sequence complete", getId());
1209 return;
1210 }
1211
1212 // Check if there is callback for this sequence
1213 // This should not happen because we always register callback (with nullptr inside)
1214 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1215 ALOGW("No callback found for sequenceId %d", sequenceId);
1216 hasCallback = false;
1217 }
1218
1219 if (lastFrameNumber <= completedFrameNumber) {
1220 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1221 sequenceId, lastFrameNumber, completedFrameNumber);
1222 seqCompleted = true;
1223 }
1224
1225 if (seqCompleted && hasCallback) {
1226 // remove callback holder from callback map
1227 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1228 CallbackHolder cbh = cbIt->second;
1229 mSequenceCallbackMap.erase(cbIt);
1230 // send seq complete callback
1231 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1232 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1233 msg->setObject(kSessionSpKey, cbh.mSession);
1234 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1235 msg->setInt32(kSequenceIdKey, sequenceId);
1236 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1237
1238 // Clear the session sp before we send out the message
1239 // This will guarantee the rare case where the message is processed
1240 // before cbh goes out of scope and causing we call the session
1241 // destructor while holding device lock
1242 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001243 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001244 }
1245
1246 // No need to track sequence complete if there is no callback registered
1247 if (seqCompleted || !hasCallback) {
1248 it = mSequenceLastFrameNumberMap.erase(it);
1249 } else {
1250 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001251 }
1252 }
1253}
1254
1255/**
1256 * Camera service callback implementation
1257 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001258binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001259CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001260 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001261 const CaptureResultExtras& resultExtras) {
1262 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1263 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001264 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001265 sp<CameraDevice> dev = mDevice.promote();
1266 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001267 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001268 }
1269
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001270 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001271 Mutex::Autolock _l(dev->mDeviceLock);
1272 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001273 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001274 }
1275 switch (errorCode) {
1276 case ERROR_CAMERA_DISCONNECTED:
1277 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001278 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001279 if (session != nullptr) {
1280 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001281 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001282 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001283 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1284 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1285 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001286 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001287 msg->post();
1288 break;
1289 }
1290 default:
1291 ALOGE("Unknown error from camera device: %d", errorCode);
1292 // no break
1293 case ERROR_CAMERA_DEVICE:
1294 case ERROR_CAMERA_SERVICE:
1295 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001296 switch (errorCode) {
1297 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001298 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001299 break;
1300 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001301 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001302 break;
1303 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001304 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001305 break;
1306 }
1307 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1308 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1309 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001310 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001311 msg->setInt32(kErrorCodeKey, errorCode);
1312 msg->post();
1313 break;
1314 }
1315 case ERROR_CAMERA_REQUEST:
1316 case ERROR_CAMERA_RESULT:
1317 case ERROR_CAMERA_BUFFER:
1318 dev->onCaptureErrorLocked(errorCode, resultExtras);
1319 break;
1320 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001321 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001322}
1323
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001324binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001325CameraDevice::ServiceCallback::onDeviceIdle() {
1326 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001327 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001328 sp<CameraDevice> dev = mDevice.promote();
1329 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001330 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001331 }
1332
1333 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001334 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001335 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001336 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001337
1338 if (dev->mIdle) {
1339 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001340 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001341 }
1342
1343 if (dev->mCurrentSession != nullptr) {
1344 ALOGE("onDeviceIdle sending state cb");
1345 if (dev->mBusySession != dev->mCurrentSession) {
1346 ALOGE("Current session != busy session");
1347 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001348 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001349 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001350
Yin-Chia Yehead91462016-01-06 16:45:08 -08001351 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1352 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1353 msg->setObject(kSessionSpKey, dev->mBusySession);
1354 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1355 // Make sure we clear the sp first so the session destructor can
1356 // only happen on handler thread (where we don't hold device/session lock)
1357 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001358 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001359 }
1360 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001361 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001362 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001363}
1364
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001365binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001366CameraDevice::ServiceCallback::onCaptureStarted(
1367 const CaptureResultExtras& resultExtras,
1368 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001369 binder::Status ret = binder::Status::ok();
1370
Yin-Chia Yehead91462016-01-06 16:45:08 -08001371 sp<CameraDevice> dev = mDevice.promote();
1372 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001373 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001374 }
1375 Mutex::Autolock _l(dev->mDeviceLock);
1376 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001377 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001378 }
1379
1380 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001381 int32_t burstId = resultExtras.burstId;
1382
1383 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1384 if (it != dev->mSequenceCallbackMap.end()) {
1385 CallbackHolder cbh = (*it).second;
1386 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1387 sp<ACameraCaptureSession> session = cbh.mSession;
1388 if ((size_t) burstId >= cbh.mRequests.size()) {
1389 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1390 __FUNCTION__, burstId, cbh.mRequests.size());
1391 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1392 }
1393 sp<CaptureRequest> request = cbh.mRequests[burstId];
1394 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1395 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1396 msg->setObject(kSessionSpKey, session);
1397 msg->setPointer(kCallbackFpKey, (void*) onStart);
1398 msg->setObject(kCaptureRequestKey, request);
1399 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001400 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001401 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001402 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001403}
1404
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001405binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001406CameraDevice::ServiceCallback::onResultReceived(
1407 const CameraMetadata& metadata,
1408 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001409 binder::Status ret = binder::Status::ok();
1410
Yin-Chia Yehead91462016-01-06 16:45:08 -08001411 sp<CameraDevice> dev = mDevice.promote();
1412 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001413 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001414 }
1415 int sequenceId = resultExtras.requestId;
1416 int64_t frameNumber = resultExtras.frameNumber;
1417 int32_t burstId = resultExtras.burstId;
1418 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1419
1420 if (!isPartialResult) {
1421 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1422 }
1423
1424 Mutex::Autolock _l(dev->mDeviceLock);
1425 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001426 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001427 }
1428
1429 if (dev->isClosed()) {
1430 if (!isPartialResult) {
1431 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1432 }
1433 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001434 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001435 }
1436
1437 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001438 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001439 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001440
1441 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1442 if (it != dev->mSequenceCallbackMap.end()) {
1443 CallbackHolder cbh = (*it).second;
1444 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1445 cbh.mCallbacks.onCaptureProgressed :
1446 cbh.mCallbacks.onCaptureCompleted;
1447 sp<ACameraCaptureSession> session = cbh.mSession;
1448 if ((size_t) burstId >= cbh.mRequests.size()) {
1449 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1450 __FUNCTION__, burstId, cbh.mRequests.size());
1451 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1452 }
1453 sp<CaptureRequest> request = cbh.mRequests[burstId];
1454 sp<ACameraMetadata> result(new ACameraMetadata(
1455 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1456
1457 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1458 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1459 msg->setObject(kSessionSpKey, session);
1460 msg->setPointer(kCallbackFpKey, (void*) onResult);
1461 msg->setObject(kCaptureRequestKey, request);
1462 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001463 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001464 }
1465
1466 if (!isPartialResult) {
1467 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1468 dev->checkAndFireSequenceCompleteLocked();
1469 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001470
1471 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001472}
1473
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001474binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001475CameraDevice::ServiceCallback::onPrepared(int) {
1476 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001477 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001478}
1479
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001480binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001481CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1482 // onRequestQueueEmpty not yet implemented in NDK
1483 return binder::Status::ok();
1484}
1485
1486binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001487CameraDevice::ServiceCallback::onRepeatingRequestError(
1488 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001489 binder::Status ret = binder::Status::ok();
1490
1491 sp<CameraDevice> dev = mDevice.promote();
1492 if (dev == nullptr) {
1493 return ret; // device has been closed
1494 }
1495
1496 Mutex::Autolock _l(dev->mDeviceLock);
1497
1498 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001499 if (stoppedSequenceId == repeatingSequenceId) {
1500 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1501 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001502
1503 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1504
1505 return ret;
1506}
1507
1508
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001509} // namespace android