blob: 5e4fcd07fd9e0431694c564437ade5161224f864 [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
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800230camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100231 camera_status_t ret = checkCameraClosedOrErrorLocked();
232 if (ret != ACAMERA_OK) {
233 return ret;
234 }
235
236 if (output == nullptr) {
237 return ACAMERA_ERROR_INVALID_PARAMETER;
238 }
239
240 if (!output->mIsShared) {
241 ALOGE("Error output configuration is not shared");
242 return ACAMERA_ERROR_INVALID_OPERATION;
243 }
244
245 int32_t streamId = -1;
246 for (auto& kvPair : mConfiguredOutputs) {
247 if (kvPair.second.first == output->mWindow) {
248 streamId = kvPair.first;
249 break;
250 }
251 }
252 if (streamId < 0) {
253 ALOGE("Error: Invalid output configuration");
254 return ACAMERA_ERROR_INVALID_PARAMETER;
255 }
256
257 sp<IGraphicBufferProducer> iGBP(nullptr);
258 ret = getIGBPfromAnw(output->mWindow, iGBP);
259 if (ret != ACAMERA_OK) {
260 ALOGE("Camera device %s failed to extract graphic producer from native window",
261 getId());
262 return ret;
263 }
264
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800265 String16 physicalId16(output->mPhysicalCameraId.c_str());
266 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
267 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100268
269 for (auto& anw : output->mSharedWindows) {
270 ret = getIGBPfromAnw(anw, iGBP);
271 if (ret != ACAMERA_OK) {
272 ALOGE("Camera device %s failed to extract graphic producer from native window",
273 getId());
274 return ret;
275 }
276 outConfig.addGraphicProducer(iGBP);
277 }
278
279 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
280 if (!remoteRet.isOk()) {
281 switch (remoteRet.serviceSpecificErrorCode()) {
282 case hardware::ICameraService::ERROR_INVALID_OPERATION:
283 ALOGE("Camera device %s invalid operation: %s", getId(),
284 remoteRet.toString8().string());
285 return ACAMERA_ERROR_INVALID_OPERATION;
286 break;
287 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
288 ALOGE("Camera device %s output surface already exists: %s", getId(),
289 remoteRet.toString8().string());
290 return ACAMERA_ERROR_INVALID_PARAMETER;
291 break;
292 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
293 ALOGE("Camera device %s invalid input argument: %s", getId(),
294 remoteRet.toString8().string());
295 return ACAMERA_ERROR_INVALID_PARAMETER;
296 break;
297 default:
298 ALOGE("Camera device %s failed to add shared output: %s", getId(),
299 remoteRet.toString8().string());
300 return ACAMERA_ERROR_UNKNOWN;
301 }
302 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800303 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100304
305 return ACAMERA_OK;
306}
307
Yin-Chia Yehead91462016-01-06 16:45:08 -0800308camera_status_t
309CameraDevice::allocateCaptureRequest(
310 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
311 camera_status_t ret;
312 sp<CaptureRequest> req(new CaptureRequest());
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800313 req->mPhysicalCameraSettings.push_back({getId(),
Emilian Peevaebbe412018-01-15 13:53:24 +0000314 request->settings->getInternalData()});
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800315 for (auto& entry : request->physicalSettings) {
316 req->mPhysicalCameraSettings.push_back({entry.first,
317 entry.second->getInternalData()});
318 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800319 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700320 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800321 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800322
323 for (auto outputTarget : request->targets->mOutputs) {
324 ANativeWindow* anw = outputTarget.mWindow;
325 sp<Surface> surface;
326 ret = getSurfaceFromANativeWindow(anw, surface);
327 if (ret != ACAMERA_OK) {
328 ALOGE("Bad output target in capture request! ret %d", ret);
329 return ret;
330 }
331 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800332
333 bool found = false;
334 // lookup stream/surface ID
335 for (const auto& kvPair : mConfiguredOutputs) {
336 int streamId = kvPair.first;
337 const OutputConfiguration& outConfig = kvPair.second.second;
338 const auto& gbps = outConfig.getGraphicBufferProducers();
339 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
340 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
341 found = true;
342 req->mStreamIdxList.push_back(streamId);
343 req->mSurfaceIdxList.push_back(surfaceId);
344 break;
345 }
346 }
347 if (found) {
348 break;
349 }
350 }
351 if (!found) {
352 ALOGE("Unconfigured output target %p in capture request!", anw);
353 return ret;
354 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800355 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800356
Yin-Chia Yehead91462016-01-06 16:45:08 -0800357 outReq = req;
358 return ACAMERA_OK;
359}
360
361ACaptureRequest*
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800362CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800363 ACaptureRequest* pRequest = new ACaptureRequest();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800364 for (auto& entry : req->mPhysicalCameraSettings) {
365 CameraMetadata clone = entry.settings;
366 if (entry.id == deviceId) {
367 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
368 } else {
369 pRequest->physicalSettings.emplace(entry.id,
370 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
371 }
372 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800373 pRequest->targets = new ACameraOutputTargets();
374 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
375 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
376 ACameraOutputTarget outputTarget(anw);
377 pRequest->targets->mOutputs.insert(outputTarget);
378 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700379 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800380 return pRequest;
381}
382
383void
384CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
385 if (req == nullptr) {
386 return;
387 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700388 req->settings.clear();
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800389 req->physicalSettings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800390 delete req->targets;
391 delete req;
392}
393
394void
395CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
396 if (isClosed()) {
397 // Device is closing already. do nothing
398 return;
399 }
400
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700401 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800402 // Session has been replaced by other seesion or device is closed
403 return;
404 }
405 mCurrentSession = nullptr;
406
407 // Should not happen
408 if (!session->mIsClosed) {
409 ALOGE("Error: unclosed session %p reaches end of life!", session);
410 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
411 return;
412 }
413
414 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100415 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800416 if (ret != ACAMERA_OK) {
417 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
418 }
419}
420
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800421void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700422CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800423 if (mClosing.exchange(true)) {
424 // Already closing, just return
425 ALOGW("Camera device %s is already closing.", getId());
426 return;
427 }
428
429 if (mRemote != nullptr) {
430 mRemote->disconnect();
431 }
432 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800433
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700434 if (session != nullptr) {
435 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800436 }
437}
438
439camera_status_t
440CameraDevice::stopRepeatingLocked() {
441 camera_status_t ret = checkCameraClosedOrErrorLocked();
442 if (ret != ACAMERA_OK) {
443 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
444 return ret;
445 }
446 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
447 int repeatingSequenceId = mRepeatingSequenceId;
448 mRepeatingSequenceId = REQUEST_ID_NONE;
449
450 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800451 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700452 if (remoteRet.serviceSpecificErrorCode() ==
453 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
454 ALOGV("Repeating request is already stopped.");
455 return ACAMERA_OK;
456 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800457 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800458 return ACAMERA_ERROR_UNKNOWN;
459 }
460 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
461 }
462 return ACAMERA_OK;
463}
464
465camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700466CameraDevice::flushLocked(ACameraCaptureSession* session) {
467 camera_status_t ret = checkCameraClosedOrErrorLocked();
468 if (ret != ACAMERA_OK) {
469 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
470 return ret;
471 }
472
473 // This should never happen because creating a new session will close
474 // previous one and thus reject any API call from previous session.
475 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700476 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700477 ALOGE("Camera %s session %p is not current active session!", getId(), session);
478 return ACAMERA_ERROR_INVALID_OPERATION;
479 }
480
481 if (mFlushing) {
482 ALOGW("Camera %s is already aborting captures", getId());
483 return ACAMERA_OK;
484 }
485
486 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700487
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700488 // Send onActive callback to guarantee there is always active->ready transition
489 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
490 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
491 msg->setObject(kSessionSpKey, session);
492 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700493 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700494
495 // If device is already idling, send callback and exit early
496 if (mIdle) {
497 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
498 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
499 msg->setObject(kSessionSpKey, session);
500 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700501 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700502 mFlushing = false;
503 return ACAMERA_OK;
504 }
505
506 int64_t lastFrameNumber;
507 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
508 if (!remoteRet.isOk()) {
509 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
510 return ACAMERA_ERROR_UNKNOWN;
511 }
512 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
513 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
514 }
515 return ACAMERA_OK;
516}
517
518camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800519CameraDevice::waitUntilIdleLocked() {
520 camera_status_t ret = checkCameraClosedOrErrorLocked();
521 if (ret != ACAMERA_OK) {
522 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
523 return ret;
524 }
525
526 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
527 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
528 return ACAMERA_ERROR_INVALID_OPERATION;
529 }
530
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800531 binder::Status remoteRet = mRemote->waitUntilIdle();
532 if (!remoteRet.isOk()) {
533 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800534 // TODO: define a function to convert status_t -> camera_status_t
535 return ACAMERA_ERROR_UNKNOWN;
536 }
537
538 return ACAMERA_OK;
539}
540
541camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700542CameraDevice::getIGBPfromAnw(
543 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800544 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800545 sp<Surface> surface;
546 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
547 if (ret != ACAMERA_OK) {
548 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800549 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800550 out = surface->getIGraphicBufferProducer();
551 return ACAMERA_OK;
552}
553
554camera_status_t
555CameraDevice::getSurfaceFromANativeWindow(
556 ANativeWindow* anw, sp<Surface>& out) {
557 if (anw == nullptr) {
558 ALOGE("Error: output ANativeWindow is null");
559 return ACAMERA_ERROR_INVALID_PARAMETER;
560 }
561 int value;
562 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800563 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800564 ALOGE("Error: ANativeWindow is not backed by Surface!");
565 return ACAMERA_ERROR_INVALID_PARAMETER;
566 }
567 sp<Surface> surface(static_cast<Surface*>(anw));
568 out = surface;
569 return ACAMERA_OK;
570}
571
572camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100573CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
574 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800575 ACaptureSessionOutputContainer emptyOutput;
576 if (outputs == nullptr) {
577 outputs = &emptyOutput;
578 }
579
Yin-Chia Yehead91462016-01-06 16:45:08 -0800580 camera_status_t ret = checkCameraClosedOrErrorLocked();
581 if (ret != ACAMERA_OK) {
582 return ret;
583 }
584
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700585 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800586 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700587 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800588 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700589 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800590 if (ret != ACAMERA_OK) {
591 return ret;
592 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800593 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700594 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800595 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100596 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800597 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700598 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800599 std::vector<int> deleteList;
600
601 // Determine which streams need to be created, which to be deleted
602 for (auto& kvPair : mConfiguredOutputs) {
603 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700604 auto& outputPair = kvPair.second;
605 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800606 deleteList.push_back(streamId); // Need to delete a no longer needed stream
607 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700608 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800609 }
610 }
611
612 ret = stopRepeatingLocked();
613 if (ret != ACAMERA_OK) {
614 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
615 return ret;
616 }
617
618 ret = waitUntilIdleLocked();
619 if (ret != ACAMERA_OK) {
620 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
621 return ret;
622 }
623
624 // Send onReady to previous session
625 // CurrentSession will be updated after configureStreamLocked, so here
626 // mCurrentSession is the session to be replaced by a new session
627 if (!mIdle && mCurrentSession != nullptr) {
628 if (mBusySession != mCurrentSession) {
629 ALOGE("Current session != busy session");
630 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
631 return ACAMERA_ERROR_CAMERA_DEVICE;
632 }
633 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
634 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
635 msg->setObject(kSessionSpKey, mBusySession);
636 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
637 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700638 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800639 }
640 mIdle = true;
641
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800642 binder::Status remoteRet = mRemote->beginConfigure();
643 if (!remoteRet.isOk()) {
644 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800645 return ACAMERA_ERROR_UNKNOWN;
646 }
647
648 // delete to-be-deleted streams
649 for (auto streamId : deleteList) {
650 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800651 if (!remoteRet.isOk()) {
652 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
653 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800654 return ACAMERA_ERROR_UNKNOWN;
655 }
656 mConfiguredOutputs.erase(streamId);
657 }
658
659 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800660 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800661 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700662 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800663 if (!remoteRet.isOk()) {
664 ALOGE("Camera device %s failed to create stream: %s", getId(),
665 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800666 return ACAMERA_ERROR_UNKNOWN;
667 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700668 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800669 }
670
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100671 CameraMetadata params;
672 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
673 params.append(sessionParameters->settings->getInternalData());
674 }
675 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800676 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
677 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
678 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800679 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800680 } else if (!remoteRet.isOk()) {
681 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800682 return ACAMERA_ERROR_UNKNOWN;
683 }
684
685 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800686}
687
688void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800689CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800690 Mutex::Autolock _l(mDeviceLock);
691 mRemote = remote;
692}
693
694camera_status_t
695CameraDevice::checkCameraClosedOrErrorLocked() const {
696 if (mRemote == nullptr) {
697 ALOGE("%s: camera device already closed", __FUNCTION__);
698 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
699 }
700 if (mInError) {// triggered by onDeviceError
701 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
702 return mError;
703 }
704 return ACAMERA_OK;
705}
706
707void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800708CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
709 mInError = true;
710 mError = error;
711 return;
712}
713
714void
715CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
716 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
717 if (isError) {
718 mFutureErrorSet.insert(frameNumber);
719 } else if (frameNumber <= mCompletedFrameNumber) {
720 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
721 frameNumber, mCompletedFrameNumber);
722 return;
723 } else {
724 if (frameNumber != mCompletedFrameNumber + 1) {
725 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
726 mCompletedFrameNumber + 1, frameNumber);
727 // Do not assert as in java implementation
728 }
729 mCompletedFrameNumber = frameNumber;
730 }
731 update();
732}
733
734void
735CameraDevice::FrameNumberTracker::update() {
736 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
737 int64_t errorFrameNumber = *it;
738 if (errorFrameNumber == mCompletedFrameNumber + 1) {
739 mCompletedFrameNumber++;
740 it = mFutureErrorSet.erase(it);
741 } else if (errorFrameNumber <= mCompletedFrameNumber) {
742 // This should not happen, but deal with it anyway
743 ALOGE("Completd frame number passed through current frame number!");
744 // erase the old error since it's no longer useful
745 it = mFutureErrorSet.erase(it);
746 } else {
747 // Normal requests hasn't catched up error frames, just break
748 break;
749 }
750 }
751 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
752}
753
754void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800755CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800756 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800757 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800758 int sequenceId = resultExtras.requestId;
759 int64_t frameNumber = resultExtras.frameNumber;
760 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700761 auto it = mSequenceCallbackMap.find(sequenceId);
762 if (it == mSequenceCallbackMap.end()) {
763 ALOGE("%s: Error: capture sequence index %d not found!",
764 __FUNCTION__, sequenceId);
765 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800766 return;
767 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700768
769 CallbackHolder cbh = (*it).second;
770 sp<ACameraCaptureSession> session = cbh.mSession;
771 if ((size_t) burstId >= cbh.mRequests.size()) {
772 ALOGE("%s: Error: request index %d out of bound (size %zu)",
773 __FUNCTION__, burstId, cbh.mRequests.size());
774 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
775 return;
776 }
777 sp<CaptureRequest> request = cbh.mRequests[burstId];
778
779 // Handle buffer error
780 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
781 int32_t streamId = resultExtras.errorStreamId;
782 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800783 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700784 auto outputPairIt = mConfiguredOutputs.find(streamId);
785 if (outputPairIt == mConfiguredOutputs.end()) {
786 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800787 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
788 return;
789 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700790
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800791 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
792 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800793 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800794 if (surface->getIGraphicBufferProducer() == outGbp) {
795 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
796 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
797 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700798
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800799 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800800 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800801 msg->setObject(kSessionSpKey, session);
802 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
803 msg->setObject(kCaptureRequestKey, request);
804 msg->setPointer(kAnwKey, (void*) anw);
805 msg->setInt64(kFrameNumberKey, frameNumber);
806 postSessionMsgAndCleanup(msg);
807 }
808 }
809 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700810 } else { // Handle other capture failures
811 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800812 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800813 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
814 failure->frameNumber = frameNumber;
815 // TODO: refine this when implementing flush
816 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
817 failure->sequenceId = sequenceId;
818 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800819 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800820
821 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800822 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800823 msg->setObject(kSessionSpKey, session);
824 msg->setPointer(kCallbackFpKey, (void*) onError);
825 msg->setObject(kCaptureRequestKey, request);
826 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700827 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800828
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700829 // Update tracker
830 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
831 checkAndFireSequenceCompleteLocked();
832 }
833 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800834}
835
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800836CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
837}
838
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800839void CameraDevice::CallbackHandler::onMessageReceived(
840 const sp<AMessage> &msg) {
841 switch (msg->what()) {
842 case kWhatOnDisconnected:
843 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800844 case kWhatSessionStateCb:
845 case kWhatCaptureStart:
846 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800847 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800848 case kWhatCaptureFail:
849 case kWhatCaptureSeqEnd:
850 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700851 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800852 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800853 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700854 case kWhatCleanUpSessions:
855 mCachedSessions.clear();
856 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800857 default:
858 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
859 return;
860 }
861 // Check the common part of all message
862 void* context;
863 bool found = msg->findPointer(kContextKey, &context);
864 if (!found) {
865 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
866 return;
867 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800868 switch (msg->what()) {
869 case kWhatOnDisconnected:
870 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800871 ACameraDevice* dev;
872 found = msg->findPointer(kDeviceKey, (void**) &dev);
873 if (!found || dev == nullptr) {
874 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
875 return;
876 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800877 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800878 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800879 if (!found) {
880 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
881 return;
882 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800883 if (onDisconnected == nullptr) {
884 return;
885 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800886 (*onDisconnected)(context, dev);
887 break;
888 }
889 case kWhatOnError:
890 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800891 ACameraDevice* dev;
892 found = msg->findPointer(kDeviceKey, (void**) &dev);
893 if (!found || dev == nullptr) {
894 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
895 return;
896 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800897 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800898 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800899 if (!found) {
900 ALOGE("%s: Cannot find onError!", __FUNCTION__);
901 return;
902 }
903 int errorCode;
904 found = msg->findInt32(kErrorCodeKey, &errorCode);
905 if (!found) {
906 ALOGE("%s: Cannot find error code!", __FUNCTION__);
907 return;
908 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800909 if (onError == nullptr) {
910 return;
911 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800912 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800913 break;
914 }
915 case kWhatSessionStateCb:
916 case kWhatCaptureStart:
917 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800918 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800919 case kWhatCaptureFail:
920 case kWhatCaptureSeqEnd:
921 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700922 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800923 {
924 sp<RefBase> obj;
925 found = msg->findObject(kSessionSpKey, &obj);
926 if (!found || obj == nullptr) {
927 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
928 return;
929 }
930 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700931 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800932 sp<CaptureRequest> requestSp = nullptr;
933 switch (msg->what()) {
934 case kWhatCaptureStart:
935 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800936 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800937 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700938 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800939 found = msg->findObject(kCaptureRequestKey, &obj);
940 if (!found) {
941 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
942 return;
943 }
944 requestSp = static_cast<CaptureRequest*>(obj.get());
945 break;
946 }
947
948 switch (msg->what()) {
949 case kWhatSessionStateCb:
950 {
951 ACameraCaptureSession_stateCallback onState;
952 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
953 if (!found) {
954 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
955 return;
956 }
957 if (onState == nullptr) {
958 return;
959 }
960 (*onState)(context, session.get());
961 break;
962 }
963 case kWhatCaptureStart:
964 {
965 ACameraCaptureSession_captureCallback_start onStart;
966 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
967 if (!found) {
968 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
969 return;
970 }
971 if (onStart == nullptr) {
972 return;
973 }
974 int64_t timestamp;
975 found = msg->findInt64(kTimeStampKey, &timestamp);
976 if (!found) {
977 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
978 return;
979 }
Shuzhen Wang6c17e212019-02-19 14:51:47 -0800980 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800981 (*onStart)(context, session.get(), request, timestamp);
982 freeACaptureRequest(request);
983 break;
984 }
985 case kWhatCaptureResult:
986 {
987 ACameraCaptureSession_captureCallback_result onResult;
988 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
989 if (!found) {
990 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
991 return;
992 }
993 if (onResult == nullptr) {
994 return;
995 }
996
997 found = msg->findObject(kCaptureResultKey, &obj);
998 if (!found) {
999 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1000 return;
1001 }
1002 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001003 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001004 (*onResult)(context, session.get(), request, result.get());
1005 freeACaptureRequest(request);
1006 break;
1007 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001008 case kWhatLogicalCaptureResult:
1009 {
1010 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1011 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1012 if (!found) {
1013 ALOGE("%s: Cannot find logicalCamera capture result callback!",
1014 __FUNCTION__);
1015 return;
1016 }
1017 if (onResult == nullptr) {
1018 return;
1019 }
1020
1021 found = msg->findObject(kCaptureResultKey, &obj);
1022 if (!found) {
1023 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1024 return;
1025 }
1026 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1027
1028 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1029 if (!found) {
1030 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1031 return;
1032 }
1033 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1034 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1035 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1036 physicalResult->mPhysicalResultInfo;
1037
1038 std::vector<std::string> physicalCameraIds;
1039 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1040 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1041 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
1042 physicalCameraIds.push_back(physicalId8.c_str());
1043
1044 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
1045 clone.update(ANDROID_SYNC_FRAME_NUMBER,
1046 &physicalResult->mFrameNumber, /*data_count*/1);
1047 sp<ACameraMetadata> metadata =
1048 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1049 physicalMetadataCopy.push_back(metadata);
1050 }
1051
1052 std::vector<const char*> physicalCameraIdPtrs;
1053 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1054 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1055 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1056 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1057 }
1058
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001059 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001060 (*onResult)(context, session.get(), request, result.get(),
1061 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1062 physicalMetadataCopyPtrs.data());
1063 freeACaptureRequest(request);
1064 break;
1065 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001066 case kWhatCaptureFail:
1067 {
1068 ACameraCaptureSession_captureCallback_failed onFail;
1069 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1070 if (!found) {
1071 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1072 return;
1073 }
1074 if (onFail == nullptr) {
1075 return;
1076 }
1077
1078 found = msg->findObject(kCaptureFailureKey, &obj);
1079 if (!found) {
1080 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1081 return;
1082 }
1083 sp<CameraCaptureFailure> failureSp(
1084 static_cast<CameraCaptureFailure*>(obj.get()));
1085 ACameraCaptureFailure* failure =
1086 static_cast<ACameraCaptureFailure*>(failureSp.get());
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001087 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001088 (*onFail)(context, session.get(), request, failure);
1089 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001090 break;
1091 }
1092 case kWhatCaptureSeqEnd:
1093 {
1094 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1095 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1096 if (!found) {
1097 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1098 return;
1099 }
1100 if (onSeqEnd == nullptr) {
1101 return;
1102 }
1103 int seqId;
1104 found = msg->findInt32(kSequenceIdKey, &seqId);
1105 if (!found) {
1106 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1107 return;
1108 }
1109 int64_t frameNumber;
1110 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1111 if (!found) {
1112 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1113 return;
1114 }
1115 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1116 break;
1117 }
1118 case kWhatCaptureSeqAbort:
1119 {
1120 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1121 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1122 if (!found) {
1123 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1124 return;
1125 }
1126 if (onSeqAbort == nullptr) {
1127 return;
1128 }
1129 int seqId;
1130 found = msg->findInt32(kSequenceIdKey, &seqId);
1131 if (!found) {
1132 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1133 return;
1134 }
1135 (*onSeqAbort)(context, session.get(), seqId);
1136 break;
1137 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001138 case kWhatCaptureBufferLost:
1139 {
1140 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1141 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1142 if (!found) {
1143 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1144 return;
1145 }
1146 if (onBufferLost == nullptr) {
1147 return;
1148 }
1149
1150 ANativeWindow* anw;
1151 found = msg->findPointer(kAnwKey, (void**) &anw);
1152 if (!found) {
1153 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1154 return;
1155 }
1156
1157 int64_t frameNumber;
1158 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1159 if (!found) {
1160 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1161 return;
1162 }
1163
Shuzhen Wang6c17e212019-02-19 14:51:47 -08001164 ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001165 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1166 freeACaptureRequest(request);
1167 break;
1168 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001169 }
1170 break;
1171 }
1172 }
1173}
1174
1175CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001176 sp<ACameraCaptureSession> session,
1177 const Vector<sp<CaptureRequest> >& requests,
1178 bool isRepeating,
1179 ACameraCaptureSession_captureCallbacks* cbs) :
1180 mSession(session), mRequests(requests),
1181 mIsRepeating(isRepeating),
1182 mIsLogicalCameraCallback(false) {
1183 initCaptureCallbacks(cbs);
1184
1185 if (cbs != nullptr) {
1186 mOnCaptureCompleted = cbs->onCaptureCompleted;
1187 }
1188}
1189
1190CameraDevice::CallbackHolder::CallbackHolder(
1191 sp<ACameraCaptureSession> session,
1192 const Vector<sp<CaptureRequest> >& requests,
1193 bool isRepeating,
1194 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1195 mSession(session), mRequests(requests),
1196 mIsRepeating(isRepeating),
1197 mIsLogicalCameraCallback(true) {
1198 initCaptureCallbacks(lcbs);
1199
1200 if (lcbs != nullptr) {
1201 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1202 }
1203}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001204
1205void
1206CameraDevice::checkRepeatingSequenceCompleteLocked(
1207 const int sequenceId, const int64_t lastFrameNumber) {
1208 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1209 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1210 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1211 ALOGW("No callback found for sequenceId %d", sequenceId);
1212 return;
1213 }
1214 // remove callback holder from callback map
1215 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1216 CallbackHolder cbh = cbIt->second;
1217 mSequenceCallbackMap.erase(cbIt);
1218 // send seq aborted callback
1219 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001220 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001221 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001222 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001223 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001224 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001225 } else {
1226 // Use mSequenceLastFrameNumberMap to track
1227 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1228
1229 // Last frame might have arrived. Check now
1230 checkAndFireSequenceCompleteLocked();
1231 }
1232}
1233
1234void
1235CameraDevice::checkAndFireSequenceCompleteLocked() {
1236 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1237 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1238 auto it = mSequenceLastFrameNumberMap.begin();
1239 while (it != mSequenceLastFrameNumberMap.end()) {
1240 int sequenceId = it->first;
1241 int64_t lastFrameNumber = it->second;
1242 bool seqCompleted = false;
1243 bool hasCallback = true;
1244
1245 if (mRemote == nullptr) {
1246 ALOGW("Camera %s closed while checking sequence complete", getId());
1247 return;
1248 }
1249
1250 // Check if there is callback for this sequence
1251 // This should not happen because we always register callback (with nullptr inside)
1252 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1253 ALOGW("No callback found for sequenceId %d", sequenceId);
1254 hasCallback = false;
1255 }
1256
1257 if (lastFrameNumber <= completedFrameNumber) {
1258 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1259 sequenceId, lastFrameNumber, completedFrameNumber);
1260 seqCompleted = true;
1261 }
1262
1263 if (seqCompleted && hasCallback) {
1264 // remove callback holder from callback map
1265 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1266 CallbackHolder cbh = cbIt->second;
1267 mSequenceCallbackMap.erase(cbIt);
1268 // send seq complete callback
1269 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001270 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001271 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001272 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001273 msg->setInt32(kSequenceIdKey, sequenceId);
1274 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1275
1276 // Clear the session sp before we send out the message
1277 // This will guarantee the rare case where the message is processed
1278 // before cbh goes out of scope and causing we call the session
1279 // destructor while holding device lock
1280 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001281 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001282 }
1283
1284 // No need to track sequence complete if there is no callback registered
1285 if (seqCompleted || !hasCallback) {
1286 it = mSequenceLastFrameNumberMap.erase(it);
1287 } else {
1288 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001289 }
1290 }
1291}
1292
1293/**
1294 * Camera service callback implementation
1295 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001296binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001297CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001298 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001299 const CaptureResultExtras& resultExtras) {
1300 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1301 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001302 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001303 sp<CameraDevice> dev = mDevice.promote();
1304 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001305 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001306 }
1307
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001308 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001309 Mutex::Autolock _l(dev->mDeviceLock);
1310 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001311 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001312 }
1313 switch (errorCode) {
1314 case ERROR_CAMERA_DISCONNECTED:
1315 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001316 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001317 if (session != nullptr) {
1318 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001319 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001320 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001321 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1322 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1323 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001324 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001325 msg->post();
1326 break;
1327 }
1328 default:
1329 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001330 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001331 case ERROR_CAMERA_DEVICE:
1332 case ERROR_CAMERA_SERVICE:
1333 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001334 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1335 // We keep this switch since this block might be encountered with
1336 // more than just 2 states. The default fallthrough could have us
1337 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001338 switch (errorCode) {
1339 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001340 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001341 break;
1342 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001343 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001344 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001345 break;
1346 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001347 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001348 break;
1349 }
1350 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1351 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1352 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001353 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001354 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001355 msg->post();
1356 break;
1357 }
1358 case ERROR_CAMERA_REQUEST:
1359 case ERROR_CAMERA_RESULT:
1360 case ERROR_CAMERA_BUFFER:
1361 dev->onCaptureErrorLocked(errorCode, resultExtras);
1362 break;
1363 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001364 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001365}
1366
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001367binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001368CameraDevice::ServiceCallback::onDeviceIdle() {
1369 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001370 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001371 sp<CameraDevice> dev = mDevice.promote();
1372 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001373 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001374 }
1375
1376 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001377 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001378 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001379 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001380
1381 if (dev->mIdle) {
1382 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001383 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001384 }
1385
1386 if (dev->mCurrentSession != nullptr) {
1387 ALOGE("onDeviceIdle sending state cb");
1388 if (dev->mBusySession != dev->mCurrentSession) {
1389 ALOGE("Current session != busy session");
1390 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001391 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001392 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001393
Yin-Chia Yehead91462016-01-06 16:45:08 -08001394 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1395 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1396 msg->setObject(kSessionSpKey, dev->mBusySession);
1397 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1398 // Make sure we clear the sp first so the session destructor can
1399 // only happen on handler thread (where we don't hold device/session lock)
1400 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001401 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001402 }
1403 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001404 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001405 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001406}
1407
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001408binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001409CameraDevice::ServiceCallback::onCaptureStarted(
1410 const CaptureResultExtras& resultExtras,
1411 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001412 binder::Status ret = binder::Status::ok();
1413
Yin-Chia Yehead91462016-01-06 16:45:08 -08001414 sp<CameraDevice> dev = mDevice.promote();
1415 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001416 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001417 }
1418 Mutex::Autolock _l(dev->mDeviceLock);
1419 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001420 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001421 }
1422
1423 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001424 int32_t burstId = resultExtras.burstId;
1425
1426 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1427 if (it != dev->mSequenceCallbackMap.end()) {
1428 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001429 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001430 sp<ACameraCaptureSession> session = cbh.mSession;
1431 if ((size_t) burstId >= cbh.mRequests.size()) {
1432 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1433 __FUNCTION__, burstId, cbh.mRequests.size());
1434 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1435 }
1436 sp<CaptureRequest> request = cbh.mRequests[burstId];
1437 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001438 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001439 msg->setObject(kSessionSpKey, session);
1440 msg->setPointer(kCallbackFpKey, (void*) onStart);
1441 msg->setObject(kCaptureRequestKey, request);
1442 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001443 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001444 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001445 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001446}
1447
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001448binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001449CameraDevice::ServiceCallback::onResultReceived(
1450 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001451 const CaptureResultExtras& resultExtras,
1452 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001453 binder::Status ret = binder::Status::ok();
1454
Yin-Chia Yehead91462016-01-06 16:45:08 -08001455 sp<CameraDevice> dev = mDevice.promote();
1456 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001457 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001458 }
1459 int sequenceId = resultExtras.requestId;
1460 int64_t frameNumber = resultExtras.frameNumber;
1461 int32_t burstId = resultExtras.burstId;
1462 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1463
1464 if (!isPartialResult) {
1465 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1466 }
1467
1468 Mutex::Autolock _l(dev->mDeviceLock);
1469 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001470 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001471 }
1472
1473 if (dev->isClosed()) {
1474 if (!isPartialResult) {
1475 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1476 }
1477 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001478 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001479 }
1480
1481 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001482 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001483 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001484
1485 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1486 if (it != dev->mSequenceCallbackMap.end()) {
1487 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001488 sp<ACameraCaptureSession> session = cbh.mSession;
1489 if ((size_t) burstId >= cbh.mRequests.size()) {
1490 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1491 __FUNCTION__, burstId, cbh.mRequests.size());
1492 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1493 }
1494 sp<CaptureRequest> request = cbh.mRequests[burstId];
1495 sp<ACameraMetadata> result(new ACameraMetadata(
1496 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001497 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1498 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001499
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001500 sp<AMessage> msg = new AMessage(
1501 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1502 dev->mHandler);
1503 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001504 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001505 msg->setObject(kCaptureRequestKey, request);
1506 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001507 if (isPartialResult) {
1508 msg->setPointer(kCallbackFpKey,
1509 (void *)cbh.mOnCaptureProgressed);
1510 } else if (cbh.mIsLogicalCameraCallback) {
1511 msg->setPointer(kCallbackFpKey,
1512 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1513 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1514 } else {
1515 msg->setPointer(kCallbackFpKey,
1516 (void *)cbh.mOnCaptureCompleted);
1517 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001518 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001519 }
1520
1521 if (!isPartialResult) {
1522 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1523 dev->checkAndFireSequenceCompleteLocked();
1524 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001525
1526 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001527}
1528
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001529binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001530CameraDevice::ServiceCallback::onPrepared(int) {
1531 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001532 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001533}
1534
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001535binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001536CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1537 // onRequestQueueEmpty not yet implemented in NDK
1538 return binder::Status::ok();
1539}
1540
1541binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001542CameraDevice::ServiceCallback::onRepeatingRequestError(
1543 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001544 binder::Status ret = binder::Status::ok();
1545
1546 sp<CameraDevice> dev = mDevice.promote();
1547 if (dev == nullptr) {
1548 return ret; // device has been closed
1549 }
1550
1551 Mutex::Autolock _l(dev->mDeviceLock);
1552
1553 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001554 if (stoppedSequenceId == repeatingSequenceId) {
1555 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1556 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001557
1558 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1559
1560 return ret;
1561}
1562
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001563} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001564} // namespace android