blob: b3de17d92aeaf2fc18dfb4b53893e61a3c94fe24 [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 Borger0fb3ad92023-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"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080029
Jayant Chowdharya8488c92019-06-21 12:45:34 -070030ACameraDevice::~ACameraDevice() {
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -070031 mDevice->stopLooperAndDisconnect();
Jayant Chowdharya8488c92019-06-21 12:45:34 -070032}
33
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080034namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080035namespace acam {
36
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080037// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080038const char* CameraDevice::kContextKey = "Context";
39const char* CameraDevice::kDeviceKey = "Device";
40const char* CameraDevice::kErrorCodeKey = "ErrorCode";
41const char* CameraDevice::kCallbackFpKey = "Callback";
42const char* CameraDevice::kSessionSpKey = "SessionSp";
43const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
44const char* CameraDevice::kTimeStampKey = "TimeStamp";
45const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080046const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080047const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
48const char* CameraDevice::kSequenceIdKey = "SequenceId";
49const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070050const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070051const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080052
53/**
54 * CameraDevice Implementation
55 */
56CameraDevice::CameraDevice(
57 const char* id,
58 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070059 sp<ACameraMetadata> chars,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080060 ACameraDevice* wrapper) :
61 mCameraId(id),
62 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070063 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 mServiceCallback(new ServiceCallback(this)),
65 mWrapper(wrapper),
66 mInError(false),
67 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070068 mIdle(true),
69 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080070 mClosing = false;
71 // Setup looper thread to perfrom device callbacks to app
72 mCbLooper = new ALooper;
73 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080074 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080075 /*runOnCallingThread*/false,
76 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080077 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080078 if (err != OK) {
79 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
80 __FUNCTION__, strerror(-err), err);
81 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
82 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080083 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080084 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080085
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080086 const CameraMetadata& metadata = mChars->getInternalData();
87 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080088 if (entry.count != 1) {
89 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
90 mPartialResultCount = 1;
91 } else {
92 mPartialResultCount = entry.data.i32[0];
93 }
94
95 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
96 if (entry.count != 2) {
97 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
98 mShadingMapSize[0] = 0;
99 mShadingMapSize[1] = 0;
100 } else {
101 mShadingMapSize[0] = entry.data.i32[0];
102 mShadingMapSize[1] = entry.data.i32[1];
103 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800104
105 size_t physicalIdCnt = 0;
106 const char*const* physicalCameraIds;
107 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
108 for (size_t i = 0; i < physicalIdCnt; i++) {
109 mPhysicalIds.push_back(physicalCameraIds[i]);
110 }
111 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800112}
113
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700114CameraDevice::~CameraDevice() { }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800115
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700116void
117CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
118 msg->post();
119 msg.clear();
120 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
121 cleanupMsg->post();
122}
123
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800124// TODO: cached created request?
125camera_status_t
126CameraDevice::createCaptureRequest(
127 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800128 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800129 ACaptureRequest** request) const {
130 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800131
132 if (physicalIdList != nullptr) {
133 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
134 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
135 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
136 return ACAMERA_ERROR_INVALID_PARAMETER;
137 }
138 for (auto i = 0; i < physicalIdList->numCameras; i++) {
139 if (physicalIdList->cameraIds[i] == nullptr) {
140 ALOGE("%s: physicalId is null!", __FUNCTION__);
141 return ACAMERA_ERROR_INVALID_PARAMETER;
142 }
143 if (mPhysicalIds.end() == std::find(
144 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
145 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
146 return ACAMERA_ERROR_INVALID_PARAMETER;
147 }
148 }
149 }
150
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800151 camera_status_t ret = checkCameraClosedOrErrorLocked();
152 if (ret != ACAMERA_OK) {
153 return ret;
154 }
155 if (mRemote == nullptr) {
156 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
157 }
158 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800159 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
160 if (remoteRet.serviceSpecificErrorCode() ==
161 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800162 ALOGW("Create capture request failed! template %d is not supported on this device",
163 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700164 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800165 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000166 ALOGE("Create capture request failed: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800167 return ACAMERA_ERROR_UNKNOWN;
168 }
169 ACaptureRequest* outReq = new ACaptureRequest();
170 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800171 if (physicalIdList != nullptr) {
172 for (auto i = 0; i < physicalIdList->numCameras; i++) {
173 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
174 new ACameraMetadata(*(outReq->settings)));
175 }
176 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800177 outReq->targets = new ACameraOutputTargets();
178 *request = outReq;
179 return ACAMERA_OK;
180}
181
Yin-Chia Yehead91462016-01-06 16:45:08 -0800182camera_status_t
183CameraDevice::createCaptureSession(
184 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100185 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800186 const ACameraCaptureSession_stateCallbacks* callbacks,
187 /*out*/ACameraCaptureSession** session) {
Shuzhen Wang316781a2020-08-18 18:11:01 -0700188 nsecs_t startTimeNs = systemTime();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700189 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800190 Mutex::Autolock _l(mDeviceLock);
191 camera_status_t ret = checkCameraClosedOrErrorLocked();
192 if (ret != ACAMERA_OK) {
193 return ret;
194 }
195
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700196 if (currentSession != nullptr) {
197 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800198 stopRepeatingLocked();
199 }
200
201 // Create new session
Shuzhen Wang316781a2020-08-18 18:11:01 -0700202 ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800203 if (ret != ACAMERA_OK) {
204 ALOGE("Fail to create new session. cannot configure streams");
205 return ret;
206 }
207
208 ACameraCaptureSession* newSession = new ACameraCaptureSession(
209 mNextSessionId++, outputs, callbacks, this);
210
Yin-Chia Yehead91462016-01-06 16:45:08 -0800211 // set new session as current session
212 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
213 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700214 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800215 *session = newSession;
216 return ACAMERA_OK;
217}
218
Shuzhen Wang24810e72019-03-18 10:55:01 -0700219camera_status_t CameraDevice::isSessionConfigurationSupported(
220 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
221 Mutex::Autolock _l(mDeviceLock);
222 camera_status_t ret = checkCameraClosedOrErrorLocked();
223 if (ret != ACAMERA_OK) {
224 return ret;
225 }
226
227 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
228 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
229 for (const auto& output : sessionOutputContainer->mOutputs) {
230 sp<IGraphicBufferProducer> iGBP(nullptr);
231 ret = getIGBPfromAnw(output.mWindow, iGBP);
232 if (ret != ACAMERA_OK) {
233 ALOGE("Camera device %s failed to extract graphic producer from native window",
234 getId());
235 return ret;
236 }
237
Austin Borger0fb3ad92023-06-01 16:51:35 -0700238 OutputConfiguration outConfig(iGBP, output.mRotation, output.mPhysicalCameraId,
Shuzhen Wang24810e72019-03-18 10:55:01 -0700239 OutputConfiguration::INVALID_SET_ID, true);
240
241 for (auto& anw : output.mSharedWindows) {
242 ret = getIGBPfromAnw(anw, iGBP);
243 if (ret != ACAMERA_OK) {
244 ALOGE("Camera device %s failed to extract graphic producer from native window",
245 getId());
246 return ret;
247 }
248 outConfig.addGraphicProducer(iGBP);
249 }
250
251 sessionConfiguration.addOutputConfiguration(outConfig);
252 }
253
254 bool supported = false;
255 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
256 sessionConfiguration, &supported);
257 if (remoteRet.serviceSpecificErrorCode() ==
258 hardware::ICameraService::ERROR_INVALID_OPERATION) {
259 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
260 } else if (!remoteRet.isOk()) {
261 return ACAMERA_ERROR_UNKNOWN;
262 } else {
263 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
264 }
265}
266
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800267camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100268 camera_status_t ret = checkCameraClosedOrErrorLocked();
269 if (ret != ACAMERA_OK) {
270 return ret;
271 }
272
273 if (output == nullptr) {
274 return ACAMERA_ERROR_INVALID_PARAMETER;
275 }
276
277 if (!output->mIsShared) {
278 ALOGE("Error output configuration is not shared");
279 return ACAMERA_ERROR_INVALID_OPERATION;
280 }
281
282 int32_t streamId = -1;
283 for (auto& kvPair : mConfiguredOutputs) {
284 if (kvPair.second.first == output->mWindow) {
285 streamId = kvPair.first;
286 break;
287 }
288 }
289 if (streamId < 0) {
290 ALOGE("Error: Invalid output configuration");
291 return ACAMERA_ERROR_INVALID_PARAMETER;
292 }
293
294 sp<IGraphicBufferProducer> iGBP(nullptr);
295 ret = getIGBPfromAnw(output->mWindow, iGBP);
296 if (ret != ACAMERA_OK) {
297 ALOGE("Camera device %s failed to extract graphic producer from native window",
298 getId());
299 return ret;
300 }
301
Austin Borger0fb3ad92023-06-01 16:51:35 -0700302 OutputConfiguration outConfig(iGBP, output->mRotation, output->mPhysicalCameraId,
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800303 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100304
305 for (auto& anw : output->mSharedWindows) {
306 ret = getIGBPfromAnw(anw, iGBP);
307 if (ret != ACAMERA_OK) {
308 ALOGE("Camera device %s failed to extract graphic producer from native window",
309 getId());
310 return ret;
311 }
312 outConfig.addGraphicProducer(iGBP);
313 }
314
315 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
316 if (!remoteRet.isOk()) {
317 switch (remoteRet.serviceSpecificErrorCode()) {
318 case hardware::ICameraService::ERROR_INVALID_OPERATION:
319 ALOGE("Camera device %s invalid operation: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000320 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100321 return ACAMERA_ERROR_INVALID_OPERATION;
322 break;
323 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
324 ALOGE("Camera device %s output surface already exists: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000325 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100326 return ACAMERA_ERROR_INVALID_PARAMETER;
327 break;
328 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
329 ALOGE("Camera device %s invalid input argument: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000330 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100331 return ACAMERA_ERROR_INVALID_PARAMETER;
332 break;
333 default:
334 ALOGE("Camera device %s failed to add shared output: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000335 remoteRet.toString8().c_str());
Emilian Peev40ead602017-09-26 15:46:36 +0100336 return ACAMERA_ERROR_UNKNOWN;
337 }
338 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800339 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100340
341 return ACAMERA_OK;
342}
343
Yin-Chia Yehead91462016-01-06 16:45:08 -0800344camera_status_t
345CameraDevice::allocateCaptureRequest(
346 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
347 camera_status_t ret;
348 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800349 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000350 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800351 for (auto& entry : request->physicalSettings) {
352 req->mPhysicalCameraSettings.push_back({entry.first,
353 entry.second->getInternalData()});
354 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800355 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700356 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800357 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800358
359 for (auto outputTarget : request->targets->mOutputs) {
360 ANativeWindow* anw = outputTarget.mWindow;
361 sp<Surface> surface;
362 ret = getSurfaceFromANativeWindow(anw, surface);
363 if (ret != ACAMERA_OK) {
364 ALOGE("Bad output target in capture request! ret %d", ret);
365 return ret;
366 }
367 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800368
369 bool found = false;
370 // lookup stream/surface ID
371 for (const auto& kvPair : mConfiguredOutputs) {
372 int streamId = kvPair.first;
373 const OutputConfiguration& outConfig = kvPair.second.second;
374 const auto& gbps = outConfig.getGraphicBufferProducers();
375 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
376 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
377 found = true;
378 req->mStreamIdxList.push_back(streamId);
379 req->mSurfaceIdxList.push_back(surfaceId);
380 break;
381 }
382 }
383 if (found) {
384 break;
385 }
386 }
387 if (!found) {
388 ALOGE("Unconfigured output target %p in capture request!", anw);
389 return ret;
390 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800391 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800392
Yin-Chia Yehead91462016-01-06 16:45:08 -0800393 outReq = req;
394 return ACAMERA_OK;
395}
396
397ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800398CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800399 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800400 for (auto& entry : req->mPhysicalCameraSettings) {
401 CameraMetadata clone = entry.settings;
402 if (entry.id == deviceId) {
403 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
404 } else {
405 pRequest->physicalSettings.emplace(entry.id,
406 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
407 }
408 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800409 pRequest->targets = new ACameraOutputTargets();
410 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
411 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
412 ACameraOutputTarget outputTarget(anw);
413 pRequest->targets->mOutputs.insert(outputTarget);
414 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700415 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800416 return pRequest;
417}
418
419void
420CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
421 if (req == nullptr) {
422 return;
423 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700424 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800425 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800426 delete req->targets;
427 delete req;
428}
429
430void
431CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
432 if (isClosed()) {
433 // Device is closing already. do nothing
434 return;
435 }
436
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700437 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800438 // Session has been replaced by other seesion or device is closed
439 return;
440 }
441 mCurrentSession = nullptr;
442
443 // Should not happen
444 if (!session->mIsClosed) {
445 ALOGE("Error: unclosed session %p reaches end of life!", session);
446 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
447 return;
448 }
449
450 // No new session, unconfigure now
Shuzhen Wang316781a2020-08-18 18:11:01 -0700451 // Note: The unconfiguration of session won't be accounted for session
452 // latency because a stream configuration with 0 streams won't ever become
453 // active.
454 nsecs_t startTimeNs = systemTime();
455 camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800456 if (ret != ACAMERA_OK) {
457 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
458 }
459}
460
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800461void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700462CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800463 if (mClosing.exchange(true)) {
464 // Already closing, just return
465 ALOGW("Camera device %s is already closing.", getId());
466 return;
467 }
468
469 if (mRemote != nullptr) {
470 mRemote->disconnect();
471 }
472 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800473
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700474 if (session != nullptr) {
475 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800476 }
477}
478
479camera_status_t
480CameraDevice::stopRepeatingLocked() {
481 camera_status_t ret = checkCameraClosedOrErrorLocked();
482 if (ret != ACAMERA_OK) {
483 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
484 return ret;
485 }
486 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
487 int repeatingSequenceId = mRepeatingSequenceId;
488 mRepeatingSequenceId = REQUEST_ID_NONE;
489
490 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800491 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700492 if (remoteRet.serviceSpecificErrorCode() ==
493 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
494 ALOGV("Repeating request is already stopped.");
495 return ACAMERA_OK;
496 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000497 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800498 return ACAMERA_ERROR_UNKNOWN;
499 }
500 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
501 }
502 return ACAMERA_OK;
503}
504
505camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700506CameraDevice::flushLocked(ACameraCaptureSession* session) {
507 camera_status_t ret = checkCameraClosedOrErrorLocked();
508 if (ret != ACAMERA_OK) {
509 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
510 return ret;
511 }
512
513 // This should never happen because creating a new session will close
514 // previous one and thus reject any API call from previous session.
515 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700516 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700517 ALOGE("Camera %s session %p is not current active session!", getId(), session);
518 return ACAMERA_ERROR_INVALID_OPERATION;
519 }
520
521 if (mFlushing) {
522 ALOGW("Camera %s is already aborting captures", getId());
523 return ACAMERA_OK;
524 }
525
526 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700527
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700528 // Send onActive callback to guarantee there is always active->ready transition
529 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
530 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
531 msg->setObject(kSessionSpKey, session);
532 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700533 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700534
535 // If device is already idling, send callback and exit early
536 if (mIdle) {
537 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
538 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
539 msg->setObject(kSessionSpKey, session);
540 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700541 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700542 mFlushing = false;
543 return ACAMERA_OK;
544 }
545
546 int64_t lastFrameNumber;
547 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
548 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000549 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().c_str());
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700550 return ACAMERA_ERROR_UNKNOWN;
551 }
552 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
553 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
554 }
555 return ACAMERA_OK;
556}
557
558camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800559CameraDevice::waitUntilIdleLocked() {
560 camera_status_t ret = checkCameraClosedOrErrorLocked();
561 if (ret != ACAMERA_OK) {
562 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
563 return ret;
564 }
565
566 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
567 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
568 return ACAMERA_ERROR_INVALID_OPERATION;
569 }
570
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800571 binder::Status remoteRet = mRemote->waitUntilIdle();
572 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000573 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800574 // TODO: define a function to convert status_t -> camera_status_t
575 return ACAMERA_ERROR_UNKNOWN;
576 }
577
578 return ACAMERA_OK;
579}
580
581camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700582CameraDevice::getIGBPfromAnw(
583 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800584 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800585 sp<Surface> surface;
586 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
587 if (ret != ACAMERA_OK) {
588 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800589 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800590 out = surface->getIGraphicBufferProducer();
591 return ACAMERA_OK;
592}
593
594camera_status_t
595CameraDevice::getSurfaceFromANativeWindow(
596 ANativeWindow* anw, sp<Surface>& out) {
597 if (anw == nullptr) {
598 ALOGE("Error: output ANativeWindow is null");
599 return ACAMERA_ERROR_INVALID_PARAMETER;
600 }
601 int value;
602 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800603 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800604 ALOGE("Error: ANativeWindow is not backed by Surface!");
605 return ACAMERA_ERROR_INVALID_PARAMETER;
606 }
607 sp<Surface> surface(static_cast<Surface*>(anw));
608 out = surface;
609 return ACAMERA_OK;
610}
611
612camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100613CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700614 const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800615 ACaptureSessionOutputContainer emptyOutput;
616 if (outputs == nullptr) {
617 outputs = &emptyOutput;
618 }
619
Yin-Chia Yehead91462016-01-06 16:45:08 -0800620 camera_status_t ret = checkCameraClosedOrErrorLocked();
621 if (ret != ACAMERA_OK) {
622 return ret;
623 }
624
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700625 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800626 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700627 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800628 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700629 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800630 if (ret != ACAMERA_OK) {
631 return ret;
632 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700633 outputSet.insert(std::make_pair(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700634 anw, OutputConfiguration(iGBP, outConfig.mRotation, outConfig.mPhysicalCameraId,
Emilian Peev40ead602017-09-26 15:46:36 +0100635 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800636 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700637 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800638 std::vector<int> deleteList;
639
640 // Determine which streams need to be created, which to be deleted
641 for (auto& kvPair : mConfiguredOutputs) {
642 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700643 auto& outputPair = kvPair.second;
644 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800645 deleteList.push_back(streamId); // Need to delete a no longer needed stream
646 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700647 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800648 }
649 }
650
651 ret = stopRepeatingLocked();
652 if (ret != ACAMERA_OK) {
653 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
654 return ret;
655 }
656
657 ret = waitUntilIdleLocked();
658 if (ret != ACAMERA_OK) {
659 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
660 return ret;
661 }
662
663 // Send onReady to previous session
664 // CurrentSession will be updated after configureStreamLocked, so here
665 // mCurrentSession is the session to be replaced by a new session
666 if (!mIdle && mCurrentSession != nullptr) {
667 if (mBusySession != mCurrentSession) {
668 ALOGE("Current session != busy session");
669 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
670 return ACAMERA_ERROR_CAMERA_DEVICE;
671 }
672 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
673 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
674 msg->setObject(kSessionSpKey, mBusySession);
675 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
676 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700677 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800678 }
679 mIdle = true;
680
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800681 binder::Status remoteRet = mRemote->beginConfigure();
682 if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000683 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800684 return ACAMERA_ERROR_UNKNOWN;
685 }
686
687 // delete to-be-deleted streams
688 for (auto streamId : deleteList) {
689 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800690 if (!remoteRet.isOk()) {
691 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000692 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800693 return ACAMERA_ERROR_UNKNOWN;
694 }
695 mConfiguredOutputs.erase(streamId);
696 }
697
698 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800699 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800700 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700701 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800702 if (!remoteRet.isOk()) {
703 ALOGE("Camera device %s failed to create stream: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000704 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800705 return ACAMERA_ERROR_UNKNOWN;
706 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700707 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800708 }
709
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100710 CameraMetadata params;
711 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
712 params.append(sessionParameters->settings->getInternalData());
713 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800714 std::vector<int> offlineStreamIds;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700715 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
716 ns2ms(startTimeNs), &offlineStreamIds);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800717 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
718 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000719 remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800720 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800721 } else if (!remoteRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000722 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().c_str());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800723 return ACAMERA_ERROR_UNKNOWN;
724 }
725
726 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800727}
728
729void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800730CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800731 Mutex::Autolock _l(mDeviceLock);
732 mRemote = remote;
733}
734
735camera_status_t
736CameraDevice::checkCameraClosedOrErrorLocked() const {
737 if (mRemote == nullptr) {
738 ALOGE("%s: camera device already closed", __FUNCTION__);
739 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
740 }
741 if (mInError) {// triggered by onDeviceError
742 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
743 return mError;
744 }
745 return ACAMERA_OK;
746}
747
748void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800749CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
750 mInError = true;
751 mError = error;
752 return;
753}
754
755void
756CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
757 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
758 if (isError) {
759 mFutureErrorSet.insert(frameNumber);
760 } else if (frameNumber <= mCompletedFrameNumber) {
761 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
762 frameNumber, mCompletedFrameNumber);
763 return;
764 } else {
765 if (frameNumber != mCompletedFrameNumber + 1) {
766 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
767 mCompletedFrameNumber + 1, frameNumber);
768 // Do not assert as in java implementation
769 }
770 mCompletedFrameNumber = frameNumber;
771 }
772 update();
773}
774
775void
776CameraDevice::FrameNumberTracker::update() {
777 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
778 int64_t errorFrameNumber = *it;
779 if (errorFrameNumber == mCompletedFrameNumber + 1) {
780 mCompletedFrameNumber++;
781 it = mFutureErrorSet.erase(it);
782 } else if (errorFrameNumber <= mCompletedFrameNumber) {
783 // This should not happen, but deal with it anyway
784 ALOGE("Completd frame number passed through current frame number!");
785 // erase the old error since it's no longer useful
786 it = mFutureErrorSet.erase(it);
787 } else {
788 // Normal requests hasn't catched up error frames, just break
789 break;
790 }
791 }
792 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
793}
794
795void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800796CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800797 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800798 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800799 int sequenceId = resultExtras.requestId;
800 int64_t frameNumber = resultExtras.frameNumber;
801 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700802 auto it = mSequenceCallbackMap.find(sequenceId);
803 if (it == mSequenceCallbackMap.end()) {
804 ALOGE("%s: Error: capture sequence index %d not found!",
805 __FUNCTION__, sequenceId);
806 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800807 return;
808 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700809
810 CallbackHolder cbh = (*it).second;
811 sp<ACameraCaptureSession> session = cbh.mSession;
812 if ((size_t) burstId >= cbh.mRequests.size()) {
813 ALOGE("%s: Error: request index %d out of bound (size %zu)",
814 __FUNCTION__, burstId, cbh.mRequests.size());
815 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
816 return;
817 }
818 sp<CaptureRequest> request = cbh.mRequests[burstId];
819
820 // Handle buffer error
821 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
822 int32_t streamId = resultExtras.errorStreamId;
823 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800824 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700825 auto outputPairIt = mConfiguredOutputs.find(streamId);
826 if (outputPairIt == mConfiguredOutputs.end()) {
827 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800828 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
829 return;
830 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700831
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800832 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
833 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800834 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800835 if (surface->getIGraphicBufferProducer() == outGbp) {
836 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
837 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
838 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700839
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800840 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800841 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800842 msg->setObject(kSessionSpKey, session);
843 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
844 msg->setObject(kCaptureRequestKey, request);
845 msg->setPointer(kAnwKey, (void*) anw);
846 msg->setInt64(kFrameNumberKey, frameNumber);
847 postSessionMsgAndCleanup(msg);
848 }
849 }
850 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700851 } else { // Handle other capture failures
852 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800853 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800854 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
855 failure->frameNumber = frameNumber;
856 // TODO: refine this when implementing flush
857 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
858 failure->sequenceId = sequenceId;
859 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800860 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800861
Emilian Peevedec62d2019-03-19 17:59:24 -0700862 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
863 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800864 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800865 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700866 if (cbh.mIsLogicalCameraCallback) {
867 if (resultExtras.errorPhysicalCameraId.size() > 0) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700868 String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000869 msg->setString(kFailingPhysicalCameraId, cameraId.c_str(), cameraId.size());
Emilian Peevedec62d2019-03-19 17:59:24 -0700870 }
871 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
872 } else {
873 msg->setPointer(kCallbackFpKey, (void*) onError);
874 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800875 msg->setObject(kCaptureRequestKey, request);
876 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700877 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800878
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700879 // Update tracker
880 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
881 checkAndFireSequenceCompleteLocked();
882 }
883 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800884}
885
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700886void CameraDevice::stopLooperAndDisconnect() {
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700887 Mutex::Autolock _l(mDeviceLock);
Jayant Chowdharya8bf1c62019-09-26 08:50:17 -0700888 sp<ACameraCaptureSession> session = mCurrentSession.promote();
889 if (!isClosed()) {
890 disconnectLocked(session);
891 }
892 mCurrentSession = nullptr;
893
Jayant Chowdharya8488c92019-06-21 12:45:34 -0700894 if (mCbLooper != nullptr) {
895 mCbLooper->unregisterHandler(mHandler->id());
896 mCbLooper->stop();
897 }
898 mCbLooper.clear();
899 mHandler.clear();
900}
901
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800902CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
903}
904
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800905void CameraDevice::CallbackHandler::onMessageReceived(
906 const sp<AMessage> &msg) {
907 switch (msg->what()) {
908 case kWhatOnDisconnected:
909 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800910 case kWhatSessionStateCb:
911 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +0000912 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800913 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800914 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800915 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700916 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800917 case kWhatCaptureSeqEnd:
918 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700919 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800920 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800921 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700922 case kWhatCleanUpSessions:
923 mCachedSessions.clear();
924 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800925 default:
926 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
927 return;
928 }
929 // Check the common part of all message
930 void* context;
931 bool found = msg->findPointer(kContextKey, &context);
932 if (!found) {
933 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
934 return;
935 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800936 switch (msg->what()) {
937 case kWhatOnDisconnected:
938 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800939 ACameraDevice* dev;
940 found = msg->findPointer(kDeviceKey, (void**) &dev);
941 if (!found || dev == nullptr) {
942 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
943 return;
944 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800945 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800946 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800947 if (!found) {
948 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
949 return;
950 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800951 if (onDisconnected == nullptr) {
952 return;
953 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800954 (*onDisconnected)(context, dev);
955 break;
956 }
957 case kWhatOnError:
958 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800959 ACameraDevice* dev;
960 found = msg->findPointer(kDeviceKey, (void**) &dev);
961 if (!found || dev == nullptr) {
962 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
963 return;
964 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800965 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800966 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800967 if (!found) {
968 ALOGE("%s: Cannot find onError!", __FUNCTION__);
969 return;
970 }
971 int errorCode;
972 found = msg->findInt32(kErrorCodeKey, &errorCode);
973 if (!found) {
974 ALOGE("%s: Cannot find error code!", __FUNCTION__);
975 return;
976 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800977 if (onError == nullptr) {
978 return;
979 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800980 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800981 break;
982 }
983 case kWhatSessionStateCb:
984 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +0000985 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800986 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800987 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800988 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700989 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800990 case kWhatCaptureSeqEnd:
991 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700992 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800993 {
994 sp<RefBase> obj;
995 found = msg->findObject(kSessionSpKey, &obj);
996 if (!found || obj == nullptr) {
997 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
998 return;
999 }
1000 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001001 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001002 sp<CaptureRequest> requestSp = nullptr;
1003 switch (msg->what()) {
1004 case kWhatCaptureStart:
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001005 case kWhatCaptureStart2:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001006 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001007 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001008 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -07001009 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001010 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001011 found = msg->findObject(kCaptureRequestKey, &obj);
1012 if (!found) {
1013 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1014 return;
1015 }
1016 requestSp = static_cast<CaptureRequest*>(obj.get());
1017 break;
1018 }
1019
1020 switch (msg->what()) {
1021 case kWhatSessionStateCb:
1022 {
1023 ACameraCaptureSession_stateCallback onState;
1024 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1025 if (!found) {
1026 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1027 return;
1028 }
1029 if (onState == nullptr) {
1030 return;
1031 }
1032 (*onState)(context, session.get());
1033 break;
1034 }
1035 case kWhatCaptureStart:
1036 {
1037 ACameraCaptureSession_captureCallback_start onStart;
1038 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1039 if (!found) {
1040 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1041 return;
1042 }
1043 if (onStart == nullptr) {
1044 return;
1045 }
1046 int64_t timestamp;
1047 found = msg->findInt64(kTimeStampKey, &timestamp);
1048 if (!found) {
1049 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1050 return;
1051 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001052 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001053 (*onStart)(context, session.get(), request, timestamp);
1054 freeACaptureRequest(request);
1055 break;
1056 }
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001057 case kWhatCaptureStart2:
1058 {
1059 ACameraCaptureSession_captureCallback_startV2 onStart2;
1060 found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
1061 if (!found) {
1062 ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
1063 return;
1064 }
1065 if (onStart2 == nullptr) {
1066 return;
1067 }
1068 int64_t timestamp;
1069 found = msg->findInt64(kTimeStampKey, &timestamp);
1070 if (!found) {
1071 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1072 return;
1073 }
1074 int64_t frameNumber;
1075 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1076 if (!found) {
1077 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1078 return;
1079 }
1080
1081 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1082 (*onStart2)(context, session.get(), request, timestamp, frameNumber);
1083 freeACaptureRequest(request);
1084 break;
1085 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001086 case kWhatCaptureResult:
1087 {
1088 ACameraCaptureSession_captureCallback_result onResult;
1089 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1090 if (!found) {
1091 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1092 return;
1093 }
1094 if (onResult == nullptr) {
1095 return;
1096 }
1097
1098 found = msg->findObject(kCaptureResultKey, &obj);
1099 if (!found) {
1100 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1101 return;
1102 }
1103 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001104 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001105 (*onResult)(context, session.get(), request, result.get());
1106 freeACaptureRequest(request);
1107 break;
1108 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001109 case kWhatLogicalCaptureResult:
1110 {
1111 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1112 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1113 if (!found) {
1114 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1115 __FUNCTION__);
1116 return;
1117 }
1118 if (onResult == nullptr) {
1119 return;
1120 }
1121
1122 found = msg->findObject(kCaptureResultKey, &obj);
1123 if (!found) {
1124 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1125 return;
1126 }
1127 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1128
1129 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1130 if (!found) {
1131 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1132 return;
1133 }
1134 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1135 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1136 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1137 physicalResult->mPhysicalResultInfo;
1138
1139 std::vector<std::string> physicalCameraIds;
1140 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1141 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
Austin Borger0fb3ad92023-06-01 16:51:35 -07001142 String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001143 physicalCameraIds.push_back(physicalId8.c_str());
1144
1145 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1146 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1147 &physicalResult->mFrameNumber, /*data_count*/1);
1148 sp<ACameraMetadata> metadata =
1149 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1150 physicalMetadataCopy.push_back(metadata);
1151 }
1152
1153 std::vector<const char*> physicalCameraIdPtrs;
1154 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1155 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1156 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1157 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1158 }
1159
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001160 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001161 (*onResult)(context, session.get(), request, result.get(),
1162 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1163 physicalMetadataCopyPtrs.data());
1164 freeACaptureRequest(request);
1165 break;
1166 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001167 case kWhatCaptureFail:
1168 {
1169 ACameraCaptureSession_captureCallback_failed onFail;
1170 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1171 if (!found) {
1172 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1173 return;
1174 }
1175 if (onFail == nullptr) {
1176 return;
1177 }
1178
1179 found = msg->findObject(kCaptureFailureKey, &obj);
1180 if (!found) {
1181 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1182 return;
1183 }
1184 sp<CameraCaptureFailure> failureSp(
1185 static_cast<CameraCaptureFailure*>(obj.get()));
1186 ACameraCaptureFailure* failure =
1187 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001188 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001189 (*onFail)(context, session.get(), request, failure);
1190 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001191 break;
1192 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001193 case kWhatLogicalCaptureFail:
1194 {
1195 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1196 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1197 if (!found) {
1198 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1199 return;
1200 }
1201 if (onFail == nullptr) {
1202 return;
1203 }
1204
1205 found = msg->findObject(kCaptureFailureKey, &obj);
1206 if (!found) {
1207 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1208 return;
1209 }
1210 sp<CameraCaptureFailure> failureSp(
1211 static_cast<CameraCaptureFailure*>(obj.get()));
1212 ALogicalCameraCaptureFailure failure;
1213 AString physicalCameraId;
1214 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1215 if (found && !physicalCameraId.empty()) {
1216 failure.physicalCameraId = physicalCameraId.c_str();
1217 } else {
1218 failure.physicalCameraId = nullptr;
1219 }
1220 failure.captureFailure = *failureSp;
1221 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1222 (*onFail)(context, session.get(), request, &failure);
1223 freeACaptureRequest(request);
1224 break;
1225 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001226 case kWhatCaptureSeqEnd:
1227 {
1228 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1229 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1230 if (!found) {
1231 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1232 return;
1233 }
1234 if (onSeqEnd == nullptr) {
1235 return;
1236 }
1237 int seqId;
1238 found = msg->findInt32(kSequenceIdKey, &seqId);
1239 if (!found) {
1240 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1241 return;
1242 }
1243 int64_t frameNumber;
1244 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1245 if (!found) {
1246 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1247 return;
1248 }
1249 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1250 break;
1251 }
1252 case kWhatCaptureSeqAbort:
1253 {
1254 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1255 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1256 if (!found) {
1257 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1258 return;
1259 }
1260 if (onSeqAbort == nullptr) {
1261 return;
1262 }
1263 int seqId;
1264 found = msg->findInt32(kSequenceIdKey, &seqId);
1265 if (!found) {
1266 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1267 return;
1268 }
1269 (*onSeqAbort)(context, session.get(), seqId);
1270 break;
1271 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001272 case kWhatCaptureBufferLost:
1273 {
1274 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1275 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1276 if (!found) {
1277 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1278 return;
1279 }
1280 if (onBufferLost == nullptr) {
1281 return;
1282 }
1283
1284 ANativeWindow* anw;
1285 found = msg->findPointer(kAnwKey, (void**) &anw);
1286 if (!found) {
1287 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1288 return;
1289 }
1290
1291 int64_t frameNumber;
1292 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1293 if (!found) {
1294 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1295 return;
1296 }
1297
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001298 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001299 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1300 freeACaptureRequest(request);
1301 break;
1302 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001303 }
1304 break;
1305 }
1306 }
1307}
1308
1309CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001310 sp<ACameraCaptureSession> session,
1311 const Vector<sp<CaptureRequest> >& requests,
1312 bool isRepeating,
1313 ACameraCaptureSession_captureCallbacks* cbs) :
1314 mSession(session), mRequests(requests),
1315 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001316 mIsLogicalCameraCallback(false),
1317 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001318 initCaptureCallbacks(cbs);
1319
1320 if (cbs != nullptr) {
1321 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001322 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001323 }
1324}
1325
1326CameraDevice::CallbackHolder::CallbackHolder(
1327 sp<ACameraCaptureSession> session,
1328 const Vector<sp<CaptureRequest> >& requests,
1329 bool isRepeating,
1330 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1331 mSession(session), mRequests(requests),
1332 mIsRepeating(isRepeating),
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001333 mIsLogicalCameraCallback(true),
1334 mIs2Callback(false) {
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001335 initCaptureCallbacks(lcbs);
1336
1337 if (lcbs != nullptr) {
1338 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001339 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001340 }
1341}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001342
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001343CameraDevice::CallbackHolder::CallbackHolder(
1344 sp<ACameraCaptureSession> session,
1345 const Vector<sp<CaptureRequest> >& requests,
1346 bool isRepeating,
1347 ACameraCaptureSession_captureCallbacksV2* cbs) :
1348 mSession(session), mRequests(requests),
1349 mIsRepeating(isRepeating),
1350 mIsLogicalCameraCallback(false),
1351 mIs2Callback(true) {
1352 initCaptureCallbacksV2(cbs);
1353
1354 if (cbs != nullptr) {
1355 mOnCaptureCompleted = cbs->onCaptureCompleted;
1356 mOnCaptureFailed = cbs->onCaptureFailed;
1357 }
1358}
1359
1360CameraDevice::CallbackHolder::CallbackHolder(
1361 sp<ACameraCaptureSession> session,
1362 const Vector<sp<CaptureRequest> >& requests,
1363 bool isRepeating,
1364 ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
1365 mSession(session), mRequests(requests),
1366 mIsRepeating(isRepeating),
1367 mIsLogicalCameraCallback(true),
1368 mIs2Callback(true) {
1369 initCaptureCallbacksV2(lcbs);
1370
1371 if (lcbs != nullptr) {
1372 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1373 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
1374 }
1375}
1376
Yin-Chia Yehead91462016-01-06 16:45:08 -08001377void
1378CameraDevice::checkRepeatingSequenceCompleteLocked(
1379 const int sequenceId, const int64_t lastFrameNumber) {
1380 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1381 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1382 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1383 ALOGW("No callback found for sequenceId %d", sequenceId);
1384 return;
1385 }
1386 // remove callback holder from callback map
1387 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1388 CallbackHolder cbh = cbIt->second;
1389 mSequenceCallbackMap.erase(cbIt);
1390 // send seq aborted callback
1391 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001392 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001393 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001394 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001395 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001396 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001397 } else {
1398 // Use mSequenceLastFrameNumberMap to track
1399 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1400
1401 // Last frame might have arrived. Check now
1402 checkAndFireSequenceCompleteLocked();
1403 }
1404}
1405
1406void
1407CameraDevice::checkAndFireSequenceCompleteLocked() {
1408 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001409 auto it = mSequenceLastFrameNumberMap.begin();
1410 while (it != mSequenceLastFrameNumberMap.end()) {
1411 int sequenceId = it->first;
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001412 int64_t lastFrameNumber = it->second.lastFrameNumber;
1413 bool hasCallback = true;
1414
1415 if (mRemote == nullptr) {
1416 ALOGW("Camera %s closed while checking sequence complete", getId());
1417 return;
1418 }
1419 ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1420 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1421 if (!it->second.isSequenceCompleted) {
1422 // Check if there is callback for this sequence
1423 // This should not happen because we always register callback (with nullptr inside)
1424 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1425 ALOGW("No callback found for sequenceId %d", sequenceId);
1426 hasCallback = false;
1427 }
1428
1429 if (lastFrameNumber <= completedFrameNumber) {
1430 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1431 it->second.isSequenceCompleted = true;
1432 }
1433
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001434 }
1435
1436 if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001437 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
1438
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001439 it = mSequenceLastFrameNumberMap.erase(it);
1440 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1441 } else {
1442 ++it;
1443 }
1444 }
1445}
1446
1447void
1448CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1449 auto it = mSequenceLastFrameNumberMap.begin();
1450 while (it != mSequenceLastFrameNumberMap.end()) {
1451 int sequenceId = it->first;
1452 int64_t lastFrameNumber = it->second.lastFrameNumber;
Shuzhen Wang730a7912020-05-07 11:59:02 -07001453
1454 if (mRemote == nullptr) {
1455 ALOGW("Camera %s closed while checking sequence complete", getId());
1456 return;
1457 }
Shuzhen Wang730a7912020-05-07 11:59:02 -07001458
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001459 ALOGV("%s: seq %d's last frame number %" PRId64
1460 ", completed inflight frame number %" PRId64,
1461 __FUNCTION__, sequenceId, lastFrameNumber,
1462 lastCompletedRegularFrameNumber);
1463 if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1464 if (it->second.isSequenceCompleted) {
Shuzhen Wangacae2642020-12-21 17:11:37 -08001465 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
Shuzhen Wang730a7912020-05-07 11:59:02 -07001466
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001467 it = mSequenceLastFrameNumberMap.erase(it);
1468 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1469 } else {
1470 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1471 it->second.isInflightCompleted = true;
1472 ++it;
1473 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001474 } else {
1475 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001476 }
1477 }
1478}
1479
1480/**
1481 * Camera service callback implementation
1482 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001483binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001484CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001485 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001486 const CaptureResultExtras& resultExtras) {
1487 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1488 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001489 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001490 sp<CameraDevice> dev = mDevice.promote();
1491 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001492 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001493 }
1494
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001495 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001496 Mutex::Autolock _l(dev->mDeviceLock);
1497 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001498 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001499 }
1500 switch (errorCode) {
1501 case ERROR_CAMERA_DISCONNECTED:
1502 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001503 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001504 if (session != nullptr) {
1505 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001506 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001507 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001508 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1509 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1510 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001511 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001512 msg->post();
1513 break;
1514 }
1515 default:
1516 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001517 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001518 case ERROR_CAMERA_DEVICE:
1519 case ERROR_CAMERA_SERVICE:
1520 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001521 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1522 // We keep this switch since this block might be encountered with
1523 // more than just 2 states. The default fallthrough could have us
1524 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001525 switch (errorCode) {
1526 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001527 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001528 break;
1529 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001530 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001531 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001532 break;
1533 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001534 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001535 break;
1536 }
1537 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1538 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1539 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001540 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001541 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001542 msg->post();
1543 break;
1544 }
1545 case ERROR_CAMERA_REQUEST:
1546 case ERROR_CAMERA_RESULT:
1547 case ERROR_CAMERA_BUFFER:
1548 dev->onCaptureErrorLocked(errorCode, resultExtras);
1549 break;
1550 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001551 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001552}
1553
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001554binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001555CameraDevice::ServiceCallback::onDeviceIdle() {
1556 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001557 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001558 sp<CameraDevice> dev = mDevice.promote();
1559 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001560 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001561 }
1562
1563 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001564 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001565 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001566 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001567
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001568 dev->removeCompletedCallbackHolderLocked(
1569 std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1570
Yin-Chia Yehead91462016-01-06 16:45:08 -08001571 if (dev->mIdle) {
1572 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001573 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001574 }
1575
1576 if (dev->mCurrentSession != nullptr) {
1577 ALOGE("onDeviceIdle sending state cb");
1578 if (dev->mBusySession != dev->mCurrentSession) {
1579 ALOGE("Current session != busy session");
1580 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001581 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001582 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001583
Yin-Chia Yehead91462016-01-06 16:45:08 -08001584 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1585 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1586 msg->setObject(kSessionSpKey, dev->mBusySession);
1587 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1588 // Make sure we clear the sp first so the session destructor can
1589 // only happen on handler thread (where we don't hold device/session lock)
1590 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001591 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001592 }
1593 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001594 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001595 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001596}
1597
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001598binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001599CameraDevice::ServiceCallback::onCaptureStarted(
1600 const CaptureResultExtras& resultExtras,
1601 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001602 binder::Status ret = binder::Status::ok();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001603 sp<CameraDevice> dev = mDevice.promote();
1604 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001605 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001606 }
1607 Mutex::Autolock _l(dev->mDeviceLock);
1608 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001609 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001610 }
1611
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001612 dev->removeCompletedCallbackHolderLocked(
1613 resultExtras.lastCompletedRegularFrameNumber);
1614
Yin-Chia Yehead91462016-01-06 16:45:08 -08001615 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001616 int32_t burstId = resultExtras.burstId;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001617 int64_t frameNumber = resultExtras.frameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001618
1619 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1620 if (it != dev->mSequenceCallbackMap.end()) {
1621 CallbackHolder cbh = (*it).second;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001622 bool v2Callback = cbh.mIs2Callback;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001623 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001624 ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001625 sp<ACameraCaptureSession> session = cbh.mSession;
1626 if ((size_t) burstId >= cbh.mRequests.size()) {
1627 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1628 __FUNCTION__, burstId, cbh.mRequests.size());
1629 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1630 }
1631 sp<CaptureRequest> request = cbh.mRequests[burstId];
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001632 sp<AMessage> msg = nullptr;
1633 if (v2Callback) {
1634 msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
1635 msg->setPointer(kCallbackFpKey, (void*) onStart2);
1636 } else {
1637 msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1638 msg->setPointer(kCallbackFpKey, (void *)onStart);
1639 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001640 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001641 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001642 msg->setObject(kCaptureRequestKey, request);
1643 msg->setInt64(kTimeStampKey, timestamp);
Jayant Chowdhary04ba13f2022-01-14 00:21:19 +00001644 msg->setInt64(kFrameNumberKey, frameNumber);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001645 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001646 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001647 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001648}
1649
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001650binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001651CameraDevice::ServiceCallback::onResultReceived(
1652 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001653 const CaptureResultExtras& resultExtras,
1654 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001655 binder::Status ret = binder::Status::ok();
1656
Yin-Chia Yehead91462016-01-06 16:45:08 -08001657 sp<CameraDevice> dev = mDevice.promote();
1658 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001659 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001660 }
1661 int sequenceId = resultExtras.requestId;
1662 int64_t frameNumber = resultExtras.frameNumber;
1663 int32_t burstId = resultExtras.burstId;
1664 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1665
1666 if (!isPartialResult) {
1667 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1668 }
1669
1670 Mutex::Autolock _l(dev->mDeviceLock);
1671 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001672 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001673 }
1674
1675 if (dev->isClosed()) {
1676 if (!isPartialResult) {
1677 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1678 }
1679 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001680 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001681 }
1682
1683 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001684 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001685 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001686
1687 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1688 if (it != dev->mSequenceCallbackMap.end()) {
1689 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001690 sp<ACameraCaptureSession> session = cbh.mSession;
1691 if ((size_t) burstId >= cbh.mRequests.size()) {
1692 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1693 __FUNCTION__, burstId, cbh.mRequests.size());
1694 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1695 }
1696 sp<CaptureRequest> request = cbh.mRequests[burstId];
1697 sp<ACameraMetadata> result(new ACameraMetadata(
1698 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001699 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1700 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001701
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001702 sp<AMessage> msg = new AMessage(
1703 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1704 dev->mHandler);
1705 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001706 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001707 msg->setObject(kCaptureRequestKey, request);
1708 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001709 if (isPartialResult) {
1710 msg->setPointer(kCallbackFpKey,
1711 (void *)cbh.mOnCaptureProgressed);
1712 } else if (cbh.mIsLogicalCameraCallback) {
1713 msg->setPointer(kCallbackFpKey,
1714 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1715 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1716 } else {
1717 msg->setPointer(kCallbackFpKey,
1718 (void *)cbh.mOnCaptureCompleted);
1719 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001720 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001721 }
1722
1723 if (!isPartialResult) {
1724 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1725 dev->checkAndFireSequenceCompleteLocked();
1726 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001727
1728 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001729}
1730
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001731binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001732CameraDevice::ServiceCallback::onPrepared(int) {
1733 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001734 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001735}
1736
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001737binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001738CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1739 // onRequestQueueEmpty not yet implemented in NDK
1740 return binder::Status::ok();
1741}
1742
1743binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001744CameraDevice::ServiceCallback::onRepeatingRequestError(
1745 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001746 binder::Status ret = binder::Status::ok();
1747
1748 sp<CameraDevice> dev = mDevice.promote();
1749 if (dev == nullptr) {
1750 return ret; // device has been closed
1751 }
1752
1753 Mutex::Autolock _l(dev->mDeviceLock);
1754
1755 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001756 if (stoppedSequenceId == repeatingSequenceId) {
1757 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1758 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001759
1760 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1761
1762 return ret;
1763}
1764
Shuzhen Wangacae2642020-12-21 17:11:37 -08001765void
1766CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
1767 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1768 if (cbIt != mSequenceCallbackMap.end()) {
1769 CallbackHolder cbh = cbIt->second;
1770 mSequenceCallbackMap.erase(cbIt);
1771
1772 // send seq complete callback
1773 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1774 msg->setPointer(kContextKey, cbh.mContext);
1775 msg->setObject(kSessionSpKey, cbh.mSession);
1776 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1777 msg->setInt32(kSequenceIdKey, sequenceId);
1778 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1779
1780 // Clear the session sp before we send out the message
1781 // This will guarantee the rare case where the message is processed
1782 // before cbh goes out of scope and causing we call the session
1783 // destructor while holding device lock
1784 cbh.mSession.clear();
1785 postSessionMsgAndCleanup(msg);
1786 } else {
1787 // Check if there is callback for this sequence
1788 // This should not happen because we always register callback (with nullptr inside)
1789 ALOGW("No callback found for sequenceId %d", sequenceId);
1790 }
1791}
1792
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001793} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001794} // namespace android