blob: 9db13ad837670f2af99a938fa715bb70a4605154 [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACameraDevice"
19
Yin-Chia Yehead91462016-01-06 16:45:08 -080020#include <vector>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080021#include <inttypes.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080022#include <android/hardware/ICameraService.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080023#include <gui/Surface.h>
Austin Borger71d8f672023-06-01 16:51:35 -070024#include <camera/StringUtils.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080025#include "ACameraDevice.h"
26#include "ACameraMetadata.h"
27#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080028#include "ACameraCaptureSession.h"
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070029#include <com_android_internal_camera_flags.h>
30
31namespace flags = com::android::internal::camera::flags;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080032
Jayant Chowdharya8488c92019-06-21 12:45:34 -070033ACameraDevice::~ACameraDevice() {
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -070034 mDevice->stopLooperAndDisconnect();
Jayant Chowdharya8488c92019-06-21 12:45:34 -070035}
36
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080037namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080038namespace acam {
39
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080040// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080041const char* CameraDevice::kContextKey = "Context";
42const char* CameraDevice::kDeviceKey = "Device";
43const char* CameraDevice::kErrorCodeKey = "ErrorCode";
44const char* CameraDevice::kCallbackFpKey = "Callback";
45const char* CameraDevice::kSessionSpKey = "SessionSp";
46const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
47const char* CameraDevice::kTimeStampKey = "TimeStamp";
48const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080049const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080050const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
51const char* CameraDevice::kSequenceIdKey = "SequenceId";
52const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070053const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070054const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080055
56/**
57 * CameraDevice Implementation
58 */
59CameraDevice::CameraDevice(
60 const char* id,
61 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070062 sp<ACameraMetadata> chars,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070063 ACameraDevice* wrapper, bool sharedMode) :
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 mCameraId(id),
65 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070066 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080067 mServiceCallback(new ServiceCallback(this)),
68 mWrapper(wrapper),
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070069 mSharedMode(sharedMode),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080070 mInError(false),
71 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070072 mIdle(true),
73 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080074 mClosing = false;
75 // Setup looper thread to perfrom device callbacks to app
76 mCbLooper = new ALooper;
77 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080078 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 /*runOnCallingThread*/false,
80 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080081 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080082 if (err != OK) {
83 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
84 __FUNCTION__, strerror(-err), err);
85 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
86 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080087 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080088 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080089
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080090 const CameraMetadata& metadata = mChars->getInternalData();
91 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080092 if (entry.count != 1) {
93 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
94 mPartialResultCount = 1;
95 } else {
96 mPartialResultCount = entry.data.i32[0];
97 }
98
99 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
100 if (entry.count != 2) {
101 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
102 mShadingMapSize[0] = 0;
103 mShadingMapSize[1] = 0;
104 } else {
105 mShadingMapSize[0] = entry.data.i32[0];
106 mShadingMapSize[1] = entry.data.i32[1];
107 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800108
109 size_t physicalIdCnt = 0;
110 const char*const* physicalCameraIds;
111 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
112 for (size_t i = 0; i < physicalIdCnt; i++) {
113 mPhysicalIds.push_back(physicalCameraIds[i]);
114 }
115 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116}
117
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700118CameraDevice::~CameraDevice() { }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800119
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700120void
121CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
122 msg->post();
123 msg.clear();
124 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
125 cleanupMsg->post();
126}
127
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800128// TODO: cached created request?
129camera_status_t
130CameraDevice::createCaptureRequest(
131 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800132 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800133 ACaptureRequest** request) const {
134 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800135
136 if (physicalIdList != nullptr) {
137 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
138 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
139 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
140 return ACAMERA_ERROR_INVALID_PARAMETER;
141 }
142 for (auto i = 0; i < physicalIdList->numCameras; i++) {
143 if (physicalIdList->cameraIds[i] == nullptr) {
144 ALOGE("%s: physicalId is null!", __FUNCTION__);
145 return ACAMERA_ERROR_INVALID_PARAMETER;
146 }
147 if (mPhysicalIds.end() == std::find(
148 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
149 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
150 return ACAMERA_ERROR_INVALID_PARAMETER;
151 }
152 }
153 }
154
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800155 camera_status_t ret = checkCameraClosedOrErrorLocked();
156 if (ret != ACAMERA_OK) {
157 return ret;
158 }
159 if (mRemote == nullptr) {
160 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
161 }
162 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800163 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
164 if (remoteRet.serviceSpecificErrorCode() ==
165 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800166 ALOGW("Create capture request failed! template %d is not supported on this device",
167 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700168 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800169 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000170 ALOGE("Create capture request failed: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800171 return ACAMERA_ERROR_UNKNOWN;
172 }
173 ACaptureRequest* outReq = new ACaptureRequest();
174 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800175 if (physicalIdList != nullptr) {
176 for (auto i = 0; i < physicalIdList->numCameras; i++) {
177 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
178 new ACameraMetadata(*(outReq->settings)));
179 }
180 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800181 outReq->targets = new ACameraOutputTargets();
182 *request = outReq;
183 return ACAMERA_OK;
184}
185
Yin-Chia Yehead91462016-01-06 16:45:08 -0800186camera_status_t
187CameraDevice::createCaptureSession(
188 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100189 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800190 const ACameraCaptureSession_stateCallbacks* callbacks,
191 /*out*/ACameraCaptureSession** session) {
Shuzhen Wang316781a2020-08-18 18:11:01 -0700192 nsecs_t startTimeNs = systemTime();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700193 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800194 Mutex::Autolock _l(mDeviceLock);
195 camera_status_t ret = checkCameraClosedOrErrorLocked();
196 if (ret != ACAMERA_OK) {
197 return ret;
198 }
199
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700200 if (currentSession != nullptr) {
201 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800202 stopRepeatingLocked();
203 }
204
205 // Create new session
Shuzhen Wang316781a2020-08-18 18:11:01 -0700206 ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800207 if (ret != ACAMERA_OK) {
208 ALOGE("Fail to create new session. cannot configure streams");
209 return ret;
210 }
211
212 ACameraCaptureSession* newSession = new ACameraCaptureSession(
213 mNextSessionId++, outputs, callbacks, this);
214
Yin-Chia Yehead91462016-01-06 16:45:08 -0800215 // set new session as current session
216 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
217 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700218 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800219 *session = newSession;
220 return ACAMERA_OK;
221}
222
Shuzhen Wang24810e72019-03-18 10:55:01 -0700223camera_status_t CameraDevice::isSessionConfigurationSupported(
224 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
225 Mutex::Autolock _l(mDeviceLock);
226 camera_status_t ret = checkCameraClosedOrErrorLocked();
227 if (ret != ACAMERA_OK) {
228 return ret;
229 }
230
231 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
232 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
233 for (const auto& output : sessionOutputContainer->mOutputs) {
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700234 sp<SurfaceType> surface(nullptr);
235 ret = getSurfacefromAnw(output.mWindow, surface);
Shuzhen Wang24810e72019-03-18 10:55:01 -0700236 if (ret != ACAMERA_OK) {
237 ALOGE("Camera device %s failed to extract graphic producer from native window",
238 getId());
239 return ret;
240 }
241
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700242 ParcelableSurfaceType pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
243 OutputConfiguration outConfig(pSurface, output.mRotation, output.mPhysicalCameraId,
Shuzhen Wang24810e72019-03-18 10:55:01 -0700244 OutputConfiguration::INVALID_SET_ID, true);
245
246 for (auto& anw : output.mSharedWindows) {
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700247 ret = getSurfacefromAnw(anw, surface);
Shuzhen Wang24810e72019-03-18 10:55:01 -0700248 if (ret != ACAMERA_OK) {
249 ALOGE("Camera device %s failed to extract graphic producer from native window",
250 getId());
251 return ret;
252 }
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700253 pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
254 outConfig.addSurface(pSurface);
Shuzhen Wang24810e72019-03-18 10:55:01 -0700255 }
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
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700300 sp<SurfaceType> surface(nullptr);
301 ret = getSurfacefromAnw(output->mWindow, surface);
Emilian Peev40ead602017-09-26 15:46:36 +0100302 if (ret != ACAMERA_OK) {
303 ALOGE("Camera device %s failed to extract graphic producer from native window",
304 getId());
305 return ret;
306 }
307
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700308 ParcelableSurfaceType pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
309 OutputConfiguration outConfig(pSurface, output->mRotation, output->mPhysicalCameraId,
310 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100311
312 for (auto& anw : output->mSharedWindows) {
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700313 ret = getSurfacefromAnw(anw, surface);
Emilian Peev40ead602017-09-26 15:46:36 +0100314 if (ret != ACAMERA_OK) {
315 ALOGE("Camera device %s failed to extract graphic producer from native window",
316 getId());
317 return ret;
318 }
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700319 pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
320 outConfig.addSurface(pSurface);
Emilian Peev40ead602017-09-26 15:46:36 +0100321 }
322
323 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
324 if (!remoteRet.isOk()) {
325 switch (remoteRet.serviceSpecificErrorCode()) {
326 case hardware::ICameraService::ERROR_INVALID_OPERATION:
327 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000328 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100329 return ACAMERA_ERROR_INVALID_OPERATION;
330 break;
331 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
332 ALOGE("Camera device %s output surface already exists: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000333 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100334 return ACAMERA_ERROR_INVALID_PARAMETER;
335 break;
336 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
337 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000338 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100339 return ACAMERA_ERROR_INVALID_PARAMETER;
340 break;
341 default:
342 ALOGE("Camera device %s failed to add shared output: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000343 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100344 return ACAMERA_ERROR_UNKNOWN;
345 }
346 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800347 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100348
349 return ACAMERA_OK;
350}
351
Avichal Rakesh8effe982023-11-13 18:53:40 -0800352camera_status_t CameraDevice::prepareLocked(ANativeWindow *window) {
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000353 camera_status_t ret = checkCameraClosedOrErrorLocked();
354 if (ret != ACAMERA_OK) {
355 return ret;
356 }
357
358 if (window == nullptr) {
359 return ACAMERA_ERROR_INVALID_PARAMETER;
360 }
361
362 int32_t streamId = -1;
363 for (auto& kvPair : mConfiguredOutputs) {
364 if (window == kvPair.second.first) {
365 streamId = kvPair.first;
366 break;
367 }
368 }
369 if (streamId < 0) {
370 ALOGE("Error: Invalid output configuration");
371 return ACAMERA_ERROR_INVALID_PARAMETER;
372 }
373 auto remoteRet = mRemote->prepare(streamId);
374 if (!remoteRet.isOk()) {
375 // TODO:(b/259735869) Do this check for all other binder calls in the
376 // ndk as well.
377 if (remoteRet.exceptionCode() != EX_SERVICE_SPECIFIC) {
378 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000379 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000380 return ACAMERA_ERROR_UNKNOWN;
381
382 }
383 switch (remoteRet.serviceSpecificErrorCode()) {
384 case hardware::ICameraService::ERROR_INVALID_OPERATION:
385 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000386 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000387 return ACAMERA_ERROR_INVALID_OPERATION;
388 break;
389 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
390 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000391 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000392 return ACAMERA_ERROR_INVALID_PARAMETER;
393 break;
394 default:
395 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000396 remoteRet.toString8().c_str());
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000397 return ACAMERA_ERROR_UNKNOWN;
398 }
399 }
400
401 return ACAMERA_OK;
402}
403
Yin-Chia Yehead91462016-01-06 16:45:08 -0800404camera_status_t
405CameraDevice::allocateCaptureRequest(
406 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
407 camera_status_t ret;
408 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800409 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000410 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800411 for (auto& entry : request->physicalSettings) {
412 req->mPhysicalCameraSettings.push_back({entry.first,
413 entry.second->getInternalData()});
414 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800415 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700416 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800417 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800418
419 for (auto outputTarget : request->targets->mOutputs) {
420 ANativeWindow* anw = outputTarget.mWindow;
421 sp<Surface> surface;
422 ret = getSurfaceFromANativeWindow(anw, surface);
423 if (ret != ACAMERA_OK) {
424 ALOGE("Bad output target in capture request! ret %d", ret);
425 return ret;
426 }
427 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800428
429 bool found = false;
430 // lookup stream/surface ID
431 for (const auto& kvPair : mConfiguredOutputs) {
432 int streamId = kvPair.first;
433 const OutputConfiguration& outConfig = kvPair.second.second;
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700434 const auto& surfaces = outConfig.getSurfaces();
435 for (int surfaceId = 0; surfaceId < (int)surfaces.size(); surfaceId++) {
436 if (surfaces[surfaceId] == flagtools::surfaceToSurfaceType(surface)) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800437 found = true;
438 req->mStreamIdxList.push_back(streamId);
439 req->mSurfaceIdxList.push_back(surfaceId);
440 break;
441 }
442 }
443 if (found) {
444 break;
445 }
446 }
447 if (!found) {
448 ALOGE("Unconfigured output target %p in capture request!", anw);
449 return ret;
450 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800451 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800452
Yin-Chia Yehead91462016-01-06 16:45:08 -0800453 outReq = req;
454 return ACAMERA_OK;
455}
456
457ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800458CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800459 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800460 for (auto& entry : req->mPhysicalCameraSettings) {
461 CameraMetadata clone = entry.settings;
462 if (entry.id == deviceId) {
463 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
464 } else {
465 pRequest->physicalSettings.emplace(entry.id,
466 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
467 }
468 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800469 pRequest->targets = new ACameraOutputTargets();
470 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
471 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
472 ACameraOutputTarget outputTarget(anw);
473 pRequest->targets->mOutputs.insert(outputTarget);
474 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700475 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800476 return pRequest;
477}
478
479void
480CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
481 if (req == nullptr) {
482 return;
483 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700484 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800485 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800486 delete req->targets;
487 delete req;
488}
489
490void
491CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
492 if (isClosed()) {
493 // Device is closing already. do nothing
494 return;
495 }
496
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700497 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800498 // Session has been replaced by other seesion or device is closed
499 return;
500 }
501 mCurrentSession = nullptr;
502
503 // Should not happen
504 if (!session->mIsClosed) {
505 ALOGE("Error: unclosed session %p reaches end of life!", session);
506 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
507 return;
508 }
509
510 // No new session, unconfigure now
Shuzhen Wang316781a2020-08-18 18:11:01 -0700511 // Note: The unconfiguration of session won't be accounted for session
512 // latency because a stream configuration with 0 streams won't ever become
513 // active.
514 nsecs_t startTimeNs = systemTime();
515 camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800516 if (ret != ACAMERA_OK) {
517 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
518 }
519}
520
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800521void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700522CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800523 if (mClosing.exchange(true)) {
524 // Already closing, just return
525 ALOGW("Camera device %s is already closing.", getId());
526 return;
527 }
528
529 if (mRemote != nullptr) {
530 mRemote->disconnect();
531 }
532 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800533
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700534 if (session != nullptr) {
535 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800536 }
537}
538
539camera_status_t
540CameraDevice::stopRepeatingLocked() {
541 camera_status_t ret = checkCameraClosedOrErrorLocked();
542 if (ret != ACAMERA_OK) {
543 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
544 return ret;
545 }
546 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
547 int repeatingSequenceId = mRepeatingSequenceId;
548 mRepeatingSequenceId = REQUEST_ID_NONE;
549
550 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800551 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700552 if (remoteRet.serviceSpecificErrorCode() ==
553 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
554 ALOGV("Repeating request is already stopped.");
555 return ACAMERA_OK;
556 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000557 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800558 return ACAMERA_ERROR_UNKNOWN;
559 }
560 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
561 }
562 return ACAMERA_OK;
563}
564
565camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700566CameraDevice::flushLocked(ACameraCaptureSession* session) {
567 camera_status_t ret = checkCameraClosedOrErrorLocked();
568 if (ret != ACAMERA_OK) {
569 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
570 return ret;
571 }
572
573 // This should never happen because creating a new session will close
574 // previous one and thus reject any API call from previous session.
575 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700576 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700577 ALOGE("Camera %s session %p is not current active session!", getId(), session);
578 return ACAMERA_ERROR_INVALID_OPERATION;
579 }
580
581 if (mFlushing) {
582 ALOGW("Camera %s is already aborting captures", getId());
583 return ACAMERA_OK;
584 }
585
586 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700587
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700588 // Send onActive callback to guarantee there is always active->ready transition
589 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
590 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
591 msg->setObject(kSessionSpKey, session);
592 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700593 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700594
595 // If device is already idling, send callback and exit early
596 if (mIdle) {
597 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
598 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
599 msg->setObject(kSessionSpKey, session);
600 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700601 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700602 mFlushing = false;
603 return ACAMERA_OK;
604 }
605
606 int64_t lastFrameNumber;
607 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
608 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000609 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700610 return ACAMERA_ERROR_UNKNOWN;
611 }
612 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
613 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
614 }
615 return ACAMERA_OK;
616}
617
618camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800619CameraDevice::waitUntilIdleLocked() {
620 camera_status_t ret = checkCameraClosedOrErrorLocked();
621 if (ret != ACAMERA_OK) {
622 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
623 return ret;
624 }
625
626 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
627 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
628 return ACAMERA_ERROR_INVALID_OPERATION;
629 }
630
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800631 binder::Status remoteRet = mRemote->waitUntilIdle();
632 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000633 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800634 // TODO: define a function to convert status_t -> camera_status_t
635 return ACAMERA_ERROR_UNKNOWN;
636 }
637
638 return ACAMERA_OK;
639}
640
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700641camera_status_t CameraDevice::getSurfacefromAnw(ANativeWindow* anw, sp<SurfaceType>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800642 sp<Surface> surface;
643 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
644 if (ret != ACAMERA_OK) {
645 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800646 }
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700647 out = flagtools::surfaceToSurfaceType(surface);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800648 return ACAMERA_OK;
649}
650
651camera_status_t
652CameraDevice::getSurfaceFromANativeWindow(
653 ANativeWindow* anw, sp<Surface>& out) {
654 if (anw == nullptr) {
655 ALOGE("Error: output ANativeWindow is null");
656 return ACAMERA_ERROR_INVALID_PARAMETER;
657 }
658 int value;
659 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800660 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800661 ALOGE("Error: ANativeWindow is not backed by Surface!");
662 return ACAMERA_ERROR_INVALID_PARAMETER;
663 }
664 sp<Surface> surface(static_cast<Surface*>(anw));
665 out = surface;
666 return ACAMERA_OK;
667}
668
669camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100670CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700671 const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800672 ACaptureSessionOutputContainer emptyOutput;
673 if (outputs == nullptr) {
674 outputs = &emptyOutput;
675 }
676
Yin-Chia Yehead91462016-01-06 16:45:08 -0800677 camera_status_t ret = checkCameraClosedOrErrorLocked();
678 if (ret != ACAMERA_OK) {
679 return ret;
680 }
681
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700682 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800683 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700684 ANativeWindow* anw = outConfig.mWindow;
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700685 sp<SurfaceType> surface(nullptr);
686 ret = getSurfacefromAnw(anw, surface);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800687 if (ret != ACAMERA_OK) {
688 return ret;
689 }
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700690 ParcelableSurfaceType pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700691 outputSet.insert(std::make_pair(
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700692 anw,
693 OutputConfiguration(pSurface, outConfig.mRotation, outConfig.mPhysicalCameraId,
694 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800695 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700696 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800697 std::vector<int> deleteList;
698
699 // Determine which streams need to be created, which to be deleted
700 for (auto& kvPair : mConfiguredOutputs) {
701 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700702 auto& outputPair = kvPair.second;
703 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800704 deleteList.push_back(streamId); // Need to delete a no longer needed stream
705 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700706 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800707 }
708 }
709
710 ret = stopRepeatingLocked();
711 if (ret != ACAMERA_OK) {
712 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
713 return ret;
714 }
715
716 ret = waitUntilIdleLocked();
717 if (ret != ACAMERA_OK) {
718 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
719 return ret;
720 }
721
722 // Send onReady to previous session
723 // CurrentSession will be updated after configureStreamLocked, so here
724 // mCurrentSession is the session to be replaced by a new session
725 if (!mIdle && mCurrentSession != nullptr) {
726 if (mBusySession != mCurrentSession) {
727 ALOGE("Current session != busy session");
728 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
729 return ACAMERA_ERROR_CAMERA_DEVICE;
730 }
731 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
732 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
733 msg->setObject(kSessionSpKey, mBusySession);
734 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
735 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700736 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800737 }
738 mIdle = true;
739
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800740 binder::Status remoteRet = mRemote->beginConfigure();
741 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000742 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800743 return ACAMERA_ERROR_UNKNOWN;
744 }
745
746 // delete to-be-deleted streams
747 for (auto streamId : deleteList) {
748 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800749 if (!remoteRet.isOk()) {
750 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000751 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800752 return ACAMERA_ERROR_UNKNOWN;
753 }
754 mConfiguredOutputs.erase(streamId);
755 }
756
757 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800758 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800759 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700760 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800761 if (!remoteRet.isOk()) {
762 ALOGE("Camera device %s failed to create stream: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000763 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800764 return ACAMERA_ERROR_UNKNOWN;
765 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700766 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800767 }
768
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100769 CameraMetadata params;
770 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
771 params.append(sessionParameters->settings->getInternalData());
772 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800773 std::vector<int> offlineStreamIds;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700774 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
775 ns2ms(startTimeNs), &offlineStreamIds);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800776 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
777 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000778 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800779 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800780 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000781 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800782 return ACAMERA_ERROR_UNKNOWN;
783 }
784
785 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800786}
787
788void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800789CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800790 Mutex::Autolock _l(mDeviceLock);
791 mRemote = remote;
792}
793
794camera_status_t
795CameraDevice::checkCameraClosedOrErrorLocked() const {
796 if (mRemote == nullptr) {
797 ALOGE("%s: camera device already closed", __FUNCTION__);
798 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
799 }
800 if (mInError) {// triggered by onDeviceError
801 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
802 return mError;
803 }
804 return ACAMERA_OK;
805}
806
807void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800808CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
809 mInError = true;
810 mError = error;
811 return;
812}
813
814void
815CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
816 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
817 if (isError) {
818 mFutureErrorSet.insert(frameNumber);
819 } else if (frameNumber <= mCompletedFrameNumber) {
820 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
821 frameNumber, mCompletedFrameNumber);
822 return;
823 } else {
824 if (frameNumber != mCompletedFrameNumber + 1) {
825 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
826 mCompletedFrameNumber + 1, frameNumber);
827 // Do not assert as in java implementation
828 }
829 mCompletedFrameNumber = frameNumber;
830 }
831 update();
832}
833
834void
835CameraDevice::FrameNumberTracker::update() {
836 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
837 int64_t errorFrameNumber = *it;
838 if (errorFrameNumber == mCompletedFrameNumber + 1) {
839 mCompletedFrameNumber++;
840 it = mFutureErrorSet.erase(it);
841 } else if (errorFrameNumber <= mCompletedFrameNumber) {
842 // This should not happen, but deal with it anyway
843 ALOGE("Completd frame number passed through current frame number!");
844 // erase the old error since it's no longer useful
845 it = mFutureErrorSet.erase(it);
846 } else {
847 // Normal requests hasn't catched up error frames, just break
848 break;
849 }
850 }
851 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
852}
853
854void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800855CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800856 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800857 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800858 int sequenceId = resultExtras.requestId;
859 int64_t frameNumber = resultExtras.frameNumber;
860 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700861 auto it = mSequenceCallbackMap.find(sequenceId);
862 if (it == mSequenceCallbackMap.end()) {
863 ALOGE("%s: Error: capture sequence index %d not found!",
864 __FUNCTION__, sequenceId);
865 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800866 return;
867 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700868
869 CallbackHolder cbh = (*it).second;
870 sp<ACameraCaptureSession> session = cbh.mSession;
871 if ((size_t) burstId >= cbh.mRequests.size()) {
872 ALOGE("%s: Error: request index %d out of bound (size %zu)",
873 __FUNCTION__, burstId, cbh.mRequests.size());
874 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
875 return;
876 }
877 sp<CaptureRequest> request = cbh.mRequests[burstId];
878
879 // Handle buffer error
880 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
881 int32_t streamId = resultExtras.errorStreamId;
882 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800883 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700884 auto outputPairIt = mConfiguredOutputs.find(streamId);
885 if (outputPairIt == mConfiguredOutputs.end()) {
886 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800887 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
888 return;
889 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700890
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700891 const auto& outSurfaces = outputPairIt->second.second.getSurfaces();
892 for (const auto& outSurface : outSurfaces) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800893 for (const auto& surface : request->mSurfaceList) {
Carlos Martinez Romeroc45bc932024-10-09 15:04:51 -0700894 if ( outSurface == surface
895#if not WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
896 ->getIGraphicBufferProducer()
897#endif
898 ) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800899 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
900 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
901 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700902
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800903 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800904 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800905 msg->setObject(kSessionSpKey, session);
906 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
907 msg->setObject(kCaptureRequestKey, request);
908 msg->setPointer(kAnwKey, (void*) anw);
909 msg->setInt64(kFrameNumberKey, frameNumber);
910 postSessionMsgAndCleanup(msg);
911 }
912 }
913 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700914 } else { // Handle other capture failures
915 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800916 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800917 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
918 failure->frameNumber = frameNumber;
919 // TODO: refine this when implementing flush
920 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
921 failure->sequenceId = sequenceId;
922 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800923 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800924
Emilian Peevedec62d2019-03-19 17:59:24 -0700925 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
926 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800927 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800928 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700929 if (cbh.mIsLogicalCameraCallback) {
930 if (resultExtras.errorPhysicalCameraId.size() > 0) {
Austin Borger71d8f672023-06-01 16:51:35 -0700931 String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000932 msg->setString(kFailingPhysicalCameraId, cameraId.c_str(), cameraId.size());
Emilian Peevedec62d2019-03-19 17:59:24 -0700933 }
934 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
935 } else {
936 msg->setPointer(kCallbackFpKey, (void*) onError);
937 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800938 msg->setObject(kCaptureRequestKey, request);
939 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700940 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800941
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700942 // Update tracker
943 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
944 checkAndFireSequenceCompleteLocked();
945 }
946 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800947}
948
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700949void CameraDevice::stopLooperAndDisconnect() {
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700950 Mutex::Autolock _l(mDeviceLock);
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700951 sp<ACameraCaptureSession> session = mCurrentSession.promote();
952 if (!isClosed()) {
953 disconnectLocked(session);
954 }
955 mCurrentSession = nullptr;
956
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700957 if (mCbLooper != nullptr) {
958 mCbLooper->unregisterHandler(mHandler->id());
959 mCbLooper->stop();
960 }
961 mCbLooper.clear();
962 mHandler.clear();
963}
964
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800965CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
966}
967
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800968void CameraDevice::CallbackHandler::onMessageReceived(
969 const sp<AMessage> &msg) {
970 switch (msg->what()) {
971 case kWhatOnDisconnected:
972 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800973 case kWhatSessionStateCb:
974 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +0000975 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800976 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800977 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800978 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700979 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800980 case kWhatCaptureSeqEnd:
981 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700982 case kWhatCaptureBufferLost:
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000983 case kWhatPreparedCb:
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700984 case kWhatClientSharedAccessPriorityChanged:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800985 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800986 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700987 case kWhatCleanUpSessions:
988 mCachedSessions.clear();
989 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800990 default:
991 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
992 return;
993 }
994 // Check the common part of all message
995 void* context;
996 bool found = msg->findPointer(kContextKey, &context);
997 if (!found) {
998 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
999 return;
1000 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001001 switch (msg->what()) {
1002 case kWhatOnDisconnected:
1003 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001004 ACameraDevice* dev;
1005 found = msg->findPointer(kDeviceKey, (void**) &dev);
1006 if (!found || dev == nullptr) {
1007 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1008 return;
1009 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001010 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001011 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001012 if (!found) {
1013 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
1014 return;
1015 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001016 if (onDisconnected == nullptr) {
1017 return;
1018 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001019 (*onDisconnected)(context, dev);
1020 break;
1021 }
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001022
1023 case kWhatClientSharedAccessPriorityChanged:
1024 {
1025 if (!flags::camera_multi_client()) {
1026 break;
1027 }
1028 ACameraDevice* dev;
1029 found = msg->findPointer(kDeviceKey, (void**) &dev);
1030 if (!found || dev == nullptr) {
1031 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1032 return;
1033 }
1034 ACameraDevice_ClientSharedAccessPriorityChangedCallback
1035 onClientSharedAccessPriorityChanged;
1036 found = msg->findPointer(kCallbackFpKey, (void**) &onClientSharedAccessPriorityChanged);
1037 if (!found) {
1038 ALOGE("%s: Cannot find onClientSharedAccessPriorityChanged!", __FUNCTION__);
1039 return;
1040 }
1041 if (onClientSharedAccessPriorityChanged == nullptr) {
1042 return;
1043 }
1044 (*onClientSharedAccessPriorityChanged)(context, dev, dev->isPrimaryClient());
1045 break;
1046 }
1047
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001048 case kWhatOnError:
1049 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001050 ACameraDevice* dev;
1051 found = msg->findPointer(kDeviceKey, (void**) &dev);
1052 if (!found || dev == nullptr) {
1053 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1054 return;
1055 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001056 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001057 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001058 if (!found) {
1059 ALOGE("%s: Cannot find onError!", __FUNCTION__);
1060 return;
1061 }
1062 int errorCode;
1063 found = msg->findInt32(kErrorCodeKey, &errorCode);
1064 if (!found) {
1065 ALOGE("%s: Cannot find error code!", __FUNCTION__);
1066 return;
1067 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001068 if (onError == nullptr) {
1069 return;
1070 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001071 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001072 break;
1073 }
1074 case kWhatSessionStateCb:
1075 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001076 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001077 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001078 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001079 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001080 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001081 case kWhatCaptureSeqEnd:
1082 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001083 case kWhatCaptureBufferLost:
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001084 case kWhatPreparedCb:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001085 {
1086 sp<RefBase> obj;
1087 found = msg->findObject(kSessionSpKey, &obj);
1088 if (!found || obj == nullptr) {
1089 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
1090 return;
1091 }
1092 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001093 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001094 sp<CaptureRequest> requestSp = nullptr;
1095 switch (msg->what()) {
1096 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001097 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001098 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001099 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001100 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001101 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001102 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001103 found = msg->findObject(kCaptureRequestKey, &obj);
1104 if (!found) {
1105 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1106 return;
1107 }
1108 requestSp = static_cast<CaptureRequest*>(obj.get());
1109 break;
1110 }
1111
1112 switch (msg->what()) {
1113 case kWhatSessionStateCb:
1114 {
1115 ACameraCaptureSession_stateCallback onState;
1116 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1117 if (!found) {
1118 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1119 return;
1120 }
1121 if (onState == nullptr) {
1122 return;
1123 }
1124 (*onState)(context, session.get());
1125 break;
1126 }
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001127 case kWhatPreparedCb:
1128 {
1129 ACameraCaptureSession_prepareCallback onWindowPrepared;
1130 found = msg->findPointer(kCallbackFpKey, (void**) &onWindowPrepared);
1131 if (!found) {
Jayant Chowdhary0f2cb992023-02-17 18:25:53 +00001132 ALOGE("%s: Cannot find window prepared callback!", __FUNCTION__);
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001133 return;
1134 }
1135 if (onWindowPrepared == nullptr) {
1136 return;
1137 }
Avichal Rakesh8effe982023-11-13 18:53:40 -08001138 ANativeWindow* anw;
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001139 found = msg->findPointer(kAnwKey, (void**) &anw);
1140 if (!found) {
1141 ALOGE("%s: Cannot find ANativeWindow: %d!", __FUNCTION__, __LINE__);
1142 return;
1143 }
1144 (*onWindowPrepared)(context, anw, session.get());
1145 break;
1146 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001147 case kWhatCaptureStart:
1148 {
1149 ACameraCaptureSession_captureCallback_start onStart;
1150 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1151 if (!found) {
1152 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1153 return;
1154 }
1155 if (onStart == nullptr) {
1156 return;
1157 }
1158 int64_t timestamp;
1159 found = msg->findInt64(kTimeStampKey, &timestamp);
1160 if (!found) {
1161 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1162 return;
1163 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001164 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001165 (*onStart)(context, session.get(), request, timestamp);
1166 freeACaptureRequest(request);
1167 break;
1168 }
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001169 case kWhatCaptureStart2:
1170 {
1171 ACameraCaptureSession_captureCallback_startV2 onStart2;
1172 found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
1173 if (!found) {
1174 ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
1175 return;
1176 }
1177 if (onStart2 == nullptr) {
1178 return;
1179 }
1180 int64_t timestamp;
1181 found = msg->findInt64(kTimeStampKey, &timestamp);
1182 if (!found) {
1183 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1184 return;
1185 }
1186 int64_t frameNumber;
1187 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1188 if (!found) {
1189 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1190 return;
1191 }
1192
1193 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1194 (*onStart2)(context, session.get(), request, timestamp, frameNumber);
1195 freeACaptureRequest(request);
1196 break;
1197 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001198 case kWhatCaptureResult:
1199 {
1200 ACameraCaptureSession_captureCallback_result onResult;
1201 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1202 if (!found) {
1203 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1204 return;
1205 }
1206 if (onResult == nullptr) {
1207 return;
1208 }
1209
1210 found = msg->findObject(kCaptureResultKey, &obj);
1211 if (!found) {
1212 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1213 return;
1214 }
1215 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001216 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001217 (*onResult)(context, session.get(), request, result.get());
1218 freeACaptureRequest(request);
1219 break;
1220 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001221 case kWhatLogicalCaptureResult:
1222 {
1223 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1224 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1225 if (!found) {
1226 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1227 __FUNCTION__);
1228 return;
1229 }
1230 if (onResult == nullptr) {
1231 return;
1232 }
1233
1234 found = msg->findObject(kCaptureResultKey, &obj);
1235 if (!found) {
1236 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1237 return;
1238 }
1239 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1240
1241 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1242 if (!found) {
1243 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1244 return;
1245 }
1246 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1247 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1248 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1249 physicalResult->mPhysicalResultInfo;
1250
1251 std::vector<std::string> physicalCameraIds;
1252 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1253 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
Austin Borger71d8f672023-06-01 16:51:35 -07001254 String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001255 physicalCameraIds.push_back(physicalId8.c_str());
1256
1257 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1258 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1259 &physicalResult->mFrameNumber, /*data_count*/1);
1260 sp<ACameraMetadata> metadata =
1261 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1262 physicalMetadataCopy.push_back(metadata);
1263 }
1264
1265 std::vector<const char*> physicalCameraIdPtrs;
1266 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1267 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1268 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1269 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1270 }
1271
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001272 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001273 (*onResult)(context, session.get(), request, result.get(),
1274 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1275 physicalMetadataCopyPtrs.data());
1276 freeACaptureRequest(request);
1277 break;
1278 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001279 case kWhatCaptureFail:
1280 {
1281 ACameraCaptureSession_captureCallback_failed onFail;
1282 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1283 if (!found) {
1284 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1285 return;
1286 }
1287 if (onFail == nullptr) {
1288 return;
1289 }
1290
1291 found = msg->findObject(kCaptureFailureKey, &obj);
1292 if (!found) {
1293 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1294 return;
1295 }
1296 sp<CameraCaptureFailure> failureSp(
1297 static_cast<CameraCaptureFailure*>(obj.get()));
1298 ACameraCaptureFailure* failure =
1299 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001300 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001301 (*onFail)(context, session.get(), request, failure);
1302 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001303 break;
1304 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001305 case kWhatLogicalCaptureFail:
1306 {
1307 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1308 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1309 if (!found) {
1310 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1311 return;
1312 }
1313 if (onFail == nullptr) {
1314 return;
1315 }
1316
1317 found = msg->findObject(kCaptureFailureKey, &obj);
1318 if (!found) {
1319 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1320 return;
1321 }
1322 sp<CameraCaptureFailure> failureSp(
1323 static_cast<CameraCaptureFailure*>(obj.get()));
1324 ALogicalCameraCaptureFailure failure;
1325 AString physicalCameraId;
1326 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1327 if (found && !physicalCameraId.empty()) {
1328 failure.physicalCameraId = physicalCameraId.c_str();
1329 } else {
1330 failure.physicalCameraId = nullptr;
1331 }
1332 failure.captureFailure = *failureSp;
1333 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1334 (*onFail)(context, session.get(), request, &failure);
1335 freeACaptureRequest(request);
1336 break;
1337 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001338 case kWhatCaptureSeqEnd:
1339 {
1340 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1341 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1342 if (!found) {
1343 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1344 return;
1345 }
1346 if (onSeqEnd == nullptr) {
1347 return;
1348 }
1349 int seqId;
1350 found = msg->findInt32(kSequenceIdKey, &seqId);
1351 if (!found) {
1352 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1353 return;
1354 }
1355 int64_t frameNumber;
1356 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1357 if (!found) {
1358 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1359 return;
1360 }
1361 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1362 break;
1363 }
1364 case kWhatCaptureSeqAbort:
1365 {
1366 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1367 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1368 if (!found) {
1369 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1370 return;
1371 }
1372 if (onSeqAbort == nullptr) {
1373 return;
1374 }
1375 int seqId;
1376 found = msg->findInt32(kSequenceIdKey, &seqId);
1377 if (!found) {
1378 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1379 return;
1380 }
1381 (*onSeqAbort)(context, session.get(), seqId);
1382 break;
1383 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001384 case kWhatCaptureBufferLost:
1385 {
1386 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1387 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1388 if (!found) {
1389 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1390 return;
1391 }
1392 if (onBufferLost == nullptr) {
1393 return;
1394 }
1395
1396 ANativeWindow* anw;
1397 found = msg->findPointer(kAnwKey, (void**) &anw);
1398 if (!found) {
1399 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1400 return;
1401 }
1402
1403 int64_t frameNumber;
1404 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1405 if (!found) {
1406 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1407 return;
1408 }
1409
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001410 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001411 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1412 freeACaptureRequest(request);
1413 break;
1414 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001415 }
1416 break;
1417 }
1418 }
1419}
1420
1421CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001422 sp<ACameraCaptureSession> session,
1423 const Vector<sp<CaptureRequest> >& requests,
1424 bool isRepeating,
1425 ACameraCaptureSession_captureCallbacks* cbs) :
1426 mSession(session), mRequests(requests),
1427 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001428 mIsLogicalCameraCallback(false),
1429 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001430 initCaptureCallbacks(cbs);
1431
1432 if (cbs != nullptr) {
1433 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001434 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001435 }
1436}
1437
1438CameraDevice::CallbackHolder::CallbackHolder(
1439 sp<ACameraCaptureSession> session,
1440 const Vector<sp<CaptureRequest> >& requests,
1441 bool isRepeating,
1442 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1443 mSession(session), mRequests(requests),
1444 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001445 mIsLogicalCameraCallback(true),
1446 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001447 initCaptureCallbacks(lcbs);
1448
1449 if (lcbs != nullptr) {
1450 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001451 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001452 }
1453}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001454
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001455CameraDevice::CallbackHolder::CallbackHolder(
1456 sp<ACameraCaptureSession> session,
1457 const Vector<sp<CaptureRequest> >& requests,
1458 bool isRepeating,
1459 ACameraCaptureSession_captureCallbacksV2* cbs) :
1460 mSession(session), mRequests(requests),
1461 mIsRepeating(isRepeating),
1462 mIsLogicalCameraCallback(false),
1463 mIs2Callback(true) {
1464 initCaptureCallbacksV2(cbs);
1465
1466 if (cbs != nullptr) {
1467 mOnCaptureCompleted = cbs->onCaptureCompleted;
1468 mOnCaptureFailed = cbs->onCaptureFailed;
1469 }
1470}
1471
1472CameraDevice::CallbackHolder::CallbackHolder(
1473 sp<ACameraCaptureSession> session,
1474 const Vector<sp<CaptureRequest> >& requests,
1475 bool isRepeating,
1476 ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
1477 mSession(session), mRequests(requests),
1478 mIsRepeating(isRepeating),
1479 mIsLogicalCameraCallback(true),
1480 mIs2Callback(true) {
1481 initCaptureCallbacksV2(lcbs);
1482
1483 if (lcbs != nullptr) {
1484 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1485 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
1486 }
1487}
1488
Yin-Chia Yehead91462016-01-06 16:45:08 -08001489void
1490CameraDevice::checkRepeatingSequenceCompleteLocked(
1491 const int sequenceId, const int64_t lastFrameNumber) {
1492 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1493 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1494 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1495 ALOGW("No callback found for sequenceId %d", sequenceId);
1496 return;
1497 }
1498 // remove callback holder from callback map
1499 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1500 CallbackHolder cbh = cbIt->second;
1501 mSequenceCallbackMap.erase(cbIt);
1502 // send seq aborted callback
1503 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001504 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001505 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001506 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001507 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001508 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001509 } else {
1510 // Use mSequenceLastFrameNumberMap to track
1511 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1512
1513 // Last frame might have arrived. Check now
1514 checkAndFireSequenceCompleteLocked();
1515 }
1516}
1517
1518void
1519CameraDevice::checkAndFireSequenceCompleteLocked() {
1520 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001521 auto it = mSequenceLastFrameNumberMap.begin();
1522 while (it != mSequenceLastFrameNumberMap.end()) {
1523 int sequenceId = it->first;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001524 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001525
1526 if (mRemote == nullptr) {
1527 ALOGW("Camera %s closed while checking sequence complete", getId());
1528 return;
1529 }
1530 ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1531 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1532 if (!it->second.isSequenceCompleted) {
1533 // Check if there is callback for this sequence
1534 // This should not happen because we always register callback (with nullptr inside)
1535 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1536 ALOGW("No callback found for sequenceId %d", sequenceId);
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001537 }
1538
1539 if (lastFrameNumber <= completedFrameNumber) {
1540 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1541 it->second.isSequenceCompleted = true;
1542 }
1543
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001544 }
1545
1546 if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001547 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
1548
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001549 it = mSequenceLastFrameNumberMap.erase(it);
1550 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1551 } else {
1552 ++it;
1553 }
1554 }
1555}
1556
1557void
1558CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1559 auto it = mSequenceLastFrameNumberMap.begin();
1560 while (it != mSequenceLastFrameNumberMap.end()) {
1561 int sequenceId = it->first;
1562 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wang730a7912020-05-07 11:59:02 -07001563
1564 if (mRemote == nullptr) {
1565 ALOGW("Camera %s closed while checking sequence complete", getId());
1566 return;
1567 }
Shuzhen Wang730a7912020-05-07 11:59:02 -07001568
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001569 ALOGV("%s: seq %d's last frame number %" PRId64
1570 ", completed inflight frame number %" PRId64,
1571 __FUNCTION__, sequenceId, lastFrameNumber,
1572 lastCompletedRegularFrameNumber);
1573 if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1574 if (it->second.isSequenceCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001575 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
Shuzhen Wang730a7912020-05-07 11:59:02 -07001576
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001577 it = mSequenceLastFrameNumberMap.erase(it);
1578 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1579 } else {
1580 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1581 it->second.isInflightCompleted = true;
1582 ++it;
1583 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001584 } else {
1585 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001586 }
1587 }
1588}
1589
1590/**
1591 * Camera service callback implementation
1592 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001593binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001594CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001595 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001596 const CaptureResultExtras& resultExtras) {
1597 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1598 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001599 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001600 sp<CameraDevice> dev = mDevice.promote();
1601 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001602 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001603 }
1604
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001605 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001606 Mutex::Autolock _l(dev->mDeviceLock);
1607 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001608 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001609 }
1610 switch (errorCode) {
1611 case ERROR_CAMERA_DISCONNECTED:
1612 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001613 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001614 if (session != nullptr) {
1615 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001616 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001617 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001618 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1619 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1620 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001621 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001622 msg->post();
1623 break;
1624 }
1625 default:
1626 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001627 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001628 case ERROR_CAMERA_DEVICE:
1629 case ERROR_CAMERA_SERVICE:
1630 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001631 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1632 // We keep this switch since this block might be encountered with
1633 // more than just 2 states. The default fallthrough could have us
1634 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001635 switch (errorCode) {
1636 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001637 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001638 break;
1639 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001640 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001641 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001642 break;
1643 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001644 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001645 break;
1646 }
1647 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1648 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1649 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001650 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001651 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001652 msg->post();
1653 break;
1654 }
1655 case ERROR_CAMERA_REQUEST:
1656 case ERROR_CAMERA_RESULT:
1657 case ERROR_CAMERA_BUFFER:
1658 dev->onCaptureErrorLocked(errorCode, resultExtras);
1659 break;
1660 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001661 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001662}
1663
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001664binder::Status
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -07001665CameraDevice::ServiceCallback::onClientSharedAccessPriorityChanged(bool primaryClient) {
1666 ALOGV("onClientSharedAccessPriorityChanged received. primaryClient = %d", primaryClient);
1667 binder::Status ret = binder::Status::ok();
1668 if (!flags::camera_multi_client()) {
1669 return ret;
1670 }
1671 sp<CameraDevice> dev = mDevice.promote();
1672 if (dev == nullptr) {
1673 return ret; // device has been closed
1674 }
1675 Mutex::Autolock _l(dev->mDeviceLock);
1676 if (dev->isClosed() || dev->mRemote == nullptr) {
1677 return ret;
1678 }
1679 dev->setPrimaryClient(primaryClient);
1680 sp<AMessage> msg = new AMessage(kWhatClientSharedAccessPriorityChanged, dev->mHandler);
1681 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1682 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
1683 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onClientSharedAccessPriorityChanged);
1684 msg->post();
1685
1686 return binder::Status::ok();
1687}
1688
1689binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001690CameraDevice::ServiceCallback::onDeviceIdle() {
1691 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001692 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001693 sp<CameraDevice> dev = mDevice.promote();
1694 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001695 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001696 }
1697
1698 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001699 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001700 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001701 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001702
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001703 dev->removeCompletedCallbackHolderLocked(
1704 std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1705
Yin-Chia Yehead91462016-01-06 16:45:08 -08001706 if (dev->mIdle) {
1707 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001708 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001709 }
1710
1711 if (dev->mCurrentSession != nullptr) {
1712 ALOGE("onDeviceIdle sending state cb");
1713 if (dev->mBusySession != dev->mCurrentSession) {
1714 ALOGE("Current session != busy session");
1715 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001716 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001717 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001718
Yin-Chia Yehead91462016-01-06 16:45:08 -08001719 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1720 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1721 msg->setObject(kSessionSpKey, dev->mBusySession);
1722 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1723 // Make sure we clear the sp first so the session destructor can
1724 // only happen on handler thread (where we don't hold device/session lock)
1725 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001726 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001727 }
1728 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001729 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001730 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001731}
1732
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001733binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001734CameraDevice::ServiceCallback::onCaptureStarted(
1735 const CaptureResultExtras& resultExtras,
1736 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001737 binder::Status ret = binder::Status::ok();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001738 sp<CameraDevice> dev = mDevice.promote();
1739 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001740 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001741 }
1742 Mutex::Autolock _l(dev->mDeviceLock);
1743 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001744 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001745 }
1746
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001747 dev->removeCompletedCallbackHolderLocked(
1748 resultExtras.lastCompletedRegularFrameNumber);
1749
Yin-Chia Yehead91462016-01-06 16:45:08 -08001750 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001751 int32_t burstId = resultExtras.burstId;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001752 int64_t frameNumber = resultExtras.frameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001753
1754 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1755 if (it != dev->mSequenceCallbackMap.end()) {
1756 CallbackHolder cbh = (*it).second;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001757 bool v2Callback = cbh.mIs2Callback;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001758 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001759 ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001760 sp<ACameraCaptureSession> session = cbh.mSession;
1761 if ((size_t) burstId >= cbh.mRequests.size()) {
1762 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1763 __FUNCTION__, burstId, cbh.mRequests.size());
1764 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1765 }
1766 sp<CaptureRequest> request = cbh.mRequests[burstId];
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001767 sp<AMessage> msg = nullptr;
1768 if (v2Callback) {
1769 msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
1770 msg->setPointer(kCallbackFpKey, (void*) onStart2);
1771 } else {
1772 msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1773 msg->setPointer(kCallbackFpKey, (void *)onStart);
1774 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001775 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001776 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001777 msg->setObject(kCaptureRequestKey, request);
1778 msg->setInt64(kTimeStampKey, timestamp);
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001779 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001780 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001781 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001782 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001783}
1784
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001785binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001786CameraDevice::ServiceCallback::onResultReceived(
1787 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001788 const CaptureResultExtras& resultExtras,
1789 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001790 binder::Status ret = binder::Status::ok();
1791
Yin-Chia Yehead91462016-01-06 16:45:08 -08001792 sp<CameraDevice> dev = mDevice.promote();
1793 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001794 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001795 }
1796 int sequenceId = resultExtras.requestId;
1797 int64_t frameNumber = resultExtras.frameNumber;
1798 int32_t burstId = resultExtras.burstId;
1799 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1800
1801 if (!isPartialResult) {
1802 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1803 }
1804
1805 Mutex::Autolock _l(dev->mDeviceLock);
1806 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001807 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001808 }
1809
1810 if (dev->isClosed()) {
1811 if (!isPartialResult) {
1812 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1813 }
1814 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001815 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001816 }
1817
1818 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001819 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001820 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001821
1822 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1823 if (it != dev->mSequenceCallbackMap.end()) {
1824 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001825 sp<ACameraCaptureSession> session = cbh.mSession;
1826 if ((size_t) burstId >= cbh.mRequests.size()) {
1827 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1828 __FUNCTION__, burstId, cbh.mRequests.size());
1829 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1830 }
1831 sp<CaptureRequest> request = cbh.mRequests[burstId];
1832 sp<ACameraMetadata> result(new ACameraMetadata(
1833 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001834 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1835 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001836
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001837 sp<AMessage> msg = new AMessage(
1838 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1839 dev->mHandler);
1840 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001841 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001842 msg->setObject(kCaptureRequestKey, request);
1843 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001844 if (isPartialResult) {
1845 msg->setPointer(kCallbackFpKey,
1846 (void *)cbh.mOnCaptureProgressed);
1847 } else if (cbh.mIsLogicalCameraCallback) {
1848 msg->setPointer(kCallbackFpKey,
1849 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1850 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1851 } else {
1852 msg->setPointer(kCallbackFpKey,
1853 (void *)cbh.mOnCaptureCompleted);
1854 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001855 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001856 }
1857
1858 if (!isPartialResult) {
1859 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1860 dev->checkAndFireSequenceCompleteLocked();
1861 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001862
1863 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001864}
1865
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001866binder::Status
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001867CameraDevice::ServiceCallback::onPrepared(int streamId) {
1868 ALOGV("%s: callback for stream id %d", __FUNCTION__, streamId);
1869 binder::Status ret = binder::Status::ok();
1870 sp<CameraDevice> dev = mDevice.promote();
1871 if (dev == nullptr) {
1872 return ret; // device has been closed
1873 }
1874 Mutex::Autolock _l(dev->mDeviceLock);
1875 if (dev->isClosed() || dev->mRemote == nullptr) {
1876 return ret;
1877 }
1878 auto it = dev->mConfiguredOutputs.find(streamId);
1879 if (it == dev->mConfiguredOutputs.end()) {
1880 ALOGE("%s: stream id %d does not exist", __FUNCTION__ , streamId);
1881 return ret;
1882 }
1883 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
1884 if (session == nullptr) {
1885 ALOGE("%s: Session is dead already", __FUNCTION__ );
1886 return ret;
1887 }
1888 // We've found the window corresponding to the surface id.
Avichal Rakesh8effe982023-11-13 18:53:40 -08001889 ANativeWindow *window = it->second.first;
Jayant Chowdhary09b368b2023-02-13 06:53:05 +00001890 sp<AMessage> msg = new AMessage(kWhatPreparedCb, dev->mHandler);
1891 msg->setPointer(kContextKey, session->mPreparedCb.context);
1892 msg->setPointer(kAnwKey, window);
1893 msg->setObject(kSessionSpKey, session);
1894 msg->setPointer(kCallbackFpKey, (void *)session->mPreparedCb.onWindowPrepared);
1895 dev->postSessionMsgAndCleanup(msg);
1896
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001897 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001898}
1899
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001900binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001901CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1902 // onRequestQueueEmpty not yet implemented in NDK
1903 return binder::Status::ok();
1904}
1905
1906binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001907CameraDevice::ServiceCallback::onRepeatingRequestError(
1908 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001909 binder::Status ret = binder::Status::ok();
1910
1911 sp<CameraDevice> dev = mDevice.promote();
1912 if (dev == nullptr) {
1913 return ret; // device has been closed
1914 }
1915
1916 Mutex::Autolock _l(dev->mDeviceLock);
1917
1918 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001919 if (stoppedSequenceId == repeatingSequenceId) {
1920 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1921 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001922
1923 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1924
1925 return ret;
1926}
1927
Shuzhen Wangacae2642020-12-21 17:11:37 -08001928void
1929CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
1930 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1931 if (cbIt != mSequenceCallbackMap.end()) {
1932 CallbackHolder cbh = cbIt->second;
1933 mSequenceCallbackMap.erase(cbIt);
1934
1935 // send seq complete callback
1936 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1937 msg->setPointer(kContextKey, cbh.mContext);
1938 msg->setObject(kSessionSpKey, cbh.mSession);
1939 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1940 msg->setInt32(kSequenceIdKey, sequenceId);
1941 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1942
1943 // Clear the session sp before we send out the message
1944 // This will guarantee the rare case where the message is processed
1945 // before cbh goes out of scope and causing we call the session
1946 // destructor while holding device lock
1947 cbh.mSession.clear();
1948 postSessionMsgAndCleanup(msg);
1949 } else {
1950 // Check if there is callback for this sequence
1951 // This should not happen because we always register callback (with nullptr inside)
1952 ALOGW("No callback found for sequenceId %d", sequenceId);
1953 }
1954}
1955
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001956} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001957} // namespace android