blob: 08c88ce8ee12265a92870830ad938eacaa78e3a7 [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) {
Shuzhen Wang316781a2020-08-18 18:11:01 -0700189 nsecs_t startTimeNs = systemTime();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700190 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800191 Mutex::Autolock _l(mDeviceLock);
192 camera_status_t ret = checkCameraClosedOrErrorLocked();
193 if (ret != ACAMERA_OK) {
194 return ret;
195 }
196
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700197 if (currentSession != nullptr) {
198 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800199 stopRepeatingLocked();
200 }
201
202 // Create new session
Shuzhen Wang316781a2020-08-18 18:11:01 -0700203 ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800204 if (ret != ACAMERA_OK) {
205 ALOGE("Fail to create new session. cannot configure streams");
206 return ret;
207 }
208
209 ACameraCaptureSession* newSession = new ACameraCaptureSession(
210 mNextSessionId++, outputs, callbacks, this);
211
Yin-Chia Yehead91462016-01-06 16:45:08 -0800212 // set new session as current session
213 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
214 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700215 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800216 *session = newSession;
217 return ACAMERA_OK;
218}
219
Shuzhen Wang24810e72019-03-18 10:55:01 -0700220camera_status_t CameraDevice::isSessionConfigurationSupported(
221 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
222 Mutex::Autolock _l(mDeviceLock);
223 camera_status_t ret = checkCameraClosedOrErrorLocked();
224 if (ret != ACAMERA_OK) {
225 return ret;
226 }
227
228 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
229 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
230 for (const auto& output : sessionOutputContainer->mOutputs) {
231 sp<IGraphicBufferProducer> iGBP(nullptr);
232 ret = getIGBPfromAnw(output.mWindow, iGBP);
233 if (ret != ACAMERA_OK) {
234 ALOGE("Camera device %s failed to extract graphic producer from native window",
235 getId());
236 return ret;
237 }
238
239 String16 physicalId16(output.mPhysicalCameraId.c_str());
240 OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
241 OutputConfiguration::INVALID_SET_ID, true);
242
243 for (auto& anw : output.mSharedWindows) {
244 ret = getIGBPfromAnw(anw, iGBP);
245 if (ret != ACAMERA_OK) {
246 ALOGE("Camera device %s failed to extract graphic producer from native window",
247 getId());
248 return ret;
249 }
250 outConfig.addGraphicProducer(iGBP);
251 }
252
253 sessionConfiguration.addOutputConfiguration(outConfig);
254 }
255
256 bool supported = false;
257 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
258 sessionConfiguration, &supported);
259 if (remoteRet.serviceSpecificErrorCode() ==
260 hardware::ICameraService::ERROR_INVALID_OPERATION) {
261 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
262 } else if (!remoteRet.isOk()) {
263 return ACAMERA_ERROR_UNKNOWN;
264 } else {
265 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
266 }
267}
268
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800269camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100270 camera_status_t ret = checkCameraClosedOrErrorLocked();
271 if (ret != ACAMERA_OK) {
272 return ret;
273 }
274
275 if (output == nullptr) {
276 return ACAMERA_ERROR_INVALID_PARAMETER;
277 }
278
279 if (!output->mIsShared) {
280 ALOGE("Error output configuration is not shared");
281 return ACAMERA_ERROR_INVALID_OPERATION;
282 }
283
284 int32_t streamId = -1;
285 for (auto& kvPair : mConfiguredOutputs) {
286 if (kvPair.second.first == output->mWindow) {
287 streamId = kvPair.first;
288 break;
289 }
290 }
291 if (streamId < 0) {
292 ALOGE("Error: Invalid output configuration");
293 return ACAMERA_ERROR_INVALID_PARAMETER;
294 }
295
296 sp<IGraphicBufferProducer> iGBP(nullptr);
297 ret = getIGBPfromAnw(output->mWindow, iGBP);
298 if (ret != ACAMERA_OK) {
299 ALOGE("Camera device %s failed to extract graphic producer from native window",
300 getId());
301 return ret;
302 }
303
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800304 String16 physicalId16(output->mPhysicalCameraId.c_str());
305 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
306 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100307
308 for (auto& anw : output->mSharedWindows) {
309 ret = getIGBPfromAnw(anw, iGBP);
310 if (ret != ACAMERA_OK) {
311 ALOGE("Camera device %s failed to extract graphic producer from native window",
312 getId());
313 return ret;
314 }
315 outConfig.addGraphicProducer(iGBP);
316 }
317
318 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
319 if (!remoteRet.isOk()) {
320 switch (remoteRet.serviceSpecificErrorCode()) {
321 case hardware::ICameraService::ERROR_INVALID_OPERATION:
322 ALOGE("Camera device %s invalid operation: %s", getId(),
323 remoteRet.toString8().string());
324 return ACAMERA_ERROR_INVALID_OPERATION;
325 break;
326 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
327 ALOGE("Camera device %s output surface already exists: %s", getId(),
328 remoteRet.toString8().string());
329 return ACAMERA_ERROR_INVALID_PARAMETER;
330 break;
331 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
332 ALOGE("Camera device %s invalid input argument: %s", getId(),
333 remoteRet.toString8().string());
334 return ACAMERA_ERROR_INVALID_PARAMETER;
335 break;
336 default:
337 ALOGE("Camera device %s failed to add shared output: %s", getId(),
338 remoteRet.toString8().string());
339 return ACAMERA_ERROR_UNKNOWN;
340 }
341 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800342 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100343
344 return ACAMERA_OK;
345}
346
Yin-Chia Yehead91462016-01-06 16:45:08 -0800347camera_status_t
348CameraDevice::allocateCaptureRequest(
349 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
350 camera_status_t ret;
351 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800352 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000353 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800354 for (auto& entry : request->physicalSettings) {
355 req->mPhysicalCameraSettings.push_back({entry.first,
356 entry.second->getInternalData()});
357 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800358 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700359 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800360 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800361
362 for (auto outputTarget : request->targets->mOutputs) {
363 ANativeWindow* anw = outputTarget.mWindow;
364 sp<Surface> surface;
365 ret = getSurfaceFromANativeWindow(anw, surface);
366 if (ret != ACAMERA_OK) {
367 ALOGE("Bad output target in capture request! ret %d", ret);
368 return ret;
369 }
370 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800371
372 bool found = false;
373 // lookup stream/surface ID
374 for (const auto& kvPair : mConfiguredOutputs) {
375 int streamId = kvPair.first;
376 const OutputConfiguration& outConfig = kvPair.second.second;
377 const auto& gbps = outConfig.getGraphicBufferProducers();
378 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
379 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
380 found = true;
381 req->mStreamIdxList.push_back(streamId);
382 req->mSurfaceIdxList.push_back(surfaceId);
383 break;
384 }
385 }
386 if (found) {
387 break;
388 }
389 }
390 if (!found) {
391 ALOGE("Unconfigured output target %p in capture request!", anw);
392 return ret;
393 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800394 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800395
Yin-Chia Yehead91462016-01-06 16:45:08 -0800396 outReq = req;
397 return ACAMERA_OK;
398}
399
400ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800401CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800402 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800403 for (auto& entry : req->mPhysicalCameraSettings) {
404 CameraMetadata clone = entry.settings;
405 if (entry.id == deviceId) {
406 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
407 } else {
408 pRequest->physicalSettings.emplace(entry.id,
409 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
410 }
411 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800412 pRequest->targets = new ACameraOutputTargets();
413 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
414 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
415 ACameraOutputTarget outputTarget(anw);
416 pRequest->targets->mOutputs.insert(outputTarget);
417 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700418 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800419 return pRequest;
420}
421
422void
423CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
424 if (req == nullptr) {
425 return;
426 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700427 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800428 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800429 delete req->targets;
430 delete req;
431}
432
433void
434CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
435 if (isClosed()) {
436 // Device is closing already. do nothing
437 return;
438 }
439
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700440 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800441 // Session has been replaced by other seesion or device is closed
442 return;
443 }
444 mCurrentSession = nullptr;
445
446 // Should not happen
447 if (!session->mIsClosed) {
448 ALOGE("Error: unclosed session %p reaches end of life!", session);
449 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
450 return;
451 }
452
453 // No new session, unconfigure now
Shuzhen Wang316781a2020-08-18 18:11:01 -0700454 // Note: The unconfiguration of session won't be accounted for session
455 // latency because a stream configuration with 0 streams won't ever become
456 // active.
457 nsecs_t startTimeNs = systemTime();
458 camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800459 if (ret != ACAMERA_OK) {
460 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
461 }
462}
463
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800464void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700465CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800466 if (mClosing.exchange(true)) {
467 // Already closing, just return
468 ALOGW("Camera device %s is already closing.", getId());
469 return;
470 }
471
472 if (mRemote != nullptr) {
473 mRemote->disconnect();
474 }
475 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800476
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700477 if (session != nullptr) {
478 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800479 }
480}
481
482camera_status_t
483CameraDevice::stopRepeatingLocked() {
484 camera_status_t ret = checkCameraClosedOrErrorLocked();
485 if (ret != ACAMERA_OK) {
486 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
487 return ret;
488 }
489 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
490 int repeatingSequenceId = mRepeatingSequenceId;
491 mRepeatingSequenceId = REQUEST_ID_NONE;
492
493 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800494 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700495 if (remoteRet.serviceSpecificErrorCode() ==
496 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
497 ALOGV("Repeating request is already stopped.");
498 return ACAMERA_OK;
499 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800500 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800501 return ACAMERA_ERROR_UNKNOWN;
502 }
503 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
504 }
505 return ACAMERA_OK;
506}
507
508camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700509CameraDevice::flushLocked(ACameraCaptureSession* session) {
510 camera_status_t ret = checkCameraClosedOrErrorLocked();
511 if (ret != ACAMERA_OK) {
512 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
513 return ret;
514 }
515
516 // This should never happen because creating a new session will close
517 // previous one and thus reject any API call from previous session.
518 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700519 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700520 ALOGE("Camera %s session %p is not current active session!", getId(), session);
521 return ACAMERA_ERROR_INVALID_OPERATION;
522 }
523
524 if (mFlushing) {
525 ALOGW("Camera %s is already aborting captures", getId());
526 return ACAMERA_OK;
527 }
528
529 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700530
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700531 // Send onActive callback to guarantee there is always active->ready transition
532 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
533 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
534 msg->setObject(kSessionSpKey, session);
535 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700536 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700537
538 // If device is already idling, send callback and exit early
539 if (mIdle) {
540 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
541 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
542 msg->setObject(kSessionSpKey, session);
543 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700544 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700545 mFlushing = false;
546 return ACAMERA_OK;
547 }
548
549 int64_t lastFrameNumber;
550 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
551 if (!remoteRet.isOk()) {
552 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
553 return ACAMERA_ERROR_UNKNOWN;
554 }
555 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
556 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
557 }
558 return ACAMERA_OK;
559}
560
561camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800562CameraDevice::waitUntilIdleLocked() {
563 camera_status_t ret = checkCameraClosedOrErrorLocked();
564 if (ret != ACAMERA_OK) {
565 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
566 return ret;
567 }
568
569 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
570 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
571 return ACAMERA_ERROR_INVALID_OPERATION;
572 }
573
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800574 binder::Status remoteRet = mRemote->waitUntilIdle();
575 if (!remoteRet.isOk()) {
576 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800577 // TODO: define a function to convert status_t -> camera_status_t
578 return ACAMERA_ERROR_UNKNOWN;
579 }
580
581 return ACAMERA_OK;
582}
583
584camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700585CameraDevice::getIGBPfromAnw(
586 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800587 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800588 sp<Surface> surface;
589 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
590 if (ret != ACAMERA_OK) {
591 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800592 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800593 out = surface->getIGraphicBufferProducer();
594 return ACAMERA_OK;
595}
596
597camera_status_t
598CameraDevice::getSurfaceFromANativeWindow(
599 ANativeWindow* anw, sp<Surface>& out) {
600 if (anw == nullptr) {
601 ALOGE("Error: output ANativeWindow is null");
602 return ACAMERA_ERROR_INVALID_PARAMETER;
603 }
604 int value;
605 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800606 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800607 ALOGE("Error: ANativeWindow is not backed by Surface!");
608 return ACAMERA_ERROR_INVALID_PARAMETER;
609 }
610 sp<Surface> surface(static_cast<Surface*>(anw));
611 out = surface;
612 return ACAMERA_OK;
613}
614
615camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100616CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700617 const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800618 ACaptureSessionOutputContainer emptyOutput;
619 if (outputs == nullptr) {
620 outputs = &emptyOutput;
621 }
622
Yin-Chia Yehead91462016-01-06 16:45:08 -0800623 camera_status_t ret = checkCameraClosedOrErrorLocked();
624 if (ret != ACAMERA_OK) {
625 return ret;
626 }
627
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700628 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800629 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700630 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800631 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700632 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800633 if (ret != ACAMERA_OK) {
634 return ret;
635 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800636 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700637 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800638 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100639 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800640 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700641 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800642 std::vector<int> deleteList;
643
644 // Determine which streams need to be created, which to be deleted
645 for (auto& kvPair : mConfiguredOutputs) {
646 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700647 auto& outputPair = kvPair.second;
648 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800649 deleteList.push_back(streamId); // Need to delete a no longer needed stream
650 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700651 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800652 }
653 }
654
655 ret = stopRepeatingLocked();
656 if (ret != ACAMERA_OK) {
657 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
658 return ret;
659 }
660
661 ret = waitUntilIdleLocked();
662 if (ret != ACAMERA_OK) {
663 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
664 return ret;
665 }
666
667 // Send onReady to previous session
668 // CurrentSession will be updated after configureStreamLocked, so here
669 // mCurrentSession is the session to be replaced by a new session
670 if (!mIdle && mCurrentSession != nullptr) {
671 if (mBusySession != mCurrentSession) {
672 ALOGE("Current session != busy session");
673 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
674 return ACAMERA_ERROR_CAMERA_DEVICE;
675 }
676 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
677 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
678 msg->setObject(kSessionSpKey, mBusySession);
679 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
680 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700681 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800682 }
683 mIdle = true;
684
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800685 binder::Status remoteRet = mRemote->beginConfigure();
686 if (!remoteRet.isOk()) {
687 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800688 return ACAMERA_ERROR_UNKNOWN;
689 }
690
691 // delete to-be-deleted streams
692 for (auto streamId : deleteList) {
693 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800694 if (!remoteRet.isOk()) {
695 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
696 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800697 return ACAMERA_ERROR_UNKNOWN;
698 }
699 mConfiguredOutputs.erase(streamId);
700 }
701
702 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800703 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800704 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700705 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800706 if (!remoteRet.isOk()) {
707 ALOGE("Camera device %s failed to create stream: %s", getId(),
708 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800709 return ACAMERA_ERROR_UNKNOWN;
710 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700711 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800712 }
713
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100714 CameraMetadata params;
715 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
716 params.append(sessionParameters->settings->getInternalData());
717 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800718 std::vector<int> offlineStreamIds;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700719 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
720 ns2ms(startTimeNs), &offlineStreamIds);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800721 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
722 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
723 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800724 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800725 } else if (!remoteRet.isOk()) {
726 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800727 return ACAMERA_ERROR_UNKNOWN;
728 }
729
730 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800731}
732
733void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800734CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800735 Mutex::Autolock _l(mDeviceLock);
736 mRemote = remote;
737}
738
739camera_status_t
740CameraDevice::checkCameraClosedOrErrorLocked() const {
741 if (mRemote == nullptr) {
742 ALOGE("%s: camera device already closed", __FUNCTION__);
743 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
744 }
745 if (mInError) {// triggered by onDeviceError
746 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
747 return mError;
748 }
749 return ACAMERA_OK;
750}
751
752void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800753CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
754 mInError = true;
755 mError = error;
756 return;
757}
758
759void
760CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
761 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
762 if (isError) {
763 mFutureErrorSet.insert(frameNumber);
764 } else if (frameNumber <= mCompletedFrameNumber) {
765 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
766 frameNumber, mCompletedFrameNumber);
767 return;
768 } else {
769 if (frameNumber != mCompletedFrameNumber + 1) {
770 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
771 mCompletedFrameNumber + 1, frameNumber);
772 // Do not assert as in java implementation
773 }
774 mCompletedFrameNumber = frameNumber;
775 }
776 update();
777}
778
779void
780CameraDevice::FrameNumberTracker::update() {
781 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
782 int64_t errorFrameNumber = *it;
783 if (errorFrameNumber == mCompletedFrameNumber + 1) {
784 mCompletedFrameNumber++;
785 it = mFutureErrorSet.erase(it);
786 } else if (errorFrameNumber <= mCompletedFrameNumber) {
787 // This should not happen, but deal with it anyway
788 ALOGE("Completd frame number passed through current frame number!");
789 // erase the old error since it's no longer useful
790 it = mFutureErrorSet.erase(it);
791 } else {
792 // Normal requests hasn't catched up error frames, just break
793 break;
794 }
795 }
796 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
797}
798
799void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800800CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800801 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800802 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800803 int sequenceId = resultExtras.requestId;
804 int64_t frameNumber = resultExtras.frameNumber;
805 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700806 auto it = mSequenceCallbackMap.find(sequenceId);
807 if (it == mSequenceCallbackMap.end()) {
808 ALOGE("%s: Error: capture sequence index %d not found!",
809 __FUNCTION__, sequenceId);
810 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800811 return;
812 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700813
814 CallbackHolder cbh = (*it).second;
815 sp<ACameraCaptureSession> session = cbh.mSession;
816 if ((size_t) burstId >= cbh.mRequests.size()) {
817 ALOGE("%s: Error: request index %d out of bound (size %zu)",
818 __FUNCTION__, burstId, cbh.mRequests.size());
819 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
820 return;
821 }
822 sp<CaptureRequest> request = cbh.mRequests[burstId];
823
824 // Handle buffer error
825 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
826 int32_t streamId = resultExtras.errorStreamId;
827 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800828 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700829 auto outputPairIt = mConfiguredOutputs.find(streamId);
830 if (outputPairIt == mConfiguredOutputs.end()) {
831 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800832 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
833 return;
834 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700835
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800836 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
837 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800838 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800839 if (surface->getIGraphicBufferProducer() == outGbp) {
840 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
841 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
842 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700843
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800844 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800845 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800846 msg->setObject(kSessionSpKey, session);
847 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
848 msg->setObject(kCaptureRequestKey, request);
849 msg->setPointer(kAnwKey, (void*) anw);
850 msg->setInt64(kFrameNumberKey, frameNumber);
851 postSessionMsgAndCleanup(msg);
852 }
853 }
854 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700855 } else { // Handle other capture failures
856 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800857 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800858 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
859 failure->frameNumber = frameNumber;
860 // TODO: refine this when implementing flush
861 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
862 failure->sequenceId = sequenceId;
863 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800864 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800865
Emilian Peevedec62d2019-03-19 17:59:24 -0700866 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
867 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800868 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800869 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700870 if (cbh.mIsLogicalCameraCallback) {
871 if (resultExtras.errorPhysicalCameraId.size() > 0) {
872 String8 cameraId(resultExtras.errorPhysicalCameraId);
873 msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
874 }
875 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
876 } else {
877 msg->setPointer(kCallbackFpKey, (void*) onError);
878 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800879 msg->setObject(kCaptureRequestKey, request);
880 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700881 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800882
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700883 // Update tracker
884 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
885 checkAndFireSequenceCompleteLocked();
886 }
887 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800888}
889
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700890void CameraDevice::stopLooperAndDisconnect() {
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700891 Mutex::Autolock _l(mDeviceLock);
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700892 sp<ACameraCaptureSession> session = mCurrentSession.promote();
893 if (!isClosed()) {
894 disconnectLocked(session);
895 }
896 mCurrentSession = nullptr;
897
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700898 if (mCbLooper != nullptr) {
899 mCbLooper->unregisterHandler(mHandler->id());
900 mCbLooper->stop();
901 }
902 mCbLooper.clear();
903 mHandler.clear();
904}
905
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800906CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
907}
908
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800909void CameraDevice::CallbackHandler::onMessageReceived(
910 const sp<AMessage> &msg) {
911 switch (msg->what()) {
912 case kWhatOnDisconnected:
913 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800914 case kWhatSessionStateCb:
915 case kWhatCaptureStart:
916 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800917 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800918 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700919 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800920 case kWhatCaptureSeqEnd:
921 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700922 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800923 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800924 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700925 case kWhatCleanUpSessions:
926 mCachedSessions.clear();
927 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800928 default:
929 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
930 return;
931 }
932 // Check the common part of all message
933 void* context;
934 bool found = msg->findPointer(kContextKey, &context);
935 if (!found) {
936 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
937 return;
938 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800939 switch (msg->what()) {
940 case kWhatOnDisconnected:
941 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800942 ACameraDevice* dev;
943 found = msg->findPointer(kDeviceKey, (void**) &dev);
944 if (!found || dev == nullptr) {
945 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
946 return;
947 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800948 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800949 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800950 if (!found) {
951 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
952 return;
953 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800954 if (onDisconnected == nullptr) {
955 return;
956 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800957 (*onDisconnected)(context, dev);
958 break;
959 }
960 case kWhatOnError:
961 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800962 ACameraDevice* dev;
963 found = msg->findPointer(kDeviceKey, (void**) &dev);
964 if (!found || dev == nullptr) {
965 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
966 return;
967 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800968 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800969 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800970 if (!found) {
971 ALOGE("%s: Cannot find onError!", __FUNCTION__);
972 return;
973 }
974 int errorCode;
975 found = msg->findInt32(kErrorCodeKey, &errorCode);
976 if (!found) {
977 ALOGE("%s: Cannot find error code!", __FUNCTION__);
978 return;
979 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800980 if (onError == nullptr) {
981 return;
982 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800983 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800984 break;
985 }
986 case kWhatSessionStateCb:
987 case kWhatCaptureStart:
988 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800989 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800990 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700991 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800992 case kWhatCaptureSeqEnd:
993 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700994 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800995 {
996 sp<RefBase> obj;
997 found = msg->findObject(kSessionSpKey, &obj);
998 if (!found || obj == nullptr) {
999 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
1000 return;
1001 }
1002 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001003 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001004 sp<CaptureRequest> requestSp = nullptr;
1005 switch (msg->what()) {
1006 case kWhatCaptureStart:
1007 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001008 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001009 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001010 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001011 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001012 found = msg->findObject(kCaptureRequestKey, &obj);
1013 if (!found) {
1014 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1015 return;
1016 }
1017 requestSp = static_cast<CaptureRequest*>(obj.get());
1018 break;
1019 }
1020
1021 switch (msg->what()) {
1022 case kWhatSessionStateCb:
1023 {
1024 ACameraCaptureSession_stateCallback onState;
1025 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1026 if (!found) {
1027 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1028 return;
1029 }
1030 if (onState == nullptr) {
1031 return;
1032 }
1033 (*onState)(context, session.get());
1034 break;
1035 }
1036 case kWhatCaptureStart:
1037 {
1038 ACameraCaptureSession_captureCallback_start onStart;
1039 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1040 if (!found) {
1041 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1042 return;
1043 }
1044 if (onStart == nullptr) {
1045 return;
1046 }
1047 int64_t timestamp;
1048 found = msg->findInt64(kTimeStampKey, &timestamp);
1049 if (!found) {
1050 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1051 return;
1052 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001053 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001054 (*onStart)(context, session.get(), request, timestamp);
1055 freeACaptureRequest(request);
1056 break;
1057 }
1058 case kWhatCaptureResult:
1059 {
1060 ACameraCaptureSession_captureCallback_result onResult;
1061 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1062 if (!found) {
1063 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1064 return;
1065 }
1066 if (onResult == nullptr) {
1067 return;
1068 }
1069
1070 found = msg->findObject(kCaptureResultKey, &obj);
1071 if (!found) {
1072 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1073 return;
1074 }
1075 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001076 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001077 (*onResult)(context, session.get(), request, result.get());
1078 freeACaptureRequest(request);
1079 break;
1080 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001081 case kWhatLogicalCaptureResult:
1082 {
1083 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1084 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1085 if (!found) {
1086 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1087 __FUNCTION__);
1088 return;
1089 }
1090 if (onResult == nullptr) {
1091 return;
1092 }
1093
1094 found = msg->findObject(kCaptureResultKey, &obj);
1095 if (!found) {
1096 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1097 return;
1098 }
1099 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1100
1101 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1102 if (!found) {
1103 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1104 return;
1105 }
1106 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1107 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1108 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1109 physicalResult->mPhysicalResultInfo;
1110
1111 std::vector<std::string> physicalCameraIds;
1112 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1113 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1114 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1115 physicalCameraIds.push_back(physicalId8.c_str());
1116
1117 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1118 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1119 &physicalResult->mFrameNumber, /*data_count*/1);
1120 sp<ACameraMetadata> metadata =
1121 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1122 physicalMetadataCopy.push_back(metadata);
1123 }
1124
1125 std::vector<const char*> physicalCameraIdPtrs;
1126 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1127 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1128 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1129 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1130 }
1131
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001132 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001133 (*onResult)(context, session.get(), request, result.get(),
1134 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1135 physicalMetadataCopyPtrs.data());
1136 freeACaptureRequest(request);
1137 break;
1138 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001139 case kWhatCaptureFail:
1140 {
1141 ACameraCaptureSession_captureCallback_failed onFail;
1142 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1143 if (!found) {
1144 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1145 return;
1146 }
1147 if (onFail == nullptr) {
1148 return;
1149 }
1150
1151 found = msg->findObject(kCaptureFailureKey, &obj);
1152 if (!found) {
1153 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1154 return;
1155 }
1156 sp<CameraCaptureFailure> failureSp(
1157 static_cast<CameraCaptureFailure*>(obj.get()));
1158 ACameraCaptureFailure* failure =
1159 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001160 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001161 (*onFail)(context, session.get(), request, failure);
1162 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001163 break;
1164 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001165 case kWhatLogicalCaptureFail:
1166 {
1167 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1168 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1169 if (!found) {
1170 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1171 return;
1172 }
1173 if (onFail == nullptr) {
1174 return;
1175 }
1176
1177 found = msg->findObject(kCaptureFailureKey, &obj);
1178 if (!found) {
1179 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1180 return;
1181 }
1182 sp<CameraCaptureFailure> failureSp(
1183 static_cast<CameraCaptureFailure*>(obj.get()));
1184 ALogicalCameraCaptureFailure failure;
1185 AString physicalCameraId;
1186 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1187 if (found && !physicalCameraId.empty()) {
1188 failure.physicalCameraId = physicalCameraId.c_str();
1189 } else {
1190 failure.physicalCameraId = nullptr;
1191 }
1192 failure.captureFailure = *failureSp;
1193 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1194 (*onFail)(context, session.get(), request, &failure);
1195 freeACaptureRequest(request);
1196 break;
1197 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001198 case kWhatCaptureSeqEnd:
1199 {
1200 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1201 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1202 if (!found) {
1203 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1204 return;
1205 }
1206 if (onSeqEnd == nullptr) {
1207 return;
1208 }
1209 int seqId;
1210 found = msg->findInt32(kSequenceIdKey, &seqId);
1211 if (!found) {
1212 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1213 return;
1214 }
1215 int64_t frameNumber;
1216 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1217 if (!found) {
1218 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1219 return;
1220 }
1221 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1222 break;
1223 }
1224 case kWhatCaptureSeqAbort:
1225 {
1226 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1227 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1228 if (!found) {
1229 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1230 return;
1231 }
1232 if (onSeqAbort == nullptr) {
1233 return;
1234 }
1235 int seqId;
1236 found = msg->findInt32(kSequenceIdKey, &seqId);
1237 if (!found) {
1238 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1239 return;
1240 }
1241 (*onSeqAbort)(context, session.get(), seqId);
1242 break;
1243 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001244 case kWhatCaptureBufferLost:
1245 {
1246 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1247 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1248 if (!found) {
1249 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1250 return;
1251 }
1252 if (onBufferLost == nullptr) {
1253 return;
1254 }
1255
1256 ANativeWindow* anw;
1257 found = msg->findPointer(kAnwKey, (void**) &anw);
1258 if (!found) {
1259 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1260 return;
1261 }
1262
1263 int64_t frameNumber;
1264 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1265 if (!found) {
1266 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1267 return;
1268 }
1269
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001270 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001271 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1272 freeACaptureRequest(request);
1273 break;
1274 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001275 }
1276 break;
1277 }
1278 }
1279}
1280
1281CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001282 sp<ACameraCaptureSession> session,
1283 const Vector<sp<CaptureRequest> >& requests,
1284 bool isRepeating,
1285 ACameraCaptureSession_captureCallbacks* cbs) :
1286 mSession(session), mRequests(requests),
1287 mIsRepeating(isRepeating),
1288 mIsLogicalCameraCallback(false) {
1289 initCaptureCallbacks(cbs);
1290
1291 if (cbs != nullptr) {
1292 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001293 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001294 }
1295}
1296
1297CameraDevice::CallbackHolder::CallbackHolder(
1298 sp<ACameraCaptureSession> session,
1299 const Vector<sp<CaptureRequest> >& requests,
1300 bool isRepeating,
1301 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1302 mSession(session), mRequests(requests),
1303 mIsRepeating(isRepeating),
1304 mIsLogicalCameraCallback(true) {
1305 initCaptureCallbacks(lcbs);
1306
1307 if (lcbs != nullptr) {
1308 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001309 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001310 }
1311}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001312
1313void
1314CameraDevice::checkRepeatingSequenceCompleteLocked(
1315 const int sequenceId, const int64_t lastFrameNumber) {
1316 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1317 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1318 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1319 ALOGW("No callback found for sequenceId %d", sequenceId);
1320 return;
1321 }
1322 // remove callback holder from callback map
1323 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1324 CallbackHolder cbh = cbIt->second;
1325 mSequenceCallbackMap.erase(cbIt);
1326 // send seq aborted callback
1327 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001328 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001329 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001330 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001331 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001332 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001333 } else {
1334 // Use mSequenceLastFrameNumberMap to track
1335 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1336
1337 // Last frame might have arrived. Check now
1338 checkAndFireSequenceCompleteLocked();
1339 }
1340}
1341
1342void
1343CameraDevice::checkAndFireSequenceCompleteLocked() {
1344 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001345 auto it = mSequenceLastFrameNumberMap.begin();
1346 while (it != mSequenceLastFrameNumberMap.end()) {
1347 int sequenceId = it->first;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001348 int64_t lastFrameNumber = it->second.lastFrameNumber;
1349 bool hasCallback = true;
1350
1351 if (mRemote == nullptr) {
1352 ALOGW("Camera %s closed while checking sequence complete", getId());
1353 return;
1354 }
1355 ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1356 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1357 if (!it->second.isSequenceCompleted) {
1358 // Check if there is callback for this sequence
1359 // This should not happen because we always register callback (with nullptr inside)
1360 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1361 ALOGW("No callback found for sequenceId %d", sequenceId);
1362 hasCallback = false;
1363 }
1364
1365 if (lastFrameNumber <= completedFrameNumber) {
1366 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1367 it->second.isSequenceCompleted = true;
1368 }
1369
1370 if (it->second.isSequenceCompleted && hasCallback) {
1371 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1372 CallbackHolder cbh = cbIt->second;
1373
1374 // send seq complete callback
1375 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1376 msg->setPointer(kContextKey, cbh.mContext);
1377 msg->setObject(kSessionSpKey, cbh.mSession);
1378 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1379 msg->setInt32(kSequenceIdKey, sequenceId);
1380 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1381
1382 // Clear the session sp before we send out the message
1383 // This will guarantee the rare case where the message is processed
1384 // before cbh goes out of scope and causing we call the session
1385 // destructor while holding device lock
1386 cbh.mSession.clear();
1387 postSessionMsgAndCleanup(msg);
1388 }
1389 }
1390
1391 if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
1392 if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
1393 mSequenceCallbackMap.erase(sequenceId);
1394 }
1395 it = mSequenceLastFrameNumberMap.erase(it);
1396 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1397 } else {
1398 ++it;
1399 }
1400 }
1401}
1402
1403void
1404CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1405 auto it = mSequenceLastFrameNumberMap.begin();
1406 while (it != mSequenceLastFrameNumberMap.end()) {
1407 int sequenceId = it->first;
1408 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wang730a7912020-05-07 11:59:02 -07001409
1410 if (mRemote == nullptr) {
1411 ALOGW("Camera %s closed while checking sequence complete", getId());
1412 return;
1413 }
Shuzhen Wang730a7912020-05-07 11:59:02 -07001414
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001415 ALOGV("%s: seq %d's last frame number %" PRId64
1416 ", completed inflight frame number %" PRId64,
1417 __FUNCTION__, sequenceId, lastFrameNumber,
1418 lastCompletedRegularFrameNumber);
1419 if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1420 if (it->second.isSequenceCompleted) {
1421 // Check if there is callback for this sequence
1422 // This should not happen because we always register callback (with nullptr inside)
1423 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1424 ALOGW("No callback found for sequenceId %d", sequenceId);
1425 } else {
1426 mSequenceCallbackMap.erase(sequenceId);
1427 }
Shuzhen Wang730a7912020-05-07 11:59:02 -07001428
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001429 it = mSequenceLastFrameNumberMap.erase(it);
1430 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1431 } else {
1432 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1433 it->second.isInflightCompleted = true;
1434 ++it;
1435 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001436 } else {
1437 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001438 }
1439 }
1440}
1441
1442/**
1443 * Camera service callback implementation
1444 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001445binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001446CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001447 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001448 const CaptureResultExtras& resultExtras) {
1449 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1450 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001451 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001452 sp<CameraDevice> dev = mDevice.promote();
1453 if (dev == 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
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001457 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001458 Mutex::Autolock _l(dev->mDeviceLock);
1459 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001460 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001461 }
1462 switch (errorCode) {
1463 case ERROR_CAMERA_DISCONNECTED:
1464 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001465 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001466 if (session != nullptr) {
1467 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001468 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001469 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001470 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1471 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1472 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001473 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001474 msg->post();
1475 break;
1476 }
1477 default:
1478 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001479 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001480 case ERROR_CAMERA_DEVICE:
1481 case ERROR_CAMERA_SERVICE:
1482 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001483 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1484 // We keep this switch since this block might be encountered with
1485 // more than just 2 states. The default fallthrough could have us
1486 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001487 switch (errorCode) {
1488 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001489 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001490 break;
1491 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001492 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001493 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001494 break;
1495 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001496 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001497 break;
1498 }
1499 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1500 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1501 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001502 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001503 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001504 msg->post();
1505 break;
1506 }
1507 case ERROR_CAMERA_REQUEST:
1508 case ERROR_CAMERA_RESULT:
1509 case ERROR_CAMERA_BUFFER:
1510 dev->onCaptureErrorLocked(errorCode, resultExtras);
1511 break;
1512 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001513 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001514}
1515
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001516binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001517CameraDevice::ServiceCallback::onDeviceIdle() {
1518 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001519 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001520 sp<CameraDevice> dev = mDevice.promote();
1521 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001522 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001523 }
1524
1525 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001526 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001527 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001528 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001529
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001530 dev->removeCompletedCallbackHolderLocked(
1531 std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1532
Yin-Chia Yehead91462016-01-06 16:45:08 -08001533 if (dev->mIdle) {
1534 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001535 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001536 }
1537
1538 if (dev->mCurrentSession != nullptr) {
1539 ALOGE("onDeviceIdle sending state cb");
1540 if (dev->mBusySession != dev->mCurrentSession) {
1541 ALOGE("Current session != busy session");
1542 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001543 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001544 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001545
Yin-Chia Yehead91462016-01-06 16:45:08 -08001546 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1547 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1548 msg->setObject(kSessionSpKey, dev->mBusySession);
1549 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1550 // Make sure we clear the sp first so the session destructor can
1551 // only happen on handler thread (where we don't hold device/session lock)
1552 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001553 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001554 }
1555 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001556 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001557 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001558}
1559
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001560binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001561CameraDevice::ServiceCallback::onCaptureStarted(
1562 const CaptureResultExtras& resultExtras,
1563 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001564 binder::Status ret = binder::Status::ok();
1565
Yin-Chia Yehead91462016-01-06 16:45:08 -08001566 sp<CameraDevice> dev = mDevice.promote();
1567 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001568 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001569 }
1570 Mutex::Autolock _l(dev->mDeviceLock);
1571 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001572 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001573 }
1574
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001575 dev->removeCompletedCallbackHolderLocked(
1576 resultExtras.lastCompletedRegularFrameNumber);
1577
Yin-Chia Yehead91462016-01-06 16:45:08 -08001578 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001579 int32_t burstId = resultExtras.burstId;
1580
1581 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1582 if (it != dev->mSequenceCallbackMap.end()) {
1583 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001584 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001585 sp<ACameraCaptureSession> session = cbh.mSession;
1586 if ((size_t) burstId >= cbh.mRequests.size()) {
1587 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1588 __FUNCTION__, burstId, cbh.mRequests.size());
1589 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1590 }
1591 sp<CaptureRequest> request = cbh.mRequests[burstId];
1592 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001593 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001594 msg->setObject(kSessionSpKey, session);
1595 msg->setPointer(kCallbackFpKey, (void*) onStart);
1596 msg->setObject(kCaptureRequestKey, request);
1597 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001598 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001599 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001600 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001601}
1602
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001603binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001604CameraDevice::ServiceCallback::onResultReceived(
1605 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001606 const CaptureResultExtras& resultExtras,
1607 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001608 binder::Status ret = binder::Status::ok();
1609
Yin-Chia Yehead91462016-01-06 16:45:08 -08001610 sp<CameraDevice> dev = mDevice.promote();
1611 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001612 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001613 }
1614 int sequenceId = resultExtras.requestId;
1615 int64_t frameNumber = resultExtras.frameNumber;
1616 int32_t burstId = resultExtras.burstId;
1617 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1618
1619 if (!isPartialResult) {
1620 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1621 }
1622
1623 Mutex::Autolock _l(dev->mDeviceLock);
1624 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001625 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001626 }
1627
1628 if (dev->isClosed()) {
1629 if (!isPartialResult) {
1630 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1631 }
1632 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001633 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001634 }
1635
1636 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001637 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001638 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001639
1640 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1641 if (it != dev->mSequenceCallbackMap.end()) {
1642 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001643 sp<ACameraCaptureSession> session = cbh.mSession;
1644 if ((size_t) burstId >= cbh.mRequests.size()) {
1645 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1646 __FUNCTION__, burstId, cbh.mRequests.size());
1647 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1648 }
1649 sp<CaptureRequest> request = cbh.mRequests[burstId];
1650 sp<ACameraMetadata> result(new ACameraMetadata(
1651 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001652 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1653 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001654
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001655 sp<AMessage> msg = new AMessage(
1656 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1657 dev->mHandler);
1658 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001659 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001660 msg->setObject(kCaptureRequestKey, request);
1661 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001662 if (isPartialResult) {
1663 msg->setPointer(kCallbackFpKey,
1664 (void *)cbh.mOnCaptureProgressed);
1665 } else if (cbh.mIsLogicalCameraCallback) {
1666 msg->setPointer(kCallbackFpKey,
1667 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1668 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1669 } else {
1670 msg->setPointer(kCallbackFpKey,
1671 (void *)cbh.mOnCaptureCompleted);
1672 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001673 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001674 }
1675
1676 if (!isPartialResult) {
1677 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1678 dev->checkAndFireSequenceCompleteLocked();
1679 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001680
1681 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001682}
1683
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001684binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001685CameraDevice::ServiceCallback::onPrepared(int) {
1686 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001687 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001688}
1689
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001690binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001691CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1692 // onRequestQueueEmpty not yet implemented in NDK
1693 return binder::Status::ok();
1694}
1695
1696binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001697CameraDevice::ServiceCallback::onRepeatingRequestError(
1698 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001699 binder::Status ret = binder::Status::ok();
1700
1701 sp<CameraDevice> dev = mDevice.promote();
1702 if (dev == nullptr) {
1703 return ret; // device has been closed
1704 }
1705
1706 Mutex::Autolock _l(dev->mDeviceLock);
1707
1708 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001709 if (stoppedSequenceId == repeatingSequenceId) {
1710 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1711 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001712
1713 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1714
1715 return ret;
1716}
1717
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001718} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001719} // namespace android