blob: c15c5a557c3747f5c12769575ae25f79c1cfe22a [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>
Yin-Chia Yehead91462016-01-06 16:45:08 -080023#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080024#include "ACameraDevice.h"
25#include "ACameraMetadata.h"
26#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080027#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080028
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080029#include "ACameraCaptureSession.inc"
30
Jayant Chowdharya8488c92019-06-21 12:45:34 -070031ACameraDevice::~ACameraDevice() {
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -070032 mDevice->stopLooperAndDisconnect();
Jayant Chowdharya8488c92019-06-21 12:45:34 -070033}
34
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080035namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080036namespace acam {
37
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080038// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080039const char* CameraDevice::kContextKey = "Context";
40const char* CameraDevice::kDeviceKey = "Device";
41const char* CameraDevice::kErrorCodeKey = "ErrorCode";
42const char* CameraDevice::kCallbackFpKey = "Callback";
43const char* CameraDevice::kSessionSpKey = "SessionSp";
44const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
45const char* CameraDevice::kTimeStampKey = "TimeStamp";
46const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080047const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080048const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
49const char* CameraDevice::kSequenceIdKey = "SequenceId";
50const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070051const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070052const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080053
54/**
55 * CameraDevice Implementation
56 */
57CameraDevice::CameraDevice(
58 const char* id,
59 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070060 sp<ACameraMetadata> chars,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080061 ACameraDevice* wrapper) :
62 mCameraId(id),
63 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070064 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080065 mServiceCallback(new ServiceCallback(this)),
66 mWrapper(wrapper),
67 mInError(false),
68 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070069 mIdle(true),
70 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080071 mClosing = false;
72 // Setup looper thread to perfrom device callbacks to app
73 mCbLooper = new ALooper;
74 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080075 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080076 /*runOnCallingThread*/false,
77 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080078 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080079 if (err != OK) {
80 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
81 __FUNCTION__, strerror(-err), err);
82 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
83 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080084 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080085 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080086
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080087 const CameraMetadata& metadata = mChars->getInternalData();
88 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080089 if (entry.count != 1) {
90 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
91 mPartialResultCount = 1;
92 } else {
93 mPartialResultCount = entry.data.i32[0];
94 }
95
96 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
97 if (entry.count != 2) {
98 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
99 mShadingMapSize[0] = 0;
100 mShadingMapSize[1] = 0;
101 } else {
102 mShadingMapSize[0] = entry.data.i32[0];
103 mShadingMapSize[1] = entry.data.i32[1];
104 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800105
106 size_t physicalIdCnt = 0;
107 const char*const* physicalCameraIds;
108 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
109 for (size_t i = 0; i < physicalIdCnt; i++) {
110 mPhysicalIds.push_back(physicalCameraIds[i]);
111 }
112 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800113}
114
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700115CameraDevice::~CameraDevice() { }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700117void
118CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
119 msg->post();
120 msg.clear();
121 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
122 cleanupMsg->post();
123}
124
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800125// TODO: cached created request?
126camera_status_t
127CameraDevice::createCaptureRequest(
128 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800129 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800130 ACaptureRequest** request) const {
131 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800132
133 if (physicalIdList != nullptr) {
134 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
135 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
136 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
137 return ACAMERA_ERROR_INVALID_PARAMETER;
138 }
139 for (auto i = 0; i < physicalIdList->numCameras; i++) {
140 if (physicalIdList->cameraIds[i] == nullptr) {
141 ALOGE("%s: physicalId is null!", __FUNCTION__);
142 return ACAMERA_ERROR_INVALID_PARAMETER;
143 }
144 if (mPhysicalIds.end() == std::find(
145 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
146 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
147 return ACAMERA_ERROR_INVALID_PARAMETER;
148 }
149 }
150 }
151
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800152 camera_status_t ret = checkCameraClosedOrErrorLocked();
153 if (ret != ACAMERA_OK) {
154 return ret;
155 }
156 if (mRemote == nullptr) {
157 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
158 }
159 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800160 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
161 if (remoteRet.serviceSpecificErrorCode() ==
162 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800163 ALOGW("Create capture request failed! template %d is not supported on this device",
164 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700165 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800166 } else if (!remoteRet.isOk()) {
167 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800168 return ACAMERA_ERROR_UNKNOWN;
169 }
170 ACaptureRequest* outReq = new ACaptureRequest();
171 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800172 if (physicalIdList != nullptr) {
173 for (auto i = 0; i < physicalIdList->numCameras; i++) {
174 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
175 new ACameraMetadata(*(outReq->settings)));
176 }
177 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800178 outReq->targets = new ACameraOutputTargets();
179 *request = outReq;
180 return ACAMERA_OK;
181}
182
Yin-Chia Yehead91462016-01-06 16:45:08 -0800183camera_status_t
184CameraDevice::createCaptureSession(
185 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100186 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800187 const ACameraCaptureSession_stateCallbacks* callbacks,
188 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700189 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800190 Mutex::Autolock _l(mDeviceLock);
191 camera_status_t ret = checkCameraClosedOrErrorLocked();
192 if (ret != ACAMERA_OK) {
193 return ret;
194 }
195
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700196 if (currentSession != nullptr) {
197 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800198 stopRepeatingLocked();
199 }
200
201 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100202 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800203 if (ret != ACAMERA_OK) {
204 ALOGE("Fail to create new session. cannot configure streams");
205 return ret;
206 }
207
208 ACameraCaptureSession* newSession = new ACameraCaptureSession(
209 mNextSessionId++, outputs, callbacks, this);
210
Yin-Chia Yehead91462016-01-06 16:45:08 -0800211 // set new session as current session
212 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
213 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700214 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800215 *session = newSession;
216 return ACAMERA_OK;
217}
218
Shuzhen Wang24810e72019-03-18 10:55:01 -0700219camera_status_t CameraDevice::isSessionConfigurationSupported(
220 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
221 Mutex::Autolock _l(mDeviceLock);
222 camera_status_t ret = checkCameraClosedOrErrorLocked();
223 if (ret != ACAMERA_OK) {
224 return ret;
225 }
226
227 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
228 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
229 for (const auto& output : sessionOutputContainer->mOutputs) {
230 sp<IGraphicBufferProducer> iGBP(nullptr);
231 ret = getIGBPfromAnw(output.mWindow, iGBP);
232 if (ret != ACAMERA_OK) {
233 ALOGE("Camera device %s failed to extract graphic producer from native window",
234 getId());
235 return ret;
236 }
237
238 String16 physicalId16(output.mPhysicalCameraId.c_str());
239 OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
240 OutputConfiguration::INVALID_SET_ID, true);
241
242 for (auto& anw : output.mSharedWindows) {
243 ret = getIGBPfromAnw(anw, iGBP);
244 if (ret != ACAMERA_OK) {
245 ALOGE("Camera device %s failed to extract graphic producer from native window",
246 getId());
247 return ret;
248 }
249 outConfig.addGraphicProducer(iGBP);
250 }
251
252 sessionConfiguration.addOutputConfiguration(outConfig);
253 }
254
255 bool supported = false;
256 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
257 sessionConfiguration, &supported);
258 if (remoteRet.serviceSpecificErrorCode() ==
259 hardware::ICameraService::ERROR_INVALID_OPERATION) {
260 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
261 } else if (!remoteRet.isOk()) {
262 return ACAMERA_ERROR_UNKNOWN;
263 } else {
264 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
265 }
266}
267
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800268camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100269 camera_status_t ret = checkCameraClosedOrErrorLocked();
270 if (ret != ACAMERA_OK) {
271 return ret;
272 }
273
274 if (output == nullptr) {
275 return ACAMERA_ERROR_INVALID_PARAMETER;
276 }
277
278 if (!output->mIsShared) {
279 ALOGE("Error output configuration is not shared");
280 return ACAMERA_ERROR_INVALID_OPERATION;
281 }
282
283 int32_t streamId = -1;
284 for (auto& kvPair : mConfiguredOutputs) {
285 if (kvPair.second.first == output->mWindow) {
286 streamId = kvPair.first;
287 break;
288 }
289 }
290 if (streamId < 0) {
291 ALOGE("Error: Invalid output configuration");
292 return ACAMERA_ERROR_INVALID_PARAMETER;
293 }
294
295 sp<IGraphicBufferProducer> iGBP(nullptr);
296 ret = getIGBPfromAnw(output->mWindow, iGBP);
297 if (ret != ACAMERA_OK) {
298 ALOGE("Camera device %s failed to extract graphic producer from native window",
299 getId());
300 return ret;
301 }
302
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800303 String16 physicalId16(output->mPhysicalCameraId.c_str());
304 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
305 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100306
307 for (auto& anw : output->mSharedWindows) {
308 ret = getIGBPfromAnw(anw, iGBP);
309 if (ret != ACAMERA_OK) {
310 ALOGE("Camera device %s failed to extract graphic producer from native window",
311 getId());
312 return ret;
313 }
314 outConfig.addGraphicProducer(iGBP);
315 }
316
317 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
318 if (!remoteRet.isOk()) {
319 switch (remoteRet.serviceSpecificErrorCode()) {
320 case hardware::ICameraService::ERROR_INVALID_OPERATION:
321 ALOGE("Camera device %s invalid operation: %s", getId(),
322 remoteRet.toString8().string());
323 return ACAMERA_ERROR_INVALID_OPERATION;
324 break;
325 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
326 ALOGE("Camera device %s output surface already exists: %s", getId(),
327 remoteRet.toString8().string());
328 return ACAMERA_ERROR_INVALID_PARAMETER;
329 break;
330 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
331 ALOGE("Camera device %s invalid input argument: %s", getId(),
332 remoteRet.toString8().string());
333 return ACAMERA_ERROR_INVALID_PARAMETER;
334 break;
335 default:
336 ALOGE("Camera device %s failed to add shared output: %s", getId(),
337 remoteRet.toString8().string());
338 return ACAMERA_ERROR_UNKNOWN;
339 }
340 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800341 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100342
343 return ACAMERA_OK;
344}
345
Yin-Chia Yehead91462016-01-06 16:45:08 -0800346camera_status_t
347CameraDevice::allocateCaptureRequest(
348 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
349 camera_status_t ret;
350 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800351 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000352 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800353 for (auto& entry : request->physicalSettings) {
354 req->mPhysicalCameraSettings.push_back({entry.first,
355 entry.second->getInternalData()});
356 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800357 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700358 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800359 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800360
361 for (auto outputTarget : request->targets->mOutputs) {
362 ANativeWindow* anw = outputTarget.mWindow;
363 sp<Surface> surface;
364 ret = getSurfaceFromANativeWindow(anw, surface);
365 if (ret != ACAMERA_OK) {
366 ALOGE("Bad output target in capture request! ret %d", ret);
367 return ret;
368 }
369 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800370
371 bool found = false;
372 // lookup stream/surface ID
373 for (const auto& kvPair : mConfiguredOutputs) {
374 int streamId = kvPair.first;
375 const OutputConfiguration& outConfig = kvPair.second.second;
376 const auto& gbps = outConfig.getGraphicBufferProducers();
377 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
378 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
379 found = true;
380 req->mStreamIdxList.push_back(streamId);
381 req->mSurfaceIdxList.push_back(surfaceId);
382 break;
383 }
384 }
385 if (found) {
386 break;
387 }
388 }
389 if (!found) {
390 ALOGE("Unconfigured output target %p in capture request!", anw);
391 return ret;
392 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800393 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800394
Yin-Chia Yehead91462016-01-06 16:45:08 -0800395 outReq = req;
396 return ACAMERA_OK;
397}
398
399ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800400CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800401 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800402 for (auto& entry : req->mPhysicalCameraSettings) {
403 CameraMetadata clone = entry.settings;
404 if (entry.id == deviceId) {
405 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
406 } else {
407 pRequest->physicalSettings.emplace(entry.id,
408 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
409 }
410 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800411 pRequest->targets = new ACameraOutputTargets();
412 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
413 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
414 ACameraOutputTarget outputTarget(anw);
415 pRequest->targets->mOutputs.insert(outputTarget);
416 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700417 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800418 return pRequest;
419}
420
421void
422CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
423 if (req == nullptr) {
424 return;
425 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700426 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800427 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800428 delete req->targets;
429 delete req;
430}
431
432void
433CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
434 if (isClosed()) {
435 // Device is closing already. do nothing
436 return;
437 }
438
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700439 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800440 // Session has been replaced by other seesion or device is closed
441 return;
442 }
443 mCurrentSession = nullptr;
444
445 // Should not happen
446 if (!session->mIsClosed) {
447 ALOGE("Error: unclosed session %p reaches end of life!", session);
448 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
449 return;
450 }
451
452 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100453 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800454 if (ret != ACAMERA_OK) {
455 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
456 }
457}
458
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800459void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700460CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800461 if (mClosing.exchange(true)) {
462 // Already closing, just return
463 ALOGW("Camera device %s is already closing.", getId());
464 return;
465 }
466
467 if (mRemote != nullptr) {
468 mRemote->disconnect();
469 }
470 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800471
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700472 if (session != nullptr) {
473 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800474 }
475}
476
477camera_status_t
478CameraDevice::stopRepeatingLocked() {
479 camera_status_t ret = checkCameraClosedOrErrorLocked();
480 if (ret != ACAMERA_OK) {
481 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
482 return ret;
483 }
484 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
485 int repeatingSequenceId = mRepeatingSequenceId;
486 mRepeatingSequenceId = REQUEST_ID_NONE;
487
488 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800489 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700490 if (remoteRet.serviceSpecificErrorCode() ==
491 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
492 ALOGV("Repeating request is already stopped.");
493 return ACAMERA_OK;
494 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800495 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800496 return ACAMERA_ERROR_UNKNOWN;
497 }
498 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
499 }
500 return ACAMERA_OK;
501}
502
503camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700504CameraDevice::flushLocked(ACameraCaptureSession* session) {
505 camera_status_t ret = checkCameraClosedOrErrorLocked();
506 if (ret != ACAMERA_OK) {
507 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
508 return ret;
509 }
510
511 // This should never happen because creating a new session will close
512 // previous one and thus reject any API call from previous session.
513 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700514 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700515 ALOGE("Camera %s session %p is not current active session!", getId(), session);
516 return ACAMERA_ERROR_INVALID_OPERATION;
517 }
518
519 if (mFlushing) {
520 ALOGW("Camera %s is already aborting captures", getId());
521 return ACAMERA_OK;
522 }
523
524 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700525
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700526 // Send onActive callback to guarantee there is always active->ready transition
527 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
528 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
529 msg->setObject(kSessionSpKey, session);
530 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700531 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700532
533 // If device is already idling, send callback and exit early
534 if (mIdle) {
535 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
536 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
537 msg->setObject(kSessionSpKey, session);
538 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700539 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700540 mFlushing = false;
541 return ACAMERA_OK;
542 }
543
544 int64_t lastFrameNumber;
545 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
546 if (!remoteRet.isOk()) {
547 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
548 return ACAMERA_ERROR_UNKNOWN;
549 }
550 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
551 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
552 }
553 return ACAMERA_OK;
554}
555
556camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800557CameraDevice::waitUntilIdleLocked() {
558 camera_status_t ret = checkCameraClosedOrErrorLocked();
559 if (ret != ACAMERA_OK) {
560 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
561 return ret;
562 }
563
564 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
565 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
566 return ACAMERA_ERROR_INVALID_OPERATION;
567 }
568
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800569 binder::Status remoteRet = mRemote->waitUntilIdle();
570 if (!remoteRet.isOk()) {
571 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800572 // TODO: define a function to convert status_t -> camera_status_t
573 return ACAMERA_ERROR_UNKNOWN;
574 }
575
576 return ACAMERA_OK;
577}
578
579camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700580CameraDevice::getIGBPfromAnw(
581 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800582 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800583 sp<Surface> surface;
584 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
585 if (ret != ACAMERA_OK) {
586 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800587 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800588 out = surface->getIGraphicBufferProducer();
589 return ACAMERA_OK;
590}
591
592camera_status_t
593CameraDevice::getSurfaceFromANativeWindow(
594 ANativeWindow* anw, sp<Surface>& out) {
595 if (anw == nullptr) {
596 ALOGE("Error: output ANativeWindow is null");
597 return ACAMERA_ERROR_INVALID_PARAMETER;
598 }
599 int value;
600 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800601 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800602 ALOGE("Error: ANativeWindow is not backed by Surface!");
603 return ACAMERA_ERROR_INVALID_PARAMETER;
604 }
605 sp<Surface> surface(static_cast<Surface*>(anw));
606 out = surface;
607 return ACAMERA_OK;
608}
609
610camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100611CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
612 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800613 ACaptureSessionOutputContainer emptyOutput;
614 if (outputs == nullptr) {
615 outputs = &emptyOutput;
616 }
617
Yin-Chia Yehead91462016-01-06 16:45:08 -0800618 camera_status_t ret = checkCameraClosedOrErrorLocked();
619 if (ret != ACAMERA_OK) {
620 return ret;
621 }
622
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700623 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800624 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700625 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800626 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700627 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800628 if (ret != ACAMERA_OK) {
629 return ret;
630 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800631 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700632 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800633 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100634 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800635 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700636 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800637 std::vector<int> deleteList;
638
639 // Determine which streams need to be created, which to be deleted
640 for (auto& kvPair : mConfiguredOutputs) {
641 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700642 auto& outputPair = kvPair.second;
643 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800644 deleteList.push_back(streamId); // Need to delete a no longer needed stream
645 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700646 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800647 }
648 }
649
650 ret = stopRepeatingLocked();
651 if (ret != ACAMERA_OK) {
652 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
653 return ret;
654 }
655
656 ret = waitUntilIdleLocked();
657 if (ret != ACAMERA_OK) {
658 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
659 return ret;
660 }
661
662 // Send onReady to previous session
663 // CurrentSession will be updated after configureStreamLocked, so here
664 // mCurrentSession is the session to be replaced by a new session
665 if (!mIdle && mCurrentSession != nullptr) {
666 if (mBusySession != mCurrentSession) {
667 ALOGE("Current session != busy session");
668 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
669 return ACAMERA_ERROR_CAMERA_DEVICE;
670 }
671 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
672 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
673 msg->setObject(kSessionSpKey, mBusySession);
674 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
675 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700676 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800677 }
678 mIdle = true;
679
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800680 binder::Status remoteRet = mRemote->beginConfigure();
681 if (!remoteRet.isOk()) {
682 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800683 return ACAMERA_ERROR_UNKNOWN;
684 }
685
686 // delete to-be-deleted streams
687 for (auto streamId : deleteList) {
688 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800689 if (!remoteRet.isOk()) {
690 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
691 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800692 return ACAMERA_ERROR_UNKNOWN;
693 }
694 mConfiguredOutputs.erase(streamId);
695 }
696
697 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800698 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800699 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700700 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800701 if (!remoteRet.isOk()) {
702 ALOGE("Camera device %s failed to create stream: %s", getId(),
703 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800704 return ACAMERA_ERROR_UNKNOWN;
705 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700706 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800707 }
708
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100709 CameraMetadata params;
710 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
711 params.append(sessionParameters->settings->getInternalData());
712 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800713 std::vector<int> offlineStreamIds;
714 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params, &offlineStreamIds);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800715 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
716 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
717 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800718 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800719 } else if (!remoteRet.isOk()) {
720 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800721 return ACAMERA_ERROR_UNKNOWN;
722 }
723
724 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800725}
726
727void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800728CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800729 Mutex::Autolock _l(mDeviceLock);
730 mRemote = remote;
731}
732
733camera_status_t
734CameraDevice::checkCameraClosedOrErrorLocked() const {
735 if (mRemote == nullptr) {
736 ALOGE("%s: camera device already closed", __FUNCTION__);
737 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
738 }
739 if (mInError) {// triggered by onDeviceError
740 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
741 return mError;
742 }
743 return ACAMERA_OK;
744}
745
746void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800747CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
748 mInError = true;
749 mError = error;
750 return;
751}
752
753void
754CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
755 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
756 if (isError) {
757 mFutureErrorSet.insert(frameNumber);
758 } else if (frameNumber <= mCompletedFrameNumber) {
759 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
760 frameNumber, mCompletedFrameNumber);
761 return;
762 } else {
763 if (frameNumber != mCompletedFrameNumber + 1) {
764 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
765 mCompletedFrameNumber + 1, frameNumber);
766 // Do not assert as in java implementation
767 }
768 mCompletedFrameNumber = frameNumber;
769 }
770 update();
771}
772
773void
774CameraDevice::FrameNumberTracker::update() {
775 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
776 int64_t errorFrameNumber = *it;
777 if (errorFrameNumber == mCompletedFrameNumber + 1) {
778 mCompletedFrameNumber++;
779 it = mFutureErrorSet.erase(it);
780 } else if (errorFrameNumber <= mCompletedFrameNumber) {
781 // This should not happen, but deal with it anyway
782 ALOGE("Completd frame number passed through current frame number!");
783 // erase the old error since it's no longer useful
784 it = mFutureErrorSet.erase(it);
785 } else {
786 // Normal requests hasn't catched up error frames, just break
787 break;
788 }
789 }
790 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
791}
792
793void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800794CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800795 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800796 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800797 int sequenceId = resultExtras.requestId;
798 int64_t frameNumber = resultExtras.frameNumber;
799 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700800 auto it = mSequenceCallbackMap.find(sequenceId);
801 if (it == mSequenceCallbackMap.end()) {
802 ALOGE("%s: Error: capture sequence index %d not found!",
803 __FUNCTION__, sequenceId);
804 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800805 return;
806 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700807
808 CallbackHolder cbh = (*it).second;
809 sp<ACameraCaptureSession> session = cbh.mSession;
810 if ((size_t) burstId >= cbh.mRequests.size()) {
811 ALOGE("%s: Error: request index %d out of bound (size %zu)",
812 __FUNCTION__, burstId, cbh.mRequests.size());
813 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
814 return;
815 }
816 sp<CaptureRequest> request = cbh.mRequests[burstId];
817
818 // Handle buffer error
819 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
820 int32_t streamId = resultExtras.errorStreamId;
821 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800822 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700823 auto outputPairIt = mConfiguredOutputs.find(streamId);
824 if (outputPairIt == mConfiguredOutputs.end()) {
825 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800826 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
827 return;
828 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700829
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800830 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
831 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800832 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800833 if (surface->getIGraphicBufferProducer() == outGbp) {
834 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
835 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
836 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700837
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800838 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800839 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800840 msg->setObject(kSessionSpKey, session);
841 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
842 msg->setObject(kCaptureRequestKey, request);
843 msg->setPointer(kAnwKey, (void*) anw);
844 msg->setInt64(kFrameNumberKey, frameNumber);
845 postSessionMsgAndCleanup(msg);
846 }
847 }
848 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700849 } else { // Handle other capture failures
850 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800851 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800852 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
853 failure->frameNumber = frameNumber;
854 // TODO: refine this when implementing flush
855 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
856 failure->sequenceId = sequenceId;
857 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800858 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800859
Emilian Peevedec62d2019-03-19 17:59:24 -0700860 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
861 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800862 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700864 if (cbh.mIsLogicalCameraCallback) {
865 if (resultExtras.errorPhysicalCameraId.size() > 0) {
866 String8 cameraId(resultExtras.errorPhysicalCameraId);
867 msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
868 }
869 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
870 } else {
871 msg->setPointer(kCallbackFpKey, (void*) onError);
872 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800873 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
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700884void CameraDevice::stopLooperAndDisconnect() {
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700885 Mutex::Autolock _l(mDeviceLock);
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700886 sp<ACameraCaptureSession> session = mCurrentSession.promote();
887 if (!isClosed()) {
888 disconnectLocked(session);
889 }
890 mCurrentSession = nullptr;
891
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700892 if (mCbLooper != nullptr) {
893 mCbLooper->unregisterHandler(mHandler->id());
894 mCbLooper->stop();
895 }
896 mCbLooper.clear();
897 mHandler.clear();
898}
899
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800900CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
901}
902
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800903void CameraDevice::CallbackHandler::onMessageReceived(
904 const sp<AMessage> &msg) {
905 switch (msg->what()) {
906 case kWhatOnDisconnected:
907 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800908 case kWhatSessionStateCb:
909 case kWhatCaptureStart:
910 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800911 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800912 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700913 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800914 case kWhatCaptureSeqEnd:
915 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700916 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800917 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800918 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700919 case kWhatCleanUpSessions:
920 mCachedSessions.clear();
921 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800922 default:
923 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
924 return;
925 }
926 // Check the common part of all message
927 void* context;
928 bool found = msg->findPointer(kContextKey, &context);
929 if (!found) {
930 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
931 return;
932 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800933 switch (msg->what()) {
934 case kWhatOnDisconnected:
935 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800936 ACameraDevice* dev;
937 found = msg->findPointer(kDeviceKey, (void**) &dev);
938 if (!found || dev == nullptr) {
939 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
940 return;
941 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800942 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800943 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800944 if (!found) {
945 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
946 return;
947 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800948 if (onDisconnected == nullptr) {
949 return;
950 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800951 (*onDisconnected)(context, dev);
952 break;
953 }
954 case kWhatOnError:
955 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800956 ACameraDevice* dev;
957 found = msg->findPointer(kDeviceKey, (void**) &dev);
958 if (!found || dev == nullptr) {
959 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
960 return;
961 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800962 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800963 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800964 if (!found) {
965 ALOGE("%s: Cannot find onError!", __FUNCTION__);
966 return;
967 }
968 int errorCode;
969 found = msg->findInt32(kErrorCodeKey, &errorCode);
970 if (!found) {
971 ALOGE("%s: Cannot find error code!", __FUNCTION__);
972 return;
973 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800974 if (onError == nullptr) {
975 return;
976 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800977 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800978 break;
979 }
980 case kWhatSessionStateCb:
981 case kWhatCaptureStart:
982 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800983 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800984 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700985 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800986 case kWhatCaptureSeqEnd:
987 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700988 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800989 {
990 sp<RefBase> obj;
991 found = msg->findObject(kSessionSpKey, &obj);
992 if (!found || obj == nullptr) {
993 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
994 return;
995 }
996 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700997 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800998 sp<CaptureRequest> requestSp = nullptr;
999 switch (msg->what()) {
1000 case kWhatCaptureStart:
1001 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001002 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001003 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001004 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001005 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001006 found = msg->findObject(kCaptureRequestKey, &obj);
1007 if (!found) {
1008 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1009 return;
1010 }
1011 requestSp = static_cast<CaptureRequest*>(obj.get());
1012 break;
1013 }
1014
1015 switch (msg->what()) {
1016 case kWhatSessionStateCb:
1017 {
1018 ACameraCaptureSession_stateCallback onState;
1019 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1020 if (!found) {
1021 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1022 return;
1023 }
1024 if (onState == nullptr) {
1025 return;
1026 }
1027 (*onState)(context, session.get());
1028 break;
1029 }
1030 case kWhatCaptureStart:
1031 {
1032 ACameraCaptureSession_captureCallback_start onStart;
1033 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1034 if (!found) {
1035 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1036 return;
1037 }
1038 if (onStart == nullptr) {
1039 return;
1040 }
1041 int64_t timestamp;
1042 found = msg->findInt64(kTimeStampKey, &timestamp);
1043 if (!found) {
1044 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1045 return;
1046 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001047 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001048 (*onStart)(context, session.get(), request, timestamp);
1049 freeACaptureRequest(request);
1050 break;
1051 }
1052 case kWhatCaptureResult:
1053 {
1054 ACameraCaptureSession_captureCallback_result onResult;
1055 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1056 if (!found) {
1057 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1058 return;
1059 }
1060 if (onResult == nullptr) {
1061 return;
1062 }
1063
1064 found = msg->findObject(kCaptureResultKey, &obj);
1065 if (!found) {
1066 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1067 return;
1068 }
1069 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001070 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001071 (*onResult)(context, session.get(), request, result.get());
1072 freeACaptureRequest(request);
1073 break;
1074 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001075 case kWhatLogicalCaptureResult:
1076 {
1077 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1078 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1079 if (!found) {
1080 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1081 __FUNCTION__);
1082 return;
1083 }
1084 if (onResult == nullptr) {
1085 return;
1086 }
1087
1088 found = msg->findObject(kCaptureResultKey, &obj);
1089 if (!found) {
1090 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1091 return;
1092 }
1093 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1094
1095 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1096 if (!found) {
1097 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1098 return;
1099 }
1100 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1101 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1102 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1103 physicalResult->mPhysicalResultInfo;
1104
1105 std::vector<std::string> physicalCameraIds;
1106 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1107 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1108 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1109 physicalCameraIds.push_back(physicalId8.c_str());
1110
1111 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1112 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1113 &physicalResult->mFrameNumber, /*data_count*/1);
1114 sp<ACameraMetadata> metadata =
1115 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1116 physicalMetadataCopy.push_back(metadata);
1117 }
1118
1119 std::vector<const char*> physicalCameraIdPtrs;
1120 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1121 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1122 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1123 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1124 }
1125
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001126 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001127 (*onResult)(context, session.get(), request, result.get(),
1128 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1129 physicalMetadataCopyPtrs.data());
1130 freeACaptureRequest(request);
1131 break;
1132 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001133 case kWhatCaptureFail:
1134 {
1135 ACameraCaptureSession_captureCallback_failed onFail;
1136 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1137 if (!found) {
1138 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1139 return;
1140 }
1141 if (onFail == nullptr) {
1142 return;
1143 }
1144
1145 found = msg->findObject(kCaptureFailureKey, &obj);
1146 if (!found) {
1147 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1148 return;
1149 }
1150 sp<CameraCaptureFailure> failureSp(
1151 static_cast<CameraCaptureFailure*>(obj.get()));
1152 ACameraCaptureFailure* failure =
1153 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001154 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001155 (*onFail)(context, session.get(), request, failure);
1156 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001157 break;
1158 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001159 case kWhatLogicalCaptureFail:
1160 {
1161 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1162 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1163 if (!found) {
1164 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1165 return;
1166 }
1167 if (onFail == nullptr) {
1168 return;
1169 }
1170
1171 found = msg->findObject(kCaptureFailureKey, &obj);
1172 if (!found) {
1173 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1174 return;
1175 }
1176 sp<CameraCaptureFailure> failureSp(
1177 static_cast<CameraCaptureFailure*>(obj.get()));
1178 ALogicalCameraCaptureFailure failure;
1179 AString physicalCameraId;
1180 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1181 if (found && !physicalCameraId.empty()) {
1182 failure.physicalCameraId = physicalCameraId.c_str();
1183 } else {
1184 failure.physicalCameraId = nullptr;
1185 }
1186 failure.captureFailure = *failureSp;
1187 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1188 (*onFail)(context, session.get(), request, &failure);
1189 freeACaptureRequest(request);
1190 break;
1191 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001192 case kWhatCaptureSeqEnd:
1193 {
1194 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1195 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1196 if (!found) {
1197 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1198 return;
1199 }
1200 if (onSeqEnd == nullptr) {
1201 return;
1202 }
1203 int seqId;
1204 found = msg->findInt32(kSequenceIdKey, &seqId);
1205 if (!found) {
1206 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1207 return;
1208 }
1209 int64_t frameNumber;
1210 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1211 if (!found) {
1212 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1213 return;
1214 }
1215 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1216 break;
1217 }
1218 case kWhatCaptureSeqAbort:
1219 {
1220 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1221 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1222 if (!found) {
1223 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1224 return;
1225 }
1226 if (onSeqAbort == nullptr) {
1227 return;
1228 }
1229 int seqId;
1230 found = msg->findInt32(kSequenceIdKey, &seqId);
1231 if (!found) {
1232 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1233 return;
1234 }
1235 (*onSeqAbort)(context, session.get(), seqId);
1236 break;
1237 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001238 case kWhatCaptureBufferLost:
1239 {
1240 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1241 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1242 if (!found) {
1243 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1244 return;
1245 }
1246 if (onBufferLost == nullptr) {
1247 return;
1248 }
1249
1250 ANativeWindow* anw;
1251 found = msg->findPointer(kAnwKey, (void**) &anw);
1252 if (!found) {
1253 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1254 return;
1255 }
1256
1257 int64_t frameNumber;
1258 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1259 if (!found) {
1260 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1261 return;
1262 }
1263
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001264 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001265 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1266 freeACaptureRequest(request);
1267 break;
1268 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001269 }
1270 break;
1271 }
1272 }
1273}
1274
1275CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001276 sp<ACameraCaptureSession> session,
1277 const Vector<sp<CaptureRequest> >& requests,
1278 bool isRepeating,
1279 ACameraCaptureSession_captureCallbacks* cbs) :
1280 mSession(session), mRequests(requests),
1281 mIsRepeating(isRepeating),
1282 mIsLogicalCameraCallback(false) {
1283 initCaptureCallbacks(cbs);
1284
1285 if (cbs != nullptr) {
1286 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001287 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001288 }
1289}
1290
1291CameraDevice::CallbackHolder::CallbackHolder(
1292 sp<ACameraCaptureSession> session,
1293 const Vector<sp<CaptureRequest> >& requests,
1294 bool isRepeating,
1295 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1296 mSession(session), mRequests(requests),
1297 mIsRepeating(isRepeating),
1298 mIsLogicalCameraCallback(true) {
1299 initCaptureCallbacks(lcbs);
1300
1301 if (lcbs != nullptr) {
1302 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001303 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001304 }
1305}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001306
1307void
1308CameraDevice::checkRepeatingSequenceCompleteLocked(
1309 const int sequenceId, const int64_t lastFrameNumber) {
1310 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1311 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1312 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1313 ALOGW("No callback found for sequenceId %d", sequenceId);
1314 return;
1315 }
1316 // remove callback holder from callback map
1317 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1318 CallbackHolder cbh = cbIt->second;
1319 mSequenceCallbackMap.erase(cbIt);
1320 // send seq aborted callback
1321 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001322 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001323 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001324 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001325 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001326 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001327 } else {
1328 // Use mSequenceLastFrameNumberMap to track
1329 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1330
1331 // Last frame might have arrived. Check now
1332 checkAndFireSequenceCompleteLocked();
1333 }
1334}
1335
1336void
1337CameraDevice::checkAndFireSequenceCompleteLocked() {
1338 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001339 auto it = mSequenceLastFrameNumberMap.begin();
1340 while (it != mSequenceLastFrameNumberMap.end()) {
1341 int sequenceId = it->first;
Shuzhen Wang730a7912020-05-07 11:59:02 -07001342 int64_t lastFrameNumber = it->second.lastFrameNumber;
1343 bool hasCallback = true;
1344
1345 if (mRemote == nullptr) {
1346 ALOGW("Camera %s closed while checking sequence complete", getId());
1347 return;
1348 }
1349 ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1350 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1351 if (!it->second.isSequenceCompleted) {
1352 // Check if there is callback for this sequence
1353 // This should not happen because we always register callback (with nullptr inside)
1354 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1355 ALOGW("No callback found for sequenceId %d", sequenceId);
1356 hasCallback = false;
1357 }
1358
1359 if (lastFrameNumber <= completedFrameNumber) {
1360 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1361 it->second.isSequenceCompleted = true;
1362 }
1363
1364 if (it->second.isSequenceCompleted && hasCallback) {
1365 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1366 CallbackHolder cbh = cbIt->second;
1367
1368 // send seq complete callback
1369 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1370 msg->setPointer(kContextKey, cbh.mContext);
1371 msg->setObject(kSessionSpKey, cbh.mSession);
1372 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1373 msg->setInt32(kSequenceIdKey, sequenceId);
1374 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1375
1376 // Clear the session sp before we send out the message
1377 // This will guarantee the rare case where the message is processed
1378 // before cbh goes out of scope and causing we call the session
1379 // destructor while holding device lock
1380 cbh.mSession.clear();
1381 postSessionMsgAndCleanup(msg);
1382 }
1383 }
1384
1385 if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
1386 if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
1387 mSequenceCallbackMap.erase(sequenceId);
1388 }
1389 it = mSequenceLastFrameNumberMap.erase(it);
1390 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1391 } else {
1392 ++it;
1393 }
1394 }
1395}
1396
1397void
1398CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1399 auto it = mSequenceLastFrameNumberMap.begin();
1400 while (it != mSequenceLastFrameNumberMap.end()) {
1401 int sequenceId = it->first;
1402 int64_t lastFrameNumber = it->second.lastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001403
1404 if (mRemote == nullptr) {
1405 ALOGW("Camera %s closed while checking sequence complete", getId());
1406 return;
1407 }
1408
Shuzhen Wang730a7912020-05-07 11:59:02 -07001409 ALOGV("%s: seq %d's last frame number %" PRId64
1410 ", completed inflight frame number %" PRId64,
1411 __FUNCTION__, sequenceId, lastFrameNumber,
1412 lastCompletedRegularFrameNumber);
1413 if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1414 if (it->second.isSequenceCompleted) {
1415 // Check if there is callback for this sequence
1416 // This should not happen because we always register callback (with nullptr inside)
1417 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1418 ALOGW("No callback found for sequenceId %d", sequenceId);
1419 } else {
1420 mSequenceCallbackMap.erase(sequenceId);
1421 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001422
Shuzhen Wang730a7912020-05-07 11:59:02 -07001423 it = mSequenceLastFrameNumberMap.erase(it);
1424 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1425 } else {
1426 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1427 it->second.isInflightCompleted = true;
1428 ++it;
1429 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001430 } else {
1431 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001432 }
1433 }
1434}
1435
1436/**
1437 * Camera service callback implementation
1438 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001439binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001440CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001441 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001442 const CaptureResultExtras& resultExtras) {
1443 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1444 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001445 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001446 sp<CameraDevice> dev = mDevice.promote();
1447 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001448 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001449 }
1450
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001451 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001452 Mutex::Autolock _l(dev->mDeviceLock);
1453 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001454 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001455 }
1456 switch (errorCode) {
1457 case ERROR_CAMERA_DISCONNECTED:
1458 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001459 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001460 if (session != nullptr) {
1461 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001462 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001463 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001464 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1465 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1466 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001467 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001468 msg->post();
1469 break;
1470 }
1471 default:
1472 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001473 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001474 case ERROR_CAMERA_DEVICE:
1475 case ERROR_CAMERA_SERVICE:
1476 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001477 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1478 // We keep this switch since this block might be encountered with
1479 // more than just 2 states. The default fallthrough could have us
1480 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001481 switch (errorCode) {
1482 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001483 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001484 break;
1485 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001486 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001487 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001488 break;
1489 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001490 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001491 break;
1492 }
1493 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1494 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1495 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001496 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001497 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001498 msg->post();
1499 break;
1500 }
1501 case ERROR_CAMERA_REQUEST:
1502 case ERROR_CAMERA_RESULT:
1503 case ERROR_CAMERA_BUFFER:
1504 dev->onCaptureErrorLocked(errorCode, resultExtras);
1505 break;
1506 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001507 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001508}
1509
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001510binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001511CameraDevice::ServiceCallback::onDeviceIdle() {
1512 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001513 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001514 sp<CameraDevice> dev = mDevice.promote();
1515 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001516 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001517 }
1518
1519 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001520 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001521 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001522 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001523
Shuzhen Wang730a7912020-05-07 11:59:02 -07001524 dev->removeCompletedCallbackHolderLocked(
1525 std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1526
Yin-Chia Yehead91462016-01-06 16:45:08 -08001527 if (dev->mIdle) {
1528 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001529 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001530 }
1531
1532 if (dev->mCurrentSession != nullptr) {
1533 ALOGE("onDeviceIdle sending state cb");
1534 if (dev->mBusySession != dev->mCurrentSession) {
1535 ALOGE("Current session != busy session");
1536 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001537 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001538 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001539
Yin-Chia Yehead91462016-01-06 16:45:08 -08001540 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1541 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1542 msg->setObject(kSessionSpKey, dev->mBusySession);
1543 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1544 // Make sure we clear the sp first so the session destructor can
1545 // only happen on handler thread (where we don't hold device/session lock)
1546 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001547 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001548 }
1549 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001550 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001551 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001552}
1553
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001554binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001555CameraDevice::ServiceCallback::onCaptureStarted(
1556 const CaptureResultExtras& resultExtras,
1557 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001558 binder::Status ret = binder::Status::ok();
1559
Yin-Chia Yehead91462016-01-06 16:45:08 -08001560 sp<CameraDevice> dev = mDevice.promote();
1561 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001562 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001563 }
1564 Mutex::Autolock _l(dev->mDeviceLock);
1565 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001566 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001567 }
1568
Shuzhen Wang730a7912020-05-07 11:59:02 -07001569 dev->removeCompletedCallbackHolderLocked(
1570 resultExtras.lastCompletedRegularFrameNumber);
1571
Yin-Chia Yehead91462016-01-06 16:45:08 -08001572 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001573 int32_t burstId = resultExtras.burstId;
1574
1575 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1576 if (it != dev->mSequenceCallbackMap.end()) {
1577 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001578 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001579 sp<ACameraCaptureSession> session = cbh.mSession;
1580 if ((size_t) burstId >= cbh.mRequests.size()) {
1581 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1582 __FUNCTION__, burstId, cbh.mRequests.size());
1583 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1584 }
1585 sp<CaptureRequest> request = cbh.mRequests[burstId];
1586 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001587 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001588 msg->setObject(kSessionSpKey, session);
1589 msg->setPointer(kCallbackFpKey, (void*) onStart);
1590 msg->setObject(kCaptureRequestKey, request);
1591 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001592 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001593 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001594 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001595}
1596
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001597binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001598CameraDevice::ServiceCallback::onResultReceived(
1599 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001600 const CaptureResultExtras& resultExtras,
1601 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001602 binder::Status ret = binder::Status::ok();
1603
Yin-Chia Yehead91462016-01-06 16:45:08 -08001604 sp<CameraDevice> dev = mDevice.promote();
1605 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001606 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001607 }
1608 int sequenceId = resultExtras.requestId;
1609 int64_t frameNumber = resultExtras.frameNumber;
1610 int32_t burstId = resultExtras.burstId;
1611 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1612
1613 if (!isPartialResult) {
1614 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1615 }
1616
1617 Mutex::Autolock _l(dev->mDeviceLock);
1618 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001619 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001620 }
1621
1622 if (dev->isClosed()) {
1623 if (!isPartialResult) {
1624 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1625 }
1626 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001627 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001628 }
1629
1630 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001631 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001632 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001633
1634 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1635 if (it != dev->mSequenceCallbackMap.end()) {
1636 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001637 sp<ACameraCaptureSession> session = cbh.mSession;
1638 if ((size_t) burstId >= cbh.mRequests.size()) {
1639 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1640 __FUNCTION__, burstId, cbh.mRequests.size());
1641 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1642 }
1643 sp<CaptureRequest> request = cbh.mRequests[burstId];
1644 sp<ACameraMetadata> result(new ACameraMetadata(
1645 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001646 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1647 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001648
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001649 sp<AMessage> msg = new AMessage(
1650 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1651 dev->mHandler);
1652 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001653 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001654 msg->setObject(kCaptureRequestKey, request);
1655 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001656 if (isPartialResult) {
1657 msg->setPointer(kCallbackFpKey,
1658 (void *)cbh.mOnCaptureProgressed);
1659 } else if (cbh.mIsLogicalCameraCallback) {
1660 msg->setPointer(kCallbackFpKey,
1661 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1662 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1663 } else {
1664 msg->setPointer(kCallbackFpKey,
1665 (void *)cbh.mOnCaptureCompleted);
1666 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001667 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001668 }
1669
1670 if (!isPartialResult) {
1671 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1672 dev->checkAndFireSequenceCompleteLocked();
1673 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001674
1675 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001676}
1677
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001678binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001679CameraDevice::ServiceCallback::onPrepared(int) {
1680 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001681 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001682}
1683
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001684binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001685CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1686 // onRequestQueueEmpty not yet implemented in NDK
1687 return binder::Status::ok();
1688}
1689
1690binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001691CameraDevice::ServiceCallback::onRepeatingRequestError(
1692 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001693 binder::Status ret = binder::Status::ok();
1694
1695 sp<CameraDevice> dev = mDevice.promote();
1696 if (dev == nullptr) {
1697 return ret; // device has been closed
1698 }
1699
1700 Mutex::Autolock _l(dev->mDeviceLock);
1701
1702 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001703 if (stoppedSequenceId == repeatingSequenceId) {
1704 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1705 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001706
1707 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1708
1709 return ret;
1710}
1711
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001712} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001713} // namespace android