blob: e52f075750a9b59fd2d7eb43d49e2c7c88ea85e2 [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACameraDevice"
19
Yin-Chia Yehead91462016-01-06 16:45:08 -080020#include <vector>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080021#include <inttypes.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080022#include <android/hardware/ICameraService.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080023#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080024#include "ACameraDevice.h"
25#include "ACameraMetadata.h"
26#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080027#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080028
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080029#include "ACameraCaptureSession.inc"
30
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080032namespace acam {
33
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080034// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080035const char* CameraDevice::kContextKey = "Context";
36const char* CameraDevice::kDeviceKey = "Device";
37const char* CameraDevice::kErrorCodeKey = "ErrorCode";
38const char* CameraDevice::kCallbackFpKey = "Callback";
39const char* CameraDevice::kSessionSpKey = "SessionSp";
40const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
41const char* CameraDevice::kTimeStampKey = "TimeStamp";
42const char* CameraDevice::kCaptureResultKey = "CaptureResult";
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080043const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
Yin-Chia Yehead91462016-01-06 16:45:08 -080044const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
45const char* CameraDevice::kSequenceIdKey = "SequenceId";
46const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070047const char* CameraDevice::kAnwKey = "Anw";
Emilian Peevedec62d2019-03-19 17:59:24 -070048const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080049
50/**
51 * CameraDevice Implementation
52 */
53CameraDevice::CameraDevice(
54 const char* id,
55 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070056 sp<ACameraMetadata> chars,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080057 ACameraDevice* wrapper) :
58 mCameraId(id),
59 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070060 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080061 mServiceCallback(new ServiceCallback(this)),
62 mWrapper(wrapper),
63 mInError(false),
64 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070065 mIdle(true),
66 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080067 mClosing = false;
68 // Setup looper thread to perfrom device callbacks to app
69 mCbLooper = new ALooper;
70 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080071 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080072 /*runOnCallingThread*/false,
73 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080074 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080075 if (err != OK) {
76 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
77 __FUNCTION__, strerror(-err), err);
78 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
79 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080080 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080081 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080082
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080083 const CameraMetadata& metadata = mChars->getInternalData();
84 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080085 if (entry.count != 1) {
86 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
87 mPartialResultCount = 1;
88 } else {
89 mPartialResultCount = entry.data.i32[0];
90 }
91
92 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
93 if (entry.count != 2) {
94 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
95 mShadingMapSize[0] = 0;
96 mShadingMapSize[1] = 0;
97 } else {
98 mShadingMapSize[0] = entry.data.i32[0];
99 mShadingMapSize[1] = entry.data.i32[1];
100 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800101
102 size_t physicalIdCnt = 0;
103 const char*const* physicalCameraIds;
104 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
105 for (size_t i = 0; i < physicalIdCnt; i++) {
106 mPhysicalIds.push_back(physicalCameraIds[i]);
107 }
108 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800109}
110
Yin-Chia Yehead91462016-01-06 16:45:08 -0800111// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800112CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700113 sp<ACameraCaptureSession> session = mCurrentSession.promote();
114 {
115 Mutex::Autolock _l(mDeviceLock);
116 if (!isClosed()) {
117 disconnectLocked(session);
118 }
119 mCurrentSession = nullptr;
120 if (mCbLooper != nullptr) {
121 mCbLooper->unregisterHandler(mHandler->id());
122 mCbLooper->stop();
123 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800124 }
125 mCbLooper.clear();
126 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800127}
128
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700129void
130CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
131 msg->post();
132 msg.clear();
133 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
134 cleanupMsg->post();
135}
136
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800137// TODO: cached created request?
138camera_status_t
139CameraDevice::createCaptureRequest(
140 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800141 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800142 ACaptureRequest** request) const {
143 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800144
145 if (physicalIdList != nullptr) {
146 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
147 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
148 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
149 return ACAMERA_ERROR_INVALID_PARAMETER;
150 }
151 for (auto i = 0; i < physicalIdList->numCameras; i++) {
152 if (physicalIdList->cameraIds[i] == nullptr) {
153 ALOGE("%s: physicalId is null!", __FUNCTION__);
154 return ACAMERA_ERROR_INVALID_PARAMETER;
155 }
156 if (mPhysicalIds.end() == std::find(
157 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
158 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
159 return ACAMERA_ERROR_INVALID_PARAMETER;
160 }
161 }
162 }
163
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800164 camera_status_t ret = checkCameraClosedOrErrorLocked();
165 if (ret != ACAMERA_OK) {
166 return ret;
167 }
168 if (mRemote == nullptr) {
169 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
170 }
171 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800172 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
173 if (remoteRet.serviceSpecificErrorCode() ==
174 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800175 ALOGW("Create capture request failed! template %d is not supported on this device",
176 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700177 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800178 } else if (!remoteRet.isOk()) {
179 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800180 return ACAMERA_ERROR_UNKNOWN;
181 }
182 ACaptureRequest* outReq = new ACaptureRequest();
183 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800184 if (physicalIdList != nullptr) {
185 for (auto i = 0; i < physicalIdList->numCameras; i++) {
186 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
187 new ACameraMetadata(*(outReq->settings)));
188 }
189 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800190 outReq->targets = new ACameraOutputTargets();
191 *request = outReq;
192 return ACAMERA_OK;
193}
194
Yin-Chia Yehead91462016-01-06 16:45:08 -0800195camera_status_t
196CameraDevice::createCaptureSession(
197 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100198 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800199 const ACameraCaptureSession_stateCallbacks* callbacks,
200 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700201 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800202 Mutex::Autolock _l(mDeviceLock);
203 camera_status_t ret = checkCameraClosedOrErrorLocked();
204 if (ret != ACAMERA_OK) {
205 return ret;
206 }
207
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700208 if (currentSession != nullptr) {
209 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800210 stopRepeatingLocked();
211 }
212
213 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100214 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800215 if (ret != ACAMERA_OK) {
216 ALOGE("Fail to create new session. cannot configure streams");
217 return ret;
218 }
219
220 ACameraCaptureSession* newSession = new ACameraCaptureSession(
221 mNextSessionId++, outputs, callbacks, this);
222
Yin-Chia Yehead91462016-01-06 16:45:08 -0800223 // set new session as current session
224 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
225 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700226 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800227 *session = newSession;
228 return ACAMERA_OK;
229}
230
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800231camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100232 camera_status_t ret = checkCameraClosedOrErrorLocked();
233 if (ret != ACAMERA_OK) {
234 return ret;
235 }
236
237 if (output == nullptr) {
238 return ACAMERA_ERROR_INVALID_PARAMETER;
239 }
240
241 if (!output->mIsShared) {
242 ALOGE("Error output configuration is not shared");
243 return ACAMERA_ERROR_INVALID_OPERATION;
244 }
245
246 int32_t streamId = -1;
247 for (auto& kvPair : mConfiguredOutputs) {
248 if (kvPair.second.first == output->mWindow) {
249 streamId = kvPair.first;
250 break;
251 }
252 }
253 if (streamId < 0) {
254 ALOGE("Error: Invalid output configuration");
255 return ACAMERA_ERROR_INVALID_PARAMETER;
256 }
257
258 sp<IGraphicBufferProducer> iGBP(nullptr);
259 ret = getIGBPfromAnw(output->mWindow, iGBP);
260 if (ret != ACAMERA_OK) {
261 ALOGE("Camera device %s failed to extract graphic producer from native window",
262 getId());
263 return ret;
264 }
265
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800266 String16 physicalId16(output->mPhysicalCameraId.c_str());
267 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
268 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100269
270 for (auto& anw : output->mSharedWindows) {
271 ret = getIGBPfromAnw(anw, iGBP);
272 if (ret != ACAMERA_OK) {
273 ALOGE("Camera device %s failed to extract graphic producer from native window",
274 getId());
275 return ret;
276 }
277 outConfig.addGraphicProducer(iGBP);
278 }
279
280 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
281 if (!remoteRet.isOk()) {
282 switch (remoteRet.serviceSpecificErrorCode()) {
283 case hardware::ICameraService::ERROR_INVALID_OPERATION:
284 ALOGE("Camera device %s invalid operation: %s", getId(),
285 remoteRet.toString8().string());
286 return ACAMERA_ERROR_INVALID_OPERATION;
287 break;
288 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
289 ALOGE("Camera device %s output surface already exists: %s", getId(),
290 remoteRet.toString8().string());
291 return ACAMERA_ERROR_INVALID_PARAMETER;
292 break;
293 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
294 ALOGE("Camera device %s invalid input argument: %s", getId(),
295 remoteRet.toString8().string());
296 return ACAMERA_ERROR_INVALID_PARAMETER;
297 break;
298 default:
299 ALOGE("Camera device %s failed to add shared output: %s", getId(),
300 remoteRet.toString8().string());
301 return ACAMERA_ERROR_UNKNOWN;
302 }
303 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800304 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100305
306 return ACAMERA_OK;
307}
308
Yin-Chia Yehead91462016-01-06 16:45:08 -0800309camera_status_t
310CameraDevice::allocateCaptureRequest(
311 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
312 camera_status_t ret;
313 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800314 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000315 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800316 for (auto& entry : request->physicalSettings) {
317 req->mPhysicalCameraSettings.push_back({entry.first,
318 entry.second->getInternalData()});
319 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800320 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700321 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800322 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800323
324 for (auto outputTarget : request->targets->mOutputs) {
325 ANativeWindow* anw = outputTarget.mWindow;
326 sp<Surface> surface;
327 ret = getSurfaceFromANativeWindow(anw, surface);
328 if (ret != ACAMERA_OK) {
329 ALOGE("Bad output target in capture request! ret %d", ret);
330 return ret;
331 }
332 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800333
334 bool found = false;
335 // lookup stream/surface ID
336 for (const auto& kvPair : mConfiguredOutputs) {
337 int streamId = kvPair.first;
338 const OutputConfiguration& outConfig = kvPair.second.second;
339 const auto& gbps = outConfig.getGraphicBufferProducers();
340 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
341 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
342 found = true;
343 req->mStreamIdxList.push_back(streamId);
344 req->mSurfaceIdxList.push_back(surfaceId);
345 break;
346 }
347 }
348 if (found) {
349 break;
350 }
351 }
352 if (!found) {
353 ALOGE("Unconfigured output target %p in capture request!", anw);
354 return ret;
355 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800356 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800357
Yin-Chia Yehead91462016-01-06 16:45:08 -0800358 outReq = req;
359 return ACAMERA_OK;
360}
361
362ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800363CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800364 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800365 for (auto& entry : req->mPhysicalCameraSettings) {
366 CameraMetadata clone = entry.settings;
367 if (entry.id == deviceId) {
368 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
369 } else {
370 pRequest->physicalSettings.emplace(entry.id,
371 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
372 }
373 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800374 pRequest->targets = new ACameraOutputTargets();
375 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
376 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
377 ACameraOutputTarget outputTarget(anw);
378 pRequest->targets->mOutputs.insert(outputTarget);
379 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700380 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800381 return pRequest;
382}
383
384void
385CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
386 if (req == nullptr) {
387 return;
388 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700389 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800390 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800391 delete req->targets;
392 delete req;
393}
394
395void
396CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
397 if (isClosed()) {
398 // Device is closing already. do nothing
399 return;
400 }
401
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700402 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800403 // Session has been replaced by other seesion or device is closed
404 return;
405 }
406 mCurrentSession = nullptr;
407
408 // Should not happen
409 if (!session->mIsClosed) {
410 ALOGE("Error: unclosed session %p reaches end of life!", session);
411 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
412 return;
413 }
414
415 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100416 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800417 if (ret != ACAMERA_OK) {
418 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
419 }
420}
421
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800422void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700423CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800424 if (mClosing.exchange(true)) {
425 // Already closing, just return
426 ALOGW("Camera device %s is already closing.", getId());
427 return;
428 }
429
430 if (mRemote != nullptr) {
431 mRemote->disconnect();
432 }
433 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800434
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700435 if (session != nullptr) {
436 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800437 }
438}
439
440camera_status_t
441CameraDevice::stopRepeatingLocked() {
442 camera_status_t ret = checkCameraClosedOrErrorLocked();
443 if (ret != ACAMERA_OK) {
444 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
445 return ret;
446 }
447 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
448 int repeatingSequenceId = mRepeatingSequenceId;
449 mRepeatingSequenceId = REQUEST_ID_NONE;
450
451 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800452 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700453 if (remoteRet.serviceSpecificErrorCode() ==
454 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
455 ALOGV("Repeating request is already stopped.");
456 return ACAMERA_OK;
457 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800458 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800459 return ACAMERA_ERROR_UNKNOWN;
460 }
461 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
462 }
463 return ACAMERA_OK;
464}
465
466camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700467CameraDevice::flushLocked(ACameraCaptureSession* session) {
468 camera_status_t ret = checkCameraClosedOrErrorLocked();
469 if (ret != ACAMERA_OK) {
470 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
471 return ret;
472 }
473
474 // This should never happen because creating a new session will close
475 // previous one and thus reject any API call from previous session.
476 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700477 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700478 ALOGE("Camera %s session %p is not current active session!", getId(), session);
479 return ACAMERA_ERROR_INVALID_OPERATION;
480 }
481
482 if (mFlushing) {
483 ALOGW("Camera %s is already aborting captures", getId());
484 return ACAMERA_OK;
485 }
486
487 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700488
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700489 // Send onActive callback to guarantee there is always active->ready transition
490 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
491 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
492 msg->setObject(kSessionSpKey, session);
493 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700494 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700495
496 // If device is already idling, send callback and exit early
497 if (mIdle) {
498 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
499 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
500 msg->setObject(kSessionSpKey, session);
501 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700502 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700503 mFlushing = false;
504 return ACAMERA_OK;
505 }
506
507 int64_t lastFrameNumber;
508 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
509 if (!remoteRet.isOk()) {
510 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
511 return ACAMERA_ERROR_UNKNOWN;
512 }
513 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
514 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
515 }
516 return ACAMERA_OK;
517}
518
519camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800520CameraDevice::waitUntilIdleLocked() {
521 camera_status_t ret = checkCameraClosedOrErrorLocked();
522 if (ret != ACAMERA_OK) {
523 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
524 return ret;
525 }
526
527 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
528 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
529 return ACAMERA_ERROR_INVALID_OPERATION;
530 }
531
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800532 binder::Status remoteRet = mRemote->waitUntilIdle();
533 if (!remoteRet.isOk()) {
534 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800535 // TODO: define a function to convert status_t -> camera_status_t
536 return ACAMERA_ERROR_UNKNOWN;
537 }
538
539 return ACAMERA_OK;
540}
541
542camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700543CameraDevice::getIGBPfromAnw(
544 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800545 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800546 sp<Surface> surface;
547 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
548 if (ret != ACAMERA_OK) {
549 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800550 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800551 out = surface->getIGraphicBufferProducer();
552 return ACAMERA_OK;
553}
554
555camera_status_t
556CameraDevice::getSurfaceFromANativeWindow(
557 ANativeWindow* anw, sp<Surface>& out) {
558 if (anw == nullptr) {
559 ALOGE("Error: output ANativeWindow is null");
560 return ACAMERA_ERROR_INVALID_PARAMETER;
561 }
562 int value;
563 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800564 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800565 ALOGE("Error: ANativeWindow is not backed by Surface!");
566 return ACAMERA_ERROR_INVALID_PARAMETER;
567 }
568 sp<Surface> surface(static_cast<Surface*>(anw));
569 out = surface;
570 return ACAMERA_OK;
571}
572
573camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100574CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
575 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800576 ACaptureSessionOutputContainer emptyOutput;
577 if (outputs == nullptr) {
578 outputs = &emptyOutput;
579 }
580
Yin-Chia Yehead91462016-01-06 16:45:08 -0800581 camera_status_t ret = checkCameraClosedOrErrorLocked();
582 if (ret != ACAMERA_OK) {
583 return ret;
584 }
585
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700586 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800587 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700588 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800589 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700590 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800591 if (ret != ACAMERA_OK) {
592 return ret;
593 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800594 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700595 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800596 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100597 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800598 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700599 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800600 std::vector<int> deleteList;
601
602 // Determine which streams need to be created, which to be deleted
603 for (auto& kvPair : mConfiguredOutputs) {
604 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700605 auto& outputPair = kvPair.second;
606 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800607 deleteList.push_back(streamId); // Need to delete a no longer needed stream
608 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700609 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800610 }
611 }
612
613 ret = stopRepeatingLocked();
614 if (ret != ACAMERA_OK) {
615 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
616 return ret;
617 }
618
619 ret = waitUntilIdleLocked();
620 if (ret != ACAMERA_OK) {
621 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
622 return ret;
623 }
624
625 // Send onReady to previous session
626 // CurrentSession will be updated after configureStreamLocked, so here
627 // mCurrentSession is the session to be replaced by a new session
628 if (!mIdle && mCurrentSession != nullptr) {
629 if (mBusySession != mCurrentSession) {
630 ALOGE("Current session != busy session");
631 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
632 return ACAMERA_ERROR_CAMERA_DEVICE;
633 }
634 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
635 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
636 msg->setObject(kSessionSpKey, mBusySession);
637 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
638 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700639 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800640 }
641 mIdle = true;
642
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800643 binder::Status remoteRet = mRemote->beginConfigure();
644 if (!remoteRet.isOk()) {
645 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800646 return ACAMERA_ERROR_UNKNOWN;
647 }
648
649 // delete to-be-deleted streams
650 for (auto streamId : deleteList) {
651 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800652 if (!remoteRet.isOk()) {
653 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
654 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800655 return ACAMERA_ERROR_UNKNOWN;
656 }
657 mConfiguredOutputs.erase(streamId);
658 }
659
660 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800661 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800662 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700663 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800664 if (!remoteRet.isOk()) {
665 ALOGE("Camera device %s failed to create stream: %s", getId(),
666 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800667 return ACAMERA_ERROR_UNKNOWN;
668 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700669 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800670 }
671
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100672 CameraMetadata params;
673 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
674 params.append(sessionParameters->settings->getInternalData());
675 }
676 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800677 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
678 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
679 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800680 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800681 } else if (!remoteRet.isOk()) {
682 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800683 return ACAMERA_ERROR_UNKNOWN;
684 }
685
686 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800687}
688
689void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800690CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800691 Mutex::Autolock _l(mDeviceLock);
692 mRemote = remote;
693}
694
695camera_status_t
696CameraDevice::checkCameraClosedOrErrorLocked() const {
697 if (mRemote == nullptr) {
698 ALOGE("%s: camera device already closed", __FUNCTION__);
699 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
700 }
701 if (mInError) {// triggered by onDeviceError
702 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
703 return mError;
704 }
705 return ACAMERA_OK;
706}
707
708void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800709CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
710 mInError = true;
711 mError = error;
712 return;
713}
714
715void
716CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
717 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
718 if (isError) {
719 mFutureErrorSet.insert(frameNumber);
720 } else if (frameNumber <= mCompletedFrameNumber) {
721 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
722 frameNumber, mCompletedFrameNumber);
723 return;
724 } else {
725 if (frameNumber != mCompletedFrameNumber + 1) {
726 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
727 mCompletedFrameNumber + 1, frameNumber);
728 // Do not assert as in java implementation
729 }
730 mCompletedFrameNumber = frameNumber;
731 }
732 update();
733}
734
735void
736CameraDevice::FrameNumberTracker::update() {
737 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
738 int64_t errorFrameNumber = *it;
739 if (errorFrameNumber == mCompletedFrameNumber + 1) {
740 mCompletedFrameNumber++;
741 it = mFutureErrorSet.erase(it);
742 } else if (errorFrameNumber <= mCompletedFrameNumber) {
743 // This should not happen, but deal with it anyway
744 ALOGE("Completd frame number passed through current frame number!");
745 // erase the old error since it's no longer useful
746 it = mFutureErrorSet.erase(it);
747 } else {
748 // Normal requests hasn't catched up error frames, just break
749 break;
750 }
751 }
752 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
753}
754
755void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800756CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800757 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800758 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800759 int sequenceId = resultExtras.requestId;
760 int64_t frameNumber = resultExtras.frameNumber;
761 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700762 auto it = mSequenceCallbackMap.find(sequenceId);
763 if (it == mSequenceCallbackMap.end()) {
764 ALOGE("%s: Error: capture sequence index %d not found!",
765 __FUNCTION__, sequenceId);
766 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800767 return;
768 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700769
770 CallbackHolder cbh = (*it).second;
771 sp<ACameraCaptureSession> session = cbh.mSession;
772 if ((size_t) burstId >= cbh.mRequests.size()) {
773 ALOGE("%s: Error: request index %d out of bound (size %zu)",
774 __FUNCTION__, burstId, cbh.mRequests.size());
775 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
776 return;
777 }
778 sp<CaptureRequest> request = cbh.mRequests[burstId];
779
780 // Handle buffer error
781 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
782 int32_t streamId = resultExtras.errorStreamId;
783 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800784 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700785 auto outputPairIt = mConfiguredOutputs.find(streamId);
786 if (outputPairIt == mConfiguredOutputs.end()) {
787 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800788 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
789 return;
790 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700791
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800792 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
793 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800794 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800795 if (surface->getIGraphicBufferProducer() == outGbp) {
796 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
797 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
798 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700799
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800800 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800801 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800802 msg->setObject(kSessionSpKey, session);
803 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
804 msg->setObject(kCaptureRequestKey, request);
805 msg->setPointer(kAnwKey, (void*) anw);
806 msg->setInt64(kFrameNumberKey, frameNumber);
807 postSessionMsgAndCleanup(msg);
808 }
809 }
810 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700811 } else { // Handle other capture failures
812 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800813 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800814 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
815 failure->frameNumber = frameNumber;
816 // TODO: refine this when implementing flush
817 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
818 failure->sequenceId = sequenceId;
819 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800820 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800821
Emilian Peevedec62d2019-03-19 17:59:24 -0700822 sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
823 kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800824 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800825 msg->setObject(kSessionSpKey, session);
Emilian Peevedec62d2019-03-19 17:59:24 -0700826 if (cbh.mIsLogicalCameraCallback) {
827 if (resultExtras.errorPhysicalCameraId.size() > 0) {
828 String8 cameraId(resultExtras.errorPhysicalCameraId);
829 msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
830 }
831 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
832 } else {
833 msg->setPointer(kCallbackFpKey, (void*) onError);
834 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800835 msg->setObject(kCaptureRequestKey, request);
836 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700837 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800838
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700839 // Update tracker
840 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
841 checkAndFireSequenceCompleteLocked();
842 }
843 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800844}
845
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800846CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
847}
848
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800849void CameraDevice::CallbackHandler::onMessageReceived(
850 const sp<AMessage> &msg) {
851 switch (msg->what()) {
852 case kWhatOnDisconnected:
853 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800854 case kWhatSessionStateCb:
855 case kWhatCaptureStart:
856 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800857 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800858 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700859 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800860 case kWhatCaptureSeqEnd:
861 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700862 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800864 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700865 case kWhatCleanUpSessions:
866 mCachedSessions.clear();
867 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800868 default:
869 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
870 return;
871 }
872 // Check the common part of all message
873 void* context;
874 bool found = msg->findPointer(kContextKey, &context);
875 if (!found) {
876 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
877 return;
878 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800879 switch (msg->what()) {
880 case kWhatOnDisconnected:
881 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800882 ACameraDevice* dev;
883 found = msg->findPointer(kDeviceKey, (void**) &dev);
884 if (!found || dev == nullptr) {
885 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
886 return;
887 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800888 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800889 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800890 if (!found) {
891 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
892 return;
893 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800894 if (onDisconnected == nullptr) {
895 return;
896 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800897 (*onDisconnected)(context, dev);
898 break;
899 }
900 case kWhatOnError:
901 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800902 ACameraDevice* dev;
903 found = msg->findPointer(kDeviceKey, (void**) &dev);
904 if (!found || dev == nullptr) {
905 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
906 return;
907 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800908 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800909 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800910 if (!found) {
911 ALOGE("%s: Cannot find onError!", __FUNCTION__);
912 return;
913 }
914 int errorCode;
915 found = msg->findInt32(kErrorCodeKey, &errorCode);
916 if (!found) {
917 ALOGE("%s: Cannot find error code!", __FUNCTION__);
918 return;
919 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800920 if (onError == nullptr) {
921 return;
922 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800923 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800924 break;
925 }
926 case kWhatSessionStateCb:
927 case kWhatCaptureStart:
928 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800929 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800930 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700931 case kWhatLogicalCaptureFail:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800932 case kWhatCaptureSeqEnd:
933 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700934 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800935 {
936 sp<RefBase> obj;
937 found = msg->findObject(kSessionSpKey, &obj);
938 if (!found || obj == nullptr) {
939 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
940 return;
941 }
942 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700943 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800944 sp<CaptureRequest> requestSp = nullptr;
945 switch (msg->what()) {
946 case kWhatCaptureStart:
947 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800948 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800949 case kWhatCaptureFail:
Emilian Peevedec62d2019-03-19 17:59:24 -0700950 case kWhatLogicalCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700951 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800952 found = msg->findObject(kCaptureRequestKey, &obj);
953 if (!found) {
954 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
955 return;
956 }
957 requestSp = static_cast<CaptureRequest*>(obj.get());
958 break;
959 }
960
961 switch (msg->what()) {
962 case kWhatSessionStateCb:
963 {
964 ACameraCaptureSession_stateCallback onState;
965 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
966 if (!found) {
967 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
968 return;
969 }
970 if (onState == nullptr) {
971 return;
972 }
973 (*onState)(context, session.get());
974 break;
975 }
976 case kWhatCaptureStart:
977 {
978 ACameraCaptureSession_captureCallback_start onStart;
979 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
980 if (!found) {
981 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
982 return;
983 }
984 if (onStart == nullptr) {
985 return;
986 }
987 int64_t timestamp;
988 found = msg->findInt64(kTimeStampKey, &timestamp);
989 if (!found) {
990 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
991 return;
992 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800993 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800994 (*onStart)(context, session.get(), request, timestamp);
995 freeACaptureRequest(request);
996 break;
997 }
998 case kWhatCaptureResult:
999 {
1000 ACameraCaptureSession_captureCallback_result onResult;
1001 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1002 if (!found) {
1003 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1004 return;
1005 }
1006 if (onResult == nullptr) {
1007 return;
1008 }
1009
1010 found = msg->findObject(kCaptureResultKey, &obj);
1011 if (!found) {
1012 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1013 return;
1014 }
1015 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001016 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001017 (*onResult)(context, session.get(), request, result.get());
1018 freeACaptureRequest(request);
1019 break;
1020 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001021 case kWhatLogicalCaptureResult:
1022 {
1023 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1024 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1025 if (!found) {
1026 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1027 __FUNCTION__);
1028 return;
1029 }
1030 if (onResult == nullptr) {
1031 return;
1032 }
1033
1034 found = msg->findObject(kCaptureResultKey, &obj);
1035 if (!found) {
1036 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1037 return;
1038 }
1039 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1040
1041 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1042 if (!found) {
1043 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1044 return;
1045 }
1046 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1047 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1048 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1049 physicalResult->mPhysicalResultInfo;
1050
1051 std::vector<std::string> physicalCameraIds;
1052 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1053 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1054 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1055 physicalCameraIds.push_back(physicalId8.c_str());
1056
1057 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1058 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1059 &physicalResult->mFrameNumber, /*data_count*/1);
1060 sp<ACameraMetadata> metadata =
1061 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1062 physicalMetadataCopy.push_back(metadata);
1063 }
1064
1065 std::vector<const char*> physicalCameraIdPtrs;
1066 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1067 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1068 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1069 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1070 }
1071
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001072 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001073 (*onResult)(context, session.get(), request, result.get(),
1074 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1075 physicalMetadataCopyPtrs.data());
1076 freeACaptureRequest(request);
1077 break;
1078 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001079 case kWhatCaptureFail:
1080 {
1081 ACameraCaptureSession_captureCallback_failed onFail;
1082 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1083 if (!found) {
1084 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1085 return;
1086 }
1087 if (onFail == nullptr) {
1088 return;
1089 }
1090
1091 found = msg->findObject(kCaptureFailureKey, &obj);
1092 if (!found) {
1093 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1094 return;
1095 }
1096 sp<CameraCaptureFailure> failureSp(
1097 static_cast<CameraCaptureFailure*>(obj.get()));
1098 ACameraCaptureFailure* failure =
1099 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001100 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001101 (*onFail)(context, session.get(), request, failure);
1102 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001103 break;
1104 }
Emilian Peevedec62d2019-03-19 17:59:24 -07001105 case kWhatLogicalCaptureFail:
1106 {
1107 ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1108 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1109 if (!found) {
1110 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1111 return;
1112 }
1113 if (onFail == nullptr) {
1114 return;
1115 }
1116
1117 found = msg->findObject(kCaptureFailureKey, &obj);
1118 if (!found) {
1119 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1120 return;
1121 }
1122 sp<CameraCaptureFailure> failureSp(
1123 static_cast<CameraCaptureFailure*>(obj.get()));
1124 ALogicalCameraCaptureFailure failure;
1125 AString physicalCameraId;
1126 found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1127 if (found && !physicalCameraId.empty()) {
1128 failure.physicalCameraId = physicalCameraId.c_str();
1129 } else {
1130 failure.physicalCameraId = nullptr;
1131 }
1132 failure.captureFailure = *failureSp;
1133 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1134 (*onFail)(context, session.get(), request, &failure);
1135 freeACaptureRequest(request);
1136 break;
1137 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001138 case kWhatCaptureSeqEnd:
1139 {
1140 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1141 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1142 if (!found) {
1143 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1144 return;
1145 }
1146 if (onSeqEnd == nullptr) {
1147 return;
1148 }
1149 int seqId;
1150 found = msg->findInt32(kSequenceIdKey, &seqId);
1151 if (!found) {
1152 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1153 return;
1154 }
1155 int64_t frameNumber;
1156 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1157 if (!found) {
1158 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1159 return;
1160 }
1161 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1162 break;
1163 }
1164 case kWhatCaptureSeqAbort:
1165 {
1166 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1167 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1168 if (!found) {
1169 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1170 return;
1171 }
1172 if (onSeqAbort == nullptr) {
1173 return;
1174 }
1175 int seqId;
1176 found = msg->findInt32(kSequenceIdKey, &seqId);
1177 if (!found) {
1178 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1179 return;
1180 }
1181 (*onSeqAbort)(context, session.get(), seqId);
1182 break;
1183 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001184 case kWhatCaptureBufferLost:
1185 {
1186 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1187 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1188 if (!found) {
1189 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1190 return;
1191 }
1192 if (onBufferLost == nullptr) {
1193 return;
1194 }
1195
1196 ANativeWindow* anw;
1197 found = msg->findPointer(kAnwKey, (void**) &anw);
1198 if (!found) {
1199 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1200 return;
1201 }
1202
1203 int64_t frameNumber;
1204 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1205 if (!found) {
1206 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1207 return;
1208 }
1209
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001210 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001211 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1212 freeACaptureRequest(request);
1213 break;
1214 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001215 }
1216 break;
1217 }
1218 }
1219}
1220
1221CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001222 sp<ACameraCaptureSession> session,
1223 const Vector<sp<CaptureRequest> >& requests,
1224 bool isRepeating,
1225 ACameraCaptureSession_captureCallbacks* cbs) :
1226 mSession(session), mRequests(requests),
1227 mIsRepeating(isRepeating),
1228 mIsLogicalCameraCallback(false) {
1229 initCaptureCallbacks(cbs);
1230
1231 if (cbs != nullptr) {
1232 mOnCaptureCompleted = cbs->onCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001233 mOnCaptureFailed = cbs->onCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001234 }
1235}
1236
1237CameraDevice::CallbackHolder::CallbackHolder(
1238 sp<ACameraCaptureSession> session,
1239 const Vector<sp<CaptureRequest> >& requests,
1240 bool isRepeating,
1241 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1242 mSession(session), mRequests(requests),
1243 mIsRepeating(isRepeating),
1244 mIsLogicalCameraCallback(true) {
1245 initCaptureCallbacks(lcbs);
1246
1247 if (lcbs != nullptr) {
1248 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
Emilian Peevedec62d2019-03-19 17:59:24 -07001249 mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001250 }
1251}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001252
1253void
1254CameraDevice::checkRepeatingSequenceCompleteLocked(
1255 const int sequenceId, const int64_t lastFrameNumber) {
1256 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1257 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1258 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1259 ALOGW("No callback found for sequenceId %d", sequenceId);
1260 return;
1261 }
1262 // remove callback holder from callback map
1263 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1264 CallbackHolder cbh = cbIt->second;
1265 mSequenceCallbackMap.erase(cbIt);
1266 // send seq aborted callback
1267 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001268 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001269 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001270 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001271 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001272 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001273 } else {
1274 // Use mSequenceLastFrameNumberMap to track
1275 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1276
1277 // Last frame might have arrived. Check now
1278 checkAndFireSequenceCompleteLocked();
1279 }
1280}
1281
1282void
1283CameraDevice::checkAndFireSequenceCompleteLocked() {
1284 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1285 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1286 auto it = mSequenceLastFrameNumberMap.begin();
1287 while (it != mSequenceLastFrameNumberMap.end()) {
1288 int sequenceId = it->first;
1289 int64_t lastFrameNumber = it->second;
1290 bool seqCompleted = false;
1291 bool hasCallback = true;
1292
1293 if (mRemote == nullptr) {
1294 ALOGW("Camera %s closed while checking sequence complete", getId());
1295 return;
1296 }
1297
1298 // Check if there is callback for this sequence
1299 // This should not happen because we always register callback (with nullptr inside)
1300 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1301 ALOGW("No callback found for sequenceId %d", sequenceId);
1302 hasCallback = false;
1303 }
1304
1305 if (lastFrameNumber <= completedFrameNumber) {
1306 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1307 sequenceId, lastFrameNumber, completedFrameNumber);
1308 seqCompleted = true;
1309 }
1310
1311 if (seqCompleted && hasCallback) {
1312 // remove callback holder from callback map
1313 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1314 CallbackHolder cbh = cbIt->second;
1315 mSequenceCallbackMap.erase(cbIt);
1316 // send seq complete callback
1317 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001318 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001319 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001320 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001321 msg->setInt32(kSequenceIdKey, sequenceId);
1322 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1323
1324 // Clear the session sp before we send out the message
1325 // This will guarantee the rare case where the message is processed
1326 // before cbh goes out of scope and causing we call the session
1327 // destructor while holding device lock
1328 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001329 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001330 }
1331
1332 // No need to track sequence complete if there is no callback registered
1333 if (seqCompleted || !hasCallback) {
1334 it = mSequenceLastFrameNumberMap.erase(it);
1335 } else {
1336 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001337 }
1338 }
1339}
1340
1341/**
1342 * Camera service callback implementation
1343 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001344binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001345CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001346 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001347 const CaptureResultExtras& resultExtras) {
1348 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1349 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001350 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001351 sp<CameraDevice> dev = mDevice.promote();
1352 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001353 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001354 }
1355
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001356 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001357 Mutex::Autolock _l(dev->mDeviceLock);
1358 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001359 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001360 }
1361 switch (errorCode) {
1362 case ERROR_CAMERA_DISCONNECTED:
1363 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001364 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001365 if (session != nullptr) {
1366 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001367 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001368 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001369 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1370 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1371 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001372 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001373 msg->post();
1374 break;
1375 }
1376 default:
1377 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001378 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001379 case ERROR_CAMERA_DEVICE:
1380 case ERROR_CAMERA_SERVICE:
1381 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001382 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1383 // We keep this switch since this block might be encountered with
1384 // more than just 2 states. The default fallthrough could have us
1385 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001386 switch (errorCode) {
1387 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001388 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001389 break;
1390 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001391 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001392 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001393 break;
1394 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001395 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001396 break;
1397 }
1398 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1399 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1400 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001401 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001402 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001403 msg->post();
1404 break;
1405 }
1406 case ERROR_CAMERA_REQUEST:
1407 case ERROR_CAMERA_RESULT:
1408 case ERROR_CAMERA_BUFFER:
1409 dev->onCaptureErrorLocked(errorCode, resultExtras);
1410 break;
1411 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001412 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001413}
1414
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001415binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001416CameraDevice::ServiceCallback::onDeviceIdle() {
1417 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001418 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001419 sp<CameraDevice> dev = mDevice.promote();
1420 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001421 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001422 }
1423
1424 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001425 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001426 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001427 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001428
1429 if (dev->mIdle) {
1430 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001431 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001432 }
1433
1434 if (dev->mCurrentSession != nullptr) {
1435 ALOGE("onDeviceIdle sending state cb");
1436 if (dev->mBusySession != dev->mCurrentSession) {
1437 ALOGE("Current session != busy session");
1438 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001439 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001440 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001441
Yin-Chia Yehead91462016-01-06 16:45:08 -08001442 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1443 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1444 msg->setObject(kSessionSpKey, dev->mBusySession);
1445 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1446 // Make sure we clear the sp first so the session destructor can
1447 // only happen on handler thread (where we don't hold device/session lock)
1448 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001449 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001450 }
1451 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001452 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001453 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001454}
1455
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001456binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001457CameraDevice::ServiceCallback::onCaptureStarted(
1458 const CaptureResultExtras& resultExtras,
1459 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001460 binder::Status ret = binder::Status::ok();
1461
Yin-Chia Yehead91462016-01-06 16:45:08 -08001462 sp<CameraDevice> dev = mDevice.promote();
1463 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001464 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001465 }
1466 Mutex::Autolock _l(dev->mDeviceLock);
1467 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001468 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001469 }
1470
1471 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001472 int32_t burstId = resultExtras.burstId;
1473
1474 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1475 if (it != dev->mSequenceCallbackMap.end()) {
1476 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001477 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001478 sp<ACameraCaptureSession> session = cbh.mSession;
1479 if ((size_t) burstId >= cbh.mRequests.size()) {
1480 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1481 __FUNCTION__, burstId, cbh.mRequests.size());
1482 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1483 }
1484 sp<CaptureRequest> request = cbh.mRequests[burstId];
1485 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001486 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001487 msg->setObject(kSessionSpKey, session);
1488 msg->setPointer(kCallbackFpKey, (void*) onStart);
1489 msg->setObject(kCaptureRequestKey, request);
1490 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001491 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001492 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001493 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001494}
1495
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001496binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001497CameraDevice::ServiceCallback::onResultReceived(
1498 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001499 const CaptureResultExtras& resultExtras,
1500 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001501 binder::Status ret = binder::Status::ok();
1502
Yin-Chia Yehead91462016-01-06 16:45:08 -08001503 sp<CameraDevice> dev = mDevice.promote();
1504 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001505 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001506 }
1507 int sequenceId = resultExtras.requestId;
1508 int64_t frameNumber = resultExtras.frameNumber;
1509 int32_t burstId = resultExtras.burstId;
1510 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1511
1512 if (!isPartialResult) {
1513 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1514 }
1515
1516 Mutex::Autolock _l(dev->mDeviceLock);
1517 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001518 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001519 }
1520
1521 if (dev->isClosed()) {
1522 if (!isPartialResult) {
1523 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1524 }
1525 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001526 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001527 }
1528
1529 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001530 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001531 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001532
1533 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1534 if (it != dev->mSequenceCallbackMap.end()) {
1535 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001536 sp<ACameraCaptureSession> session = cbh.mSession;
1537 if ((size_t) burstId >= cbh.mRequests.size()) {
1538 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1539 __FUNCTION__, burstId, cbh.mRequests.size());
1540 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1541 }
1542 sp<CaptureRequest> request = cbh.mRequests[burstId];
1543 sp<ACameraMetadata> result(new ACameraMetadata(
1544 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001545 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1546 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001547
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001548 sp<AMessage> msg = new AMessage(
1549 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1550 dev->mHandler);
1551 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001552 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001553 msg->setObject(kCaptureRequestKey, request);
1554 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001555 if (isPartialResult) {
1556 msg->setPointer(kCallbackFpKey,
1557 (void *)cbh.mOnCaptureProgressed);
1558 } else if (cbh.mIsLogicalCameraCallback) {
1559 msg->setPointer(kCallbackFpKey,
1560 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1561 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1562 } else {
1563 msg->setPointer(kCallbackFpKey,
1564 (void *)cbh.mOnCaptureCompleted);
1565 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001566 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001567 }
1568
1569 if (!isPartialResult) {
1570 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1571 dev->checkAndFireSequenceCompleteLocked();
1572 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001573
1574 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001575}
1576
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001577binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001578CameraDevice::ServiceCallback::onPrepared(int) {
1579 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001580 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001581}
1582
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001583binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001584CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1585 // onRequestQueueEmpty not yet implemented in NDK
1586 return binder::Status::ok();
1587}
1588
1589binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001590CameraDevice::ServiceCallback::onRepeatingRequestError(
1591 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001592 binder::Status ret = binder::Status::ok();
1593
1594 sp<CameraDevice> dev = mDevice.promote();
1595 if (dev == nullptr) {
1596 return ret; // device has been closed
1597 }
1598
1599 Mutex::Autolock _l(dev->mDeviceLock);
1600
1601 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001602 if (stoppedSequenceId == repeatingSequenceId) {
1603 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1604 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001605
1606 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1607
1608 return ret;
1609}
1610
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001611} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001612} // namespace android