blob: c9db01e0bd6ab8061a2397824acfe6560b3e0b8f [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";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080048
49/**
50 * CameraDevice Implementation
51 */
52CameraDevice::CameraDevice(
53 const char* id,
54 ACameraDevice_StateCallbacks* cb,
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070055 sp<ACameraMetadata> chars,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080056 ACameraDevice* wrapper) :
57 mCameraId(id),
58 mAppCallbacks(*cb),
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -070059 mChars(chars),
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080060 mServiceCallback(new ServiceCallback(this)),
61 mWrapper(wrapper),
62 mInError(false),
63 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070064 mIdle(true),
65 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080066 mClosing = false;
67 // Setup looper thread to perfrom device callbacks to app
68 mCbLooper = new ALooper;
69 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080070 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080071 /*runOnCallingThread*/false,
72 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080073 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080074 if (err != OK) {
75 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
76 __FUNCTION__, strerror(-err), err);
77 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
78 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -080079 mHandler = new CallbackHandler(id);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080080 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080081
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080082 const CameraMetadata& metadata = mChars->getInternalData();
83 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080084 if (entry.count != 1) {
85 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
86 mPartialResultCount = 1;
87 } else {
88 mPartialResultCount = entry.data.i32[0];
89 }
90
91 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
92 if (entry.count != 2) {
93 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
94 mShadingMapSize[0] = 0;
95 mShadingMapSize[1] = 0;
96 } else {
97 mShadingMapSize[0] = entry.data.i32[0];
98 mShadingMapSize[1] = entry.data.i32[1];
99 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800100
101 size_t physicalIdCnt = 0;
102 const char*const* physicalCameraIds;
103 if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
104 for (size_t i = 0; i < physicalIdCnt; i++) {
105 mPhysicalIds.push_back(physicalCameraIds[i]);
106 }
107 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800108}
109
Yin-Chia Yehead91462016-01-06 16:45:08 -0800110// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800111CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700112 sp<ACameraCaptureSession> session = mCurrentSession.promote();
113 {
114 Mutex::Autolock _l(mDeviceLock);
115 if (!isClosed()) {
116 disconnectLocked(session);
117 }
118 mCurrentSession = nullptr;
119 if (mCbLooper != nullptr) {
120 mCbLooper->unregisterHandler(mHandler->id());
121 mCbLooper->stop();
122 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800123 }
124 mCbLooper.clear();
125 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126}
127
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700128void
129CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
130 msg->post();
131 msg.clear();
132 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
133 cleanupMsg->post();
134}
135
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800136// TODO: cached created request?
137camera_status_t
138CameraDevice::createCaptureRequest(
139 ACameraDevice_request_template templateId,
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800140 const ACameraIdList* physicalIdList,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800141 ACaptureRequest** request) const {
142 Mutex::Autolock _l(mDeviceLock);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800143
144 if (physicalIdList != nullptr) {
145 if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
146 ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
147 __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
148 return ACAMERA_ERROR_INVALID_PARAMETER;
149 }
150 for (auto i = 0; i < physicalIdList->numCameras; i++) {
151 if (physicalIdList->cameraIds[i] == nullptr) {
152 ALOGE("%s: physicalId is null!", __FUNCTION__);
153 return ACAMERA_ERROR_INVALID_PARAMETER;
154 }
155 if (mPhysicalIds.end() == std::find(
156 mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
157 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
158 return ACAMERA_ERROR_INVALID_PARAMETER;
159 }
160 }
161 }
162
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800163 camera_status_t ret = checkCameraClosedOrErrorLocked();
164 if (ret != ACAMERA_OK) {
165 return ret;
166 }
167 if (mRemote == nullptr) {
168 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
169 }
170 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800171 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
172 if (remoteRet.serviceSpecificErrorCode() ==
173 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800174 ALOGW("Create capture request failed! template %d is not supported on this device",
175 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700176 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800177 } else if (!remoteRet.isOk()) {
178 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800179 return ACAMERA_ERROR_UNKNOWN;
180 }
181 ACaptureRequest* outReq = new ACaptureRequest();
182 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800183 if (physicalIdList != nullptr) {
184 for (auto i = 0; i < physicalIdList->numCameras; i++) {
185 outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
186 new ACameraMetadata(*(outReq->settings)));
187 }
188 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800189 outReq->targets = new ACameraOutputTargets();
190 *request = outReq;
191 return ACAMERA_OK;
192}
193
Yin-Chia Yehead91462016-01-06 16:45:08 -0800194camera_status_t
195CameraDevice::createCaptureSession(
196 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100197 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800198 const ACameraCaptureSession_stateCallbacks* callbacks,
199 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700200 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800201 Mutex::Autolock _l(mDeviceLock);
202 camera_status_t ret = checkCameraClosedOrErrorLocked();
203 if (ret != ACAMERA_OK) {
204 return ret;
205 }
206
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700207 if (currentSession != nullptr) {
208 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800209 stopRepeatingLocked();
210 }
211
212 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100213 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800214 if (ret != ACAMERA_OK) {
215 ALOGE("Fail to create new session. cannot configure streams");
216 return ret;
217 }
218
219 ACameraCaptureSession* newSession = new ACameraCaptureSession(
220 mNextSessionId++, outputs, callbacks, this);
221
Yin-Chia Yehead91462016-01-06 16:45:08 -0800222 // set new session as current session
223 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
224 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700225 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800226 *session = newSession;
227 return ACAMERA_OK;
228}
229
Shuzhen Wang24810e72019-03-18 10:55:01 -0700230camera_status_t CameraDevice::isSessionConfigurationSupported(
231 const ACaptureSessionOutputContainer* sessionOutputContainer) const {
232 Mutex::Autolock _l(mDeviceLock);
233 camera_status_t ret = checkCameraClosedOrErrorLocked();
234 if (ret != ACAMERA_OK) {
235 return ret;
236 }
237
238 SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
239 -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
240 for (const auto& output : sessionOutputContainer->mOutputs) {
241 sp<IGraphicBufferProducer> iGBP(nullptr);
242 ret = getIGBPfromAnw(output.mWindow, 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
249 String16 physicalId16(output.mPhysicalCameraId.c_str());
250 OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
251 OutputConfiguration::INVALID_SET_ID, true);
252
253 for (auto& anw : output.mSharedWindows) {
254 ret = getIGBPfromAnw(anw, iGBP);
255 if (ret != ACAMERA_OK) {
256 ALOGE("Camera device %s failed to extract graphic producer from native window",
257 getId());
258 return ret;
259 }
260 outConfig.addGraphicProducer(iGBP);
261 }
262
263 sessionConfiguration.addOutputConfiguration(outConfig);
264 }
265
266 bool supported = false;
267 binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
268 sessionConfiguration, &supported);
269 if (remoteRet.serviceSpecificErrorCode() ==
270 hardware::ICameraService::ERROR_INVALID_OPERATION) {
271 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
272 } else if (!remoteRet.isOk()) {
273 return ACAMERA_ERROR_UNKNOWN;
274 } else {
275 return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
276 }
277}
278
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800279camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100280 camera_status_t ret = checkCameraClosedOrErrorLocked();
281 if (ret != ACAMERA_OK) {
282 return ret;
283 }
284
285 if (output == nullptr) {
286 return ACAMERA_ERROR_INVALID_PARAMETER;
287 }
288
289 if (!output->mIsShared) {
290 ALOGE("Error output configuration is not shared");
291 return ACAMERA_ERROR_INVALID_OPERATION;
292 }
293
294 int32_t streamId = -1;
295 for (auto& kvPair : mConfiguredOutputs) {
296 if (kvPair.second.first == output->mWindow) {
297 streamId = kvPair.first;
298 break;
299 }
300 }
301 if (streamId < 0) {
302 ALOGE("Error: Invalid output configuration");
303 return ACAMERA_ERROR_INVALID_PARAMETER;
304 }
305
306 sp<IGraphicBufferProducer> iGBP(nullptr);
307 ret = getIGBPfromAnw(output->mWindow, iGBP);
308 if (ret != ACAMERA_OK) {
309 ALOGE("Camera device %s failed to extract graphic producer from native window",
310 getId());
311 return ret;
312 }
313
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800314 String16 physicalId16(output->mPhysicalCameraId.c_str());
315 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
316 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100317
318 for (auto& anw : output->mSharedWindows) {
319 ret = getIGBPfromAnw(anw, iGBP);
320 if (ret != ACAMERA_OK) {
321 ALOGE("Camera device %s failed to extract graphic producer from native window",
322 getId());
323 return ret;
324 }
325 outConfig.addGraphicProducer(iGBP);
326 }
327
328 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
329 if (!remoteRet.isOk()) {
330 switch (remoteRet.serviceSpecificErrorCode()) {
331 case hardware::ICameraService::ERROR_INVALID_OPERATION:
332 ALOGE("Camera device %s invalid operation: %s", getId(),
333 remoteRet.toString8().string());
334 return ACAMERA_ERROR_INVALID_OPERATION;
335 break;
336 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
337 ALOGE("Camera device %s output surface already exists: %s", getId(),
338 remoteRet.toString8().string());
339 return ACAMERA_ERROR_INVALID_PARAMETER;
340 break;
341 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
342 ALOGE("Camera device %s invalid input argument: %s", getId(),
343 remoteRet.toString8().string());
344 return ACAMERA_ERROR_INVALID_PARAMETER;
345 break;
346 default:
347 ALOGE("Camera device %s failed to add shared output: %s", getId(),
348 remoteRet.toString8().string());
349 return ACAMERA_ERROR_UNKNOWN;
350 }
351 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800352 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100353
354 return ACAMERA_OK;
355}
356
Yin-Chia Yehead91462016-01-06 16:45:08 -0800357camera_status_t
358CameraDevice::allocateCaptureRequest(
359 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
360 camera_status_t ret;
361 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800362 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000363 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800364 for (auto& entry : request->physicalSettings) {
365 req->mPhysicalCameraSettings.push_back({entry.first,
366 entry.second->getInternalData()});
367 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800368 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700369 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800370 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800371
372 for (auto outputTarget : request->targets->mOutputs) {
373 ANativeWindow* anw = outputTarget.mWindow;
374 sp<Surface> surface;
375 ret = getSurfaceFromANativeWindow(anw, surface);
376 if (ret != ACAMERA_OK) {
377 ALOGE("Bad output target in capture request! ret %d", ret);
378 return ret;
379 }
380 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800381
382 bool found = false;
383 // lookup stream/surface ID
384 for (const auto& kvPair : mConfiguredOutputs) {
385 int streamId = kvPair.first;
386 const OutputConfiguration& outConfig = kvPair.second.second;
387 const auto& gbps = outConfig.getGraphicBufferProducers();
388 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
389 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
390 found = true;
391 req->mStreamIdxList.push_back(streamId);
392 req->mSurfaceIdxList.push_back(surfaceId);
393 break;
394 }
395 }
396 if (found) {
397 break;
398 }
399 }
400 if (!found) {
401 ALOGE("Unconfigured output target %p in capture request!", anw);
402 return ret;
403 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800404 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800405
Yin-Chia Yehead91462016-01-06 16:45:08 -0800406 outReq = req;
407 return ACAMERA_OK;
408}
409
410ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800411CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800412 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800413 for (auto& entry : req->mPhysicalCameraSettings) {
414 CameraMetadata clone = entry.settings;
415 if (entry.id == deviceId) {
416 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
417 } else {
418 pRequest->physicalSettings.emplace(entry.id,
419 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
420 }
421 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800422 pRequest->targets = new ACameraOutputTargets();
423 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
424 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
425 ACameraOutputTarget outputTarget(anw);
426 pRequest->targets->mOutputs.insert(outputTarget);
427 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700428 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800429 return pRequest;
430}
431
432void
433CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
434 if (req == nullptr) {
435 return;
436 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700437 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800438 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800439 delete req->targets;
440 delete req;
441}
442
443void
444CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
445 if (isClosed()) {
446 // Device is closing already. do nothing
447 return;
448 }
449
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700450 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800451 // Session has been replaced by other seesion or device is closed
452 return;
453 }
454 mCurrentSession = nullptr;
455
456 // Should not happen
457 if (!session->mIsClosed) {
458 ALOGE("Error: unclosed session %p reaches end of life!", session);
459 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
460 return;
461 }
462
463 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100464 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800465 if (ret != ACAMERA_OK) {
466 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
467 }
468}
469
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700471CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800472 if (mClosing.exchange(true)) {
473 // Already closing, just return
474 ALOGW("Camera device %s is already closing.", getId());
475 return;
476 }
477
478 if (mRemote != nullptr) {
479 mRemote->disconnect();
480 }
481 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800482
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700483 if (session != nullptr) {
484 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800485 }
486}
487
488camera_status_t
489CameraDevice::stopRepeatingLocked() {
490 camera_status_t ret = checkCameraClosedOrErrorLocked();
491 if (ret != ACAMERA_OK) {
492 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
493 return ret;
494 }
495 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
496 int repeatingSequenceId = mRepeatingSequenceId;
497 mRepeatingSequenceId = REQUEST_ID_NONE;
498
499 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800500 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700501 if (remoteRet.serviceSpecificErrorCode() ==
502 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
503 ALOGV("Repeating request is already stopped.");
504 return ACAMERA_OK;
505 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800506 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800507 return ACAMERA_ERROR_UNKNOWN;
508 }
509 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
510 }
511 return ACAMERA_OK;
512}
513
514camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700515CameraDevice::flushLocked(ACameraCaptureSession* session) {
516 camera_status_t ret = checkCameraClosedOrErrorLocked();
517 if (ret != ACAMERA_OK) {
518 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
519 return ret;
520 }
521
522 // This should never happen because creating a new session will close
523 // previous one and thus reject any API call from previous session.
524 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700525 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700526 ALOGE("Camera %s session %p is not current active session!", getId(), session);
527 return ACAMERA_ERROR_INVALID_OPERATION;
528 }
529
530 if (mFlushing) {
531 ALOGW("Camera %s is already aborting captures", getId());
532 return ACAMERA_OK;
533 }
534
535 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700536
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700537 // Send onActive callback to guarantee there is always active->ready transition
538 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
539 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
540 msg->setObject(kSessionSpKey, session);
541 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700542 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700543
544 // If device is already idling, send callback and exit early
545 if (mIdle) {
546 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
547 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
548 msg->setObject(kSessionSpKey, session);
549 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700550 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700551 mFlushing = false;
552 return ACAMERA_OK;
553 }
554
555 int64_t lastFrameNumber;
556 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
557 if (!remoteRet.isOk()) {
558 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
559 return ACAMERA_ERROR_UNKNOWN;
560 }
561 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
562 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
563 }
564 return ACAMERA_OK;
565}
566
567camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800568CameraDevice::waitUntilIdleLocked() {
569 camera_status_t ret = checkCameraClosedOrErrorLocked();
570 if (ret != ACAMERA_OK) {
571 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
572 return ret;
573 }
574
575 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
576 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
577 return ACAMERA_ERROR_INVALID_OPERATION;
578 }
579
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800580 binder::Status remoteRet = mRemote->waitUntilIdle();
581 if (!remoteRet.isOk()) {
582 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800583 // TODO: define a function to convert status_t -> camera_status_t
584 return ACAMERA_ERROR_UNKNOWN;
585 }
586
587 return ACAMERA_OK;
588}
589
590camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700591CameraDevice::getIGBPfromAnw(
592 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800593 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800594 sp<Surface> surface;
595 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
596 if (ret != ACAMERA_OK) {
597 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800598 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800599 out = surface->getIGraphicBufferProducer();
600 return ACAMERA_OK;
601}
602
603camera_status_t
604CameraDevice::getSurfaceFromANativeWindow(
605 ANativeWindow* anw, sp<Surface>& out) {
606 if (anw == nullptr) {
607 ALOGE("Error: output ANativeWindow is null");
608 return ACAMERA_ERROR_INVALID_PARAMETER;
609 }
610 int value;
611 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800612 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800613 ALOGE("Error: ANativeWindow is not backed by Surface!");
614 return ACAMERA_ERROR_INVALID_PARAMETER;
615 }
616 sp<Surface> surface(static_cast<Surface*>(anw));
617 out = surface;
618 return ACAMERA_OK;
619}
620
621camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100622CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
623 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800624 ACaptureSessionOutputContainer emptyOutput;
625 if (outputs == nullptr) {
626 outputs = &emptyOutput;
627 }
628
Yin-Chia Yehead91462016-01-06 16:45:08 -0800629 camera_status_t ret = checkCameraClosedOrErrorLocked();
630 if (ret != ACAMERA_OK) {
631 return ret;
632 }
633
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700634 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800635 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700636 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800637 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700638 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800639 if (ret != ACAMERA_OK) {
640 return ret;
641 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800642 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700643 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800644 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100645 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800646 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700647 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800648 std::vector<int> deleteList;
649
650 // Determine which streams need to be created, which to be deleted
651 for (auto& kvPair : mConfiguredOutputs) {
652 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700653 auto& outputPair = kvPair.second;
654 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800655 deleteList.push_back(streamId); // Need to delete a no longer needed stream
656 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700657 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800658 }
659 }
660
661 ret = stopRepeatingLocked();
662 if (ret != ACAMERA_OK) {
663 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
664 return ret;
665 }
666
667 ret = waitUntilIdleLocked();
668 if (ret != ACAMERA_OK) {
669 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
670 return ret;
671 }
672
673 // Send onReady to previous session
674 // CurrentSession will be updated after configureStreamLocked, so here
675 // mCurrentSession is the session to be replaced by a new session
676 if (!mIdle && mCurrentSession != nullptr) {
677 if (mBusySession != mCurrentSession) {
678 ALOGE("Current session != busy session");
679 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
680 return ACAMERA_ERROR_CAMERA_DEVICE;
681 }
682 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
683 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
684 msg->setObject(kSessionSpKey, mBusySession);
685 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
686 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700687 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800688 }
689 mIdle = true;
690
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800691 binder::Status remoteRet = mRemote->beginConfigure();
692 if (!remoteRet.isOk()) {
693 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800694 return ACAMERA_ERROR_UNKNOWN;
695 }
696
697 // delete to-be-deleted streams
698 for (auto streamId : deleteList) {
699 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800700 if (!remoteRet.isOk()) {
701 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
702 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800703 return ACAMERA_ERROR_UNKNOWN;
704 }
705 mConfiguredOutputs.erase(streamId);
706 }
707
708 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800709 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800710 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700711 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800712 if (!remoteRet.isOk()) {
713 ALOGE("Camera device %s failed to create stream: %s", getId(),
714 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800715 return ACAMERA_ERROR_UNKNOWN;
716 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700717 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800718 }
719
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100720 CameraMetadata params;
721 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
722 params.append(sessionParameters->settings->getInternalData());
723 }
724 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800725 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
726 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
727 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800728 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800729 } else if (!remoteRet.isOk()) {
730 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800731 return ACAMERA_ERROR_UNKNOWN;
732 }
733
734 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800735}
736
737void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800738CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800739 Mutex::Autolock _l(mDeviceLock);
740 mRemote = remote;
741}
742
743camera_status_t
744CameraDevice::checkCameraClosedOrErrorLocked() const {
745 if (mRemote == nullptr) {
746 ALOGE("%s: camera device already closed", __FUNCTION__);
747 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
748 }
749 if (mInError) {// triggered by onDeviceError
750 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
751 return mError;
752 }
753 return ACAMERA_OK;
754}
755
756void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800757CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
758 mInError = true;
759 mError = error;
760 return;
761}
762
763void
764CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
765 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
766 if (isError) {
767 mFutureErrorSet.insert(frameNumber);
768 } else if (frameNumber <= mCompletedFrameNumber) {
769 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
770 frameNumber, mCompletedFrameNumber);
771 return;
772 } else {
773 if (frameNumber != mCompletedFrameNumber + 1) {
774 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
775 mCompletedFrameNumber + 1, frameNumber);
776 // Do not assert as in java implementation
777 }
778 mCompletedFrameNumber = frameNumber;
779 }
780 update();
781}
782
783void
784CameraDevice::FrameNumberTracker::update() {
785 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
786 int64_t errorFrameNumber = *it;
787 if (errorFrameNumber == mCompletedFrameNumber + 1) {
788 mCompletedFrameNumber++;
789 it = mFutureErrorSet.erase(it);
790 } else if (errorFrameNumber <= mCompletedFrameNumber) {
791 // This should not happen, but deal with it anyway
792 ALOGE("Completd frame number passed through current frame number!");
793 // erase the old error since it's no longer useful
794 it = mFutureErrorSet.erase(it);
795 } else {
796 // Normal requests hasn't catched up error frames, just break
797 break;
798 }
799 }
800 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
801}
802
803void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800804CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800805 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800806 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800807 int sequenceId = resultExtras.requestId;
808 int64_t frameNumber = resultExtras.frameNumber;
809 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700810 auto it = mSequenceCallbackMap.find(sequenceId);
811 if (it == mSequenceCallbackMap.end()) {
812 ALOGE("%s: Error: capture sequence index %d not found!",
813 __FUNCTION__, sequenceId);
814 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800815 return;
816 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700817
818 CallbackHolder cbh = (*it).second;
819 sp<ACameraCaptureSession> session = cbh.mSession;
820 if ((size_t) burstId >= cbh.mRequests.size()) {
821 ALOGE("%s: Error: request index %d out of bound (size %zu)",
822 __FUNCTION__, burstId, cbh.mRequests.size());
823 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
824 return;
825 }
826 sp<CaptureRequest> request = cbh.mRequests[burstId];
827
828 // Handle buffer error
829 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
830 int32_t streamId = resultExtras.errorStreamId;
831 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800832 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700833 auto outputPairIt = mConfiguredOutputs.find(streamId);
834 if (outputPairIt == mConfiguredOutputs.end()) {
835 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800836 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
837 return;
838 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700839
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800840 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
841 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800842 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800843 if (surface->getIGraphicBufferProducer() == outGbp) {
844 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
845 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
846 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700847
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800848 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800849 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800850 msg->setObject(kSessionSpKey, session);
851 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
852 msg->setObject(kCaptureRequestKey, request);
853 msg->setPointer(kAnwKey, (void*) anw);
854 msg->setInt64(kFrameNumberKey, frameNumber);
855 postSessionMsgAndCleanup(msg);
856 }
857 }
858 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700859 } else { // Handle other capture failures
860 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800861 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800862 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
863 failure->frameNumber = frameNumber;
864 // TODO: refine this when implementing flush
865 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
866 failure->sequenceId = sequenceId;
867 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800868 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800869
870 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800871 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800872 msg->setObject(kSessionSpKey, session);
873 msg->setPointer(kCallbackFpKey, (void*) onError);
874 msg->setObject(kCaptureRequestKey, request);
875 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700876 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800877
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700878 // Update tracker
879 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
880 checkAndFireSequenceCompleteLocked();
881 }
882 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800883}
884
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800885CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
886}
887
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800888void CameraDevice::CallbackHandler::onMessageReceived(
889 const sp<AMessage> &msg) {
890 switch (msg->what()) {
891 case kWhatOnDisconnected:
892 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800893 case kWhatSessionStateCb:
894 case kWhatCaptureStart:
895 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800896 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800897 case kWhatCaptureFail:
898 case kWhatCaptureSeqEnd:
899 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700900 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800901 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800902 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700903 case kWhatCleanUpSessions:
904 mCachedSessions.clear();
905 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800906 default:
907 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
908 return;
909 }
910 // Check the common part of all message
911 void* context;
912 bool found = msg->findPointer(kContextKey, &context);
913 if (!found) {
914 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
915 return;
916 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800917 switch (msg->what()) {
918 case kWhatOnDisconnected:
919 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800920 ACameraDevice* dev;
921 found = msg->findPointer(kDeviceKey, (void**) &dev);
922 if (!found || dev == nullptr) {
923 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
924 return;
925 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800926 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800927 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800928 if (!found) {
929 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
930 return;
931 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800932 if (onDisconnected == nullptr) {
933 return;
934 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800935 (*onDisconnected)(context, dev);
936 break;
937 }
938 case kWhatOnError:
939 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800940 ACameraDevice* dev;
941 found = msg->findPointer(kDeviceKey, (void**) &dev);
942 if (!found || dev == nullptr) {
943 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
944 return;
945 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800946 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800947 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800948 if (!found) {
949 ALOGE("%s: Cannot find onError!", __FUNCTION__);
950 return;
951 }
952 int errorCode;
953 found = msg->findInt32(kErrorCodeKey, &errorCode);
954 if (!found) {
955 ALOGE("%s: Cannot find error code!", __FUNCTION__);
956 return;
957 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800958 if (onError == nullptr) {
959 return;
960 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800961 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800962 break;
963 }
964 case kWhatSessionStateCb:
965 case kWhatCaptureStart:
966 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800967 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800968 case kWhatCaptureFail:
969 case kWhatCaptureSeqEnd:
970 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700971 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800972 {
973 sp<RefBase> obj;
974 found = msg->findObject(kSessionSpKey, &obj);
975 if (!found || obj == nullptr) {
976 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
977 return;
978 }
979 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700980 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800981 sp<CaptureRequest> requestSp = nullptr;
982 switch (msg->what()) {
983 case kWhatCaptureStart:
984 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800985 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800986 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700987 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800988 found = msg->findObject(kCaptureRequestKey, &obj);
989 if (!found) {
990 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
991 return;
992 }
993 requestSp = static_cast<CaptureRequest*>(obj.get());
994 break;
995 }
996
997 switch (msg->what()) {
998 case kWhatSessionStateCb:
999 {
1000 ACameraCaptureSession_stateCallback onState;
1001 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1002 if (!found) {
1003 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1004 return;
1005 }
1006 if (onState == nullptr) {
1007 return;
1008 }
1009 (*onState)(context, session.get());
1010 break;
1011 }
1012 case kWhatCaptureStart:
1013 {
1014 ACameraCaptureSession_captureCallback_start onStart;
1015 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1016 if (!found) {
1017 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1018 return;
1019 }
1020 if (onStart == nullptr) {
1021 return;
1022 }
1023 int64_t timestamp;
1024 found = msg->findInt64(kTimeStampKey, &timestamp);
1025 if (!found) {
1026 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1027 return;
1028 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001029 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001030 (*onStart)(context, session.get(), request, timestamp);
1031 freeACaptureRequest(request);
1032 break;
1033 }
1034 case kWhatCaptureResult:
1035 {
1036 ACameraCaptureSession_captureCallback_result onResult;
1037 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1038 if (!found) {
1039 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1040 return;
1041 }
1042 if (onResult == nullptr) {
1043 return;
1044 }
1045
1046 found = msg->findObject(kCaptureResultKey, &obj);
1047 if (!found) {
1048 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1049 return;
1050 }
1051 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001052 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001053 (*onResult)(context, session.get(), request, result.get());
1054 freeACaptureRequest(request);
1055 break;
1056 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001057 case kWhatLogicalCaptureResult:
1058 {
1059 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1060 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1061 if (!found) {
1062 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1063 __FUNCTION__);
1064 return;
1065 }
1066 if (onResult == nullptr) {
1067 return;
1068 }
1069
1070 found = msg->findObject(kCaptureResultKey, &obj);
1071 if (!found) {
1072 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1073 return;
1074 }
1075 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1076
1077 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1078 if (!found) {
1079 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1080 return;
1081 }
1082 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1083 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1084 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1085 physicalResult->mPhysicalResultInfo;
1086
1087 std::vector<std::string> physicalCameraIds;
1088 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1089 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1090 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1091 physicalCameraIds.push_back(physicalId8.c_str());
1092
1093 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1094 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1095 &physicalResult->mFrameNumber, /*data_count*/1);
1096 sp<ACameraMetadata> metadata =
1097 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1098 physicalMetadataCopy.push_back(metadata);
1099 }
1100
1101 std::vector<const char*> physicalCameraIdPtrs;
1102 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1103 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1104 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1105 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1106 }
1107
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001108 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001109 (*onResult)(context, session.get(), request, result.get(),
1110 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1111 physicalMetadataCopyPtrs.data());
1112 freeACaptureRequest(request);
1113 break;
1114 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001115 case kWhatCaptureFail:
1116 {
1117 ACameraCaptureSession_captureCallback_failed onFail;
1118 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1119 if (!found) {
1120 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1121 return;
1122 }
1123 if (onFail == nullptr) {
1124 return;
1125 }
1126
1127 found = msg->findObject(kCaptureFailureKey, &obj);
1128 if (!found) {
1129 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1130 return;
1131 }
1132 sp<CameraCaptureFailure> failureSp(
1133 static_cast<CameraCaptureFailure*>(obj.get()));
1134 ACameraCaptureFailure* failure =
1135 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001136 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001137 (*onFail)(context, session.get(), request, failure);
1138 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001139 break;
1140 }
1141 case kWhatCaptureSeqEnd:
1142 {
1143 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1144 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1145 if (!found) {
1146 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1147 return;
1148 }
1149 if (onSeqEnd == nullptr) {
1150 return;
1151 }
1152 int seqId;
1153 found = msg->findInt32(kSequenceIdKey, &seqId);
1154 if (!found) {
1155 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1156 return;
1157 }
1158 int64_t frameNumber;
1159 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1160 if (!found) {
1161 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1162 return;
1163 }
1164 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1165 break;
1166 }
1167 case kWhatCaptureSeqAbort:
1168 {
1169 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1170 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1171 if (!found) {
1172 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1173 return;
1174 }
1175 if (onSeqAbort == nullptr) {
1176 return;
1177 }
1178 int seqId;
1179 found = msg->findInt32(kSequenceIdKey, &seqId);
1180 if (!found) {
1181 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1182 return;
1183 }
1184 (*onSeqAbort)(context, session.get(), seqId);
1185 break;
1186 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001187 case kWhatCaptureBufferLost:
1188 {
1189 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1190 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1191 if (!found) {
1192 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1193 return;
1194 }
1195 if (onBufferLost == nullptr) {
1196 return;
1197 }
1198
1199 ANativeWindow* anw;
1200 found = msg->findPointer(kAnwKey, (void**) &anw);
1201 if (!found) {
1202 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1203 return;
1204 }
1205
1206 int64_t frameNumber;
1207 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1208 if (!found) {
1209 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1210 return;
1211 }
1212
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001213 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001214 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1215 freeACaptureRequest(request);
1216 break;
1217 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001218 }
1219 break;
1220 }
1221 }
1222}
1223
1224CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001225 sp<ACameraCaptureSession> session,
1226 const Vector<sp<CaptureRequest> >& requests,
1227 bool isRepeating,
1228 ACameraCaptureSession_captureCallbacks* cbs) :
1229 mSession(session), mRequests(requests),
1230 mIsRepeating(isRepeating),
1231 mIsLogicalCameraCallback(false) {
1232 initCaptureCallbacks(cbs);
1233
1234 if (cbs != nullptr) {
1235 mOnCaptureCompleted = cbs->onCaptureCompleted;
1236 }
1237}
1238
1239CameraDevice::CallbackHolder::CallbackHolder(
1240 sp<ACameraCaptureSession> session,
1241 const Vector<sp<CaptureRequest> >& requests,
1242 bool isRepeating,
1243 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1244 mSession(session), mRequests(requests),
1245 mIsRepeating(isRepeating),
1246 mIsLogicalCameraCallback(true) {
1247 initCaptureCallbacks(lcbs);
1248
1249 if (lcbs != nullptr) {
1250 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1251 }
1252}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001253
1254void
1255CameraDevice::checkRepeatingSequenceCompleteLocked(
1256 const int sequenceId, const int64_t lastFrameNumber) {
1257 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1258 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1259 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1260 ALOGW("No callback found for sequenceId %d", sequenceId);
1261 return;
1262 }
1263 // remove callback holder from callback map
1264 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1265 CallbackHolder cbh = cbIt->second;
1266 mSequenceCallbackMap.erase(cbIt);
1267 // send seq aborted callback
1268 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001269 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001270 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001271 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001272 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001273 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001274 } else {
1275 // Use mSequenceLastFrameNumberMap to track
1276 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1277
1278 // Last frame might have arrived. Check now
1279 checkAndFireSequenceCompleteLocked();
1280 }
1281}
1282
1283void
1284CameraDevice::checkAndFireSequenceCompleteLocked() {
1285 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1286 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1287 auto it = mSequenceLastFrameNumberMap.begin();
1288 while (it != mSequenceLastFrameNumberMap.end()) {
1289 int sequenceId = it->first;
1290 int64_t lastFrameNumber = it->second;
1291 bool seqCompleted = false;
1292 bool hasCallback = true;
1293
1294 if (mRemote == nullptr) {
1295 ALOGW("Camera %s closed while checking sequence complete", getId());
1296 return;
1297 }
1298
1299 // Check if there is callback for this sequence
1300 // This should not happen because we always register callback (with nullptr inside)
1301 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1302 ALOGW("No callback found for sequenceId %d", sequenceId);
1303 hasCallback = false;
1304 }
1305
1306 if (lastFrameNumber <= completedFrameNumber) {
1307 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1308 sequenceId, lastFrameNumber, completedFrameNumber);
1309 seqCompleted = true;
1310 }
1311
1312 if (seqCompleted && hasCallback) {
1313 // remove callback holder from callback map
1314 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1315 CallbackHolder cbh = cbIt->second;
1316 mSequenceCallbackMap.erase(cbIt);
1317 // send seq complete callback
1318 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001319 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001320 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001321 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001322 msg->setInt32(kSequenceIdKey, sequenceId);
1323 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1324
1325 // Clear the session sp before we send out the message
1326 // This will guarantee the rare case where the message is processed
1327 // before cbh goes out of scope and causing we call the session
1328 // destructor while holding device lock
1329 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001330 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001331 }
1332
1333 // No need to track sequence complete if there is no callback registered
1334 if (seqCompleted || !hasCallback) {
1335 it = mSequenceLastFrameNumberMap.erase(it);
1336 } else {
1337 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001338 }
1339 }
1340}
1341
1342/**
1343 * Camera service callback implementation
1344 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001345binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001346CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001347 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001348 const CaptureResultExtras& resultExtras) {
1349 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1350 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001351 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001352 sp<CameraDevice> dev = mDevice.promote();
1353 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001354 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001355 }
1356
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001357 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001358 Mutex::Autolock _l(dev->mDeviceLock);
1359 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001360 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001361 }
1362 switch (errorCode) {
1363 case ERROR_CAMERA_DISCONNECTED:
1364 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001365 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001366 if (session != nullptr) {
1367 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001368 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001369 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001370 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1371 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1372 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001373 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001374 msg->post();
1375 break;
1376 }
1377 default:
1378 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001379 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001380 case ERROR_CAMERA_DEVICE:
1381 case ERROR_CAMERA_SERVICE:
1382 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001383 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1384 // We keep this switch since this block might be encountered with
1385 // more than just 2 states. The default fallthrough could have us
1386 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001387 switch (errorCode) {
1388 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001389 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001390 break;
1391 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001392 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001393 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001394 break;
1395 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001396 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001397 break;
1398 }
1399 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1400 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1401 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001402 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001403 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001404 msg->post();
1405 break;
1406 }
1407 case ERROR_CAMERA_REQUEST:
1408 case ERROR_CAMERA_RESULT:
1409 case ERROR_CAMERA_BUFFER:
1410 dev->onCaptureErrorLocked(errorCode, resultExtras);
1411 break;
1412 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001413 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001414}
1415
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001416binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001417CameraDevice::ServiceCallback::onDeviceIdle() {
1418 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001419 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001420 sp<CameraDevice> dev = mDevice.promote();
1421 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001422 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001423 }
1424
1425 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001426 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001427 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001428 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001429
1430 if (dev->mIdle) {
1431 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001432 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001433 }
1434
1435 if (dev->mCurrentSession != nullptr) {
1436 ALOGE("onDeviceIdle sending state cb");
1437 if (dev->mBusySession != dev->mCurrentSession) {
1438 ALOGE("Current session != busy session");
1439 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001440 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001441 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001442
Yin-Chia Yehead91462016-01-06 16:45:08 -08001443 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1444 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1445 msg->setObject(kSessionSpKey, dev->mBusySession);
1446 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1447 // Make sure we clear the sp first so the session destructor can
1448 // only happen on handler thread (where we don't hold device/session lock)
1449 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001450 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001451 }
1452 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001453 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001454 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001455}
1456
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001457binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001458CameraDevice::ServiceCallback::onCaptureStarted(
1459 const CaptureResultExtras& resultExtras,
1460 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001461 binder::Status ret = binder::Status::ok();
1462
Yin-Chia Yehead91462016-01-06 16:45:08 -08001463 sp<CameraDevice> dev = mDevice.promote();
1464 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001465 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001466 }
1467 Mutex::Autolock _l(dev->mDeviceLock);
1468 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001469 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001470 }
1471
1472 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001473 int32_t burstId = resultExtras.burstId;
1474
1475 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1476 if (it != dev->mSequenceCallbackMap.end()) {
1477 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001478 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001479 sp<ACameraCaptureSession> session = cbh.mSession;
1480 if ((size_t) burstId >= cbh.mRequests.size()) {
1481 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1482 __FUNCTION__, burstId, cbh.mRequests.size());
1483 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1484 }
1485 sp<CaptureRequest> request = cbh.mRequests[burstId];
1486 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001487 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001488 msg->setObject(kSessionSpKey, session);
1489 msg->setPointer(kCallbackFpKey, (void*) onStart);
1490 msg->setObject(kCaptureRequestKey, request);
1491 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001492 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001493 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001494 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001495}
1496
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001497binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001498CameraDevice::ServiceCallback::onResultReceived(
1499 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001500 const CaptureResultExtras& resultExtras,
1501 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001502 binder::Status ret = binder::Status::ok();
1503
Yin-Chia Yehead91462016-01-06 16:45:08 -08001504 sp<CameraDevice> dev = mDevice.promote();
1505 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001506 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001507 }
1508 int sequenceId = resultExtras.requestId;
1509 int64_t frameNumber = resultExtras.frameNumber;
1510 int32_t burstId = resultExtras.burstId;
1511 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1512
1513 if (!isPartialResult) {
1514 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1515 }
1516
1517 Mutex::Autolock _l(dev->mDeviceLock);
1518 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001519 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001520 }
1521
1522 if (dev->isClosed()) {
1523 if (!isPartialResult) {
1524 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1525 }
1526 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001527 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001528 }
1529
1530 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001531 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001532 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001533
1534 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1535 if (it != dev->mSequenceCallbackMap.end()) {
1536 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001537 sp<ACameraCaptureSession> session = cbh.mSession;
1538 if ((size_t) burstId >= cbh.mRequests.size()) {
1539 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1540 __FUNCTION__, burstId, cbh.mRequests.size());
1541 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1542 }
1543 sp<CaptureRequest> request = cbh.mRequests[burstId];
1544 sp<ACameraMetadata> result(new ACameraMetadata(
1545 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001546 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1547 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001548
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001549 sp<AMessage> msg = new AMessage(
1550 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1551 dev->mHandler);
1552 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001553 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001554 msg->setObject(kCaptureRequestKey, request);
1555 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001556 if (isPartialResult) {
1557 msg->setPointer(kCallbackFpKey,
1558 (void *)cbh.mOnCaptureProgressed);
1559 } else if (cbh.mIsLogicalCameraCallback) {
1560 msg->setPointer(kCallbackFpKey,
1561 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1562 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1563 } else {
1564 msg->setPointer(kCallbackFpKey,
1565 (void *)cbh.mOnCaptureCompleted);
1566 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001567 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001568 }
1569
1570 if (!isPartialResult) {
1571 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1572 dev->checkAndFireSequenceCompleteLocked();
1573 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001574
1575 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001576}
1577
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001578binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001579CameraDevice::ServiceCallback::onPrepared(int) {
1580 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001581 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001582}
1583
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001584binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001585CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1586 // onRequestQueueEmpty not yet implemented in NDK
1587 return binder::Status::ok();
1588}
1589
1590binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001591CameraDevice::ServiceCallback::onRepeatingRequestError(
1592 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001593 binder::Status ret = binder::Status::ok();
1594
1595 sp<CameraDevice> dev = mDevice.promote();
1596 if (dev == nullptr) {
1597 return ret; // device has been closed
1598 }
1599
1600 Mutex::Autolock _l(dev->mDeviceLock);
1601
1602 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001603 if (stoppedSequenceId == repeatingSequenceId) {
1604 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1605 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001606
1607 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1608
1609 return ret;
1610}
1611
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001612} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001613} // namespace android