blob: 25a81ebc28554332c53549f5a724ac32331881e6 [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
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080032namespace acam {
33
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080034// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080035const char* CameraDevice::kContextKey = "Context";
36const char* CameraDevice::kDeviceKey = "Device";
37const char* CameraDevice::kErrorCodeKey = "ErrorCode";
38const char* CameraDevice::kCallbackFpKey = "Callback";
39const char* CameraDevice::kSessionSpKey = "SessionSp";
40const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
41const char* CameraDevice::kTimeStampKey = "TimeStamp";
42const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080043const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080044const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
45const char* CameraDevice::kSequenceIdKey = "SequenceId";
46const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070047const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070048const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080049
50/**
51 * CameraDevice Implementation
52 */
53CameraDevice::CameraDevice(
54 const char* id,
55 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070056 sp<ACameraMetadata> chars,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080057 ACameraDevice* wrapper) :
58 mCameraId(id),
59 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070060 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080061 mServiceCallback(new ServiceCallback(this)),
62 mWrapper(wrapper),
63 mInError(false),
64 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070065 mIdle(true),
66 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080067 mClosing = false;
68 // Setup looper thread to perfrom device callbacks to app
69 mCbLooper = new ALooper;
70 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080071 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080072 /*runOnCallingThread*/false,
73 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080074 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080075 if (err != OK) {
76 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
77 __FUNCTION__, strerror(-err), err);
78 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
79 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080080 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080081 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080082
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080083 const CameraMetadata& metadata = mChars->getInternalData();
84 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080085 if (entry.count != 1) {
86 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
87 mPartialResultCount = 1;
88 } else {
89 mPartialResultCount = entry.data.i32[0];
90 }
91
92 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
93 if (entry.count != 2) {
94 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
95 mShadingMapSize[0] = 0;
96 mShadingMapSize[1] = 0;
97 } else {
98 mShadingMapSize[0] = entry.data.i32[0];
99 mShadingMapSize[1] = entry.data.i32[1];
100 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800101
102 size_t physicalIdCnt = 0;
103 const char*const* physicalCameraIds;
104 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
105 for (size_t i = 0; i < physicalIdCnt; i++) {
106 mPhysicalIds.push_back(physicalCameraIds[i]);
107 }
108 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800109}
110
Yin-Chia Yehead91462016-01-06 16:45:08 -0800111// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800112CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700113 sp<ACameraCaptureSession> session = mCurrentSession.promote();
114 {
115 Mutex::Autolock _l(mDeviceLock);
116 if (!isClosed()) {
117 disconnectLocked(session);
118 }
119 mCurrentSession = nullptr;
120 if (mCbLooper != nullptr) {
121 mCbLooper->unregisterHandler(mHandler->id());
122 mCbLooper->stop();
123 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800124 }
125 mCbLooper.clear();
126 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800127}
128
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700129void
130CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
131 msg->post();
132 msg.clear();
133 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
134 cleanupMsg->post();
135}
136
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800137// TODO: cached created request?
138camera_status_t
139CameraDevice::createCaptureRequest(
140 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800141 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800142 ACaptureRequest** request) const {
143 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800144
145 if (physicalIdList != nullptr) {
146 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
147 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
148 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
149 return ACAMERA_ERROR_INVALID_PARAMETER;
150 }
151 for (auto i = 0; i < physicalIdList->numCameras; i++) {
152 if (physicalIdList->cameraIds[i] == nullptr) {
153 ALOGE("%s: physicalId is null!", __FUNCTION__);
154 return ACAMERA_ERROR_INVALID_PARAMETER;
155 }
156 if (mPhysicalIds.end() == std::find(
157 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
158 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
159 return ACAMERA_ERROR_INVALID_PARAMETER;
160 }
161 }
162 }
163
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800164 camera_status_t ret = checkCameraClosedOrErrorLocked();
165 if (ret != ACAMERA_OK) {
166 return ret;
167 }
168 if (mRemote == nullptr) {
169 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
170 }
171 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800172 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
173 if (remoteRet.serviceSpecificErrorCode() ==
174 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800175 ALOGW("Create capture request failed! template %d is not supported on this device",
176 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700177 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800178 } else if (!remoteRet.isOk()) {
179 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800180 return ACAMERA_ERROR_UNKNOWN;
181 }
182 ACaptureRequest* outReq = new ACaptureRequest();
183 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800184 if (physicalIdList != nullptr) {
185 for (auto i = 0; i < physicalIdList->numCameras; i++) {
186 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
187 new ACameraMetadata(*(outReq->settings)));
188 }
189 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800190 outReq->targets = new ACameraOutputTargets();
191 *request = outReq;
192 return ACAMERA_OK;
193}
194
Yin-Chia Yehead91462016-01-06 16:45:08 -0800195camera_status_t
196CameraDevice::createCaptureSession(
197 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100198 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800199 const ACameraCaptureSession_stateCallbacks* callbacks,
200 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700201 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800202 Mutex::Autolock _l(mDeviceLock);
203 camera_status_t ret = checkCameraClosedOrErrorLocked();
204 if (ret != ACAMERA_OK) {
205 return ret;
206 }
207
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700208 if (currentSession != nullptr) {
209 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800210 stopRepeatingLocked();
211 }
212
213 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100214 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800215 if (ret != ACAMERA_OK) {
216 ALOGE("Fail to create new session. cannot configure streams");
217 return ret;
218 }
219
220 ACameraCaptureSession* newSession = new ACameraCaptureSession(
221 mNextSessionId++, outputs, callbacks, this);
222
Yin-Chia Yehead91462016-01-06 16:45:08 -0800223 // set new session as current session
224 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
225 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700226 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800227 *session = newSession;
228 return ACAMERA_OK;
229}
230
Shuzhen Wang24810e72019-03-18 10:55:01 -0700231camera_status_t CameraDevice::isSessionConfigurationSupported(
232 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
233 Mutex::Autolock _l(mDeviceLock);
234 camera_status_t ret = checkCameraClosedOrErrorLocked();
235 if (ret != ACAMERA_OK) {
236 return ret;
237 }
238
239 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
240 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
241 for (const auto& output : sessionOutputContainer->mOutputs) {
242 sp<IGraphicBufferProducer> iGBP(nullptr);
243 ret = getIGBPfromAnw(output.mWindow, 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
250 String16 physicalId16(output.mPhysicalCameraId.c_str());
251 OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
252 OutputConfiguration::INVALID_SET_ID, true);
253
254 for (auto& anw : output.mSharedWindows) {
255 ret = getIGBPfromAnw(anw, iGBP);
256 if (ret != ACAMERA_OK) {
257 ALOGE("Camera device %s failed to extract graphic producer from native window",
258 getId());
259 return ret;
260 }
261 outConfig.addGraphicProducer(iGBP);
262 }
263
264 sessionConfiguration.addOutputConfiguration(outConfig);
265 }
266
267 bool supported = false;
268 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
269 sessionConfiguration, &supported);
270 if (remoteRet.serviceSpecificErrorCode() ==
271 hardware::ICameraService::ERROR_INVALID_OPERATION) {
272 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
273 } else if (!remoteRet.isOk()) {
274 return ACAMERA_ERROR_UNKNOWN;
275 } else {
276 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
277 }
278}
279
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800280camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100281 camera_status_t ret = checkCameraClosedOrErrorLocked();
282 if (ret != ACAMERA_OK) {
283 return ret;
284 }
285
286 if (output == nullptr) {
287 return ACAMERA_ERROR_INVALID_PARAMETER;
288 }
289
290 if (!output->mIsShared) {
291 ALOGE("Error output configuration is not shared");
292 return ACAMERA_ERROR_INVALID_OPERATION;
293 }
294
295 int32_t streamId = -1;
296 for (auto& kvPair : mConfiguredOutputs) {
297 if (kvPair.second.first == output->mWindow) {
298 streamId = kvPair.first;
299 break;
300 }
301 }
302 if (streamId < 0) {
303 ALOGE("Error: Invalid output configuration");
304 return ACAMERA_ERROR_INVALID_PARAMETER;
305 }
306
307 sp<IGraphicBufferProducer> iGBP(nullptr);
308 ret = getIGBPfromAnw(output->mWindow, 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
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800315 String16 physicalId16(output->mPhysicalCameraId.c_str());
316 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
317 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100318
319 for (auto& anw : output->mSharedWindows) {
320 ret = getIGBPfromAnw(anw, iGBP);
321 if (ret != ACAMERA_OK) {
322 ALOGE("Camera device %s failed to extract graphic producer from native window",
323 getId());
324 return ret;
325 }
326 outConfig.addGraphicProducer(iGBP);
327 }
328
329 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
330 if (!remoteRet.isOk()) {
331 switch (remoteRet.serviceSpecificErrorCode()) {
332 case hardware::ICameraService::ERROR_INVALID_OPERATION:
333 ALOGE("Camera device %s invalid operation: %s", getId(),
334 remoteRet.toString8().string());
335 return ACAMERA_ERROR_INVALID_OPERATION;
336 break;
337 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
338 ALOGE("Camera device %s output surface already exists: %s", getId(),
339 remoteRet.toString8().string());
340 return ACAMERA_ERROR_INVALID_PARAMETER;
341 break;
342 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
343 ALOGE("Camera device %s invalid input argument: %s", getId(),
344 remoteRet.toString8().string());
345 return ACAMERA_ERROR_INVALID_PARAMETER;
346 break;
347 default:
348 ALOGE("Camera device %s failed to add shared output: %s", getId(),
349 remoteRet.toString8().string());
350 return ACAMERA_ERROR_UNKNOWN;
351 }
352 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800353 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100354
355 return ACAMERA_OK;
356}
357
Yin-Chia Yehead91462016-01-06 16:45:08 -0800358camera_status_t
359CameraDevice::allocateCaptureRequest(
360 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
361 camera_status_t ret;
362 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800363 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000364 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800365 for (auto& entry : request->physicalSettings) {
366 req->mPhysicalCameraSettings.push_back({entry.first,
367 entry.second->getInternalData()});
368 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800369 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700370 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800371 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800372
373 for (auto outputTarget : request->targets->mOutputs) {
374 ANativeWindow* anw = outputTarget.mWindow;
375 sp<Surface> surface;
376 ret = getSurfaceFromANativeWindow(anw, surface);
377 if (ret != ACAMERA_OK) {
378 ALOGE("Bad output target in capture request! ret %d", ret);
379 return ret;
380 }
381 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800382
383 bool found = false;
384 // lookup stream/surface ID
385 for (const auto& kvPair : mConfiguredOutputs) {
386 int streamId = kvPair.first;
387 const OutputConfiguration& outConfig = kvPair.second.second;
388 const auto& gbps = outConfig.getGraphicBufferProducers();
389 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
390 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
391 found = true;
392 req->mStreamIdxList.push_back(streamId);
393 req->mSurfaceIdxList.push_back(surfaceId);
394 break;
395 }
396 }
397 if (found) {
398 break;
399 }
400 }
401 if (!found) {
402 ALOGE("Unconfigured output target %p in capture request!", anw);
403 return ret;
404 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800405 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800406
Yin-Chia Yehead91462016-01-06 16:45:08 -0800407 outReq = req;
408 return ACAMERA_OK;
409}
410
411ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800412CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800413 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800414 for (auto& entry : req->mPhysicalCameraSettings) {
415 CameraMetadata clone = entry.settings;
416 if (entry.id == deviceId) {
417 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
418 } else {
419 pRequest->physicalSettings.emplace(entry.id,
420 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
421 }
422 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800423 pRequest->targets = new ACameraOutputTargets();
424 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
425 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
426 ACameraOutputTarget outputTarget(anw);
427 pRequest->targets->mOutputs.insert(outputTarget);
428 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700429 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800430 return pRequest;
431}
432
433void
434CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
435 if (req == nullptr) {
436 return;
437 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700438 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800439 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800440 delete req->targets;
441 delete req;
442}
443
444void
445CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
446 if (isClosed()) {
447 // Device is closing already. do nothing
448 return;
449 }
450
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700451 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800452 // Session has been replaced by other seesion or device is closed
453 return;
454 }
455 mCurrentSession = nullptr;
456
457 // Should not happen
458 if (!session->mIsClosed) {
459 ALOGE("Error: unclosed session %p reaches end of life!", session);
460 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
461 return;
462 }
463
464 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100465 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800466 if (ret != ACAMERA_OK) {
467 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
468 }
469}
470
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800471void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700472CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800473 if (mClosing.exchange(true)) {
474 // Already closing, just return
475 ALOGW("Camera device %s is already closing.", getId());
476 return;
477 }
478
479 if (mRemote != nullptr) {
480 mRemote->disconnect();
481 }
482 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800483
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700484 if (session != nullptr) {
485 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800486 }
487}
488
489camera_status_t
490CameraDevice::stopRepeatingLocked() {
491 camera_status_t ret = checkCameraClosedOrErrorLocked();
492 if (ret != ACAMERA_OK) {
493 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
494 return ret;
495 }
496 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
497 int repeatingSequenceId = mRepeatingSequenceId;
498 mRepeatingSequenceId = REQUEST_ID_NONE;
499
500 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800501 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700502 if (remoteRet.serviceSpecificErrorCode() ==
503 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
504 ALOGV("Repeating request is already stopped.");
505 return ACAMERA_OK;
506 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800507 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800508 return ACAMERA_ERROR_UNKNOWN;
509 }
510 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
511 }
512 return ACAMERA_OK;
513}
514
515camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700516CameraDevice::flushLocked(ACameraCaptureSession* session) {
517 camera_status_t ret = checkCameraClosedOrErrorLocked();
518 if (ret != ACAMERA_OK) {
519 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
520 return ret;
521 }
522
523 // This should never happen because creating a new session will close
524 // previous one and thus reject any API call from previous session.
525 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700526 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700527 ALOGE("Camera %s session %p is not current active session!", getId(), session);
528 return ACAMERA_ERROR_INVALID_OPERATION;
529 }
530
531 if (mFlushing) {
532 ALOGW("Camera %s is already aborting captures", getId());
533 return ACAMERA_OK;
534 }
535
536 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700537
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700538 // Send onActive callback to guarantee there is always active->ready transition
539 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
540 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
541 msg->setObject(kSessionSpKey, session);
542 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700543 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700544
545 // If device is already idling, send callback and exit early
546 if (mIdle) {
547 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
548 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
549 msg->setObject(kSessionSpKey, session);
550 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700551 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700552 mFlushing = false;
553 return ACAMERA_OK;
554 }
555
556 int64_t lastFrameNumber;
557 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
558 if (!remoteRet.isOk()) {
559 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
560 return ACAMERA_ERROR_UNKNOWN;
561 }
562 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
563 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
564 }
565 return ACAMERA_OK;
566}
567
568camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800569CameraDevice::waitUntilIdleLocked() {
570 camera_status_t ret = checkCameraClosedOrErrorLocked();
571 if (ret != ACAMERA_OK) {
572 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
573 return ret;
574 }
575
576 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
577 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
578 return ACAMERA_ERROR_INVALID_OPERATION;
579 }
580
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800581 binder::Status remoteRet = mRemote->waitUntilIdle();
582 if (!remoteRet.isOk()) {
583 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800584 // TODO: define a function to convert status_t -> camera_status_t
585 return ACAMERA_ERROR_UNKNOWN;
586 }
587
588 return ACAMERA_OK;
589}
590
591camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700592CameraDevice::getIGBPfromAnw(
593 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800594 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800595 sp<Surface> surface;
596 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
597 if (ret != ACAMERA_OK) {
598 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800599 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800600 out = surface->getIGraphicBufferProducer();
601 return ACAMERA_OK;
602}
603
604camera_status_t
605CameraDevice::getSurfaceFromANativeWindow(
606 ANativeWindow* anw, sp<Surface>& out) {
607 if (anw == nullptr) {
608 ALOGE("Error: output ANativeWindow is null");
609 return ACAMERA_ERROR_INVALID_PARAMETER;
610 }
611 int value;
612 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800613 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800614 ALOGE("Error: ANativeWindow is not backed by Surface!");
615 return ACAMERA_ERROR_INVALID_PARAMETER;
616 }
617 sp<Surface> surface(static_cast<Surface*>(anw));
618 out = surface;
619 return ACAMERA_OK;
620}
621
622camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100623CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
624 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800625 ACaptureSessionOutputContainer emptyOutput;
626 if (outputs == nullptr) {
627 outputs = &emptyOutput;
628 }
629
Yin-Chia Yehead91462016-01-06 16:45:08 -0800630 camera_status_t ret = checkCameraClosedOrErrorLocked();
631 if (ret != ACAMERA_OK) {
632 return ret;
633 }
634
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700635 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800636 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700637 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800638 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700639 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800640 if (ret != ACAMERA_OK) {
641 return ret;
642 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800643 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700644 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800645 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100646 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800647 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700648 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800649 std::vector<int> deleteList;
650
651 // Determine which streams need to be created, which to be deleted
652 for (auto& kvPair : mConfiguredOutputs) {
653 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700654 auto& outputPair = kvPair.second;
655 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800656 deleteList.push_back(streamId); // Need to delete a no longer needed stream
657 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700658 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800659 }
660 }
661
662 ret = stopRepeatingLocked();
663 if (ret != ACAMERA_OK) {
664 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
665 return ret;
666 }
667
668 ret = waitUntilIdleLocked();
669 if (ret != ACAMERA_OK) {
670 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
671 return ret;
672 }
673
674 // Send onReady to previous session
675 // CurrentSession will be updated after configureStreamLocked, so here
676 // mCurrentSession is the session to be replaced by a new session
677 if (!mIdle && mCurrentSession != nullptr) {
678 if (mBusySession != mCurrentSession) {
679 ALOGE("Current session != busy session");
680 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
681 return ACAMERA_ERROR_CAMERA_DEVICE;
682 }
683 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
684 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
685 msg->setObject(kSessionSpKey, mBusySession);
686 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
687 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700688 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800689 }
690 mIdle = true;
691
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800692 binder::Status remoteRet = mRemote->beginConfigure();
693 if (!remoteRet.isOk()) {
694 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800695 return ACAMERA_ERROR_UNKNOWN;
696 }
697
698 // delete to-be-deleted streams
699 for (auto streamId : deleteList) {
700 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800701 if (!remoteRet.isOk()) {
702 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
703 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800704 return ACAMERA_ERROR_UNKNOWN;
705 }
706 mConfiguredOutputs.erase(streamId);
707 }
708
709 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800710 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800711 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700712 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800713 if (!remoteRet.isOk()) {
714 ALOGE("Camera device %s failed to create stream: %s", getId(),
715 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800716 return ACAMERA_ERROR_UNKNOWN;
717 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700718 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800719 }
720
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100721 CameraMetadata params;
722 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
723 params.append(sessionParameters->settings->getInternalData());
724 }
725 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800726 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
727 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
728 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800729 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800730 } else if (!remoteRet.isOk()) {
731 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800732 return ACAMERA_ERROR_UNKNOWN;
733 }
734
735 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800736}
737
738void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800739CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800740 Mutex::Autolock _l(mDeviceLock);
741 mRemote = remote;
742}
743
744camera_status_t
745CameraDevice::checkCameraClosedOrErrorLocked() const {
746 if (mRemote == nullptr) {
747 ALOGE("%s: camera device already closed", __FUNCTION__);
748 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
749 }
750 if (mInError) {// triggered by onDeviceError
751 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
752 return mError;
753 }
754 return ACAMERA_OK;
755}
756
757void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800758CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
759 mInError = true;
760 mError = error;
761 return;
762}
763
764void
765CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
766 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
767 if (isError) {
768 mFutureErrorSet.insert(frameNumber);
769 } else if (frameNumber <= mCompletedFrameNumber) {
770 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
771 frameNumber, mCompletedFrameNumber);
772 return;
773 } else {
774 if (frameNumber != mCompletedFrameNumber + 1) {
775 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
776 mCompletedFrameNumber + 1, frameNumber);
777 // Do not assert as in java implementation
778 }
779 mCompletedFrameNumber = frameNumber;
780 }
781 update();
782}
783
784void
785CameraDevice::FrameNumberTracker::update() {
786 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
787 int64_t errorFrameNumber = *it;
788 if (errorFrameNumber == mCompletedFrameNumber + 1) {
789 mCompletedFrameNumber++;
790 it = mFutureErrorSet.erase(it);
791 } else if (errorFrameNumber <= mCompletedFrameNumber) {
792 // This should not happen, but deal with it anyway
793 ALOGE("Completd frame number passed through current frame number!");
794 // erase the old error since it's no longer useful
795 it = mFutureErrorSet.erase(it);
796 } else {
797 // Normal requests hasn't catched up error frames, just break
798 break;
799 }
800 }
801 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
802}
803
804void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800805CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800806 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800807 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800808 int sequenceId = resultExtras.requestId;
809 int64_t frameNumber = resultExtras.frameNumber;
810 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700811 auto it = mSequenceCallbackMap.find(sequenceId);
812 if (it == mSequenceCallbackMap.end()) {
813 ALOGE("%s: Error: capture sequence index %d not found!",
814 __FUNCTION__, sequenceId);
815 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800816 return;
817 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700818
819 CallbackHolder cbh = (*it).second;
820 sp<ACameraCaptureSession> session = cbh.mSession;
821 if ((size_t) burstId >= cbh.mRequests.size()) {
822 ALOGE("%s: Error: request index %d out of bound (size %zu)",
823 __FUNCTION__, burstId, cbh.mRequests.size());
824 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
825 return;
826 }
827 sp<CaptureRequest> request = cbh.mRequests[burstId];
828
829 // Handle buffer error
830 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
831 int32_t streamId = resultExtras.errorStreamId;
832 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800833 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700834 auto outputPairIt = mConfiguredOutputs.find(streamId);
835 if (outputPairIt == mConfiguredOutputs.end()) {
836 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800837 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
838 return;
839 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700840
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800841 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
842 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800843 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800844 if (surface->getIGraphicBufferProducer() == outGbp) {
845 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
846 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
847 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700848
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800849 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800850 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800851 msg->setObject(kSessionSpKey, session);
852 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
853 msg->setObject(kCaptureRequestKey, request);
854 msg->setPointer(kAnwKey, (void*) anw);
855 msg->setInt64(kFrameNumberKey, frameNumber);
856 postSessionMsgAndCleanup(msg);
857 }
858 }
859 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700860 } else { // Handle other capture failures
861 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800862 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
864 failure->frameNumber = frameNumber;
865 // TODO: refine this when implementing flush
866 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
867 failure->sequenceId = sequenceId;
868 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800869 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800870
Emilian Peevedec62d2019-03-19 17:59:24 -0700871 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
872 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800873 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800874 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700875 if (cbh.mIsLogicalCameraCallback) {
876 if (resultExtras.errorPhysicalCameraId.size() > 0) {
877 String8 cameraId(resultExtras.errorPhysicalCameraId);
878 msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
879 }
880 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
881 } else {
882 msg->setPointer(kCallbackFpKey, (void*) onError);
883 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800884 msg->setObject(kCaptureRequestKey, request);
885 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700886 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800887
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700888 // Update tracker
889 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
890 checkAndFireSequenceCompleteLocked();
891 }
892 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800893}
894
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800895CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
896}
897
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800898void CameraDevice::CallbackHandler::onMessageReceived(
899 const sp<AMessage> &msg) {
900 switch (msg->what()) {
901 case kWhatOnDisconnected:
902 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800903 case kWhatSessionStateCb:
904 case kWhatCaptureStart:
905 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800906 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800907 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700908 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800909 case kWhatCaptureSeqEnd:
910 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700911 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800912 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800913 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700914 case kWhatCleanUpSessions:
915 mCachedSessions.clear();
916 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800917 default:
918 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
919 return;
920 }
921 // Check the common part of all message
922 void* context;
923 bool found = msg->findPointer(kContextKey, &context);
924 if (!found) {
925 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
926 return;
927 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800928 switch (msg->what()) {
929 case kWhatOnDisconnected:
930 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800931 ACameraDevice* dev;
932 found = msg->findPointer(kDeviceKey, (void**) &dev);
933 if (!found || dev == nullptr) {
934 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
935 return;
936 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800937 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800938 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800939 if (!found) {
940 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
941 return;
942 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800943 if (onDisconnected == nullptr) {
944 return;
945 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800946 (*onDisconnected)(context, dev);
947 break;
948 }
949 case kWhatOnError:
950 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800951 ACameraDevice* dev;
952 found = msg->findPointer(kDeviceKey, (void**) &dev);
953 if (!found || dev == nullptr) {
954 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
955 return;
956 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800957 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800958 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800959 if (!found) {
960 ALOGE("%s: Cannot find onError!", __FUNCTION__);
961 return;
962 }
963 int errorCode;
964 found = msg->findInt32(kErrorCodeKey, &errorCode);
965 if (!found) {
966 ALOGE("%s: Cannot find error code!", __FUNCTION__);
967 return;
968 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800969 if (onError == nullptr) {
970 return;
971 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800972 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800973 break;
974 }
975 case kWhatSessionStateCb:
976 case kWhatCaptureStart:
977 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800978 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800979 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700980 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800981 case kWhatCaptureSeqEnd:
982 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700983 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800984 {
985 sp<RefBase> obj;
986 found = msg->findObject(kSessionSpKey, &obj);
987 if (!found || obj == nullptr) {
988 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
989 return;
990 }
991 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700992 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800993 sp<CaptureRequest> requestSp = nullptr;
994 switch (msg->what()) {
995 case kWhatCaptureStart:
996 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800997 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800998 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700999 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001000 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001001 found = msg->findObject(kCaptureRequestKey, &obj);
1002 if (!found) {
1003 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1004 return;
1005 }
1006 requestSp = static_cast<CaptureRequest*>(obj.get());
1007 break;
1008 }
1009
1010 switch (msg->what()) {
1011 case kWhatSessionStateCb:
1012 {
1013 ACameraCaptureSession_stateCallback onState;
1014 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1015 if (!found) {
1016 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1017 return;
1018 }
1019 if (onState == nullptr) {
1020 return;
1021 }
1022 (*onState)(context, session.get());
1023 break;
1024 }
1025 case kWhatCaptureStart:
1026 {
1027 ACameraCaptureSession_captureCallback_start onStart;
1028 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1029 if (!found) {
1030 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1031 return;
1032 }
1033 if (onStart == nullptr) {
1034 return;
1035 }
1036 int64_t timestamp;
1037 found = msg->findInt64(kTimeStampKey, &timestamp);
1038 if (!found) {
1039 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1040 return;
1041 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001042 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001043 (*onStart)(context, session.get(), request, timestamp);
1044 freeACaptureRequest(request);
1045 break;
1046 }
1047 case kWhatCaptureResult:
1048 {
1049 ACameraCaptureSession_captureCallback_result onResult;
1050 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1051 if (!found) {
1052 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1053 return;
1054 }
1055 if (onResult == nullptr) {
1056 return;
1057 }
1058
1059 found = msg->findObject(kCaptureResultKey, &obj);
1060 if (!found) {
1061 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1062 return;
1063 }
1064 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001065 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001066 (*onResult)(context, session.get(), request, result.get());
1067 freeACaptureRequest(request);
1068 break;
1069 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001070 case kWhatLogicalCaptureResult:
1071 {
1072 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1073 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1074 if (!found) {
1075 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1076 __FUNCTION__);
1077 return;
1078 }
1079 if (onResult == nullptr) {
1080 return;
1081 }
1082
1083 found = msg->findObject(kCaptureResultKey, &obj);
1084 if (!found) {
1085 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1086 return;
1087 }
1088 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1089
1090 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1091 if (!found) {
1092 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1093 return;
1094 }
1095 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1096 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1097 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1098 physicalResult->mPhysicalResultInfo;
1099
1100 std::vector<std::string> physicalCameraIds;
1101 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1102 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1103 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1104 physicalCameraIds.push_back(physicalId8.c_str());
1105
1106 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1107 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1108 &physicalResult->mFrameNumber, /*data_count*/1);
1109 sp<ACameraMetadata> metadata =
1110 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1111 physicalMetadataCopy.push_back(metadata);
1112 }
1113
1114 std::vector<const char*> physicalCameraIdPtrs;
1115 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1116 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1117 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1118 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1119 }
1120
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001121 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001122 (*onResult)(context, session.get(), request, result.get(),
1123 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1124 physicalMetadataCopyPtrs.data());
1125 freeACaptureRequest(request);
1126 break;
1127 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001128 case kWhatCaptureFail:
1129 {
1130 ACameraCaptureSession_captureCallback_failed onFail;
1131 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1132 if (!found) {
1133 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1134 return;
1135 }
1136 if (onFail == nullptr) {
1137 return;
1138 }
1139
1140 found = msg->findObject(kCaptureFailureKey, &obj);
1141 if (!found) {
1142 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1143 return;
1144 }
1145 sp<CameraCaptureFailure> failureSp(
1146 static_cast<CameraCaptureFailure*>(obj.get()));
1147 ACameraCaptureFailure* failure =
1148 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001149 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001150 (*onFail)(context, session.get(), request, failure);
1151 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001152 break;
1153 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001154 case kWhatLogicalCaptureFail:
1155 {
1156 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1157 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1158 if (!found) {
1159 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1160 return;
1161 }
1162 if (onFail == nullptr) {
1163 return;
1164 }
1165
1166 found = msg->findObject(kCaptureFailureKey, &obj);
1167 if (!found) {
1168 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1169 return;
1170 }
1171 sp<CameraCaptureFailure> failureSp(
1172 static_cast<CameraCaptureFailure*>(obj.get()));
1173 ALogicalCameraCaptureFailure failure;
1174 AString physicalCameraId;
1175 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1176 if (found && !physicalCameraId.empty()) {
1177 failure.physicalCameraId = physicalCameraId.c_str();
1178 } else {
1179 failure.physicalCameraId = nullptr;
1180 }
1181 failure.captureFailure = *failureSp;
1182 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1183 (*onFail)(context, session.get(), request, &failure);
1184 freeACaptureRequest(request);
1185 break;
1186 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001187 case kWhatCaptureSeqEnd:
1188 {
1189 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1190 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1191 if (!found) {
1192 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1193 return;
1194 }
1195 if (onSeqEnd == nullptr) {
1196 return;
1197 }
1198 int seqId;
1199 found = msg->findInt32(kSequenceIdKey, &seqId);
1200 if (!found) {
1201 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1202 return;
1203 }
1204 int64_t frameNumber;
1205 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1206 if (!found) {
1207 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1208 return;
1209 }
1210 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1211 break;
1212 }
1213 case kWhatCaptureSeqAbort:
1214 {
1215 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1216 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1217 if (!found) {
1218 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1219 return;
1220 }
1221 if (onSeqAbort == nullptr) {
1222 return;
1223 }
1224 int seqId;
1225 found = msg->findInt32(kSequenceIdKey, &seqId);
1226 if (!found) {
1227 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1228 return;
1229 }
1230 (*onSeqAbort)(context, session.get(), seqId);
1231 break;
1232 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001233 case kWhatCaptureBufferLost:
1234 {
1235 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1236 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1237 if (!found) {
1238 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1239 return;
1240 }
1241 if (onBufferLost == nullptr) {
1242 return;
1243 }
1244
1245 ANativeWindow* anw;
1246 found = msg->findPointer(kAnwKey, (void**) &anw);
1247 if (!found) {
1248 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1249 return;
1250 }
1251
1252 int64_t frameNumber;
1253 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1254 if (!found) {
1255 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1256 return;
1257 }
1258
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001259 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001260 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1261 freeACaptureRequest(request);
1262 break;
1263 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001264 }
1265 break;
1266 }
1267 }
1268}
1269
1270CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001271 sp<ACameraCaptureSession> session,
1272 const Vector<sp<CaptureRequest> >& requests,
1273 bool isRepeating,
1274 ACameraCaptureSession_captureCallbacks* cbs) :
1275 mSession(session), mRequests(requests),
1276 mIsRepeating(isRepeating),
1277 mIsLogicalCameraCallback(false) {
1278 initCaptureCallbacks(cbs);
1279
1280 if (cbs != nullptr) {
1281 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001282 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001283 }
1284}
1285
1286CameraDevice::CallbackHolder::CallbackHolder(
1287 sp<ACameraCaptureSession> session,
1288 const Vector<sp<CaptureRequest> >& requests,
1289 bool isRepeating,
1290 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1291 mSession(session), mRequests(requests),
1292 mIsRepeating(isRepeating),
1293 mIsLogicalCameraCallback(true) {
1294 initCaptureCallbacks(lcbs);
1295
1296 if (lcbs != nullptr) {
1297 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001298 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001299 }
1300}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001301
1302void
1303CameraDevice::checkRepeatingSequenceCompleteLocked(
1304 const int sequenceId, const int64_t lastFrameNumber) {
1305 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1306 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1307 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1308 ALOGW("No callback found for sequenceId %d", sequenceId);
1309 return;
1310 }
1311 // remove callback holder from callback map
1312 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1313 CallbackHolder cbh = cbIt->second;
1314 mSequenceCallbackMap.erase(cbIt);
1315 // send seq aborted callback
1316 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001317 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001318 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001319 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001320 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001321 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001322 } else {
1323 // Use mSequenceLastFrameNumberMap to track
1324 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1325
1326 // Last frame might have arrived. Check now
1327 checkAndFireSequenceCompleteLocked();
1328 }
1329}
1330
1331void
1332CameraDevice::checkAndFireSequenceCompleteLocked() {
1333 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1334 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1335 auto it = mSequenceLastFrameNumberMap.begin();
1336 while (it != mSequenceLastFrameNumberMap.end()) {
1337 int sequenceId = it->first;
1338 int64_t lastFrameNumber = it->second;
1339 bool seqCompleted = false;
1340 bool hasCallback = true;
1341
1342 if (mRemote == nullptr) {
1343 ALOGW("Camera %s closed while checking sequence complete", getId());
1344 return;
1345 }
1346
1347 // Check if there is callback for this sequence
1348 // This should not happen because we always register callback (with nullptr inside)
1349 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1350 ALOGW("No callback found for sequenceId %d", sequenceId);
1351 hasCallback = false;
1352 }
1353
1354 if (lastFrameNumber <= completedFrameNumber) {
1355 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1356 sequenceId, lastFrameNumber, completedFrameNumber);
1357 seqCompleted = true;
1358 }
1359
1360 if (seqCompleted && hasCallback) {
1361 // remove callback holder from callback map
1362 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1363 CallbackHolder cbh = cbIt->second;
1364 mSequenceCallbackMap.erase(cbIt);
1365 // send seq complete callback
1366 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001367 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001368 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001369 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001370 msg->setInt32(kSequenceIdKey, sequenceId);
1371 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1372
1373 // Clear the session sp before we send out the message
1374 // This will guarantee the rare case where the message is processed
1375 // before cbh goes out of scope and causing we call the session
1376 // destructor while holding device lock
1377 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001378 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001379 }
1380
1381 // No need to track sequence complete if there is no callback registered
1382 if (seqCompleted || !hasCallback) {
1383 it = mSequenceLastFrameNumberMap.erase(it);
1384 } else {
1385 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001386 }
1387 }
1388}
1389
1390/**
1391 * Camera service callback implementation
1392 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001393binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001394CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001395 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001396 const CaptureResultExtras& resultExtras) {
1397 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1398 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001399 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001400 sp<CameraDevice> dev = mDevice.promote();
1401 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001402 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001403 }
1404
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001405 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001406 Mutex::Autolock _l(dev->mDeviceLock);
1407 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001408 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001409 }
1410 switch (errorCode) {
1411 case ERROR_CAMERA_DISCONNECTED:
1412 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001413 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001414 if (session != nullptr) {
1415 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001416 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001417 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001418 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1419 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1420 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001421 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001422 msg->post();
1423 break;
1424 }
1425 default:
1426 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001427 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001428 case ERROR_CAMERA_DEVICE:
1429 case ERROR_CAMERA_SERVICE:
1430 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001431 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1432 // We keep this switch since this block might be encountered with
1433 // more than just 2 states. The default fallthrough could have us
1434 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001435 switch (errorCode) {
1436 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001437 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001438 break;
1439 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001440 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001441 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001442 break;
1443 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001444 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001445 break;
1446 }
1447 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1448 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1449 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001450 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001451 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001452 msg->post();
1453 break;
1454 }
1455 case ERROR_CAMERA_REQUEST:
1456 case ERROR_CAMERA_RESULT:
1457 case ERROR_CAMERA_BUFFER:
1458 dev->onCaptureErrorLocked(errorCode, resultExtras);
1459 break;
1460 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001461 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001462}
1463
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001464binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001465CameraDevice::ServiceCallback::onDeviceIdle() {
1466 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001467 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001468 sp<CameraDevice> dev = mDevice.promote();
1469 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001470 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001471 }
1472
1473 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001474 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001475 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001476 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001477
1478 if (dev->mIdle) {
1479 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001480 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001481 }
1482
1483 if (dev->mCurrentSession != nullptr) {
1484 ALOGE("onDeviceIdle sending state cb");
1485 if (dev->mBusySession != dev->mCurrentSession) {
1486 ALOGE("Current session != busy session");
1487 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001488 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001489 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001490
Yin-Chia Yehead91462016-01-06 16:45:08 -08001491 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1492 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1493 msg->setObject(kSessionSpKey, dev->mBusySession);
1494 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1495 // Make sure we clear the sp first so the session destructor can
1496 // only happen on handler thread (where we don't hold device/session lock)
1497 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001498 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001499 }
1500 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001501 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001502 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001503}
1504
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001505binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001506CameraDevice::ServiceCallback::onCaptureStarted(
1507 const CaptureResultExtras& resultExtras,
1508 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001509 binder::Status ret = binder::Status::ok();
1510
Yin-Chia Yehead91462016-01-06 16:45:08 -08001511 sp<CameraDevice> dev = mDevice.promote();
1512 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001513 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001514 }
1515 Mutex::Autolock _l(dev->mDeviceLock);
1516 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001517 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001518 }
1519
1520 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001521 int32_t burstId = resultExtras.burstId;
1522
1523 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1524 if (it != dev->mSequenceCallbackMap.end()) {
1525 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001526 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001527 sp<ACameraCaptureSession> session = cbh.mSession;
1528 if ((size_t) burstId >= cbh.mRequests.size()) {
1529 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1530 __FUNCTION__, burstId, cbh.mRequests.size());
1531 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1532 }
1533 sp<CaptureRequest> request = cbh.mRequests[burstId];
1534 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001535 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001536 msg->setObject(kSessionSpKey, session);
1537 msg->setPointer(kCallbackFpKey, (void*) onStart);
1538 msg->setObject(kCaptureRequestKey, request);
1539 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001540 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001541 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001542 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001543}
1544
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001545binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001546CameraDevice::ServiceCallback::onResultReceived(
1547 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001548 const CaptureResultExtras& resultExtras,
1549 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001550 binder::Status ret = binder::Status::ok();
1551
Yin-Chia Yehead91462016-01-06 16:45:08 -08001552 sp<CameraDevice> dev = mDevice.promote();
1553 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001554 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001555 }
1556 int sequenceId = resultExtras.requestId;
1557 int64_t frameNumber = resultExtras.frameNumber;
1558 int32_t burstId = resultExtras.burstId;
1559 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1560
1561 if (!isPartialResult) {
1562 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1563 }
1564
1565 Mutex::Autolock _l(dev->mDeviceLock);
1566 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001567 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001568 }
1569
1570 if (dev->isClosed()) {
1571 if (!isPartialResult) {
1572 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1573 }
1574 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001575 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001576 }
1577
1578 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001579 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001580 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001581
1582 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1583 if (it != dev->mSequenceCallbackMap.end()) {
1584 CallbackHolder cbh = (*it).second;
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<ACameraMetadata> result(new ACameraMetadata(
1593 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001594 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1595 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001596
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001597 sp<AMessage> msg = new AMessage(
1598 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1599 dev->mHandler);
1600 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001601 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001602 msg->setObject(kCaptureRequestKey, request);
1603 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001604 if (isPartialResult) {
1605 msg->setPointer(kCallbackFpKey,
1606 (void *)cbh.mOnCaptureProgressed);
1607 } else if (cbh.mIsLogicalCameraCallback) {
1608 msg->setPointer(kCallbackFpKey,
1609 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1610 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1611 } else {
1612 msg->setPointer(kCallbackFpKey,
1613 (void *)cbh.mOnCaptureCompleted);
1614 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001615 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001616 }
1617
1618 if (!isPartialResult) {
1619 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1620 dev->checkAndFireSequenceCompleteLocked();
1621 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001622
1623 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001624}
1625
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001626binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001627CameraDevice::ServiceCallback::onPrepared(int) {
1628 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001629 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001630}
1631
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001632binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001633CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1634 // onRequestQueueEmpty not yet implemented in NDK
1635 return binder::Status::ok();
1636}
1637
1638binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001639CameraDevice::ServiceCallback::onRepeatingRequestError(
1640 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001641 binder::Status ret = binder::Status::ok();
1642
1643 sp<CameraDevice> dev = mDevice.promote();
1644 if (dev == nullptr) {
1645 return ret; // device has been closed
1646 }
1647
1648 Mutex::Autolock _l(dev->mDeviceLock);
1649
1650 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001651 if (stoppedSequenceId == repeatingSequenceId) {
1652 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1653 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001654
1655 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1656
1657 return ret;
1658}
1659
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001660} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001661} // namespace android