blob: 7840fa0a2b5f7e7ddc3383d8eeea651a7465b8b9 [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
Jayant Chowdharydcae7962024-08-20 21:20:10 +000040using android::hardware::common::fmq::MQDescriptor;
41
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080042// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080043const char* CameraDevice::kContextKey = "Context";
44const char* CameraDevice::kDeviceKey = "Device";
45const char* CameraDevice::kErrorCodeKey = "ErrorCode";
46const char* CameraDevice::kCallbackFpKey = "Callback";
47const char* CameraDevice::kSessionSpKey = "SessionSp";
48const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
49const char* CameraDevice::kTimeStampKey = "TimeStamp";
50const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080051const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080052const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
53const char* CameraDevice::kSequenceIdKey = "SequenceId";
54const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070055const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070056const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080057
58/**
59 * CameraDevice Implementation
60 */
61CameraDevice::CameraDevice(
62 const char* id,
63 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070064 sp<ACameraMetadata> chars,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070065 ACameraDevice* wrapper, bool sharedMode) :
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080066 mCameraId(id),
67 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070068 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080069 mServiceCallback(new ServiceCallback(this)),
70 mWrapper(wrapper),
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070071 mSharedMode(sharedMode),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080072 mInError(false),
73 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070074 mIdle(true),
75 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080076 mClosing = false;
77 // Setup looper thread to perfrom device callbacks to app
78 mCbLooper = new ALooper;
79 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080080 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080081 /*runOnCallingThread*/false,
82 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080083 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080084 if (err != OK) {
85 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
86 __FUNCTION__, strerror(-err), err);
87 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
88 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080089 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080090 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080091
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080092 const CameraMetadata& metadata = mChars->getInternalData();
93 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080094 if (entry.count != 1) {
95 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
96 mPartialResultCount = 1;
97 } else {
98 mPartialResultCount = entry.data.i32[0];
99 }
100
101 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
102 if (entry.count != 2) {
103 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
104 mShadingMapSize[0] = 0;
105 mShadingMapSize[1] = 0;
106 } else {
107 mShadingMapSize[0] = entry.data.i32[0];
108 mShadingMapSize[1] = entry.data.i32[1];
109 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800110
111 size_t physicalIdCnt = 0;
112 const char*const* physicalCameraIds;
113 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
114 for (size_t i = 0; i < physicalIdCnt; i++) {
115 mPhysicalIds.push_back(physicalCameraIds[i]);
116 }
117 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800118}
119
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700120CameraDevice::~CameraDevice() { }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800121
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700122void
123CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
124 msg->post();
125 msg.clear();
126 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
127 cleanupMsg->post();
128}
129
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800130// TODO: cached created request?
131camera_status_t
132CameraDevice::createCaptureRequest(
133 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800134 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800135 ACaptureRequest** request) const {
136 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800137
138 if (physicalIdList != nullptr) {
139 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
140 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
141 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
142 return ACAMERA_ERROR_INVALID_PARAMETER;
143 }
144 for (auto i = 0; i < physicalIdList->numCameras; i++) {
145 if (physicalIdList->cameraIds[i] == nullptr) {
146 ALOGE("%s: physicalId is null!", __FUNCTION__);
147 return ACAMERA_ERROR_INVALID_PARAMETER;
148 }
149 if (mPhysicalIds.end() == std::find(
150 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
151 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
152 return ACAMERA_ERROR_INVALID_PARAMETER;
153 }
154 }
155 }
156
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800157 camera_status_t ret = checkCameraClosedOrErrorLocked();
158 if (ret != ACAMERA_OK) {
159 return ret;
160 }
161 if (mRemote == nullptr) {
162 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
163 }
164 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800165 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
166 if (remoteRet.serviceSpecificErrorCode() ==
167 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800168 ALOGW("Create capture request failed! template %d is not supported on this device",
169 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700170 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800171 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000172 ALOGE("Create capture request failed: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800173 return ACAMERA_ERROR_UNKNOWN;
174 }
175 ACaptureRequest* outReq = new ACaptureRequest();
176 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800177 if (physicalIdList != nullptr) {
178 for (auto i = 0; i < physicalIdList->numCameras; i++) {
179 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
180 new ACameraMetadata(*(outReq->settings)));
181 }
182 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800183 outReq->targets = new ACameraOutputTargets();
184 *request = outReq;
185 return ACAMERA_OK;
186}
187
Yin-Chia Yehead91462016-01-06 16:45:08 -0800188camera_status_t
189CameraDevice::createCaptureSession(
190 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100191 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800192 const ACameraCaptureSession_stateCallbacks* callbacks,
193 /*out*/ACameraCaptureSession** session) {
Shuzhen Wang316781a2020-08-18 18:11:01 -0700194 nsecs_t startTimeNs = systemTime();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700195 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800196 Mutex::Autolock _l(mDeviceLock);
197 camera_status_t ret = checkCameraClosedOrErrorLocked();
198 if (ret != ACAMERA_OK) {
199 return ret;
200 }
201
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700202 if (currentSession != nullptr) {
203 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800204 stopRepeatingLocked();
205 }
206
207 // Create new session
Shuzhen Wang316781a2020-08-18 18:11:01 -0700208 ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800209 if (ret != ACAMERA_OK) {
210 ALOGE("Fail to create new session. cannot configure streams");
211 return ret;
212 }
213
214 ACameraCaptureSession* newSession = new ACameraCaptureSession(
215 mNextSessionId++, outputs, callbacks, this);
216
Yin-Chia Yehead91462016-01-06 16:45:08 -0800217 // set new session as current session
218 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
219 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700220 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800221 *session = newSession;
222 return ACAMERA_OK;
223}
224
Shuzhen Wang24810e72019-03-18 10:55:01 -0700225camera_status_t CameraDevice::isSessionConfigurationSupported(
226 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
227 Mutex::Autolock _l(mDeviceLock);
228 camera_status_t ret = checkCameraClosedOrErrorLocked();
229 if (ret != ACAMERA_OK) {
230 return ret;
231 }
232
233 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
234 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
235 for (const auto& output : sessionOutputContainer->mOutputs) {
236 sp<IGraphicBufferProducer> iGBP(nullptr);
237 ret = getIGBPfromAnw(output.mWindow, iGBP);
238 if (ret != ACAMERA_OK) {
239 ALOGE("Camera device %s failed to extract graphic producer from native window",
240 getId());
241 return ret;
242 }
243
Austin Borger71d8f672023-06-01 16:51:35 -0700244 OutputConfiguration outConfig(iGBP, output.mRotation, output.mPhysicalCameraId,
Shuzhen Wang24810e72019-03-18 10:55:01 -0700245 OutputConfiguration::INVALID_SET_ID, true);
246
247 for (auto& anw : output.mSharedWindows) {
248 ret = getIGBPfromAnw(anw, iGBP);
249 if (ret != ACAMERA_OK) {
250 ALOGE("Camera device %s failed to extract graphic producer from native window",
251 getId());
252 return ret;
253 }
254 outConfig.addGraphicProducer(iGBP);
255 }
256
257 sessionConfiguration.addOutputConfiguration(outConfig);
258 }
259
260 bool supported = false;
261 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
262 sessionConfiguration, &supported);
263 if (remoteRet.serviceSpecificErrorCode() ==
264 hardware::ICameraService::ERROR_INVALID_OPERATION) {
265 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
266 } else if (!remoteRet.isOk()) {
267 return ACAMERA_ERROR_UNKNOWN;
268 } else {
269 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
270 }
271}
272
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800273camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100274 camera_status_t ret = checkCameraClosedOrErrorLocked();
275 if (ret != ACAMERA_OK) {
276 return ret;
277 }
278
279 if (output == nullptr) {
280 return ACAMERA_ERROR_INVALID_PARAMETER;
281 }
282
283 if (!output->mIsShared) {
284 ALOGE("Error output configuration is not shared");
285 return ACAMERA_ERROR_INVALID_OPERATION;
286 }
287
288 int32_t streamId = -1;
289 for (auto& kvPair : mConfiguredOutputs) {
290 if (kvPair.second.first == output->mWindow) {
291 streamId = kvPair.first;
292 break;
293 }
294 }
295 if (streamId < 0) {
296 ALOGE("Error: Invalid output configuration");
297 return ACAMERA_ERROR_INVALID_PARAMETER;
298 }
299
300 sp<IGraphicBufferProducer> iGBP(nullptr);
301 ret = getIGBPfromAnw(output->mWindow, iGBP);
302 if (ret != ACAMERA_OK) {
303 ALOGE("Camera device %s failed to extract graphic producer from native window",
304 getId());
305 return ret;
306 }
307
Austin Borger71d8f672023-06-01 16:51:35 -0700308 OutputConfiguration outConfig(iGBP, output->mRotation, output->mPhysicalCameraId,
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800309 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100310
311 for (auto& anw : output->mSharedWindows) {
312 ret = getIGBPfromAnw(anw, iGBP);
313 if (ret != ACAMERA_OK) {
314 ALOGE("Camera device %s failed to extract graphic producer from native window",
315 getId());
316 return ret;
317 }
318 outConfig.addGraphicProducer(iGBP);
319 }
320
321 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
322 if (!remoteRet.isOk()) {
323 switch (remoteRet.serviceSpecificErrorCode()) {
324 case hardware::ICameraService::ERROR_INVALID_OPERATION:
325 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000326 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100327 return ACAMERA_ERROR_INVALID_OPERATION;
328 break;
329 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
330 ALOGE("Camera device %s output surface already exists: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000331 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100332 return ACAMERA_ERROR_INVALID_PARAMETER;
333 break;
334 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
335 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000336 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100337 return ACAMERA_ERROR_INVALID_PARAMETER;
338 break;
339 default:
340 ALOGE("Camera device %s failed to add shared output: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000341 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100342 return ACAMERA_ERROR_UNKNOWN;
343 }
344 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800345 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100346
347 return ACAMERA_OK;
348}
349
Avichal Rakesh8effe982023-11-13 18:53:40 -0800350camera_status_t CameraDevice::prepareLocked(ANativeWindow *window) {
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000351 camera_status_t ret = checkCameraClosedOrErrorLocked();
352 if (ret != ACAMERA_OK) {
353 return ret;
354 }
355
356 if (window == nullptr) {
357 return ACAMERA_ERROR_INVALID_PARAMETER;
358 }
359
360 int32_t streamId = -1;
361 for (auto& kvPair : mConfiguredOutputs) {
362 if (window == kvPair.second.first) {
363 streamId = kvPair.first;
364 break;
365 }
366 }
367 if (streamId < 0) {
368 ALOGE("Error: Invalid output configuration");
369 return ACAMERA_ERROR_INVALID_PARAMETER;
370 }
371 auto remoteRet = mRemote->prepare(streamId);
372 if (!remoteRet.isOk()) {
373 // TODO:(b/259735869) Do this check for all other binder calls in the
374 // ndk as well.
375 if (remoteRet.exceptionCode() != EX_SERVICE_SPECIFIC) {
376 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000377 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000378 return ACAMERA_ERROR_UNKNOWN;
379
380 }
381 switch (remoteRet.serviceSpecificErrorCode()) {
382 case hardware::ICameraService::ERROR_INVALID_OPERATION:
383 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000384 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000385 return ACAMERA_ERROR_INVALID_OPERATION;
386 break;
387 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
388 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000389 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000390 return ACAMERA_ERROR_INVALID_PARAMETER;
391 break;
392 default:
393 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000394 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000395 return ACAMERA_ERROR_UNKNOWN;
396 }
397 }
398
399 return ACAMERA_OK;
400}
401
Yin-Chia Yehead91462016-01-06 16:45:08 -0800402camera_status_t
403CameraDevice::allocateCaptureRequest(
404 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
405 camera_status_t ret;
406 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800407 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000408 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800409 for (auto& entry : request->physicalSettings) {
410 req->mPhysicalCameraSettings.push_back({entry.first,
411 entry.second->getInternalData()});
412 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800413 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700414 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800415 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800416
417 for (auto outputTarget : request->targets->mOutputs) {
418 ANativeWindow* anw = outputTarget.mWindow;
419 sp<Surface> surface;
420 ret = getSurfaceFromANativeWindow(anw, surface);
421 if (ret != ACAMERA_OK) {
422 ALOGE("Bad output target in capture request! ret %d", ret);
423 return ret;
424 }
425 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800426
427 bool found = false;
428 // lookup stream/surface ID
429 for (const auto& kvPair : mConfiguredOutputs) {
430 int streamId = kvPair.first;
431 const OutputConfiguration& outConfig = kvPair.second.second;
432 const auto& gbps = outConfig.getGraphicBufferProducers();
433 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
434 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
435 found = true;
436 req->mStreamIdxList.push_back(streamId);
437 req->mSurfaceIdxList.push_back(surfaceId);
438 break;
439 }
440 }
441 if (found) {
442 break;
443 }
444 }
445 if (!found) {
446 ALOGE("Unconfigured output target %p in capture request!", anw);
447 return ret;
448 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800449 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800450
Yin-Chia Yehead91462016-01-06 16:45:08 -0800451 outReq = req;
452 return ACAMERA_OK;
453}
454
455ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800456CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800457 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800458 for (auto& entry : req->mPhysicalCameraSettings) {
459 CameraMetadata clone = entry.settings;
460 if (entry.id == deviceId) {
461 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
462 } else {
463 pRequest->physicalSettings.emplace(entry.id,
464 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
465 }
466 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800467 pRequest->targets = new ACameraOutputTargets();
468 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
469 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
470 ACameraOutputTarget outputTarget(anw);
471 pRequest->targets->mOutputs.insert(outputTarget);
472 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700473 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800474 return pRequest;
475}
476
477void
478CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
479 if (req == nullptr) {
480 return;
481 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700482 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800483 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800484 delete req->targets;
485 delete req;
486}
487
488void
489CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
490 if (isClosed()) {
491 // Device is closing already. do nothing
492 return;
493 }
494
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700495 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800496 // Session has been replaced by other seesion or device is closed
497 return;
498 }
499 mCurrentSession = nullptr;
500
501 // Should not happen
502 if (!session->mIsClosed) {
503 ALOGE("Error: unclosed session %p reaches end of life!", session);
504 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
505 return;
506 }
507
508 // No new session, unconfigure now
Shuzhen Wang316781a2020-08-18 18:11:01 -0700509 // Note: The unconfiguration of session won't be accounted for session
510 // latency because a stream configuration with 0 streams won't ever become
511 // active.
512 nsecs_t startTimeNs = systemTime();
513 camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800514 if (ret != ACAMERA_OK) {
515 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
516 }
517}
518
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800519void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700520CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800521 if (mClosing.exchange(true)) {
522 // Already closing, just return
523 ALOGW("Camera device %s is already closing.", getId());
524 return;
525 }
526
527 if (mRemote != nullptr) {
528 mRemote->disconnect();
529 }
530 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800531
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700532 if (session != nullptr) {
533 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800534 }
535}
536
537camera_status_t
538CameraDevice::stopRepeatingLocked() {
539 camera_status_t ret = checkCameraClosedOrErrorLocked();
540 if (ret != ACAMERA_OK) {
541 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
542 return ret;
543 }
544 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
545 int repeatingSequenceId = mRepeatingSequenceId;
546 mRepeatingSequenceId = REQUEST_ID_NONE;
547
548 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800549 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700550 if (remoteRet.serviceSpecificErrorCode() ==
551 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
552 ALOGV("Repeating request is already stopped.");
553 return ACAMERA_OK;
554 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000555 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800556 return ACAMERA_ERROR_UNKNOWN;
557 }
558 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
559 }
560 return ACAMERA_OK;
561}
562
563camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700564CameraDevice::flushLocked(ACameraCaptureSession* session) {
565 camera_status_t ret = checkCameraClosedOrErrorLocked();
566 if (ret != ACAMERA_OK) {
567 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
568 return ret;
569 }
570
571 // This should never happen because creating a new session will close
572 // previous one and thus reject any API call from previous session.
573 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700574 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700575 ALOGE("Camera %s session %p is not current active session!", getId(), session);
576 return ACAMERA_ERROR_INVALID_OPERATION;
577 }
578
579 if (mFlushing) {
580 ALOGW("Camera %s is already aborting captures", getId());
581 return ACAMERA_OK;
582 }
583
584 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700585
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700586 // Send onActive callback to guarantee there is always active->ready transition
587 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
588 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
589 msg->setObject(kSessionSpKey, session);
590 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700591 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700592
593 // If device is already idling, send callback and exit early
594 if (mIdle) {
595 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
596 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
597 msg->setObject(kSessionSpKey, session);
598 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700599 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700600 mFlushing = false;
601 return ACAMERA_OK;
602 }
603
604 int64_t lastFrameNumber;
605 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
606 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000607 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700608 return ACAMERA_ERROR_UNKNOWN;
609 }
610 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
611 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
612 }
613 return ACAMERA_OK;
614}
615
616camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800617CameraDevice::waitUntilIdleLocked() {
618 camera_status_t ret = checkCameraClosedOrErrorLocked();
619 if (ret != ACAMERA_OK) {
620 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
621 return ret;
622 }
623
624 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
625 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
626 return ACAMERA_ERROR_INVALID_OPERATION;
627 }
628
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800629 binder::Status remoteRet = mRemote->waitUntilIdle();
630 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000631 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800632 // TODO: define a function to convert status_t -> camera_status_t
633 return ACAMERA_ERROR_UNKNOWN;
634 }
635
636 return ACAMERA_OK;
637}
638
639camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700640CameraDevice::getIGBPfromAnw(
641 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800642 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800643 sp<Surface> surface;
644 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
645 if (ret != ACAMERA_OK) {
646 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800647 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800648 out = surface->getIGraphicBufferProducer();
649 return ACAMERA_OK;
650}
651
652camera_status_t
653CameraDevice::getSurfaceFromANativeWindow(
654 ANativeWindow* anw, sp<Surface>& out) {
655 if (anw == nullptr) {
656 ALOGE("Error: output ANativeWindow is null");
657 return ACAMERA_ERROR_INVALID_PARAMETER;
658 }
659 int value;
660 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800661 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800662 ALOGE("Error: ANativeWindow is not backed by Surface!");
663 return ACAMERA_ERROR_INVALID_PARAMETER;
664 }
665 sp<Surface> surface(static_cast<Surface*>(anw));
666 out = surface;
667 return ACAMERA_OK;
668}
669
670camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100671CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700672 const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800673 ACaptureSessionOutputContainer emptyOutput;
674 if (outputs == nullptr) {
675 outputs = &emptyOutput;
676 }
677
Yin-Chia Yehead91462016-01-06 16:45:08 -0800678 camera_status_t ret = checkCameraClosedOrErrorLocked();
679 if (ret != ACAMERA_OK) {
680 return ret;
681 }
682
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700683 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800684 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700685 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800686 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700687 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800688 if (ret != ACAMERA_OK) {
689 return ret;
690 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700691 outputSet.insert(std::make_pair(
Austin Borger71d8f672023-06-01 16:51:35 -0700692 anw, OutputConfiguration(iGBP, outConfig.mRotation, outConfig.mPhysicalCameraId,
Emilian Peev40ead602017-09-26 15:46:36 +0100693 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800694 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700695 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800696 std::vector<int> deleteList;
697
698 // Determine which streams need to be created, which to be deleted
699 for (auto& kvPair : mConfiguredOutputs) {
700 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700701 auto& outputPair = kvPair.second;
702 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800703 deleteList.push_back(streamId); // Need to delete a no longer needed stream
704 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700705 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800706 }
707 }
708
709 ret = stopRepeatingLocked();
710 if (ret != ACAMERA_OK) {
711 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
712 return ret;
713 }
714
715 ret = waitUntilIdleLocked();
716 if (ret != ACAMERA_OK) {
717 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
718 return ret;
719 }
720
721 // Send onReady to previous session
722 // CurrentSession will be updated after configureStreamLocked, so here
723 // mCurrentSession is the session to be replaced by a new session
724 if (!mIdle && mCurrentSession != nullptr) {
725 if (mBusySession != mCurrentSession) {
726 ALOGE("Current session != busy session");
727 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
728 return ACAMERA_ERROR_CAMERA_DEVICE;
729 }
730 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
731 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
732 msg->setObject(kSessionSpKey, mBusySession);
733 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
734 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700735 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800736 }
737 mIdle = true;
738
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800739 binder::Status remoteRet = mRemote->beginConfigure();
740 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000741 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800742 return ACAMERA_ERROR_UNKNOWN;
743 }
744
745 // delete to-be-deleted streams
746 for (auto streamId : deleteList) {
747 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800748 if (!remoteRet.isOk()) {
749 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000750 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800751 return ACAMERA_ERROR_UNKNOWN;
752 }
753 mConfiguredOutputs.erase(streamId);
754 }
755
756 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800757 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800758 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700759 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800760 if (!remoteRet.isOk()) {
761 ALOGE("Camera device %s failed to create stream: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000762 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800763 return ACAMERA_ERROR_UNKNOWN;
764 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700765 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800766 }
767
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100768 CameraMetadata params;
769 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
770 params.append(sessionParameters->settings->getInternalData());
771 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800772 std::vector<int> offlineStreamIds;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700773 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
774 ns2ms(startTimeNs), &offlineStreamIds);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800775 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
776 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000777 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800778 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800779 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000780 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800781 return ACAMERA_ERROR_UNKNOWN;
782 }
783
784 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800785}
786
787void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800788CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800789 Mutex::Autolock _l(mDeviceLock);
790 mRemote = remote;
791}
792
Jayant Chowdharydcae7962024-08-20 21:20:10 +0000793bool CameraDevice::setDeviceMetadataQueues() {
794 if (mRemote == nullptr) {
795 ALOGE("mRemote must not be null while trying to fetch metadata queues");
796 return false;
797 }
798 MQDescriptor<int8_t, SynchronizedReadWrite> resMqDescriptor;
799 binder::Status ret = mRemote->getCaptureResultMetadataQueue(&resMqDescriptor);
800 if (!ret.isOk()) {
801 ALOGE("Transaction error trying to get capture result metadata queue");
802 return false;
803 }
804 mCaptureResultMetadataQueue = std::make_unique<ResultMetadataQueue>(resMqDescriptor);
805 if (!mCaptureResultMetadataQueue->isValid()) {
806 ALOGE("Empty fmq from cameraserver");
807 mCaptureResultMetadataQueue = nullptr;
808 return false;
809 }
810
811 return true;
812}
813
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800814camera_status_t
815CameraDevice::checkCameraClosedOrErrorLocked() const {
816 if (mRemote == nullptr) {
817 ALOGE("%s: camera device already closed", __FUNCTION__);
818 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
819 }
820 if (mInError) {// triggered by onDeviceError
821 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
822 return mError;
823 }
824 return ACAMERA_OK;
825}
826
827void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800828CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
829 mInError = true;
830 mError = error;
831 return;
832}
833
834void
835CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
836 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
837 if (isError) {
838 mFutureErrorSet.insert(frameNumber);
839 } else if (frameNumber <= mCompletedFrameNumber) {
840 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
841 frameNumber, mCompletedFrameNumber);
842 return;
843 } else {
844 if (frameNumber != mCompletedFrameNumber + 1) {
845 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
846 mCompletedFrameNumber + 1, frameNumber);
847 // Do not assert as in java implementation
848 }
849 mCompletedFrameNumber = frameNumber;
850 }
851 update();
852}
853
854void
855CameraDevice::FrameNumberTracker::update() {
856 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
857 int64_t errorFrameNumber = *it;
858 if (errorFrameNumber == mCompletedFrameNumber + 1) {
859 mCompletedFrameNumber++;
860 it = mFutureErrorSet.erase(it);
861 } else if (errorFrameNumber <= mCompletedFrameNumber) {
862 // This should not happen, but deal with it anyway
863 ALOGE("Completd frame number passed through current frame number!");
864 // erase the old error since it's no longer useful
865 it = mFutureErrorSet.erase(it);
866 } else {
867 // Normal requests hasn't catched up error frames, just break
868 break;
869 }
870 }
871 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
872}
873
874void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800875CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800876 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800877 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800878 int sequenceId = resultExtras.requestId;
879 int64_t frameNumber = resultExtras.frameNumber;
880 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700881 auto it = mSequenceCallbackMap.find(sequenceId);
882 if (it == mSequenceCallbackMap.end()) {
883 ALOGE("%s: Error: capture sequence index %d not found!",
884 __FUNCTION__, sequenceId);
885 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800886 return;
887 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700888
889 CallbackHolder cbh = (*it).second;
890 sp<ACameraCaptureSession> session = cbh.mSession;
891 if ((size_t) burstId >= cbh.mRequests.size()) {
892 ALOGE("%s: Error: request index %d out of bound (size %zu)",
893 __FUNCTION__, burstId, cbh.mRequests.size());
894 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
895 return;
896 }
897 sp<CaptureRequest> request = cbh.mRequests[burstId];
898
899 // Handle buffer error
900 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
901 int32_t streamId = resultExtras.errorStreamId;
902 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800903 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700904 auto outputPairIt = mConfiguredOutputs.find(streamId);
905 if (outputPairIt == mConfiguredOutputs.end()) {
906 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800907 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
908 return;
909 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700910
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800911 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
912 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800913 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800914 if (surface->getIGraphicBufferProducer() == outGbp) {
915 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
916 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
917 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700918
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800919 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800920 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800921 msg->setObject(kSessionSpKey, session);
922 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
923 msg->setObject(kCaptureRequestKey, request);
924 msg->setPointer(kAnwKey, (void*) anw);
925 msg->setInt64(kFrameNumberKey, frameNumber);
926 postSessionMsgAndCleanup(msg);
927 }
928 }
929 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700930 } else { // Handle other capture failures
931 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800932 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800933 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
934 failure->frameNumber = frameNumber;
935 // TODO: refine this when implementing flush
936 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
937 failure->sequenceId = sequenceId;
938 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800939 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800940
Emilian Peevedec62d2019-03-19 17:59:24 -0700941 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
942 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800943 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800944 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700945 if (cbh.mIsLogicalCameraCallback) {
946 if (resultExtras.errorPhysicalCameraId.size() > 0) {
Austin Borger71d8f672023-06-01 16:51:35 -0700947 String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000948 msg->setString(kFailingPhysicalCameraId, cameraId.c_str(), cameraId.size());
Emilian Peevedec62d2019-03-19 17:59:24 -0700949 }
950 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
951 } else {
952 msg->setPointer(kCallbackFpKey, (void*) onError);
953 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800954 msg->setObject(kCaptureRequestKey, request);
955 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700956 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800957
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700958 // Update tracker
959 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
960 checkAndFireSequenceCompleteLocked();
961 }
962 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800963}
964
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700965void CameraDevice::stopLooperAndDisconnect() {
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700966 Mutex::Autolock _l(mDeviceLock);
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700967 sp<ACameraCaptureSession> session = mCurrentSession.promote();
968 if (!isClosed()) {
969 disconnectLocked(session);
970 }
971 mCurrentSession = nullptr;
972
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700973 if (mCbLooper != nullptr) {
974 mCbLooper->unregisterHandler(mHandler->id());
975 mCbLooper->stop();
976 }
977 mCbLooper.clear();
978 mHandler.clear();
979}
980
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800981CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
982}
983
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800984void CameraDevice::CallbackHandler::onMessageReceived(
985 const sp<AMessage> &msg) {
986 switch (msg->what()) {
987 case kWhatOnDisconnected:
988 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800989 case kWhatSessionStateCb:
990 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +0000991 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800992 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800993 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800994 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700995 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800996 case kWhatCaptureSeqEnd:
997 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700998 case kWhatCaptureBufferLost:
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000999 case kWhatPreparedCb:
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001000 case kWhatClientSharedAccessPriorityChanged:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001001 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001002 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001003 case kWhatCleanUpSessions:
1004 mCachedSessions.clear();
1005 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001006 default:
1007 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
1008 return;
1009 }
1010 // Check the common part of all message
1011 void* context;
1012 bool found = msg->findPointer(kContextKey, &context);
1013 if (!found) {
1014 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
1015 return;
1016 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001017 switch (msg->what()) {
1018 case kWhatOnDisconnected:
1019 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001020 ACameraDevice* dev;
1021 found = msg->findPointer(kDeviceKey, (void**) &dev);
1022 if (!found || dev == nullptr) {
1023 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1024 return;
1025 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001026 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001027 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001028 if (!found) {
1029 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
1030 return;
1031 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001032 if (onDisconnected == nullptr) {
1033 return;
1034 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001035 (*onDisconnected)(context, dev);
1036 break;
1037 }
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001038
1039 case kWhatClientSharedAccessPriorityChanged:
1040 {
1041 if (!flags::camera_multi_client()) {
1042 break;
1043 }
1044 ACameraDevice* dev;
1045 found = msg->findPointer(kDeviceKey, (void**) &dev);
1046 if (!found || dev == nullptr) {
1047 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1048 return;
1049 }
1050 ACameraDevice_ClientSharedAccessPriorityChangedCallback
1051 onClientSharedAccessPriorityChanged;
1052 found = msg->findPointer(kCallbackFpKey, (void**) &onClientSharedAccessPriorityChanged);
1053 if (!found) {
1054 ALOGE("%s: Cannot find onClientSharedAccessPriorityChanged!", __FUNCTION__);
1055 return;
1056 }
1057 if (onClientSharedAccessPriorityChanged == nullptr) {
1058 return;
1059 }
1060 (*onClientSharedAccessPriorityChanged)(context, dev, dev->isPrimaryClient());
1061 break;
1062 }
1063
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001064 case kWhatOnError:
1065 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001066 ACameraDevice* dev;
1067 found = msg->findPointer(kDeviceKey, (void**) &dev);
1068 if (!found || dev == nullptr) {
1069 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1070 return;
1071 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001072 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001073 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001074 if (!found) {
1075 ALOGE("%s: Cannot find onError!", __FUNCTION__);
1076 return;
1077 }
1078 int errorCode;
1079 found = msg->findInt32(kErrorCodeKey, &errorCode);
1080 if (!found) {
1081 ALOGE("%s: Cannot find error code!", __FUNCTION__);
1082 return;
1083 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001084 if (onError == nullptr) {
1085 return;
1086 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001087 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001088 break;
1089 }
1090 case kWhatSessionStateCb:
1091 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001092 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001093 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001094 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001095 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001096 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001097 case kWhatCaptureSeqEnd:
1098 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001099 case kWhatCaptureBufferLost:
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001100 case kWhatPreparedCb:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001101 {
1102 sp<RefBase> obj;
1103 found = msg->findObject(kSessionSpKey, &obj);
1104 if (!found || obj == nullptr) {
1105 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
1106 return;
1107 }
1108 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001109 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001110 sp<CaptureRequest> requestSp = nullptr;
1111 switch (msg->what()) {
1112 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001113 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001114 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001115 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001116 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001117 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001118 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001119 found = msg->findObject(kCaptureRequestKey, &obj);
1120 if (!found) {
1121 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1122 return;
1123 }
1124 requestSp = static_cast<CaptureRequest*>(obj.get());
1125 break;
1126 }
1127
1128 switch (msg->what()) {
1129 case kWhatSessionStateCb:
1130 {
1131 ACameraCaptureSession_stateCallback onState;
1132 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1133 if (!found) {
1134 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1135 return;
1136 }
1137 if (onState == nullptr) {
1138 return;
1139 }
1140 (*onState)(context, session.get());
1141 break;
1142 }
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001143 case kWhatPreparedCb:
1144 {
1145 ACameraCaptureSession_prepareCallback onWindowPrepared;
1146 found = msg->findPointer(kCallbackFpKey, (void**) &onWindowPrepared);
1147 if (!found) {
Jayant Chowdhary0f2cb992023-02-17 18:25:53 +00001148 ALOGE("%s: Cannot find window prepared callback!", __FUNCTION__);
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001149 return;
1150 }
1151 if (onWindowPrepared == nullptr) {
1152 return;
1153 }
Avichal Rakesh8effe982023-11-13 18:53:40 -08001154 ANativeWindow* anw;
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001155 found = msg->findPointer(kAnwKey, (void**) &anw);
1156 if (!found) {
1157 ALOGE("%s: Cannot find ANativeWindow: %d!", __FUNCTION__, __LINE__);
1158 return;
1159 }
1160 (*onWindowPrepared)(context, anw, session.get());
1161 break;
1162 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001163 case kWhatCaptureStart:
1164 {
1165 ACameraCaptureSession_captureCallback_start onStart;
1166 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1167 if (!found) {
1168 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1169 return;
1170 }
1171 if (onStart == nullptr) {
1172 return;
1173 }
1174 int64_t timestamp;
1175 found = msg->findInt64(kTimeStampKey, &timestamp);
1176 if (!found) {
1177 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1178 return;
1179 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001180 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001181 (*onStart)(context, session.get(), request, timestamp);
1182 freeACaptureRequest(request);
1183 break;
1184 }
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001185 case kWhatCaptureStart2:
1186 {
1187 ACameraCaptureSession_captureCallback_startV2 onStart2;
1188 found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
1189 if (!found) {
1190 ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
1191 return;
1192 }
1193 if (onStart2 == nullptr) {
1194 return;
1195 }
1196 int64_t timestamp;
1197 found = msg->findInt64(kTimeStampKey, &timestamp);
1198 if (!found) {
1199 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1200 return;
1201 }
1202 int64_t frameNumber;
1203 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1204 if (!found) {
1205 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1206 return;
1207 }
1208
1209 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1210 (*onStart2)(context, session.get(), request, timestamp, frameNumber);
1211 freeACaptureRequest(request);
1212 break;
1213 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001214 case kWhatCaptureResult:
1215 {
1216 ACameraCaptureSession_captureCallback_result onResult;
1217 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1218 if (!found) {
1219 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1220 return;
1221 }
1222 if (onResult == nullptr) {
1223 return;
1224 }
1225
1226 found = msg->findObject(kCaptureResultKey, &obj);
1227 if (!found) {
1228 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1229 return;
1230 }
1231 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001232 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001233 (*onResult)(context, session.get(), request, result.get());
1234 freeACaptureRequest(request);
1235 break;
1236 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001237 case kWhatLogicalCaptureResult:
1238 {
1239 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1240 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1241 if (!found) {
1242 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1243 __FUNCTION__);
1244 return;
1245 }
1246 if (onResult == nullptr) {
1247 return;
1248 }
1249
1250 found = msg->findObject(kCaptureResultKey, &obj);
1251 if (!found) {
1252 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1253 return;
1254 }
1255 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1256
1257 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1258 if (!found) {
1259 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1260 return;
1261 }
1262 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1263 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1264 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1265 physicalResult->mPhysicalResultInfo;
1266
1267 std::vector<std::string> physicalCameraIds;
1268 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1269 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
Austin Borger71d8f672023-06-01 16:51:35 -07001270 String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001271 physicalCameraIds.push_back(physicalId8.c_str());
1272
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001273 CameraMetadata clone =
1274 physicalResultInfo[i].
1275 mCameraMetadataInfo.get<CameraMetadataInfo::metadata>();
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001276 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1277 &physicalResult->mFrameNumber, /*data_count*/1);
1278 sp<ACameraMetadata> metadata =
1279 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1280 physicalMetadataCopy.push_back(metadata);
1281 }
1282
1283 std::vector<const char*> physicalCameraIdPtrs;
1284 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1285 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1286 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1287 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1288 }
1289
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001290 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001291 (*onResult)(context, session.get(), request, result.get(),
1292 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1293 physicalMetadataCopyPtrs.data());
1294 freeACaptureRequest(request);
1295 break;
1296 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001297 case kWhatCaptureFail:
1298 {
1299 ACameraCaptureSession_captureCallback_failed onFail;
1300 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1301 if (!found) {
1302 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1303 return;
1304 }
1305 if (onFail == nullptr) {
1306 return;
1307 }
1308
1309 found = msg->findObject(kCaptureFailureKey, &obj);
1310 if (!found) {
1311 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1312 return;
1313 }
1314 sp<CameraCaptureFailure> failureSp(
1315 static_cast<CameraCaptureFailure*>(obj.get()));
1316 ACameraCaptureFailure* failure =
1317 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001318 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001319 (*onFail)(context, session.get(), request, failure);
1320 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001321 break;
1322 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001323 case kWhatLogicalCaptureFail:
1324 {
1325 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1326 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1327 if (!found) {
1328 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1329 return;
1330 }
1331 if (onFail == nullptr) {
1332 return;
1333 }
1334
1335 found = msg->findObject(kCaptureFailureKey, &obj);
1336 if (!found) {
1337 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1338 return;
1339 }
1340 sp<CameraCaptureFailure> failureSp(
1341 static_cast<CameraCaptureFailure*>(obj.get()));
1342 ALogicalCameraCaptureFailure failure;
1343 AString physicalCameraId;
1344 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1345 if (found && !physicalCameraId.empty()) {
1346 failure.physicalCameraId = physicalCameraId.c_str();
1347 } else {
1348 failure.physicalCameraId = nullptr;
1349 }
1350 failure.captureFailure = *failureSp;
1351 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1352 (*onFail)(context, session.get(), request, &failure);
1353 freeACaptureRequest(request);
1354 break;
1355 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001356 case kWhatCaptureSeqEnd:
1357 {
1358 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1359 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1360 if (!found) {
1361 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1362 return;
1363 }
1364 if (onSeqEnd == nullptr) {
1365 return;
1366 }
1367 int seqId;
1368 found = msg->findInt32(kSequenceIdKey, &seqId);
1369 if (!found) {
1370 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1371 return;
1372 }
1373 int64_t frameNumber;
1374 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1375 if (!found) {
1376 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1377 return;
1378 }
1379 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1380 break;
1381 }
1382 case kWhatCaptureSeqAbort:
1383 {
1384 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1385 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1386 if (!found) {
1387 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1388 return;
1389 }
1390 if (onSeqAbort == nullptr) {
1391 return;
1392 }
1393 int seqId;
1394 found = msg->findInt32(kSequenceIdKey, &seqId);
1395 if (!found) {
1396 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1397 return;
1398 }
1399 (*onSeqAbort)(context, session.get(), seqId);
1400 break;
1401 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001402 case kWhatCaptureBufferLost:
1403 {
1404 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1405 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1406 if (!found) {
1407 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1408 return;
1409 }
1410 if (onBufferLost == nullptr) {
1411 return;
1412 }
1413
1414 ANativeWindow* anw;
1415 found = msg->findPointer(kAnwKey, (void**) &anw);
1416 if (!found) {
1417 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1418 return;
1419 }
1420
1421 int64_t frameNumber;
1422 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1423 if (!found) {
1424 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1425 return;
1426 }
1427
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001428 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001429 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1430 freeACaptureRequest(request);
1431 break;
1432 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001433 }
1434 break;
1435 }
1436 }
1437}
1438
1439CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001440 sp<ACameraCaptureSession> session,
1441 const Vector<sp<CaptureRequest> >& requests,
1442 bool isRepeating,
1443 ACameraCaptureSession_captureCallbacks* cbs) :
1444 mSession(session), mRequests(requests),
1445 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001446 mIsLogicalCameraCallback(false),
1447 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001448 initCaptureCallbacks(cbs);
1449
1450 if (cbs != nullptr) {
1451 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001452 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001453 }
1454}
1455
1456CameraDevice::CallbackHolder::CallbackHolder(
1457 sp<ACameraCaptureSession> session,
1458 const Vector<sp<CaptureRequest> >& requests,
1459 bool isRepeating,
1460 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1461 mSession(session), mRequests(requests),
1462 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001463 mIsLogicalCameraCallback(true),
1464 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001465 initCaptureCallbacks(lcbs);
1466
1467 if (lcbs != nullptr) {
1468 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001469 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001470 }
1471}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001472
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001473CameraDevice::CallbackHolder::CallbackHolder(
1474 sp<ACameraCaptureSession> session,
1475 const Vector<sp<CaptureRequest> >& requests,
1476 bool isRepeating,
1477 ACameraCaptureSession_captureCallbacksV2* cbs) :
1478 mSession(session), mRequests(requests),
1479 mIsRepeating(isRepeating),
1480 mIsLogicalCameraCallback(false),
1481 mIs2Callback(true) {
1482 initCaptureCallbacksV2(cbs);
1483
1484 if (cbs != nullptr) {
1485 mOnCaptureCompleted = cbs->onCaptureCompleted;
1486 mOnCaptureFailed = cbs->onCaptureFailed;
1487 }
1488}
1489
1490CameraDevice::CallbackHolder::CallbackHolder(
1491 sp<ACameraCaptureSession> session,
1492 const Vector<sp<CaptureRequest> >& requests,
1493 bool isRepeating,
1494 ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
1495 mSession(session), mRequests(requests),
1496 mIsRepeating(isRepeating),
1497 mIsLogicalCameraCallback(true),
1498 mIs2Callback(true) {
1499 initCaptureCallbacksV2(lcbs);
1500
1501 if (lcbs != nullptr) {
1502 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1503 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
1504 }
1505}
1506
Yin-Chia Yehead91462016-01-06 16:45:08 -08001507void
1508CameraDevice::checkRepeatingSequenceCompleteLocked(
1509 const int sequenceId, const int64_t lastFrameNumber) {
1510 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1511 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1512 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1513 ALOGW("No callback found for sequenceId %d", sequenceId);
1514 return;
1515 }
1516 // remove callback holder from callback map
1517 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1518 CallbackHolder cbh = cbIt->second;
1519 mSequenceCallbackMap.erase(cbIt);
1520 // send seq aborted callback
1521 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001522 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001523 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001524 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001525 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001526 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001527 } else {
1528 // Use mSequenceLastFrameNumberMap to track
1529 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1530
1531 // Last frame might have arrived. Check now
1532 checkAndFireSequenceCompleteLocked();
1533 }
1534}
1535
1536void
1537CameraDevice::checkAndFireSequenceCompleteLocked() {
1538 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001539 auto it = mSequenceLastFrameNumberMap.begin();
1540 while (it != mSequenceLastFrameNumberMap.end()) {
1541 int sequenceId = it->first;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001542 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001543
1544 if (mRemote == nullptr) {
1545 ALOGW("Camera %s closed while checking sequence complete", getId());
1546 return;
1547 }
1548 ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1549 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1550 if (!it->second.isSequenceCompleted) {
1551 // Check if there is callback for this sequence
1552 // This should not happen because we always register callback (with nullptr inside)
1553 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1554 ALOGW("No callback found for sequenceId %d", sequenceId);
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001555 }
1556
1557 if (lastFrameNumber <= completedFrameNumber) {
1558 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1559 it->second.isSequenceCompleted = true;
1560 }
1561
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001562 }
1563
1564 if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001565 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
1566
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001567 it = mSequenceLastFrameNumberMap.erase(it);
1568 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1569 } else {
1570 ++it;
1571 }
1572 }
1573}
1574
1575void
1576CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1577 auto it = mSequenceLastFrameNumberMap.begin();
1578 while (it != mSequenceLastFrameNumberMap.end()) {
1579 int sequenceId = it->first;
1580 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wang730a7912020-05-07 11:59:02 -07001581
1582 if (mRemote == nullptr) {
1583 ALOGW("Camera %s closed while checking sequence complete", getId());
1584 return;
1585 }
Shuzhen Wang730a7912020-05-07 11:59:02 -07001586
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001587 ALOGV("%s: seq %d's last frame number %" PRId64
1588 ", completed inflight frame number %" PRId64,
1589 __FUNCTION__, sequenceId, lastFrameNumber,
1590 lastCompletedRegularFrameNumber);
1591 if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1592 if (it->second.isSequenceCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001593 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
Shuzhen Wang730a7912020-05-07 11:59:02 -07001594
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001595 it = mSequenceLastFrameNumberMap.erase(it);
1596 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1597 } else {
1598 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1599 it->second.isInflightCompleted = true;
1600 ++it;
1601 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001602 } else {
1603 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001604 }
1605 }
1606}
1607
1608/**
1609 * Camera service callback implementation
1610 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001611binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001612CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001613 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001614 const CaptureResultExtras& resultExtras) {
1615 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1616 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001617 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001618 sp<CameraDevice> dev = mDevice.promote();
1619 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001620 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001621 }
1622
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001623 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001624 Mutex::Autolock _l(dev->mDeviceLock);
1625 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001626 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001627 }
1628 switch (errorCode) {
1629 case ERROR_CAMERA_DISCONNECTED:
1630 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001631 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001632 if (session != nullptr) {
1633 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001634 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001635 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001636 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1637 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1638 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001639 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001640 msg->post();
1641 break;
1642 }
1643 default:
1644 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001645 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001646 case ERROR_CAMERA_DEVICE:
1647 case ERROR_CAMERA_SERVICE:
1648 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001649 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1650 // We keep this switch since this block might be encountered with
1651 // more than just 2 states. The default fallthrough could have us
1652 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001653 switch (errorCode) {
1654 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001655 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001656 break;
1657 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001658 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001659 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001660 break;
1661 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001662 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001663 break;
1664 }
1665 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1666 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1667 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001668 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001669 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001670 msg->post();
1671 break;
1672 }
1673 case ERROR_CAMERA_REQUEST:
1674 case ERROR_CAMERA_RESULT:
1675 case ERROR_CAMERA_BUFFER:
1676 dev->onCaptureErrorLocked(errorCode, resultExtras);
1677 break;
1678 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001679 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001680}
1681
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001682binder::Status
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001683CameraDevice::ServiceCallback::onClientSharedAccessPriorityChanged(bool primaryClient) {
1684 ALOGV("onClientSharedAccessPriorityChanged received. primaryClient = %d", primaryClient);
1685 binder::Status ret = binder::Status::ok();
1686 if (!flags::camera_multi_client()) {
1687 return ret;
1688 }
1689 sp<CameraDevice> dev = mDevice.promote();
1690 if (dev == nullptr) {
1691 return ret; // device has been closed
1692 }
1693 Mutex::Autolock _l(dev->mDeviceLock);
1694 if (dev->isClosed() || dev->mRemote == nullptr) {
1695 return ret;
1696 }
1697 dev->setPrimaryClient(primaryClient);
1698 sp<AMessage> msg = new AMessage(kWhatClientSharedAccessPriorityChanged, dev->mHandler);
1699 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1700 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
1701 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onClientSharedAccessPriorityChanged);
1702 msg->post();
1703
1704 return binder::Status::ok();
1705}
1706
1707binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001708CameraDevice::ServiceCallback::onDeviceIdle() {
1709 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001710 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001711 sp<CameraDevice> dev = mDevice.promote();
1712 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001713 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001714 }
1715
1716 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001717 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001718 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001719 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001720
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001721 dev->removeCompletedCallbackHolderLocked(
1722 std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1723
Yin-Chia Yehead91462016-01-06 16:45:08 -08001724 if (dev->mIdle) {
1725 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001726 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001727 }
1728
1729 if (dev->mCurrentSession != nullptr) {
1730 ALOGE("onDeviceIdle sending state cb");
1731 if (dev->mBusySession != dev->mCurrentSession) {
1732 ALOGE("Current session != busy session");
1733 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001734 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001735 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001736
Yin-Chia Yehead91462016-01-06 16:45:08 -08001737 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1738 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1739 msg->setObject(kSessionSpKey, dev->mBusySession);
1740 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1741 // Make sure we clear the sp first so the session destructor can
1742 // only happen on handler thread (where we don't hold device/session lock)
1743 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001744 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001745 }
1746 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001747 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001748 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001749}
1750
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001751binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001752CameraDevice::ServiceCallback::onCaptureStarted(
1753 const CaptureResultExtras& resultExtras,
1754 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001755 binder::Status ret = binder::Status::ok();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001756 sp<CameraDevice> dev = mDevice.promote();
1757 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001758 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001759 }
1760 Mutex::Autolock _l(dev->mDeviceLock);
1761 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001762 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001763 }
1764
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001765 dev->removeCompletedCallbackHolderLocked(
1766 resultExtras.lastCompletedRegularFrameNumber);
1767
Yin-Chia Yehead91462016-01-06 16:45:08 -08001768 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001769 int32_t burstId = resultExtras.burstId;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001770 int64_t frameNumber = resultExtras.frameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001771
1772 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1773 if (it != dev->mSequenceCallbackMap.end()) {
1774 CallbackHolder cbh = (*it).second;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001775 bool v2Callback = cbh.mIs2Callback;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001776 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001777 ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001778 sp<ACameraCaptureSession> session = cbh.mSession;
1779 if ((size_t) burstId >= cbh.mRequests.size()) {
1780 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1781 __FUNCTION__, burstId, cbh.mRequests.size());
1782 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1783 }
1784 sp<CaptureRequest> request = cbh.mRequests[burstId];
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001785 sp<AMessage> msg = nullptr;
1786 if (v2Callback) {
1787 msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
1788 msg->setPointer(kCallbackFpKey, (void*) onStart2);
1789 } else {
1790 msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1791 msg->setPointer(kCallbackFpKey, (void *)onStart);
1792 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001793 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001794 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001795 msg->setObject(kCaptureRequestKey, request);
1796 msg->setInt64(kTimeStampKey, timestamp);
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001797 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001798 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001799 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001800 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001801}
1802
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001803binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001804CameraDevice::ServiceCallback::onResultReceived(
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001805 const CameraMetadataInfo &resultMetadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001806 const CaptureResultExtras& resultExtras,
1807 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001808 binder::Status ret = binder::Status::ok();
1809
Yin-Chia Yehead91462016-01-06 16:45:08 -08001810 sp<CameraDevice> dev = mDevice.promote();
1811 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001812 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001813 }
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001814
Yin-Chia Yehead91462016-01-06 16:45:08 -08001815 int sequenceId = resultExtras.requestId;
1816 int64_t frameNumber = resultExtras.frameNumber;
1817 int32_t burstId = resultExtras.burstId;
1818 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001819 if (!isPartialResult) {
1820 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1821 }
1822
1823 Mutex::Autolock _l(dev->mDeviceLock);
1824 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001825 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001826 }
1827
1828 if (dev->isClosed()) {
1829 if (!isPartialResult) {
1830 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1831 }
1832 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001833 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001834 }
1835
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001836 CameraMetadata metadataCopy;
1837 camera_status_t status = readOneResultMetadata(resultMetadata,
1838 dev->mCaptureResultMetadataQueue.get(), &metadataCopy);
1839 if (status != ACAMERA_OK) {
1840 ALOGE("%s: result metadata couldn't be converted", __FUNCTION__);
1841 return ret;
1842 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001843 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001844 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001845
1846 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1847 if (it != dev->mSequenceCallbackMap.end()) {
1848 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001849 sp<ACameraCaptureSession> session = cbh.mSession;
1850 if ((size_t) burstId >= cbh.mRequests.size()) {
1851 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1852 __FUNCTION__, burstId, cbh.mRequests.size());
1853 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1854 }
1855 sp<CaptureRequest> request = cbh.mRequests[burstId];
1856 sp<ACameraMetadata> result(new ACameraMetadata(
1857 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001858
1859 std::vector<PhysicalCaptureResultInfo> localPhysicalResult;
1860 localPhysicalResult.resize(physicalResultInfos.size());
1861 for (size_t i = 0; i < physicalResultInfos.size(); i++) {
1862 CameraMetadata physicalMetadata;
1863 localPhysicalResult[i].mPhysicalCameraId = physicalResultInfos[i].mPhysicalCameraId;
1864 status = readOneResultMetadata(physicalResultInfos[i].mCameraMetadataInfo,
1865 dev->mCaptureResultMetadataQueue.get(),
1866 &physicalMetadata);
1867 if (status != ACAMERA_OK) {
1868 ALOGE("%s: physical camera result metadata couldn't be converted", __FUNCTION__);
1869 return ret;
1870 }
1871 localPhysicalResult[i].mCameraMetadataInfo.set<CameraMetadataInfo::metadata>(
1872 std::move(physicalMetadata));
1873 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001874 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001875 new ACameraPhysicalCaptureResultInfo(localPhysicalResult, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001876
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001877 sp<AMessage> msg = new AMessage(
1878 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1879 dev->mHandler);
1880 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001881 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001882 msg->setObject(kCaptureRequestKey, request);
1883 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001884 if (isPartialResult) {
1885 msg->setPointer(kCallbackFpKey,
1886 (void *)cbh.mOnCaptureProgressed);
1887 } else if (cbh.mIsLogicalCameraCallback) {
1888 msg->setPointer(kCallbackFpKey,
1889 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1890 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1891 } else {
1892 msg->setPointer(kCallbackFpKey,
1893 (void *)cbh.mOnCaptureCompleted);
1894 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001895 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001896 }
1897
1898 if (!isPartialResult) {
1899 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1900 dev->checkAndFireSequenceCompleteLocked();
1901 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001902
1903 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001904}
1905
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001906binder::Status
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001907CameraDevice::ServiceCallback::onPrepared(int streamId) {
1908 ALOGV("%s: callback for stream id %d", __FUNCTION__, streamId);
1909 binder::Status ret = binder::Status::ok();
1910 sp<CameraDevice> dev = mDevice.promote();
1911 if (dev == nullptr) {
1912 return ret; // device has been closed
1913 }
1914 Mutex::Autolock _l(dev->mDeviceLock);
1915 if (dev->isClosed() || dev->mRemote == nullptr) {
1916 return ret;
1917 }
1918 auto it = dev->mConfiguredOutputs.find(streamId);
1919 if (it == dev->mConfiguredOutputs.end()) {
1920 ALOGE("%s: stream id %d does not exist", __FUNCTION__ , streamId);
1921 return ret;
1922 }
1923 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
1924 if (session == nullptr) {
1925 ALOGE("%s: Session is dead already", __FUNCTION__ );
1926 return ret;
1927 }
1928 // We've found the window corresponding to the surface id.
Avichal Rakesh8effe982023-11-13 18:53:40 -08001929 ANativeWindow *window = it->second.first;
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001930 sp<AMessage> msg = new AMessage(kWhatPreparedCb, dev->mHandler);
1931 msg->setPointer(kContextKey, session->mPreparedCb.context);
1932 msg->setPointer(kAnwKey, window);
1933 msg->setObject(kSessionSpKey, session);
1934 msg->setPointer(kCallbackFpKey, (void *)session->mPreparedCb.onWindowPrepared);
1935 dev->postSessionMsgAndCleanup(msg);
1936
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001937 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001938}
1939
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001940binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001941CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1942 // onRequestQueueEmpty not yet implemented in NDK
1943 return binder::Status::ok();
1944}
1945
1946binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001947CameraDevice::ServiceCallback::onRepeatingRequestError(
1948 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001949 binder::Status ret = binder::Status::ok();
1950
1951 sp<CameraDevice> dev = mDevice.promote();
1952 if (dev == nullptr) {
1953 return ret; // device has been closed
1954 }
1955
1956 Mutex::Autolock _l(dev->mDeviceLock);
1957
1958 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001959 if (stoppedSequenceId == repeatingSequenceId) {
1960 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1961 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001962
1963 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1964
1965 return ret;
1966}
1967
Shuzhen Wangacae2642020-12-21 17:11:37 -08001968void
1969CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
1970 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1971 if (cbIt != mSequenceCallbackMap.end()) {
1972 CallbackHolder cbh = cbIt->second;
1973 mSequenceCallbackMap.erase(cbIt);
1974
1975 // send seq complete callback
1976 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1977 msg->setPointer(kContextKey, cbh.mContext);
1978 msg->setObject(kSessionSpKey, cbh.mSession);
1979 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1980 msg->setInt32(kSequenceIdKey, sequenceId);
1981 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1982
1983 // Clear the session sp before we send out the message
1984 // This will guarantee the rare case where the message is processed
1985 // before cbh goes out of scope and causing we call the session
1986 // destructor while holding device lock
1987 cbh.mSession.clear();
1988 postSessionMsgAndCleanup(msg);
1989 } else {
1990 // Check if there is callback for this sequence
1991 // This should not happen because we always register callback (with nullptr inside)
1992 ALOGW("No callback found for sequenceId %d", sequenceId);
1993 }
1994}
1995
Jayant Chowdharydcae7962024-08-20 21:20:10 +00001996camera_status_t CameraDevice::ServiceCallback::readOneResultMetadata(
1997 const CameraMetadataInfo& resultInfo, ResultMetadataQueue* metadataQueue,
1998 CameraMetadata* metadata) {
1999 if (metadataQueue == nullptr || metadata == nullptr) {
2000 return ACAMERA_ERROR_INVALID_PARAMETER;
2001 }
2002 if (resultInfo.getTag() == CameraMetadataInfo::fmqSize) {
2003 int64_t metadataSize = resultInfo.get<CameraMetadataInfo::fmqSize>();
2004 auto metadataVec = std::make_unique<int8_t []>(metadataSize);
2005 bool read = metadataQueue->read(reinterpret_cast<int8_t*>(metadataVec.get()), metadataSize);
2006 if (!read) {
2007 ALOGE("%s capture request settings could't be read from fmq", __FUNCTION__);
2008 return ACAMERA_ERROR_UNKNOWN;
2009 }
2010 *metadata = CameraMetadata(reinterpret_cast<camera_metadata_t *>(metadataVec.release()));
2011 } else {
2012 *metadata =
2013 resultInfo.get<CameraMetadataInfo::metadata>();
2014 }
2015
2016 return ACAMERA_OK;
2017}
2018
Jayant Chowdhary6df26072018-11-06 23:55:12 -08002019} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08002020} // namespace android