blob: aed740fc71585333de0816e0277f55fba0fa65de [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>
Austin Borger71d8f672023-06-01 16:51:35 -070024#include <camera/StringUtils.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080025#include "ACameraDevice.h"
26#include "ACameraMetadata.h"
27#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080028#include "ACameraCaptureSession.h"
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070029#include <com_android_internal_camera_flags.h>
30
31namespace flags = com::android::internal::camera::flags;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080032
Jayant Chowdharya8488c92019-06-21 12:45:34 -070033ACameraDevice::~ACameraDevice() {
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -070034 mDevice->stopLooperAndDisconnect();
Jayant Chowdharya8488c92019-06-21 12:45:34 -070035}
36
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080037namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080038namespace acam {
39
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080040// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080041const char* CameraDevice::kContextKey = "Context";
42const char* CameraDevice::kDeviceKey = "Device";
43const char* CameraDevice::kErrorCodeKey = "ErrorCode";
44const char* CameraDevice::kCallbackFpKey = "Callback";
45const char* CameraDevice::kSessionSpKey = "SessionSp";
46const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
47const char* CameraDevice::kTimeStampKey = "TimeStamp";
48const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080049const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080050const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
51const char* CameraDevice::kSequenceIdKey = "SequenceId";
52const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070053const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070054const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080055
56/**
57 * CameraDevice Implementation
58 */
59CameraDevice::CameraDevice(
60 const char* id,
61 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070062 sp<ACameraMetadata> chars,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070063 ACameraDevice* wrapper, bool sharedMode) :
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 mCameraId(id),
65 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070066 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080067 mServiceCallback(new ServiceCallback(this)),
68 mWrapper(wrapper),
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070069 mSharedMode(sharedMode),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080070 mInError(false),
71 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070072 mIdle(true),
73 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080074 mClosing = false;
75 // Setup looper thread to perfrom device callbacks to app
76 mCbLooper = new ALooper;
77 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080078 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 /*runOnCallingThread*/false,
80 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080081 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080082 if (err != OK) {
83 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
84 __FUNCTION__, strerror(-err), err);
85 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
86 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080087 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080088 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080089
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080090 const CameraMetadata& metadata = mChars->getInternalData();
91 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080092 if (entry.count != 1) {
93 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
94 mPartialResultCount = 1;
95 } else {
96 mPartialResultCount = entry.data.i32[0];
97 }
98
99 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
100 if (entry.count != 2) {
101 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
102 mShadingMapSize[0] = 0;
103 mShadingMapSize[1] = 0;
104 } else {
105 mShadingMapSize[0] = entry.data.i32[0];
106 mShadingMapSize[1] = entry.data.i32[1];
107 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800108
109 size_t physicalIdCnt = 0;
110 const char*const* physicalCameraIds;
111 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
112 for (size_t i = 0; i < physicalIdCnt; i++) {
113 mPhysicalIds.push_back(physicalCameraIds[i]);
114 }
115 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116}
117
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700118CameraDevice::~CameraDevice() { }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800119
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700120void
121CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
122 msg->post();
123 msg.clear();
124 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
125 cleanupMsg->post();
126}
127
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800128// TODO: cached created request?
129camera_status_t
130CameraDevice::createCaptureRequest(
131 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800132 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800133 ACaptureRequest** request) const {
134 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800135
136 if (physicalIdList != nullptr) {
137 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
138 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
139 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
140 return ACAMERA_ERROR_INVALID_PARAMETER;
141 }
142 for (auto i = 0; i < physicalIdList->numCameras; i++) {
143 if (physicalIdList->cameraIds[i] == nullptr) {
144 ALOGE("%s: physicalId is null!", __FUNCTION__);
145 return ACAMERA_ERROR_INVALID_PARAMETER;
146 }
147 if (mPhysicalIds.end() == std::find(
148 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
149 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
150 return ACAMERA_ERROR_INVALID_PARAMETER;
151 }
152 }
153 }
154
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800155 camera_status_t ret = checkCameraClosedOrErrorLocked();
156 if (ret != ACAMERA_OK) {
157 return ret;
158 }
159 if (mRemote == nullptr) {
160 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
161 }
162 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800163 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
164 if (remoteRet.serviceSpecificErrorCode() ==
165 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800166 ALOGW("Create capture request failed! template %d is not supported on this device",
167 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700168 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800169 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000170 ALOGE("Create capture request failed: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800171 return ACAMERA_ERROR_UNKNOWN;
172 }
173 ACaptureRequest* outReq = new ACaptureRequest();
174 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800175 if (physicalIdList != nullptr) {
176 for (auto i = 0; i < physicalIdList->numCameras; i++) {
177 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
178 new ACameraMetadata(*(outReq->settings)));
179 }
180 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800181 outReq->targets = new ACameraOutputTargets();
182 *request = outReq;
183 return ACAMERA_OK;
184}
185
Yin-Chia Yehead91462016-01-06 16:45:08 -0800186camera_status_t
187CameraDevice::createCaptureSession(
188 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100189 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800190 const ACameraCaptureSession_stateCallbacks* callbacks,
191 /*out*/ACameraCaptureSession** session) {
Shuzhen Wang316781a2020-08-18 18:11:01 -0700192 nsecs_t startTimeNs = systemTime();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700193 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800194 Mutex::Autolock _l(mDeviceLock);
195 camera_status_t ret = checkCameraClosedOrErrorLocked();
196 if (ret != ACAMERA_OK) {
197 return ret;
198 }
199
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700200 if (currentSession != nullptr) {
201 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800202 stopRepeatingLocked();
203 }
204
205 // Create new session
Shuzhen Wang316781a2020-08-18 18:11:01 -0700206 ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800207 if (ret != ACAMERA_OK) {
208 ALOGE("Fail to create new session. cannot configure streams");
209 return ret;
210 }
211
212 ACameraCaptureSession* newSession = new ACameraCaptureSession(
213 mNextSessionId++, outputs, callbacks, this);
214
Yin-Chia Yehead91462016-01-06 16:45:08 -0800215 // set new session as current session
216 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
217 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700218 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800219 *session = newSession;
220 return ACAMERA_OK;
221}
222
Shuzhen Wang24810e72019-03-18 10:55:01 -0700223camera_status_t CameraDevice::isSessionConfigurationSupported(
224 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
225 Mutex::Autolock _l(mDeviceLock);
226 camera_status_t ret = checkCameraClosedOrErrorLocked();
227 if (ret != ACAMERA_OK) {
228 return ret;
229 }
230
231 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
232 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
233 for (const auto& output : sessionOutputContainer->mOutputs) {
234 sp<IGraphicBufferProducer> iGBP(nullptr);
235 ret = getIGBPfromAnw(output.mWindow, iGBP);
236 if (ret != ACAMERA_OK) {
237 ALOGE("Camera device %s failed to extract graphic producer from native window",
238 getId());
239 return ret;
240 }
241
Austin Borger71d8f672023-06-01 16:51:35 -0700242 OutputConfiguration outConfig(iGBP, output.mRotation, output.mPhysicalCameraId,
Shuzhen Wang24810e72019-03-18 10:55:01 -0700243 OutputConfiguration::INVALID_SET_ID, true);
244
245 for (auto& anw : output.mSharedWindows) {
246 ret = getIGBPfromAnw(anw, iGBP);
247 if (ret != ACAMERA_OK) {
248 ALOGE("Camera device %s failed to extract graphic producer from native window",
249 getId());
250 return ret;
251 }
252 outConfig.addGraphicProducer(iGBP);
253 }
254
255 sessionConfiguration.addOutputConfiguration(outConfig);
256 }
257
258 bool supported = false;
259 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
260 sessionConfiguration, &supported);
261 if (remoteRet.serviceSpecificErrorCode() ==
262 hardware::ICameraService::ERROR_INVALID_OPERATION) {
263 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
264 } else if (!remoteRet.isOk()) {
265 return ACAMERA_ERROR_UNKNOWN;
266 } else {
267 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
268 }
269}
270
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800271camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100272 camera_status_t ret = checkCameraClosedOrErrorLocked();
273 if (ret != ACAMERA_OK) {
274 return ret;
275 }
276
277 if (output == nullptr) {
278 return ACAMERA_ERROR_INVALID_PARAMETER;
279 }
280
281 if (!output->mIsShared) {
282 ALOGE("Error output configuration is not shared");
283 return ACAMERA_ERROR_INVALID_OPERATION;
284 }
285
286 int32_t streamId = -1;
287 for (auto& kvPair : mConfiguredOutputs) {
288 if (kvPair.second.first == output->mWindow) {
289 streamId = kvPair.first;
290 break;
291 }
292 }
293 if (streamId < 0) {
294 ALOGE("Error: Invalid output configuration");
295 return ACAMERA_ERROR_INVALID_PARAMETER;
296 }
297
298 sp<IGraphicBufferProducer> iGBP(nullptr);
299 ret = getIGBPfromAnw(output->mWindow, iGBP);
300 if (ret != ACAMERA_OK) {
301 ALOGE("Camera device %s failed to extract graphic producer from native window",
302 getId());
303 return ret;
304 }
305
Austin Borger71d8f672023-06-01 16:51:35 -0700306 OutputConfiguration outConfig(iGBP, output->mRotation, output->mPhysicalCameraId,
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800307 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100308
309 for (auto& anw : output->mSharedWindows) {
310 ret = getIGBPfromAnw(anw, iGBP);
311 if (ret != ACAMERA_OK) {
312 ALOGE("Camera device %s failed to extract graphic producer from native window",
313 getId());
314 return ret;
315 }
316 outConfig.addGraphicProducer(iGBP);
317 }
318
319 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
320 if (!remoteRet.isOk()) {
321 switch (remoteRet.serviceSpecificErrorCode()) {
322 case hardware::ICameraService::ERROR_INVALID_OPERATION:
323 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000324 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100325 return ACAMERA_ERROR_INVALID_OPERATION;
326 break;
327 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
328 ALOGE("Camera device %s output surface already exists: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000329 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100330 return ACAMERA_ERROR_INVALID_PARAMETER;
331 break;
332 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
333 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000334 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100335 return ACAMERA_ERROR_INVALID_PARAMETER;
336 break;
337 default:
338 ALOGE("Camera device %s failed to add shared output: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000339 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100340 return ACAMERA_ERROR_UNKNOWN;
341 }
342 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800343 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100344
345 return ACAMERA_OK;
346}
347
Avichal Rakesh8effe982023-11-13 18:53:40 -0800348camera_status_t CameraDevice::prepareLocked(ANativeWindow *window) {
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000349 camera_status_t ret = checkCameraClosedOrErrorLocked();
350 if (ret != ACAMERA_OK) {
351 return ret;
352 }
353
354 if (window == nullptr) {
355 return ACAMERA_ERROR_INVALID_PARAMETER;
356 }
357
358 int32_t streamId = -1;
359 for (auto& kvPair : mConfiguredOutputs) {
360 if (window == kvPair.second.first) {
361 streamId = kvPair.first;
362 break;
363 }
364 }
365 if (streamId < 0) {
366 ALOGE("Error: Invalid output configuration");
367 return ACAMERA_ERROR_INVALID_PARAMETER;
368 }
369 auto remoteRet = mRemote->prepare(streamId);
370 if (!remoteRet.isOk()) {
371 // TODO:(b/259735869) Do this check for all other binder calls in the
372 // ndk as well.
373 if (remoteRet.exceptionCode() != EX_SERVICE_SPECIFIC) {
374 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000375 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000376 return ACAMERA_ERROR_UNKNOWN;
377
378 }
379 switch (remoteRet.serviceSpecificErrorCode()) {
380 case hardware::ICameraService::ERROR_INVALID_OPERATION:
381 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000382 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000383 return ACAMERA_ERROR_INVALID_OPERATION;
384 break;
385 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
386 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000387 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000388 return ACAMERA_ERROR_INVALID_PARAMETER;
389 break;
390 default:
391 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000392 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000393 return ACAMERA_ERROR_UNKNOWN;
394 }
395 }
396
397 return ACAMERA_OK;
398}
399
Yin-Chia Yehead91462016-01-06 16:45:08 -0800400camera_status_t
401CameraDevice::allocateCaptureRequest(
402 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
403 camera_status_t ret;
404 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800405 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000406 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800407 for (auto& entry : request->physicalSettings) {
408 req->mPhysicalCameraSettings.push_back({entry.first,
409 entry.second->getInternalData()});
410 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800411 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700412 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800413 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800414
415 for (auto outputTarget : request->targets->mOutputs) {
416 ANativeWindow* anw = outputTarget.mWindow;
417 sp<Surface> surface;
418 ret = getSurfaceFromANativeWindow(anw, surface);
419 if (ret != ACAMERA_OK) {
420 ALOGE("Bad output target in capture request! ret %d", ret);
421 return ret;
422 }
423 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800424
425 bool found = false;
426 // lookup stream/surface ID
427 for (const auto& kvPair : mConfiguredOutputs) {
428 int streamId = kvPair.first;
429 const OutputConfiguration& outConfig = kvPair.second.second;
430 const auto& gbps = outConfig.getGraphicBufferProducers();
431 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
432 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
433 found = true;
434 req->mStreamIdxList.push_back(streamId);
435 req->mSurfaceIdxList.push_back(surfaceId);
436 break;
437 }
438 }
439 if (found) {
440 break;
441 }
442 }
443 if (!found) {
444 ALOGE("Unconfigured output target %p in capture request!", anw);
445 return ret;
446 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800447 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800448
Yin-Chia Yehead91462016-01-06 16:45:08 -0800449 outReq = req;
450 return ACAMERA_OK;
451}
452
453ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800454CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800455 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800456 for (auto& entry : req->mPhysicalCameraSettings) {
457 CameraMetadata clone = entry.settings;
458 if (entry.id == deviceId) {
459 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
460 } else {
461 pRequest->physicalSettings.emplace(entry.id,
462 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
463 }
464 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800465 pRequest->targets = new ACameraOutputTargets();
466 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
467 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
468 ACameraOutputTarget outputTarget(anw);
469 pRequest->targets->mOutputs.insert(outputTarget);
470 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700471 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800472 return pRequest;
473}
474
475void
476CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
477 if (req == nullptr) {
478 return;
479 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700480 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800481 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800482 delete req->targets;
483 delete req;
484}
485
486void
487CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
488 if (isClosed()) {
489 // Device is closing already. do nothing
490 return;
491 }
492
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700493 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800494 // Session has been replaced by other seesion or device is closed
495 return;
496 }
497 mCurrentSession = nullptr;
498
499 // Should not happen
500 if (!session->mIsClosed) {
501 ALOGE("Error: unclosed session %p reaches end of life!", session);
502 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
503 return;
504 }
505
506 // No new session, unconfigure now
Shuzhen Wang316781a2020-08-18 18:11:01 -0700507 // Note: The unconfiguration of session won't be accounted for session
508 // latency because a stream configuration with 0 streams won't ever become
509 // active.
510 nsecs_t startTimeNs = systemTime();
511 camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800512 if (ret != ACAMERA_OK) {
513 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
514 }
515}
516
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800517void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700518CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800519 if (mClosing.exchange(true)) {
520 // Already closing, just return
521 ALOGW("Camera device %s is already closing.", getId());
522 return;
523 }
524
525 if (mRemote != nullptr) {
526 mRemote->disconnect();
527 }
528 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800529
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700530 if (session != nullptr) {
531 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800532 }
533}
534
535camera_status_t
536CameraDevice::stopRepeatingLocked() {
537 camera_status_t ret = checkCameraClosedOrErrorLocked();
538 if (ret != ACAMERA_OK) {
539 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
540 return ret;
541 }
542 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
543 int repeatingSequenceId = mRepeatingSequenceId;
544 mRepeatingSequenceId = REQUEST_ID_NONE;
545
546 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800547 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700548 if (remoteRet.serviceSpecificErrorCode() ==
549 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
550 ALOGV("Repeating request is already stopped.");
551 return ACAMERA_OK;
552 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000553 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800554 return ACAMERA_ERROR_UNKNOWN;
555 }
556 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
557 }
558 return ACAMERA_OK;
559}
560
561camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700562CameraDevice::flushLocked(ACameraCaptureSession* session) {
563 camera_status_t ret = checkCameraClosedOrErrorLocked();
564 if (ret != ACAMERA_OK) {
565 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
566 return ret;
567 }
568
569 // This should never happen because creating a new session will close
570 // previous one and thus reject any API call from previous session.
571 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700572 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700573 ALOGE("Camera %s session %p is not current active session!", getId(), session);
574 return ACAMERA_ERROR_INVALID_OPERATION;
575 }
576
577 if (mFlushing) {
578 ALOGW("Camera %s is already aborting captures", getId());
579 return ACAMERA_OK;
580 }
581
582 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700583
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700584 // Send onActive callback to guarantee there is always active->ready transition
585 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
586 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
587 msg->setObject(kSessionSpKey, session);
588 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700589 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700590
591 // If device is already idling, send callback and exit early
592 if (mIdle) {
593 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
594 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
595 msg->setObject(kSessionSpKey, session);
596 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700597 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700598 mFlushing = false;
599 return ACAMERA_OK;
600 }
601
602 int64_t lastFrameNumber;
603 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
604 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000605 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700606 return ACAMERA_ERROR_UNKNOWN;
607 }
608 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
609 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
610 }
611 return ACAMERA_OK;
612}
613
614camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800615CameraDevice::waitUntilIdleLocked() {
616 camera_status_t ret = checkCameraClosedOrErrorLocked();
617 if (ret != ACAMERA_OK) {
618 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
619 return ret;
620 }
621
622 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
623 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
624 return ACAMERA_ERROR_INVALID_OPERATION;
625 }
626
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800627 binder::Status remoteRet = mRemote->waitUntilIdle();
628 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000629 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800630 // TODO: define a function to convert status_t -> camera_status_t
631 return ACAMERA_ERROR_UNKNOWN;
632 }
633
634 return ACAMERA_OK;
635}
636
637camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700638CameraDevice::getIGBPfromAnw(
639 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800640 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800641 sp<Surface> surface;
642 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
643 if (ret != ACAMERA_OK) {
644 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800645 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800646 out = surface->getIGraphicBufferProducer();
647 return ACAMERA_OK;
648}
649
650camera_status_t
651CameraDevice::getSurfaceFromANativeWindow(
652 ANativeWindow* anw, sp<Surface>& out) {
653 if (anw == nullptr) {
654 ALOGE("Error: output ANativeWindow is null");
655 return ACAMERA_ERROR_INVALID_PARAMETER;
656 }
657 int value;
658 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800659 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800660 ALOGE("Error: ANativeWindow is not backed by Surface!");
661 return ACAMERA_ERROR_INVALID_PARAMETER;
662 }
663 sp<Surface> surface(static_cast<Surface*>(anw));
664 out = surface;
665 return ACAMERA_OK;
666}
667
668camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100669CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700670 const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800671 ACaptureSessionOutputContainer emptyOutput;
672 if (outputs == nullptr) {
673 outputs = &emptyOutput;
674 }
675
Yin-Chia Yehead91462016-01-06 16:45:08 -0800676 camera_status_t ret = checkCameraClosedOrErrorLocked();
677 if (ret != ACAMERA_OK) {
678 return ret;
679 }
680
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700681 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800682 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700683 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800684 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700685 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800686 if (ret != ACAMERA_OK) {
687 return ret;
688 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700689 outputSet.insert(std::make_pair(
Austin Borger71d8f672023-06-01 16:51:35 -0700690 anw, OutputConfiguration(iGBP, outConfig.mRotation, outConfig.mPhysicalCameraId,
Emilian Peev40ead602017-09-26 15:46:36 +0100691 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800692 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700693 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800694 std::vector<int> deleteList;
695
696 // Determine which streams need to be created, which to be deleted
697 for (auto& kvPair : mConfiguredOutputs) {
698 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700699 auto& outputPair = kvPair.second;
700 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800701 deleteList.push_back(streamId); // Need to delete a no longer needed stream
702 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700703 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800704 }
705 }
706
707 ret = stopRepeatingLocked();
708 if (ret != ACAMERA_OK) {
709 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
710 return ret;
711 }
712
713 ret = waitUntilIdleLocked();
714 if (ret != ACAMERA_OK) {
715 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
716 return ret;
717 }
718
719 // Send onReady to previous session
720 // CurrentSession will be updated after configureStreamLocked, so here
721 // mCurrentSession is the session to be replaced by a new session
722 if (!mIdle && mCurrentSession != nullptr) {
723 if (mBusySession != mCurrentSession) {
724 ALOGE("Current session != busy session");
725 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
726 return ACAMERA_ERROR_CAMERA_DEVICE;
727 }
728 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
729 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
730 msg->setObject(kSessionSpKey, mBusySession);
731 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
732 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700733 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800734 }
735 mIdle = true;
736
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800737 binder::Status remoteRet = mRemote->beginConfigure();
738 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000739 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800740 return ACAMERA_ERROR_UNKNOWN;
741 }
742
743 // delete to-be-deleted streams
744 for (auto streamId : deleteList) {
745 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800746 if (!remoteRet.isOk()) {
747 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000748 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800749 return ACAMERA_ERROR_UNKNOWN;
750 }
751 mConfiguredOutputs.erase(streamId);
752 }
753
754 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800755 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800756 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700757 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800758 if (!remoteRet.isOk()) {
759 ALOGE("Camera device %s failed to create stream: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000760 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800761 return ACAMERA_ERROR_UNKNOWN;
762 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700763 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800764 }
765
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100766 CameraMetadata params;
767 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
768 params.append(sessionParameters->settings->getInternalData());
769 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800770 std::vector<int> offlineStreamIds;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700771 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
772 ns2ms(startTimeNs), &offlineStreamIds);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800773 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
774 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000775 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800776 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800777 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000778 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800779 return ACAMERA_ERROR_UNKNOWN;
780 }
781
782 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800783}
784
785void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800786CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800787 Mutex::Autolock _l(mDeviceLock);
788 mRemote = remote;
789}
790
791camera_status_t
792CameraDevice::checkCameraClosedOrErrorLocked() const {
793 if (mRemote == nullptr) {
794 ALOGE("%s: camera device already closed", __FUNCTION__);
795 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
796 }
797 if (mInError) {// triggered by onDeviceError
798 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
799 return mError;
800 }
801 return ACAMERA_OK;
802}
803
804void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800805CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
806 mInError = true;
807 mError = error;
808 return;
809}
810
811void
812CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
813 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
814 if (isError) {
815 mFutureErrorSet.insert(frameNumber);
816 } else if (frameNumber <= mCompletedFrameNumber) {
817 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
818 frameNumber, mCompletedFrameNumber);
819 return;
820 } else {
821 if (frameNumber != mCompletedFrameNumber + 1) {
822 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
823 mCompletedFrameNumber + 1, frameNumber);
824 // Do not assert as in java implementation
825 }
826 mCompletedFrameNumber = frameNumber;
827 }
828 update();
829}
830
831void
832CameraDevice::FrameNumberTracker::update() {
833 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
834 int64_t errorFrameNumber = *it;
835 if (errorFrameNumber == mCompletedFrameNumber + 1) {
836 mCompletedFrameNumber++;
837 it = mFutureErrorSet.erase(it);
838 } else if (errorFrameNumber <= mCompletedFrameNumber) {
839 // This should not happen, but deal with it anyway
840 ALOGE("Completd frame number passed through current frame number!");
841 // erase the old error since it's no longer useful
842 it = mFutureErrorSet.erase(it);
843 } else {
844 // Normal requests hasn't catched up error frames, just break
845 break;
846 }
847 }
848 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
849}
850
851void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800852CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800853 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800854 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800855 int sequenceId = resultExtras.requestId;
856 int64_t frameNumber = resultExtras.frameNumber;
857 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700858 auto it = mSequenceCallbackMap.find(sequenceId);
859 if (it == mSequenceCallbackMap.end()) {
860 ALOGE("%s: Error: capture sequence index %d not found!",
861 __FUNCTION__, sequenceId);
862 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 return;
864 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700865
866 CallbackHolder cbh = (*it).second;
867 sp<ACameraCaptureSession> session = cbh.mSession;
868 if ((size_t) burstId >= cbh.mRequests.size()) {
869 ALOGE("%s: Error: request index %d out of bound (size %zu)",
870 __FUNCTION__, burstId, cbh.mRequests.size());
871 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
872 return;
873 }
874 sp<CaptureRequest> request = cbh.mRequests[burstId];
875
876 // Handle buffer error
877 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
878 int32_t streamId = resultExtras.errorStreamId;
879 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800880 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700881 auto outputPairIt = mConfiguredOutputs.find(streamId);
882 if (outputPairIt == mConfiguredOutputs.end()) {
883 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800884 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
885 return;
886 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700887
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800888 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
889 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800890 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800891 if (surface->getIGraphicBufferProducer() == outGbp) {
892 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
893 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
894 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700895
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800896 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800897 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800898 msg->setObject(kSessionSpKey, session);
899 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
900 msg->setObject(kCaptureRequestKey, request);
901 msg->setPointer(kAnwKey, (void*) anw);
902 msg->setInt64(kFrameNumberKey, frameNumber);
903 postSessionMsgAndCleanup(msg);
904 }
905 }
906 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700907 } else { // Handle other capture failures
908 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800909 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800910 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
911 failure->frameNumber = frameNumber;
912 // TODO: refine this when implementing flush
913 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
914 failure->sequenceId = sequenceId;
915 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800916 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800917
Emilian Peevedec62d2019-03-19 17:59:24 -0700918 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
919 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800920 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800921 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700922 if (cbh.mIsLogicalCameraCallback) {
923 if (resultExtras.errorPhysicalCameraId.size() > 0) {
Austin Borger71d8f672023-06-01 16:51:35 -0700924 String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000925 msg->setString(kFailingPhysicalCameraId, cameraId.c_str(), cameraId.size());
Emilian Peevedec62d2019-03-19 17:59:24 -0700926 }
927 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
928 } else {
929 msg->setPointer(kCallbackFpKey, (void*) onError);
930 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800931 msg->setObject(kCaptureRequestKey, request);
932 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700933 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800934
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700935 // Update tracker
936 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
937 checkAndFireSequenceCompleteLocked();
938 }
939 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800940}
941
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700942void CameraDevice::stopLooperAndDisconnect() {
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700943 Mutex::Autolock _l(mDeviceLock);
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700944 sp<ACameraCaptureSession> session = mCurrentSession.promote();
945 if (!isClosed()) {
946 disconnectLocked(session);
947 }
948 mCurrentSession = nullptr;
949
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700950 if (mCbLooper != nullptr) {
951 mCbLooper->unregisterHandler(mHandler->id());
952 mCbLooper->stop();
953 }
954 mCbLooper.clear();
955 mHandler.clear();
956}
957
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800958CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
959}
960
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800961void CameraDevice::CallbackHandler::onMessageReceived(
962 const sp<AMessage> &msg) {
963 switch (msg->what()) {
964 case kWhatOnDisconnected:
965 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800966 case kWhatSessionStateCb:
967 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +0000968 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800969 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800970 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800971 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700972 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800973 case kWhatCaptureSeqEnd:
974 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700975 case kWhatCaptureBufferLost:
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000976 case kWhatPreparedCb:
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700977 case kWhatClientSharedAccessPriorityChanged:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800978 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800979 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700980 case kWhatCleanUpSessions:
981 mCachedSessions.clear();
982 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800983 default:
984 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
985 return;
986 }
987 // Check the common part of all message
988 void* context;
989 bool found = msg->findPointer(kContextKey, &context);
990 if (!found) {
991 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
992 return;
993 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800994 switch (msg->what()) {
995 case kWhatOnDisconnected:
996 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800997 ACameraDevice* dev;
998 found = msg->findPointer(kDeviceKey, (void**) &dev);
999 if (!found || dev == nullptr) {
1000 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1001 return;
1002 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001003 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001004 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001005 if (!found) {
1006 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
1007 return;
1008 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001009 if (onDisconnected == nullptr) {
1010 return;
1011 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001012 (*onDisconnected)(context, dev);
1013 break;
1014 }
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001015
1016 case kWhatClientSharedAccessPriorityChanged:
1017 {
1018 if (!flags::camera_multi_client()) {
1019 break;
1020 }
1021 ACameraDevice* dev;
1022 found = msg->findPointer(kDeviceKey, (void**) &dev);
1023 if (!found || dev == nullptr) {
1024 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1025 return;
1026 }
1027 ACameraDevice_ClientSharedAccessPriorityChangedCallback
1028 onClientSharedAccessPriorityChanged;
1029 found = msg->findPointer(kCallbackFpKey, (void**) &onClientSharedAccessPriorityChanged);
1030 if (!found) {
1031 ALOGE("%s: Cannot find onClientSharedAccessPriorityChanged!", __FUNCTION__);
1032 return;
1033 }
1034 if (onClientSharedAccessPriorityChanged == nullptr) {
1035 return;
1036 }
1037 (*onClientSharedAccessPriorityChanged)(context, dev, dev->isPrimaryClient());
1038 break;
1039 }
1040
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001041 case kWhatOnError:
1042 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001043 ACameraDevice* dev;
1044 found = msg->findPointer(kDeviceKey, (void**) &dev);
1045 if (!found || dev == nullptr) {
1046 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1047 return;
1048 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001049 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001050 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001051 if (!found) {
1052 ALOGE("%s: Cannot find onError!", __FUNCTION__);
1053 return;
1054 }
1055 int errorCode;
1056 found = msg->findInt32(kErrorCodeKey, &errorCode);
1057 if (!found) {
1058 ALOGE("%s: Cannot find error code!", __FUNCTION__);
1059 return;
1060 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001061 if (onError == nullptr) {
1062 return;
1063 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001064 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001065 break;
1066 }
1067 case kWhatSessionStateCb:
1068 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001069 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001070 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001071 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001072 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001073 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001074 case kWhatCaptureSeqEnd:
1075 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001076 case kWhatCaptureBufferLost:
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001077 case kWhatPreparedCb:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001078 {
1079 sp<RefBase> obj;
1080 found = msg->findObject(kSessionSpKey, &obj);
1081 if (!found || obj == nullptr) {
1082 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
1083 return;
1084 }
1085 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001086 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001087 sp<CaptureRequest> requestSp = nullptr;
1088 switch (msg->what()) {
1089 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001090 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001091 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001092 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001093 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001094 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001095 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001096 found = msg->findObject(kCaptureRequestKey, &obj);
1097 if (!found) {
1098 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1099 return;
1100 }
1101 requestSp = static_cast<CaptureRequest*>(obj.get());
1102 break;
1103 }
1104
1105 switch (msg->what()) {
1106 case kWhatSessionStateCb:
1107 {
1108 ACameraCaptureSession_stateCallback onState;
1109 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1110 if (!found) {
1111 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1112 return;
1113 }
1114 if (onState == nullptr) {
1115 return;
1116 }
1117 (*onState)(context, session.get());
1118 break;
1119 }
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001120 case kWhatPreparedCb:
1121 {
1122 ACameraCaptureSession_prepareCallback onWindowPrepared;
1123 found = msg->findPointer(kCallbackFpKey, (void**) &onWindowPrepared);
1124 if (!found) {
Jayant Chowdhary0f2cb992023-02-17 18:25:53 +00001125 ALOGE("%s: Cannot find window prepared callback!", __FUNCTION__);
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001126 return;
1127 }
1128 if (onWindowPrepared == nullptr) {
1129 return;
1130 }
Avichal Rakesh8effe982023-11-13 18:53:40 -08001131 ANativeWindow* anw;
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001132 found = msg->findPointer(kAnwKey, (void**) &anw);
1133 if (!found) {
1134 ALOGE("%s: Cannot find ANativeWindow: %d!", __FUNCTION__, __LINE__);
1135 return;
1136 }
1137 (*onWindowPrepared)(context, anw, session.get());
1138 break;
1139 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001140 case kWhatCaptureStart:
1141 {
1142 ACameraCaptureSession_captureCallback_start onStart;
1143 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1144 if (!found) {
1145 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1146 return;
1147 }
1148 if (onStart == nullptr) {
1149 return;
1150 }
1151 int64_t timestamp;
1152 found = msg->findInt64(kTimeStampKey, &timestamp);
1153 if (!found) {
1154 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1155 return;
1156 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001157 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001158 (*onStart)(context, session.get(), request, timestamp);
1159 freeACaptureRequest(request);
1160 break;
1161 }
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001162 case kWhatCaptureStart2:
1163 {
1164 ACameraCaptureSession_captureCallback_startV2 onStart2;
1165 found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
1166 if (!found) {
1167 ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
1168 return;
1169 }
1170 if (onStart2 == nullptr) {
1171 return;
1172 }
1173 int64_t timestamp;
1174 found = msg->findInt64(kTimeStampKey, &timestamp);
1175 if (!found) {
1176 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1177 return;
1178 }
1179 int64_t frameNumber;
1180 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1181 if (!found) {
1182 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1183 return;
1184 }
1185
1186 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1187 (*onStart2)(context, session.get(), request, timestamp, frameNumber);
1188 freeACaptureRequest(request);
1189 break;
1190 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001191 case kWhatCaptureResult:
1192 {
1193 ACameraCaptureSession_captureCallback_result onResult;
1194 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1195 if (!found) {
1196 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1197 return;
1198 }
1199 if (onResult == nullptr) {
1200 return;
1201 }
1202
1203 found = msg->findObject(kCaptureResultKey, &obj);
1204 if (!found) {
1205 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1206 return;
1207 }
1208 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001209 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001210 (*onResult)(context, session.get(), request, result.get());
1211 freeACaptureRequest(request);
1212 break;
1213 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001214 case kWhatLogicalCaptureResult:
1215 {
1216 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1217 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1218 if (!found) {
1219 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1220 __FUNCTION__);
1221 return;
1222 }
1223 if (onResult == nullptr) {
1224 return;
1225 }
1226
1227 found = msg->findObject(kCaptureResultKey, &obj);
1228 if (!found) {
1229 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1230 return;
1231 }
1232 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1233
1234 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1235 if (!found) {
1236 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1237 return;
1238 }
1239 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1240 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1241 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1242 physicalResult->mPhysicalResultInfo;
1243
1244 std::vector<std::string> physicalCameraIds;
1245 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1246 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
Austin Borger71d8f672023-06-01 16:51:35 -07001247 String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001248 physicalCameraIds.push_back(physicalId8.c_str());
1249
1250 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1251 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1252 &physicalResult->mFrameNumber, /*data_count*/1);
1253 sp<ACameraMetadata> metadata =
1254 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1255 physicalMetadataCopy.push_back(metadata);
1256 }
1257
1258 std::vector<const char*> physicalCameraIdPtrs;
1259 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1260 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1261 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1262 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1263 }
1264
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001265 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001266 (*onResult)(context, session.get(), request, result.get(),
1267 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1268 physicalMetadataCopyPtrs.data());
1269 freeACaptureRequest(request);
1270 break;
1271 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001272 case kWhatCaptureFail:
1273 {
1274 ACameraCaptureSession_captureCallback_failed onFail;
1275 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1276 if (!found) {
1277 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1278 return;
1279 }
1280 if (onFail == nullptr) {
1281 return;
1282 }
1283
1284 found = msg->findObject(kCaptureFailureKey, &obj);
1285 if (!found) {
1286 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1287 return;
1288 }
1289 sp<CameraCaptureFailure> failureSp(
1290 static_cast<CameraCaptureFailure*>(obj.get()));
1291 ACameraCaptureFailure* failure =
1292 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001293 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001294 (*onFail)(context, session.get(), request, failure);
1295 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001296 break;
1297 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001298 case kWhatLogicalCaptureFail:
1299 {
1300 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1301 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1302 if (!found) {
1303 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1304 return;
1305 }
1306 if (onFail == nullptr) {
1307 return;
1308 }
1309
1310 found = msg->findObject(kCaptureFailureKey, &obj);
1311 if (!found) {
1312 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1313 return;
1314 }
1315 sp<CameraCaptureFailure> failureSp(
1316 static_cast<CameraCaptureFailure*>(obj.get()));
1317 ALogicalCameraCaptureFailure failure;
1318 AString physicalCameraId;
1319 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1320 if (found && !physicalCameraId.empty()) {
1321 failure.physicalCameraId = physicalCameraId.c_str();
1322 } else {
1323 failure.physicalCameraId = nullptr;
1324 }
1325 failure.captureFailure = *failureSp;
1326 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1327 (*onFail)(context, session.get(), request, &failure);
1328 freeACaptureRequest(request);
1329 break;
1330 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001331 case kWhatCaptureSeqEnd:
1332 {
1333 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1334 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1335 if (!found) {
1336 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1337 return;
1338 }
1339 if (onSeqEnd == nullptr) {
1340 return;
1341 }
1342 int seqId;
1343 found = msg->findInt32(kSequenceIdKey, &seqId);
1344 if (!found) {
1345 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1346 return;
1347 }
1348 int64_t frameNumber;
1349 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1350 if (!found) {
1351 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1352 return;
1353 }
1354 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1355 break;
1356 }
1357 case kWhatCaptureSeqAbort:
1358 {
1359 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1360 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1361 if (!found) {
1362 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1363 return;
1364 }
1365 if (onSeqAbort == nullptr) {
1366 return;
1367 }
1368 int seqId;
1369 found = msg->findInt32(kSequenceIdKey, &seqId);
1370 if (!found) {
1371 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1372 return;
1373 }
1374 (*onSeqAbort)(context, session.get(), seqId);
1375 break;
1376 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001377 case kWhatCaptureBufferLost:
1378 {
1379 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1380 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1381 if (!found) {
1382 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1383 return;
1384 }
1385 if (onBufferLost == nullptr) {
1386 return;
1387 }
1388
1389 ANativeWindow* anw;
1390 found = msg->findPointer(kAnwKey, (void**) &anw);
1391 if (!found) {
1392 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1393 return;
1394 }
1395
1396 int64_t frameNumber;
1397 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1398 if (!found) {
1399 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1400 return;
1401 }
1402
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001403 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001404 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1405 freeACaptureRequest(request);
1406 break;
1407 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001408 }
1409 break;
1410 }
1411 }
1412}
1413
1414CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001415 sp<ACameraCaptureSession> session,
1416 const Vector<sp<CaptureRequest> >& requests,
1417 bool isRepeating,
1418 ACameraCaptureSession_captureCallbacks* cbs) :
1419 mSession(session), mRequests(requests),
1420 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001421 mIsLogicalCameraCallback(false),
1422 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001423 initCaptureCallbacks(cbs);
1424
1425 if (cbs != nullptr) {
1426 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001427 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001428 }
1429}
1430
1431CameraDevice::CallbackHolder::CallbackHolder(
1432 sp<ACameraCaptureSession> session,
1433 const Vector<sp<CaptureRequest> >& requests,
1434 bool isRepeating,
1435 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1436 mSession(session), mRequests(requests),
1437 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001438 mIsLogicalCameraCallback(true),
1439 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001440 initCaptureCallbacks(lcbs);
1441
1442 if (lcbs != nullptr) {
1443 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001444 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001445 }
1446}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001447
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001448CameraDevice::CallbackHolder::CallbackHolder(
1449 sp<ACameraCaptureSession> session,
1450 const Vector<sp<CaptureRequest> >& requests,
1451 bool isRepeating,
1452 ACameraCaptureSession_captureCallbacksV2* cbs) :
1453 mSession(session), mRequests(requests),
1454 mIsRepeating(isRepeating),
1455 mIsLogicalCameraCallback(false),
1456 mIs2Callback(true) {
1457 initCaptureCallbacksV2(cbs);
1458
1459 if (cbs != nullptr) {
1460 mOnCaptureCompleted = cbs->onCaptureCompleted;
1461 mOnCaptureFailed = cbs->onCaptureFailed;
1462 }
1463}
1464
1465CameraDevice::CallbackHolder::CallbackHolder(
1466 sp<ACameraCaptureSession> session,
1467 const Vector<sp<CaptureRequest> >& requests,
1468 bool isRepeating,
1469 ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
1470 mSession(session), mRequests(requests),
1471 mIsRepeating(isRepeating),
1472 mIsLogicalCameraCallback(true),
1473 mIs2Callback(true) {
1474 initCaptureCallbacksV2(lcbs);
1475
1476 if (lcbs != nullptr) {
1477 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1478 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
1479 }
1480}
1481
Yin-Chia Yehead91462016-01-06 16:45:08 -08001482void
1483CameraDevice::checkRepeatingSequenceCompleteLocked(
1484 const int sequenceId, const int64_t lastFrameNumber) {
1485 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1486 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1487 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1488 ALOGW("No callback found for sequenceId %d", sequenceId);
1489 return;
1490 }
1491 // remove callback holder from callback map
1492 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1493 CallbackHolder cbh = cbIt->second;
1494 mSequenceCallbackMap.erase(cbIt);
1495 // send seq aborted callback
1496 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001497 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001498 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001499 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001500 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001501 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001502 } else {
1503 // Use mSequenceLastFrameNumberMap to track
1504 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1505
1506 // Last frame might have arrived. Check now
1507 checkAndFireSequenceCompleteLocked();
1508 }
1509}
1510
1511void
1512CameraDevice::checkAndFireSequenceCompleteLocked() {
1513 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001514 auto it = mSequenceLastFrameNumberMap.begin();
1515 while (it != mSequenceLastFrameNumberMap.end()) {
1516 int sequenceId = it->first;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001517 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001518
1519 if (mRemote == nullptr) {
1520 ALOGW("Camera %s closed while checking sequence complete", getId());
1521 return;
1522 }
1523 ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1524 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1525 if (!it->second.isSequenceCompleted) {
1526 // Check if there is callback for this sequence
1527 // This should not happen because we always register callback (with nullptr inside)
1528 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1529 ALOGW("No callback found for sequenceId %d", sequenceId);
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001530 }
1531
1532 if (lastFrameNumber <= completedFrameNumber) {
1533 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1534 it->second.isSequenceCompleted = true;
1535 }
1536
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001537 }
1538
1539 if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001540 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
1541
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001542 it = mSequenceLastFrameNumberMap.erase(it);
1543 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1544 } else {
1545 ++it;
1546 }
1547 }
1548}
1549
1550void
1551CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1552 auto it = mSequenceLastFrameNumberMap.begin();
1553 while (it != mSequenceLastFrameNumberMap.end()) {
1554 int sequenceId = it->first;
1555 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wang730a7912020-05-07 11:59:02 -07001556
1557 if (mRemote == nullptr) {
1558 ALOGW("Camera %s closed while checking sequence complete", getId());
1559 return;
1560 }
Shuzhen Wang730a7912020-05-07 11:59:02 -07001561
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001562 ALOGV("%s: seq %d's last frame number %" PRId64
1563 ", completed inflight frame number %" PRId64,
1564 __FUNCTION__, sequenceId, lastFrameNumber,
1565 lastCompletedRegularFrameNumber);
1566 if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1567 if (it->second.isSequenceCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001568 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
Shuzhen Wang730a7912020-05-07 11:59:02 -07001569
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001570 it = mSequenceLastFrameNumberMap.erase(it);
1571 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1572 } else {
1573 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1574 it->second.isInflightCompleted = true;
1575 ++it;
1576 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001577 } else {
1578 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001579 }
1580 }
1581}
1582
1583/**
1584 * Camera service callback implementation
1585 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001586binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001587CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001588 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001589 const CaptureResultExtras& resultExtras) {
1590 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1591 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001592 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001593 sp<CameraDevice> dev = mDevice.promote();
1594 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001595 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001596 }
1597
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001598 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001599 Mutex::Autolock _l(dev->mDeviceLock);
1600 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001601 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001602 }
1603 switch (errorCode) {
1604 case ERROR_CAMERA_DISCONNECTED:
1605 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001606 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001607 if (session != nullptr) {
1608 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001609 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001610 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001611 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1612 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1613 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001614 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001615 msg->post();
1616 break;
1617 }
1618 default:
1619 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001620 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001621 case ERROR_CAMERA_DEVICE:
1622 case ERROR_CAMERA_SERVICE:
1623 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001624 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1625 // We keep this switch since this block might be encountered with
1626 // more than just 2 states. The default fallthrough could have us
1627 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001628 switch (errorCode) {
1629 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001630 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001631 break;
1632 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001633 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001634 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001635 break;
1636 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001637 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001638 break;
1639 }
1640 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1641 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1642 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001643 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001644 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001645 msg->post();
1646 break;
1647 }
1648 case ERROR_CAMERA_REQUEST:
1649 case ERROR_CAMERA_RESULT:
1650 case ERROR_CAMERA_BUFFER:
1651 dev->onCaptureErrorLocked(errorCode, resultExtras);
1652 break;
1653 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001654 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001655}
1656
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001657binder::Status
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001658CameraDevice::ServiceCallback::onClientSharedAccessPriorityChanged(bool primaryClient) {
1659 ALOGV("onClientSharedAccessPriorityChanged received. primaryClient = %d", primaryClient);
1660 binder::Status ret = binder::Status::ok();
1661 if (!flags::camera_multi_client()) {
1662 return ret;
1663 }
1664 sp<CameraDevice> dev = mDevice.promote();
1665 if (dev == nullptr) {
1666 return ret; // device has been closed
1667 }
1668 Mutex::Autolock _l(dev->mDeviceLock);
1669 if (dev->isClosed() || dev->mRemote == nullptr) {
1670 return ret;
1671 }
1672 dev->setPrimaryClient(primaryClient);
1673 sp<AMessage> msg = new AMessage(kWhatClientSharedAccessPriorityChanged, dev->mHandler);
1674 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1675 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
1676 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onClientSharedAccessPriorityChanged);
1677 msg->post();
1678
1679 return binder::Status::ok();
1680}
1681
1682binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001683CameraDevice::ServiceCallback::onDeviceIdle() {
1684 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001685 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001686 sp<CameraDevice> dev = mDevice.promote();
1687 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001688 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001689 }
1690
1691 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001692 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001693 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001694 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001695
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001696 dev->removeCompletedCallbackHolderLocked(
1697 std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1698
Yin-Chia Yehead91462016-01-06 16:45:08 -08001699 if (dev->mIdle) {
1700 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001701 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001702 }
1703
1704 if (dev->mCurrentSession != nullptr) {
1705 ALOGE("onDeviceIdle sending state cb");
1706 if (dev->mBusySession != dev->mCurrentSession) {
1707 ALOGE("Current session != busy session");
1708 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001709 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001710 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001711
Yin-Chia Yehead91462016-01-06 16:45:08 -08001712 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1713 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1714 msg->setObject(kSessionSpKey, dev->mBusySession);
1715 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1716 // Make sure we clear the sp first so the session destructor can
1717 // only happen on handler thread (where we don't hold device/session lock)
1718 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001719 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001720 }
1721 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001722 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001723 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001724}
1725
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001726binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001727CameraDevice::ServiceCallback::onCaptureStarted(
1728 const CaptureResultExtras& resultExtras,
1729 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001730 binder::Status ret = binder::Status::ok();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001731 sp<CameraDevice> dev = mDevice.promote();
1732 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001733 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001734 }
1735 Mutex::Autolock _l(dev->mDeviceLock);
1736 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001737 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001738 }
1739
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001740 dev->removeCompletedCallbackHolderLocked(
1741 resultExtras.lastCompletedRegularFrameNumber);
1742
Yin-Chia Yehead91462016-01-06 16:45:08 -08001743 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001744 int32_t burstId = resultExtras.burstId;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001745 int64_t frameNumber = resultExtras.frameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001746
1747 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1748 if (it != dev->mSequenceCallbackMap.end()) {
1749 CallbackHolder cbh = (*it).second;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001750 bool v2Callback = cbh.mIs2Callback;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001751 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001752 ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001753 sp<ACameraCaptureSession> session = cbh.mSession;
1754 if ((size_t) burstId >= cbh.mRequests.size()) {
1755 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1756 __FUNCTION__, burstId, cbh.mRequests.size());
1757 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1758 }
1759 sp<CaptureRequest> request = cbh.mRequests[burstId];
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001760 sp<AMessage> msg = nullptr;
1761 if (v2Callback) {
1762 msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
1763 msg->setPointer(kCallbackFpKey, (void*) onStart2);
1764 } else {
1765 msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1766 msg->setPointer(kCallbackFpKey, (void *)onStart);
1767 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001768 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001769 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001770 msg->setObject(kCaptureRequestKey, request);
1771 msg->setInt64(kTimeStampKey, timestamp);
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001772 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001773 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001774 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001775 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001776}
1777
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001778binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001779CameraDevice::ServiceCallback::onResultReceived(
1780 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001781 const CaptureResultExtras& resultExtras,
1782 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001783 binder::Status ret = binder::Status::ok();
1784
Yin-Chia Yehead91462016-01-06 16:45:08 -08001785 sp<CameraDevice> dev = mDevice.promote();
1786 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001787 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001788 }
1789 int sequenceId = resultExtras.requestId;
1790 int64_t frameNumber = resultExtras.frameNumber;
1791 int32_t burstId = resultExtras.burstId;
1792 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1793
1794 if (!isPartialResult) {
1795 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1796 }
1797
1798 Mutex::Autolock _l(dev->mDeviceLock);
1799 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001800 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001801 }
1802
1803 if (dev->isClosed()) {
1804 if (!isPartialResult) {
1805 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1806 }
1807 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001808 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001809 }
1810
1811 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001812 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001813 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001814
1815 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1816 if (it != dev->mSequenceCallbackMap.end()) {
1817 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001818 sp<ACameraCaptureSession> session = cbh.mSession;
1819 if ((size_t) burstId >= cbh.mRequests.size()) {
1820 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1821 __FUNCTION__, burstId, cbh.mRequests.size());
1822 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1823 }
1824 sp<CaptureRequest> request = cbh.mRequests[burstId];
1825 sp<ACameraMetadata> result(new ACameraMetadata(
1826 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001827 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1828 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001829
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001830 sp<AMessage> msg = new AMessage(
1831 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1832 dev->mHandler);
1833 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001834 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001835 msg->setObject(kCaptureRequestKey, request);
1836 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001837 if (isPartialResult) {
1838 msg->setPointer(kCallbackFpKey,
1839 (void *)cbh.mOnCaptureProgressed);
1840 } else if (cbh.mIsLogicalCameraCallback) {
1841 msg->setPointer(kCallbackFpKey,
1842 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1843 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1844 } else {
1845 msg->setPointer(kCallbackFpKey,
1846 (void *)cbh.mOnCaptureCompleted);
1847 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001848 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001849 }
1850
1851 if (!isPartialResult) {
1852 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1853 dev->checkAndFireSequenceCompleteLocked();
1854 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001855
1856 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001857}
1858
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001859binder::Status
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001860CameraDevice::ServiceCallback::onPrepared(int streamId) {
1861 ALOGV("%s: callback for stream id %d", __FUNCTION__, streamId);
1862 binder::Status ret = binder::Status::ok();
1863 sp<CameraDevice> dev = mDevice.promote();
1864 if (dev == nullptr) {
1865 return ret; // device has been closed
1866 }
1867 Mutex::Autolock _l(dev->mDeviceLock);
1868 if (dev->isClosed() || dev->mRemote == nullptr) {
1869 return ret;
1870 }
1871 auto it = dev->mConfiguredOutputs.find(streamId);
1872 if (it == dev->mConfiguredOutputs.end()) {
1873 ALOGE("%s: stream id %d does not exist", __FUNCTION__ , streamId);
1874 return ret;
1875 }
1876 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
1877 if (session == nullptr) {
1878 ALOGE("%s: Session is dead already", __FUNCTION__ );
1879 return ret;
1880 }
1881 // We've found the window corresponding to the surface id.
Avichal Rakesh8effe982023-11-13 18:53:40 -08001882 ANativeWindow *window = it->second.first;
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001883 sp<AMessage> msg = new AMessage(kWhatPreparedCb, dev->mHandler);
1884 msg->setPointer(kContextKey, session->mPreparedCb.context);
1885 msg->setPointer(kAnwKey, window);
1886 msg->setObject(kSessionSpKey, session);
1887 msg->setPointer(kCallbackFpKey, (void *)session->mPreparedCb.onWindowPrepared);
1888 dev->postSessionMsgAndCleanup(msg);
1889
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001890 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001891}
1892
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001893binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001894CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1895 // onRequestQueueEmpty not yet implemented in NDK
1896 return binder::Status::ok();
1897}
1898
1899binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001900CameraDevice::ServiceCallback::onRepeatingRequestError(
1901 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001902 binder::Status ret = binder::Status::ok();
1903
1904 sp<CameraDevice> dev = mDevice.promote();
1905 if (dev == nullptr) {
1906 return ret; // device has been closed
1907 }
1908
1909 Mutex::Autolock _l(dev->mDeviceLock);
1910
1911 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001912 if (stoppedSequenceId == repeatingSequenceId) {
1913 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1914 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001915
1916 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1917
1918 return ret;
1919}
1920
Shuzhen Wangacae2642020-12-21 17:11:37 -08001921void
1922CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
1923 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1924 if (cbIt != mSequenceCallbackMap.end()) {
1925 CallbackHolder cbh = cbIt->second;
1926 mSequenceCallbackMap.erase(cbIt);
1927
1928 // send seq complete callback
1929 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1930 msg->setPointer(kContextKey, cbh.mContext);
1931 msg->setObject(kSessionSpKey, cbh.mSession);
1932 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1933 msg->setInt32(kSequenceIdKey, sequenceId);
1934 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1935
1936 // Clear the session sp before we send out the message
1937 // This will guarantee the rare case where the message is processed
1938 // before cbh goes out of scope and causing we call the session
1939 // destructor while holding device lock
1940 cbh.mSession.clear();
1941 postSessionMsgAndCleanup(msg);
1942 } else {
1943 // Check if there is callback for this sequence
1944 // This should not happen because we always register callback (with nullptr inside)
1945 ALOGW("No callback found for sequenceId %d", sequenceId);
1946 }
1947}
1948
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001949} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001950} // namespace android