blob: d24cb814a32ade3fe4e6de223d15e8341b18fe0a [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 Chowdhary17408402019-06-21 12:45:34 -070031ACameraDevice::~ACameraDevice() {
32 mDevice->stopLooper();
33}
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
Yin-Chia Yehead91462016-01-06 16:45:08 -0800115// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700117 sp<ACameraCaptureSession> session = mCurrentSession.promote();
118 {
119 Mutex::Autolock _l(mDeviceLock);
120 if (!isClosed()) {
121 disconnectLocked(session);
122 }
Jayant Chowdhary17408402019-06-21 12:45:34 -0700123 LOG_ALWAYS_FATAL_IF(mCbLooper != nullptr,
124 "CameraDevice looper should've been stopped before ~CameraDevice");
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700125 mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126 }
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
Jayant Chowdhary17408402019-06-21 12:45:34 -0700895void CameraDevice::stopLooper() {
896 Mutex::Autolock _l(mDeviceLock);
897 if (mCbLooper != nullptr) {
898 mCbLooper->unregisterHandler(mHandler->id());
899 mCbLooper->stop();
900 }
901 mCbLooper.clear();
902 mHandler.clear();
903}
904
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800905CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
906}
907
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800908void CameraDevice::CallbackHandler::onMessageReceived(
909 const sp<AMessage> &msg) {
910 switch (msg->what()) {
911 case kWhatOnDisconnected:
912 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800913 case kWhatSessionStateCb:
914 case kWhatCaptureStart:
915 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800916 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800917 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700918 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800919 case kWhatCaptureSeqEnd:
920 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700921 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800922 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800923 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700924 case kWhatCleanUpSessions:
925 mCachedSessions.clear();
926 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800927 default:
928 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
929 return;
930 }
931 // Check the common part of all message
932 void* context;
933 bool found = msg->findPointer(kContextKey, &context);
934 if (!found) {
935 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
936 return;
937 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800938 switch (msg->what()) {
939 case kWhatOnDisconnected:
940 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800941 ACameraDevice* dev;
942 found = msg->findPointer(kDeviceKey, (void**) &dev);
943 if (!found || dev == nullptr) {
944 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
945 return;
946 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800947 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800948 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800949 if (!found) {
950 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
951 return;
952 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800953 if (onDisconnected == nullptr) {
954 return;
955 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800956 (*onDisconnected)(context, dev);
957 break;
958 }
959 case kWhatOnError:
960 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800961 ACameraDevice* dev;
962 found = msg->findPointer(kDeviceKey, (void**) &dev);
963 if (!found || dev == nullptr) {
964 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
965 return;
966 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800967 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800968 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800969 if (!found) {
970 ALOGE("%s: Cannot find onError!", __FUNCTION__);
971 return;
972 }
973 int errorCode;
974 found = msg->findInt32(kErrorCodeKey, &errorCode);
975 if (!found) {
976 ALOGE("%s: Cannot find error code!", __FUNCTION__);
977 return;
978 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800979 if (onError == nullptr) {
980 return;
981 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800982 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800983 break;
984 }
985 case kWhatSessionStateCb:
986 case kWhatCaptureStart:
987 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800988 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800989 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700990 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800991 case kWhatCaptureSeqEnd:
992 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700993 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800994 {
995 sp<RefBase> obj;
996 found = msg->findObject(kSessionSpKey, &obj);
997 if (!found || obj == nullptr) {
998 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
999 return;
1000 }
1001 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001002 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001003 sp<CaptureRequest> requestSp = nullptr;
1004 switch (msg->what()) {
1005 case kWhatCaptureStart:
1006 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001007 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001008 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001009 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001010 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001011 found = msg->findObject(kCaptureRequestKey, &obj);
1012 if (!found) {
1013 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1014 return;
1015 }
1016 requestSp = static_cast<CaptureRequest*>(obj.get());
1017 break;
1018 }
1019
1020 switch (msg->what()) {
1021 case kWhatSessionStateCb:
1022 {
1023 ACameraCaptureSession_stateCallback onState;
1024 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1025 if (!found) {
1026 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1027 return;
1028 }
1029 if (onState == nullptr) {
1030 return;
1031 }
1032 (*onState)(context, session.get());
1033 break;
1034 }
1035 case kWhatCaptureStart:
1036 {
1037 ACameraCaptureSession_captureCallback_start onStart;
1038 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1039 if (!found) {
1040 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1041 return;
1042 }
1043 if (onStart == nullptr) {
1044 return;
1045 }
1046 int64_t timestamp;
1047 found = msg->findInt64(kTimeStampKey, &timestamp);
1048 if (!found) {
1049 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1050 return;
1051 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001052 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001053 (*onStart)(context, session.get(), request, timestamp);
1054 freeACaptureRequest(request);
1055 break;
1056 }
1057 case kWhatCaptureResult:
1058 {
1059 ACameraCaptureSession_captureCallback_result onResult;
1060 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1061 if (!found) {
1062 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1063 return;
1064 }
1065 if (onResult == nullptr) {
1066 return;
1067 }
1068
1069 found = msg->findObject(kCaptureResultKey, &obj);
1070 if (!found) {
1071 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1072 return;
1073 }
1074 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001075 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001076 (*onResult)(context, session.get(), request, result.get());
1077 freeACaptureRequest(request);
1078 break;
1079 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001080 case kWhatLogicalCaptureResult:
1081 {
1082 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1083 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1084 if (!found) {
1085 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1086 __FUNCTION__);
1087 return;
1088 }
1089 if (onResult == nullptr) {
1090 return;
1091 }
1092
1093 found = msg->findObject(kCaptureResultKey, &obj);
1094 if (!found) {
1095 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1096 return;
1097 }
1098 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1099
1100 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1101 if (!found) {
1102 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1103 return;
1104 }
1105 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1106 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1107 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1108 physicalResult->mPhysicalResultInfo;
1109
1110 std::vector<std::string> physicalCameraIds;
1111 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1112 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1113 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1114 physicalCameraIds.push_back(physicalId8.c_str());
1115
1116 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1117 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1118 &physicalResult->mFrameNumber, /*data_count*/1);
1119 sp<ACameraMetadata> metadata =
1120 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1121 physicalMetadataCopy.push_back(metadata);
1122 }
1123
1124 std::vector<const char*> physicalCameraIdPtrs;
1125 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1126 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1127 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1128 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1129 }
1130
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001131 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001132 (*onResult)(context, session.get(), request, result.get(),
1133 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1134 physicalMetadataCopyPtrs.data());
1135 freeACaptureRequest(request);
1136 break;
1137 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001138 case kWhatCaptureFail:
1139 {
1140 ACameraCaptureSession_captureCallback_failed onFail;
1141 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1142 if (!found) {
1143 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1144 return;
1145 }
1146 if (onFail == nullptr) {
1147 return;
1148 }
1149
1150 found = msg->findObject(kCaptureFailureKey, &obj);
1151 if (!found) {
1152 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1153 return;
1154 }
1155 sp<CameraCaptureFailure> failureSp(
1156 static_cast<CameraCaptureFailure*>(obj.get()));
1157 ACameraCaptureFailure* failure =
1158 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001159 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001160 (*onFail)(context, session.get(), request, failure);
1161 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001162 break;
1163 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001164 case kWhatLogicalCaptureFail:
1165 {
1166 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1167 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1168 if (!found) {
1169 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1170 return;
1171 }
1172 if (onFail == nullptr) {
1173 return;
1174 }
1175
1176 found = msg->findObject(kCaptureFailureKey, &obj);
1177 if (!found) {
1178 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1179 return;
1180 }
1181 sp<CameraCaptureFailure> failureSp(
1182 static_cast<CameraCaptureFailure*>(obj.get()));
1183 ALogicalCameraCaptureFailure failure;
1184 AString physicalCameraId;
1185 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1186 if (found && !physicalCameraId.empty()) {
1187 failure.physicalCameraId = physicalCameraId.c_str();
1188 } else {
1189 failure.physicalCameraId = nullptr;
1190 }
1191 failure.captureFailure = *failureSp;
1192 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1193 (*onFail)(context, session.get(), request, &failure);
1194 freeACaptureRequest(request);
1195 break;
1196 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001197 case kWhatCaptureSeqEnd:
1198 {
1199 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1200 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1201 if (!found) {
1202 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1203 return;
1204 }
1205 if (onSeqEnd == nullptr) {
1206 return;
1207 }
1208 int seqId;
1209 found = msg->findInt32(kSequenceIdKey, &seqId);
1210 if (!found) {
1211 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1212 return;
1213 }
1214 int64_t frameNumber;
1215 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1216 if (!found) {
1217 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1218 return;
1219 }
1220 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1221 break;
1222 }
1223 case kWhatCaptureSeqAbort:
1224 {
1225 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1226 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1227 if (!found) {
1228 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1229 return;
1230 }
1231 if (onSeqAbort == nullptr) {
1232 return;
1233 }
1234 int seqId;
1235 found = msg->findInt32(kSequenceIdKey, &seqId);
1236 if (!found) {
1237 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1238 return;
1239 }
1240 (*onSeqAbort)(context, session.get(), seqId);
1241 break;
1242 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001243 case kWhatCaptureBufferLost:
1244 {
1245 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1246 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1247 if (!found) {
1248 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1249 return;
1250 }
1251 if (onBufferLost == nullptr) {
1252 return;
1253 }
1254
1255 ANativeWindow* anw;
1256 found = msg->findPointer(kAnwKey, (void**) &anw);
1257 if (!found) {
1258 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1259 return;
1260 }
1261
1262 int64_t frameNumber;
1263 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1264 if (!found) {
1265 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1266 return;
1267 }
1268
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001269 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001270 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1271 freeACaptureRequest(request);
1272 break;
1273 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001274 }
1275 break;
1276 }
1277 }
1278}
1279
1280CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001281 sp<ACameraCaptureSession> session,
1282 const Vector<sp<CaptureRequest> >& requests,
1283 bool isRepeating,
1284 ACameraCaptureSession_captureCallbacks* cbs) :
1285 mSession(session), mRequests(requests),
1286 mIsRepeating(isRepeating),
1287 mIsLogicalCameraCallback(false) {
1288 initCaptureCallbacks(cbs);
1289
1290 if (cbs != nullptr) {
1291 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001292 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001293 }
1294}
1295
1296CameraDevice::CallbackHolder::CallbackHolder(
1297 sp<ACameraCaptureSession> session,
1298 const Vector<sp<CaptureRequest> >& requests,
1299 bool isRepeating,
1300 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1301 mSession(session), mRequests(requests),
1302 mIsRepeating(isRepeating),
1303 mIsLogicalCameraCallback(true) {
1304 initCaptureCallbacks(lcbs);
1305
1306 if (lcbs != nullptr) {
1307 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001308 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001309 }
1310}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001311
1312void
1313CameraDevice::checkRepeatingSequenceCompleteLocked(
1314 const int sequenceId, const int64_t lastFrameNumber) {
1315 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1316 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1317 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1318 ALOGW("No callback found for sequenceId %d", sequenceId);
1319 return;
1320 }
1321 // remove callback holder from callback map
1322 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1323 CallbackHolder cbh = cbIt->second;
1324 mSequenceCallbackMap.erase(cbIt);
1325 // send seq aborted callback
1326 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001327 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001328 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001329 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001330 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001331 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001332 } else {
1333 // Use mSequenceLastFrameNumberMap to track
1334 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1335
1336 // Last frame might have arrived. Check now
1337 checkAndFireSequenceCompleteLocked();
1338 }
1339}
1340
1341void
1342CameraDevice::checkAndFireSequenceCompleteLocked() {
1343 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1344 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1345 auto it = mSequenceLastFrameNumberMap.begin();
1346 while (it != mSequenceLastFrameNumberMap.end()) {
1347 int sequenceId = it->first;
1348 int64_t lastFrameNumber = it->second;
1349 bool seqCompleted = false;
1350 bool hasCallback = true;
1351
1352 if (mRemote == nullptr) {
1353 ALOGW("Camera %s closed while checking sequence complete", getId());
1354 return;
1355 }
1356
1357 // Check if there is callback for this sequence
1358 // This should not happen because we always register callback (with nullptr inside)
1359 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1360 ALOGW("No callback found for sequenceId %d", sequenceId);
1361 hasCallback = false;
1362 }
1363
1364 if (lastFrameNumber <= completedFrameNumber) {
1365 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1366 sequenceId, lastFrameNumber, completedFrameNumber);
1367 seqCompleted = true;
1368 }
1369
1370 if (seqCompleted && hasCallback) {
1371 // remove callback holder from callback map
1372 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1373 CallbackHolder cbh = cbIt->second;
1374 mSequenceCallbackMap.erase(cbIt);
1375 // send seq complete callback
1376 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001377 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001378 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001379 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001380 msg->setInt32(kSequenceIdKey, sequenceId);
1381 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1382
1383 // Clear the session sp before we send out the message
1384 // This will guarantee the rare case where the message is processed
1385 // before cbh goes out of scope and causing we call the session
1386 // destructor while holding device lock
1387 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001388 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001389 }
1390
1391 // No need to track sequence complete if there is no callback registered
1392 if (seqCompleted || !hasCallback) {
1393 it = mSequenceLastFrameNumberMap.erase(it);
1394 } else {
1395 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001396 }
1397 }
1398}
1399
1400/**
1401 * Camera service callback implementation
1402 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001403binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001404CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001405 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001406 const CaptureResultExtras& resultExtras) {
1407 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1408 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001409 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001410 sp<CameraDevice> dev = mDevice.promote();
1411 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001412 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001413 }
1414
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001415 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001416 Mutex::Autolock _l(dev->mDeviceLock);
1417 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001418 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001419 }
1420 switch (errorCode) {
1421 case ERROR_CAMERA_DISCONNECTED:
1422 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001423 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001424 if (session != nullptr) {
1425 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001426 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001427 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001428 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1429 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1430 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001431 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001432 msg->post();
1433 break;
1434 }
1435 default:
1436 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001437 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001438 case ERROR_CAMERA_DEVICE:
1439 case ERROR_CAMERA_SERVICE:
1440 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001441 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1442 // We keep this switch since this block might be encountered with
1443 // more than just 2 states. The default fallthrough could have us
1444 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001445 switch (errorCode) {
1446 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001447 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001448 break;
1449 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001450 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001451 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001452 break;
1453 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001454 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001455 break;
1456 }
1457 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1458 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1459 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001460 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001461 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001462 msg->post();
1463 break;
1464 }
1465 case ERROR_CAMERA_REQUEST:
1466 case ERROR_CAMERA_RESULT:
1467 case ERROR_CAMERA_BUFFER:
1468 dev->onCaptureErrorLocked(errorCode, resultExtras);
1469 break;
1470 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001471 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001472}
1473
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001474binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001475CameraDevice::ServiceCallback::onDeviceIdle() {
1476 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001477 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001478 sp<CameraDevice> dev = mDevice.promote();
1479 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001480 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001481 }
1482
1483 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001484 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001485 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001486 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001487
1488 if (dev->mIdle) {
1489 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001490 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001491 }
1492
1493 if (dev->mCurrentSession != nullptr) {
1494 ALOGE("onDeviceIdle sending state cb");
1495 if (dev->mBusySession != dev->mCurrentSession) {
1496 ALOGE("Current session != busy session");
1497 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001498 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001499 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001500
Yin-Chia Yehead91462016-01-06 16:45:08 -08001501 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1502 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1503 msg->setObject(kSessionSpKey, dev->mBusySession);
1504 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1505 // Make sure we clear the sp first so the session destructor can
1506 // only happen on handler thread (where we don't hold device/session lock)
1507 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001508 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001509 }
1510 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001511 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001512 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001513}
1514
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001515binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001516CameraDevice::ServiceCallback::onCaptureStarted(
1517 const CaptureResultExtras& resultExtras,
1518 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001519 binder::Status ret = binder::Status::ok();
1520
Yin-Chia Yehead91462016-01-06 16:45:08 -08001521 sp<CameraDevice> dev = mDevice.promote();
1522 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001523 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001524 }
1525 Mutex::Autolock _l(dev->mDeviceLock);
1526 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001527 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001528 }
1529
1530 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001531 int32_t burstId = resultExtras.burstId;
1532
1533 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1534 if (it != dev->mSequenceCallbackMap.end()) {
1535 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001536 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001537 sp<ACameraCaptureSession> session = cbh.mSession;
1538 if ((size_t) burstId >= cbh.mRequests.size()) {
1539 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1540 __FUNCTION__, burstId, cbh.mRequests.size());
1541 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1542 }
1543 sp<CaptureRequest> request = cbh.mRequests[burstId];
1544 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001545 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001546 msg->setObject(kSessionSpKey, session);
1547 msg->setPointer(kCallbackFpKey, (void*) onStart);
1548 msg->setObject(kCaptureRequestKey, request);
1549 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001550 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001551 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001552 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001553}
1554
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001555binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001556CameraDevice::ServiceCallback::onResultReceived(
1557 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001558 const CaptureResultExtras& resultExtras,
1559 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001560 binder::Status ret = binder::Status::ok();
1561
Yin-Chia Yehead91462016-01-06 16:45:08 -08001562 sp<CameraDevice> dev = mDevice.promote();
1563 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001564 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001565 }
1566 int sequenceId = resultExtras.requestId;
1567 int64_t frameNumber = resultExtras.frameNumber;
1568 int32_t burstId = resultExtras.burstId;
1569 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1570
1571 if (!isPartialResult) {
1572 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1573 }
1574
1575 Mutex::Autolock _l(dev->mDeviceLock);
1576 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001577 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001578 }
1579
1580 if (dev->isClosed()) {
1581 if (!isPartialResult) {
1582 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1583 }
1584 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001585 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001586 }
1587
1588 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001589 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001590 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001591
1592 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1593 if (it != dev->mSequenceCallbackMap.end()) {
1594 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001595 sp<ACameraCaptureSession> session = cbh.mSession;
1596 if ((size_t) burstId >= cbh.mRequests.size()) {
1597 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1598 __FUNCTION__, burstId, cbh.mRequests.size());
1599 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1600 }
1601 sp<CaptureRequest> request = cbh.mRequests[burstId];
1602 sp<ACameraMetadata> result(new ACameraMetadata(
1603 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001604 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1605 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001606
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001607 sp<AMessage> msg = new AMessage(
1608 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1609 dev->mHandler);
1610 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001611 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001612 msg->setObject(kCaptureRequestKey, request);
1613 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001614 if (isPartialResult) {
1615 msg->setPointer(kCallbackFpKey,
1616 (void *)cbh.mOnCaptureProgressed);
1617 } else if (cbh.mIsLogicalCameraCallback) {
1618 msg->setPointer(kCallbackFpKey,
1619 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1620 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1621 } else {
1622 msg->setPointer(kCallbackFpKey,
1623 (void *)cbh.mOnCaptureCompleted);
1624 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001625 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001626 }
1627
1628 if (!isPartialResult) {
1629 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1630 dev->checkAndFireSequenceCompleteLocked();
1631 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001632
1633 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001634}
1635
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001636binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001637CameraDevice::ServiceCallback::onPrepared(int) {
1638 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001639 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001640}
1641
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001642binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001643CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1644 // onRequestQueueEmpty not yet implemented in NDK
1645 return binder::Status::ok();
1646}
1647
1648binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001649CameraDevice::ServiceCallback::onRepeatingRequestError(
1650 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001651 binder::Status ret = binder::Status::ok();
1652
1653 sp<CameraDevice> dev = mDevice.promote();
1654 if (dev == nullptr) {
1655 return ret; // device has been closed
1656 }
1657
1658 Mutex::Autolock _l(dev->mDeviceLock);
1659
1660 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001661 if (stoppedSequenceId == repeatingSequenceId) {
1662 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1663 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001664
1665 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1666
1667 return ret;
1668}
1669
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001670} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001671} // namespace android