blob: d8a57650c8119e28e22685a00f8865991eca67a5 [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 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 mHandler = new CallbackHandler();
80 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 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800100}
101
Yin-Chia Yehead91462016-01-06 16:45:08 -0800102// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800103CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700104 sp<ACameraCaptureSession> session = mCurrentSession.promote();
105 {
106 Mutex::Autolock _l(mDeviceLock);
107 if (!isClosed()) {
108 disconnectLocked(session);
109 }
110 mCurrentSession = nullptr;
111 if (mCbLooper != nullptr) {
112 mCbLooper->unregisterHandler(mHandler->id());
113 mCbLooper->stop();
114 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800115 }
116 mCbLooper.clear();
117 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800118}
119
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700120void
121CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
122 msg->post();
123 msg.clear();
124 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
125 cleanupMsg->post();
126}
127
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800128// TODO: cached created request?
129camera_status_t
130CameraDevice::createCaptureRequest(
131 ACameraDevice_request_template templateId,
132 ACaptureRequest** request) const {
133 Mutex::Autolock _l(mDeviceLock);
134 camera_status_t ret = checkCameraClosedOrErrorLocked();
135 if (ret != ACAMERA_OK) {
136 return ret;
137 }
138 if (mRemote == nullptr) {
139 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
140 }
141 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800142 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
143 if (remoteRet.serviceSpecificErrorCode() ==
144 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800145 ALOGW("Create capture request failed! template %d is not supported on this device",
146 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700147 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800148 } else if (!remoteRet.isOk()) {
149 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800150 return ACAMERA_ERROR_UNKNOWN;
151 }
152 ACaptureRequest* outReq = new ACaptureRequest();
153 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
154 outReq->targets = new ACameraOutputTargets();
155 *request = outReq;
156 return ACAMERA_OK;
157}
158
Yin-Chia Yehead91462016-01-06 16:45:08 -0800159camera_status_t
160CameraDevice::createCaptureSession(
161 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100162 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800163 const ACameraCaptureSession_stateCallbacks* callbacks,
164 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700165 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800166 Mutex::Autolock _l(mDeviceLock);
167 camera_status_t ret = checkCameraClosedOrErrorLocked();
168 if (ret != ACAMERA_OK) {
169 return ret;
170 }
171
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700172 if (currentSession != nullptr) {
173 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800174 stopRepeatingLocked();
175 }
176
177 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100178 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800179 if (ret != ACAMERA_OK) {
180 ALOGE("Fail to create new session. cannot configure streams");
181 return ret;
182 }
183
184 ACameraCaptureSession* newSession = new ACameraCaptureSession(
185 mNextSessionId++, outputs, callbacks, this);
186
Yin-Chia Yehead91462016-01-06 16:45:08 -0800187 // set new session as current session
188 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
189 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700190 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800191 *session = newSession;
192 return ACAMERA_OK;
193}
194
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800195camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100196 camera_status_t ret = checkCameraClosedOrErrorLocked();
197 if (ret != ACAMERA_OK) {
198 return ret;
199 }
200
201 if (output == nullptr) {
202 return ACAMERA_ERROR_INVALID_PARAMETER;
203 }
204
205 if (!output->mIsShared) {
206 ALOGE("Error output configuration is not shared");
207 return ACAMERA_ERROR_INVALID_OPERATION;
208 }
209
210 int32_t streamId = -1;
211 for (auto& kvPair : mConfiguredOutputs) {
212 if (kvPair.second.first == output->mWindow) {
213 streamId = kvPair.first;
214 break;
215 }
216 }
217 if (streamId < 0) {
218 ALOGE("Error: Invalid output configuration");
219 return ACAMERA_ERROR_INVALID_PARAMETER;
220 }
221
222 sp<IGraphicBufferProducer> iGBP(nullptr);
223 ret = getIGBPfromAnw(output->mWindow, iGBP);
224 if (ret != ACAMERA_OK) {
225 ALOGE("Camera device %s failed to extract graphic producer from native window",
226 getId());
227 return ret;
228 }
229
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800230 String16 physicalId16(output->mPhysicalCameraId.c_str());
231 OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
232 OutputConfiguration::INVALID_SET_ID, true);
Emilian Peev40ead602017-09-26 15:46:36 +0100233
234 for (auto& anw : output->mSharedWindows) {
235 ret = getIGBPfromAnw(anw, iGBP);
236 if (ret != ACAMERA_OK) {
237 ALOGE("Camera device %s failed to extract graphic producer from native window",
238 getId());
239 return ret;
240 }
241 outConfig.addGraphicProducer(iGBP);
242 }
243
244 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
245 if (!remoteRet.isOk()) {
246 switch (remoteRet.serviceSpecificErrorCode()) {
247 case hardware::ICameraService::ERROR_INVALID_OPERATION:
248 ALOGE("Camera device %s invalid operation: %s", getId(),
249 remoteRet.toString8().string());
250 return ACAMERA_ERROR_INVALID_OPERATION;
251 break;
252 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
253 ALOGE("Camera device %s output surface already exists: %s", getId(),
254 remoteRet.toString8().string());
255 return ACAMERA_ERROR_INVALID_PARAMETER;
256 break;
257 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
258 ALOGE("Camera device %s invalid input argument: %s", getId(),
259 remoteRet.toString8().string());
260 return ACAMERA_ERROR_INVALID_PARAMETER;
261 break;
262 default:
263 ALOGE("Camera device %s failed to add shared output: %s", getId(),
264 remoteRet.toString8().string());
265 return ACAMERA_ERROR_UNKNOWN;
266 }
267 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800268 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100269
270 return ACAMERA_OK;
271}
272
Yin-Chia Yehead91462016-01-06 16:45:08 -0800273camera_status_t
274CameraDevice::allocateCaptureRequest(
275 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
276 camera_status_t ret;
277 sp<CaptureRequest> req(new CaptureRequest());
Emilian Peevaebbe412018-01-15 13:53:24 +0000278 req->mPhysicalCameraSettings.push_back({std::string(mCameraId.string()),
279 request->settings->getInternalData()});
Yin-Chia Yehead91462016-01-06 16:45:08 -0800280 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700281 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800282 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800283
284 for (auto outputTarget : request->targets->mOutputs) {
285 ANativeWindow* anw = outputTarget.mWindow;
286 sp<Surface> surface;
287 ret = getSurfaceFromANativeWindow(anw, surface);
288 if (ret != ACAMERA_OK) {
289 ALOGE("Bad output target in capture request! ret %d", ret);
290 return ret;
291 }
292 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800293
294 bool found = false;
295 // lookup stream/surface ID
296 for (const auto& kvPair : mConfiguredOutputs) {
297 int streamId = kvPair.first;
298 const OutputConfiguration& outConfig = kvPair.second.second;
299 const auto& gbps = outConfig.getGraphicBufferProducers();
300 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
301 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
302 found = true;
303 req->mStreamIdxList.push_back(streamId);
304 req->mSurfaceIdxList.push_back(surfaceId);
305 break;
306 }
307 }
308 if (found) {
309 break;
310 }
311 }
312 if (!found) {
313 ALOGE("Unconfigured output target %p in capture request!", anw);
314 return ret;
315 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800316 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800317
Yin-Chia Yehead91462016-01-06 16:45:08 -0800318 outReq = req;
319 return ACAMERA_OK;
320}
321
322ACaptureRequest*
323CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
324 ACaptureRequest* pRequest = new ACaptureRequest();
Emilian Peevaebbe412018-01-15 13:53:24 +0000325 CameraMetadata clone = req->mPhysicalCameraSettings.begin()->settings;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800326 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
327 pRequest->targets = new ACameraOutputTargets();
328 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
329 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
330 ACameraOutputTarget outputTarget(anw);
331 pRequest->targets->mOutputs.insert(outputTarget);
332 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700333 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800334 return pRequest;
335}
336
337void
338CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
339 if (req == nullptr) {
340 return;
341 }
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700342 req->settings.clear();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800343 delete req->targets;
344 delete req;
345}
346
347void
348CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
349 if (isClosed()) {
350 // Device is closing already. do nothing
351 return;
352 }
353
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700354 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800355 // Session has been replaced by other seesion or device is closed
356 return;
357 }
358 mCurrentSession = nullptr;
359
360 // Should not happen
361 if (!session->mIsClosed) {
362 ALOGE("Error: unclosed session %p reaches end of life!", session);
363 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
364 return;
365 }
366
367 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100368 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800369 if (ret != ACAMERA_OK) {
370 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
371 }
372}
373
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800374void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700375CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800376 if (mClosing.exchange(true)) {
377 // Already closing, just return
378 ALOGW("Camera device %s is already closing.", getId());
379 return;
380 }
381
382 if (mRemote != nullptr) {
383 mRemote->disconnect();
384 }
385 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800386
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700387 if (session != nullptr) {
388 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800389 }
390}
391
392camera_status_t
393CameraDevice::stopRepeatingLocked() {
394 camera_status_t ret = checkCameraClosedOrErrorLocked();
395 if (ret != ACAMERA_OK) {
396 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
397 return ret;
398 }
399 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
400 int repeatingSequenceId = mRepeatingSequenceId;
401 mRepeatingSequenceId = REQUEST_ID_NONE;
402
403 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800404 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700405 if (remoteRet.serviceSpecificErrorCode() ==
406 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
407 ALOGV("Repeating request is already stopped.");
408 return ACAMERA_OK;
409 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800410 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800411 return ACAMERA_ERROR_UNKNOWN;
412 }
413 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
414 }
415 return ACAMERA_OK;
416}
417
418camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700419CameraDevice::flushLocked(ACameraCaptureSession* session) {
420 camera_status_t ret = checkCameraClosedOrErrorLocked();
421 if (ret != ACAMERA_OK) {
422 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
423 return ret;
424 }
425
426 // This should never happen because creating a new session will close
427 // previous one and thus reject any API call from previous session.
428 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700429 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700430 ALOGE("Camera %s session %p is not current active session!", getId(), session);
431 return ACAMERA_ERROR_INVALID_OPERATION;
432 }
433
434 if (mFlushing) {
435 ALOGW("Camera %s is already aborting captures", getId());
436 return ACAMERA_OK;
437 }
438
439 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700440
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700441 // Send onActive callback to guarantee there is always active->ready transition
442 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
443 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
444 msg->setObject(kSessionSpKey, session);
445 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700446 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700447
448 // If device is already idling, send callback and exit early
449 if (mIdle) {
450 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
451 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
452 msg->setObject(kSessionSpKey, session);
453 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700454 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700455 mFlushing = false;
456 return ACAMERA_OK;
457 }
458
459 int64_t lastFrameNumber;
460 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
461 if (!remoteRet.isOk()) {
462 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
463 return ACAMERA_ERROR_UNKNOWN;
464 }
465 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
466 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
467 }
468 return ACAMERA_OK;
469}
470
471camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800472CameraDevice::waitUntilIdleLocked() {
473 camera_status_t ret = checkCameraClosedOrErrorLocked();
474 if (ret != ACAMERA_OK) {
475 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
476 return ret;
477 }
478
479 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
480 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
481 return ACAMERA_ERROR_INVALID_OPERATION;
482 }
483
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800484 binder::Status remoteRet = mRemote->waitUntilIdle();
485 if (!remoteRet.isOk()) {
486 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800487 // TODO: define a function to convert status_t -> camera_status_t
488 return ACAMERA_ERROR_UNKNOWN;
489 }
490
491 return ACAMERA_OK;
492}
493
494camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700495CameraDevice::getIGBPfromAnw(
496 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800497 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800498 sp<Surface> surface;
499 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
500 if (ret != ACAMERA_OK) {
501 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800502 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800503 out = surface->getIGraphicBufferProducer();
504 return ACAMERA_OK;
505}
506
507camera_status_t
508CameraDevice::getSurfaceFromANativeWindow(
509 ANativeWindow* anw, sp<Surface>& out) {
510 if (anw == nullptr) {
511 ALOGE("Error: output ANativeWindow is null");
512 return ACAMERA_ERROR_INVALID_PARAMETER;
513 }
514 int value;
515 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800516 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800517 ALOGE("Error: ANativeWindow is not backed by Surface!");
518 return ACAMERA_ERROR_INVALID_PARAMETER;
519 }
520 sp<Surface> surface(static_cast<Surface*>(anw));
521 out = surface;
522 return ACAMERA_OK;
523}
524
525camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100526CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
527 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800528 ACaptureSessionOutputContainer emptyOutput;
529 if (outputs == nullptr) {
530 outputs = &emptyOutput;
531 }
532
Yin-Chia Yehead91462016-01-06 16:45:08 -0800533 camera_status_t ret = checkCameraClosedOrErrorLocked();
534 if (ret != ACAMERA_OK) {
535 return ret;
536 }
537
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700538 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800539 for (const auto& outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700540 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800541 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700542 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800543 if (ret != ACAMERA_OK) {
544 return ret;
545 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800546 String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700547 outputSet.insert(std::make_pair(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800548 anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
Emilian Peev40ead602017-09-26 15:46:36 +0100549 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800550 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700551 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800552 std::vector<int> deleteList;
553
554 // Determine which streams need to be created, which to be deleted
555 for (auto& kvPair : mConfiguredOutputs) {
556 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700557 auto& outputPair = kvPair.second;
558 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800559 deleteList.push_back(streamId); // Need to delete a no longer needed stream
560 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700561 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800562 }
563 }
564
565 ret = stopRepeatingLocked();
566 if (ret != ACAMERA_OK) {
567 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
568 return ret;
569 }
570
571 ret = waitUntilIdleLocked();
572 if (ret != ACAMERA_OK) {
573 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
574 return ret;
575 }
576
577 // Send onReady to previous session
578 // CurrentSession will be updated after configureStreamLocked, so here
579 // mCurrentSession is the session to be replaced by a new session
580 if (!mIdle && mCurrentSession != nullptr) {
581 if (mBusySession != mCurrentSession) {
582 ALOGE("Current session != busy session");
583 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
584 return ACAMERA_ERROR_CAMERA_DEVICE;
585 }
586 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
587 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
588 msg->setObject(kSessionSpKey, mBusySession);
589 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
590 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700591 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800592 }
593 mIdle = true;
594
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800595 binder::Status remoteRet = mRemote->beginConfigure();
596 if (!remoteRet.isOk()) {
597 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800598 return ACAMERA_ERROR_UNKNOWN;
599 }
600
601 // delete to-be-deleted streams
602 for (auto streamId : deleteList) {
603 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800604 if (!remoteRet.isOk()) {
605 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
606 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800607 return ACAMERA_ERROR_UNKNOWN;
608 }
609 mConfiguredOutputs.erase(streamId);
610 }
611
612 // add new streams
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800613 for (const auto& outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800614 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700615 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800616 if (!remoteRet.isOk()) {
617 ALOGE("Camera device %s failed to create stream: %s", getId(),
618 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800619 return ACAMERA_ERROR_UNKNOWN;
620 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700621 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800622 }
623
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100624 CameraMetadata params;
625 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
626 params.append(sessionParameters->settings->getInternalData());
627 }
628 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800629 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
630 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
631 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800632 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800633 } else if (!remoteRet.isOk()) {
634 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800635 return ACAMERA_ERROR_UNKNOWN;
636 }
637
638 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800639}
640
641void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800642CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800643 Mutex::Autolock _l(mDeviceLock);
644 mRemote = remote;
645}
646
647camera_status_t
648CameraDevice::checkCameraClosedOrErrorLocked() const {
649 if (mRemote == nullptr) {
650 ALOGE("%s: camera device already closed", __FUNCTION__);
651 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
652 }
653 if (mInError) {// triggered by onDeviceError
654 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
655 return mError;
656 }
657 return ACAMERA_OK;
658}
659
660void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800661CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
662 mInError = true;
663 mError = error;
664 return;
665}
666
667void
668CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
669 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
670 if (isError) {
671 mFutureErrorSet.insert(frameNumber);
672 } else if (frameNumber <= mCompletedFrameNumber) {
673 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
674 frameNumber, mCompletedFrameNumber);
675 return;
676 } else {
677 if (frameNumber != mCompletedFrameNumber + 1) {
678 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
679 mCompletedFrameNumber + 1, frameNumber);
680 // Do not assert as in java implementation
681 }
682 mCompletedFrameNumber = frameNumber;
683 }
684 update();
685}
686
687void
688CameraDevice::FrameNumberTracker::update() {
689 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
690 int64_t errorFrameNumber = *it;
691 if (errorFrameNumber == mCompletedFrameNumber + 1) {
692 mCompletedFrameNumber++;
693 it = mFutureErrorSet.erase(it);
694 } else if (errorFrameNumber <= mCompletedFrameNumber) {
695 // This should not happen, but deal with it anyway
696 ALOGE("Completd frame number passed through current frame number!");
697 // erase the old error since it's no longer useful
698 it = mFutureErrorSet.erase(it);
699 } else {
700 // Normal requests hasn't catched up error frames, just break
701 break;
702 }
703 }
704 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
705}
706
707void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800708CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800709 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800710 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800711 int sequenceId = resultExtras.requestId;
712 int64_t frameNumber = resultExtras.frameNumber;
713 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700714 auto it = mSequenceCallbackMap.find(sequenceId);
715 if (it == mSequenceCallbackMap.end()) {
716 ALOGE("%s: Error: capture sequence index %d not found!",
717 __FUNCTION__, sequenceId);
718 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800719 return;
720 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700721
722 CallbackHolder cbh = (*it).second;
723 sp<ACameraCaptureSession> session = cbh.mSession;
724 if ((size_t) burstId >= cbh.mRequests.size()) {
725 ALOGE("%s: Error: request index %d out of bound (size %zu)",
726 __FUNCTION__, burstId, cbh.mRequests.size());
727 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
728 return;
729 }
730 sp<CaptureRequest> request = cbh.mRequests[burstId];
731
732 // Handle buffer error
733 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
734 int32_t streamId = resultExtras.errorStreamId;
735 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800736 cbh.mOnCaptureBufferLost;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700737 auto outputPairIt = mConfiguredOutputs.find(streamId);
738 if (outputPairIt == mConfiguredOutputs.end()) {
739 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800740 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
741 return;
742 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700743
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800744 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
745 for (const auto& outGbp : gbps) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800746 for (const auto& surface : request->mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800747 if (surface->getIGraphicBufferProducer() == outGbp) {
748 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
749 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
750 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700751
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800752 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800753 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800754 msg->setObject(kSessionSpKey, session);
755 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
756 msg->setObject(kCaptureRequestKey, request);
757 msg->setPointer(kAnwKey, (void*) anw);
758 msg->setInt64(kFrameNumberKey, frameNumber);
759 postSessionMsgAndCleanup(msg);
760 }
761 }
762 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700763 } else { // Handle other capture failures
764 // Fire capture failure callback if there is one registered
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800765 ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800766 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
767 failure->frameNumber = frameNumber;
768 // TODO: refine this when implementing flush
769 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
770 failure->sequenceId = sequenceId;
771 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800772 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800773
774 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800775 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800776 msg->setObject(kSessionSpKey, session);
777 msg->setPointer(kCallbackFpKey, (void*) onError);
778 msg->setObject(kCaptureRequestKey, request);
779 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700780 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800781
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700782 // Update tracker
783 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
784 checkAndFireSequenceCompleteLocked();
785 }
786 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800787}
788
789void CameraDevice::CallbackHandler::onMessageReceived(
790 const sp<AMessage> &msg) {
791 switch (msg->what()) {
792 case kWhatOnDisconnected:
793 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800794 case kWhatSessionStateCb:
795 case kWhatCaptureStart:
796 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800797 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800798 case kWhatCaptureFail:
799 case kWhatCaptureSeqEnd:
800 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700801 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800802 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800803 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700804 case kWhatCleanUpSessions:
805 mCachedSessions.clear();
806 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800807 default:
808 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
809 return;
810 }
811 // Check the common part of all message
812 void* context;
813 bool found = msg->findPointer(kContextKey, &context);
814 if (!found) {
815 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
816 return;
817 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800818 switch (msg->what()) {
819 case kWhatOnDisconnected:
820 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800821 ACameraDevice* dev;
822 found = msg->findPointer(kDeviceKey, (void**) &dev);
823 if (!found || dev == nullptr) {
824 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
825 return;
826 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800827 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800828 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800829 if (!found) {
830 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
831 return;
832 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800833 if (onDisconnected == nullptr) {
834 return;
835 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800836 (*onDisconnected)(context, dev);
837 break;
838 }
839 case kWhatOnError:
840 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800841 ACameraDevice* dev;
842 found = msg->findPointer(kDeviceKey, (void**) &dev);
843 if (!found || dev == nullptr) {
844 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
845 return;
846 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800847 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800848 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800849 if (!found) {
850 ALOGE("%s: Cannot find onError!", __FUNCTION__);
851 return;
852 }
853 int errorCode;
854 found = msg->findInt32(kErrorCodeKey, &errorCode);
855 if (!found) {
856 ALOGE("%s: Cannot find error code!", __FUNCTION__);
857 return;
858 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800859 if (onError == nullptr) {
860 return;
861 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800862 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800863 break;
864 }
865 case kWhatSessionStateCb:
866 case kWhatCaptureStart:
867 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800868 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800869 case kWhatCaptureFail:
870 case kWhatCaptureSeqEnd:
871 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700872 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800873 {
874 sp<RefBase> obj;
875 found = msg->findObject(kSessionSpKey, &obj);
876 if (!found || obj == nullptr) {
877 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
878 return;
879 }
880 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700881 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800882 sp<CaptureRequest> requestSp = nullptr;
883 switch (msg->what()) {
884 case kWhatCaptureStart:
885 case kWhatCaptureResult:
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800886 case kWhatLogicalCaptureResult:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800887 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700888 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800889 found = msg->findObject(kCaptureRequestKey, &obj);
890 if (!found) {
891 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
892 return;
893 }
894 requestSp = static_cast<CaptureRequest*>(obj.get());
895 break;
896 }
897
898 switch (msg->what()) {
899 case kWhatSessionStateCb:
900 {
901 ACameraCaptureSession_stateCallback onState;
902 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
903 if (!found) {
904 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
905 return;
906 }
907 if (onState == nullptr) {
908 return;
909 }
910 (*onState)(context, session.get());
911 break;
912 }
913 case kWhatCaptureStart:
914 {
915 ACameraCaptureSession_captureCallback_start onStart;
916 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
917 if (!found) {
918 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
919 return;
920 }
921 if (onStart == nullptr) {
922 return;
923 }
924 int64_t timestamp;
925 found = msg->findInt64(kTimeStampKey, &timestamp);
926 if (!found) {
927 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
928 return;
929 }
930 ACaptureRequest* request = allocateACaptureRequest(requestSp);
931 (*onStart)(context, session.get(), request, timestamp);
932 freeACaptureRequest(request);
933 break;
934 }
935 case kWhatCaptureResult:
936 {
937 ACameraCaptureSession_captureCallback_result onResult;
938 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
939 if (!found) {
940 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
941 return;
942 }
943 if (onResult == nullptr) {
944 return;
945 }
946
947 found = msg->findObject(kCaptureResultKey, &obj);
948 if (!found) {
949 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
950 return;
951 }
952 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
953 ACaptureRequest* request = allocateACaptureRequest(requestSp);
954 (*onResult)(context, session.get(), request, result.get());
955 freeACaptureRequest(request);
956 break;
957 }
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800958 case kWhatLogicalCaptureResult:
959 {
960 ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
961 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
962 if (!found) {
963 ALOGE("%s: Cannot find logicalCamera capture result callback!",
964 __FUNCTION__);
965 return;
966 }
967 if (onResult == nullptr) {
968 return;
969 }
970
971 found = msg->findObject(kCaptureResultKey, &obj);
972 if (!found) {
973 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
974 return;
975 }
976 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
977
978 found = msg->findObject(kPhysicalCaptureResultKey, &obj);
979 if (!found) {
980 ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
981 return;
982 }
983 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
984 static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
985 std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
986 physicalResult->mPhysicalResultInfo;
987
988 std::vector<std::string> physicalCameraIds;
989 std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
990 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
991 String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
992 physicalCameraIds.push_back(physicalId8.c_str());
993
994 CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
995 clone.update(ANDROID_SYNC_FRAME_NUMBER,
996 &physicalResult->mFrameNumber, /*data_count*/1);
997 sp<ACameraMetadata> metadata =
998 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
999 physicalMetadataCopy.push_back(metadata);
1000 }
1001
1002 std::vector<const char*> physicalCameraIdPtrs;
1003 std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1004 for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1005 physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1006 physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1007 }
1008
1009 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1010 (*onResult)(context, session.get(), request, result.get(),
1011 physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1012 physicalMetadataCopyPtrs.data());
1013 freeACaptureRequest(request);
1014 break;
1015 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001016 case kWhatCaptureFail:
1017 {
1018 ACameraCaptureSession_captureCallback_failed onFail;
1019 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1020 if (!found) {
1021 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1022 return;
1023 }
1024 if (onFail == nullptr) {
1025 return;
1026 }
1027
1028 found = msg->findObject(kCaptureFailureKey, &obj);
1029 if (!found) {
1030 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1031 return;
1032 }
1033 sp<CameraCaptureFailure> failureSp(
1034 static_cast<CameraCaptureFailure*>(obj.get()));
1035 ACameraCaptureFailure* failure =
1036 static_cast<ACameraCaptureFailure*>(failureSp.get());
1037 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1038 (*onFail)(context, session.get(), request, failure);
1039 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001040 break;
1041 }
1042 case kWhatCaptureSeqEnd:
1043 {
1044 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1045 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1046 if (!found) {
1047 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1048 return;
1049 }
1050 if (onSeqEnd == nullptr) {
1051 return;
1052 }
1053 int seqId;
1054 found = msg->findInt32(kSequenceIdKey, &seqId);
1055 if (!found) {
1056 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1057 return;
1058 }
1059 int64_t frameNumber;
1060 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1061 if (!found) {
1062 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1063 return;
1064 }
1065 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1066 break;
1067 }
1068 case kWhatCaptureSeqAbort:
1069 {
1070 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1071 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1072 if (!found) {
1073 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1074 return;
1075 }
1076 if (onSeqAbort == nullptr) {
1077 return;
1078 }
1079 int seqId;
1080 found = msg->findInt32(kSequenceIdKey, &seqId);
1081 if (!found) {
1082 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1083 return;
1084 }
1085 (*onSeqAbort)(context, session.get(), seqId);
1086 break;
1087 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001088 case kWhatCaptureBufferLost:
1089 {
1090 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1091 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1092 if (!found) {
1093 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1094 return;
1095 }
1096 if (onBufferLost == nullptr) {
1097 return;
1098 }
1099
1100 ANativeWindow* anw;
1101 found = msg->findPointer(kAnwKey, (void**) &anw);
1102 if (!found) {
1103 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1104 return;
1105 }
1106
1107 int64_t frameNumber;
1108 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1109 if (!found) {
1110 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1111 return;
1112 }
1113
1114 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1115 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1116 freeACaptureRequest(request);
1117 break;
1118 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001119 }
1120 break;
1121 }
1122 }
1123}
1124
1125CameraDevice::CallbackHolder::CallbackHolder(
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001126 sp<ACameraCaptureSession> session,
1127 const Vector<sp<CaptureRequest> >& requests,
1128 bool isRepeating,
1129 ACameraCaptureSession_captureCallbacks* cbs) :
1130 mSession(session), mRequests(requests),
1131 mIsRepeating(isRepeating),
1132 mIsLogicalCameraCallback(false) {
1133 initCaptureCallbacks(cbs);
1134
1135 if (cbs != nullptr) {
1136 mOnCaptureCompleted = cbs->onCaptureCompleted;
1137 }
1138}
1139
1140CameraDevice::CallbackHolder::CallbackHolder(
1141 sp<ACameraCaptureSession> session,
1142 const Vector<sp<CaptureRequest> >& requests,
1143 bool isRepeating,
1144 ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1145 mSession(session), mRequests(requests),
1146 mIsRepeating(isRepeating),
1147 mIsLogicalCameraCallback(true) {
1148 initCaptureCallbacks(lcbs);
1149
1150 if (lcbs != nullptr) {
1151 mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1152 }
1153}
Yin-Chia Yehead91462016-01-06 16:45:08 -08001154
1155void
1156CameraDevice::checkRepeatingSequenceCompleteLocked(
1157 const int sequenceId, const int64_t lastFrameNumber) {
1158 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1159 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1160 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1161 ALOGW("No callback found for sequenceId %d", sequenceId);
1162 return;
1163 }
1164 // remove callback holder from callback map
1165 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1166 CallbackHolder cbh = cbIt->second;
1167 mSequenceCallbackMap.erase(cbIt);
1168 // send seq aborted callback
1169 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001170 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001171 msg->setObject(kSessionSpKey, cbh.mSession);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001172 msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001173 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001174 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001175 } else {
1176 // Use mSequenceLastFrameNumberMap to track
1177 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1178
1179 // Last frame might have arrived. Check now
1180 checkAndFireSequenceCompleteLocked();
1181 }
1182}
1183
1184void
1185CameraDevice::checkAndFireSequenceCompleteLocked() {
1186 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1187 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1188 auto it = mSequenceLastFrameNumberMap.begin();
1189 while (it != mSequenceLastFrameNumberMap.end()) {
1190 int sequenceId = it->first;
1191 int64_t lastFrameNumber = it->second;
1192 bool seqCompleted = false;
1193 bool hasCallback = true;
1194
1195 if (mRemote == nullptr) {
1196 ALOGW("Camera %s closed while checking sequence complete", getId());
1197 return;
1198 }
1199
1200 // Check if there is callback for this sequence
1201 // This should not happen because we always register callback (with nullptr inside)
1202 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1203 ALOGW("No callback found for sequenceId %d", sequenceId);
1204 hasCallback = false;
1205 }
1206
1207 if (lastFrameNumber <= completedFrameNumber) {
1208 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1209 sequenceId, lastFrameNumber, completedFrameNumber);
1210 seqCompleted = true;
1211 }
1212
1213 if (seqCompleted && hasCallback) {
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 complete callback
1219 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, 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.mOnCaptureSequenceCompleted);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001223 msg->setInt32(kSequenceIdKey, sequenceId);
1224 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1225
1226 // Clear the session sp before we send out the message
1227 // This will guarantee the rare case where the message is processed
1228 // before cbh goes out of scope and causing we call the session
1229 // destructor while holding device lock
1230 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001231 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001232 }
1233
1234 // No need to track sequence complete if there is no callback registered
1235 if (seqCompleted || !hasCallback) {
1236 it = mSequenceLastFrameNumberMap.erase(it);
1237 } else {
1238 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001239 }
1240 }
1241}
1242
1243/**
1244 * Camera service callback implementation
1245 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001246binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001247CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001248 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001249 const CaptureResultExtras& resultExtras) {
1250 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1251 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001252 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001253 sp<CameraDevice> dev = mDevice.promote();
1254 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001255 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001256 }
1257
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001258 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001259 Mutex::Autolock _l(dev->mDeviceLock);
1260 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001261 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001262 }
1263 switch (errorCode) {
1264 case ERROR_CAMERA_DISCONNECTED:
1265 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001266 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001267 if (session != nullptr) {
1268 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001269 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001270 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001271 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1272 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1273 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001274 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001275 msg->post();
1276 break;
1277 }
1278 default:
1279 ALOGE("Unknown error from camera device: %d", errorCode);
Chih-Hung Hsiehe6a2f212018-10-16 12:16:31 -07001280 [[fallthrough]];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001281 case ERROR_CAMERA_DEVICE:
1282 case ERROR_CAMERA_SERVICE:
1283 {
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001284 int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1285 // We keep this switch since this block might be encountered with
1286 // more than just 2 states. The default fallthrough could have us
1287 // handling more unmatched error cases.
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001288 switch (errorCode) {
1289 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001290 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001291 break;
1292 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001293 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001294 errorVal = ::ERROR_CAMERA_SERVICE;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001295 break;
1296 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001297 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001298 break;
1299 }
1300 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1301 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1302 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001303 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Jayant Chowdhary694cd472018-10-16 12:44:58 -07001304 msg->setInt32(kErrorCodeKey, errorVal);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001305 msg->post();
1306 break;
1307 }
1308 case ERROR_CAMERA_REQUEST:
1309 case ERROR_CAMERA_RESULT:
1310 case ERROR_CAMERA_BUFFER:
1311 dev->onCaptureErrorLocked(errorCode, resultExtras);
1312 break;
1313 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001314 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001315}
1316
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001317binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001318CameraDevice::ServiceCallback::onDeviceIdle() {
1319 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001320 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001321 sp<CameraDevice> dev = mDevice.promote();
1322 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001323 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001324 }
1325
1326 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001327 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001328 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001329 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001330
1331 if (dev->mIdle) {
1332 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001333 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001334 }
1335
1336 if (dev->mCurrentSession != nullptr) {
1337 ALOGE("onDeviceIdle sending state cb");
1338 if (dev->mBusySession != dev->mCurrentSession) {
1339 ALOGE("Current session != busy session");
1340 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001341 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001342 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001343
Yin-Chia Yehead91462016-01-06 16:45:08 -08001344 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1345 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1346 msg->setObject(kSessionSpKey, dev->mBusySession);
1347 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1348 // Make sure we clear the sp first so the session destructor can
1349 // only happen on handler thread (where we don't hold device/session lock)
1350 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001351 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001352 }
1353 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001354 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001355 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001356}
1357
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001358binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001359CameraDevice::ServiceCallback::onCaptureStarted(
1360 const CaptureResultExtras& resultExtras,
1361 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001362 binder::Status ret = binder::Status::ok();
1363
Yin-Chia Yehead91462016-01-06 16:45:08 -08001364 sp<CameraDevice> dev = mDevice.promote();
1365 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001366 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001367 }
1368 Mutex::Autolock _l(dev->mDeviceLock);
1369 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001370 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001371 }
1372
1373 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001374 int32_t burstId = resultExtras.burstId;
1375
1376 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1377 if (it != dev->mSequenceCallbackMap.end()) {
1378 CallbackHolder cbh = (*it).second;
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001379 ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001380 sp<ACameraCaptureSession> session = cbh.mSession;
1381 if ((size_t) burstId >= cbh.mRequests.size()) {
1382 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1383 __FUNCTION__, burstId, cbh.mRequests.size());
1384 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1385 }
1386 sp<CaptureRequest> request = cbh.mRequests[burstId];
1387 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001388 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001389 msg->setObject(kSessionSpKey, session);
1390 msg->setPointer(kCallbackFpKey, (void*) onStart);
1391 msg->setObject(kCaptureRequestKey, request);
1392 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001393 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001394 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001395 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001396}
1397
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001398binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001399CameraDevice::ServiceCallback::onResultReceived(
1400 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001401 const CaptureResultExtras& resultExtras,
1402 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001403 binder::Status ret = binder::Status::ok();
1404
Yin-Chia Yehead91462016-01-06 16:45:08 -08001405 sp<CameraDevice> dev = mDevice.promote();
1406 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001407 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001408 }
1409 int sequenceId = resultExtras.requestId;
1410 int64_t frameNumber = resultExtras.frameNumber;
1411 int32_t burstId = resultExtras.burstId;
1412 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1413
1414 if (!isPartialResult) {
1415 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1416 }
1417
1418 Mutex::Autolock _l(dev->mDeviceLock);
1419 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001420 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001421 }
1422
1423 if (dev->isClosed()) {
1424 if (!isPartialResult) {
1425 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1426 }
1427 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001428 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001429 }
1430
1431 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001432 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001433 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001434
1435 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1436 if (it != dev->mSequenceCallbackMap.end()) {
1437 CallbackHolder cbh = (*it).second;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001438 sp<ACameraCaptureSession> session = cbh.mSession;
1439 if ((size_t) burstId >= cbh.mRequests.size()) {
1440 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1441 __FUNCTION__, burstId, cbh.mRequests.size());
1442 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1443 }
1444 sp<CaptureRequest> request = cbh.mRequests[burstId];
1445 sp<ACameraMetadata> result(new ACameraMetadata(
1446 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001447 sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1448 new ACameraPhysicalCaptureResultInfo(physicalResultInfos, frameNumber));
Yin-Chia Yehead91462016-01-06 16:45:08 -08001449
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001450 sp<AMessage> msg = new AMessage(
1451 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1452 dev->mHandler);
1453 msg->setPointer(kContextKey, cbh.mContext);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001454 msg->setObject(kSessionSpKey, session);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001455 msg->setObject(kCaptureRequestKey, request);
1456 msg->setObject(kCaptureResultKey, result);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -08001457 if (isPartialResult) {
1458 msg->setPointer(kCallbackFpKey,
1459 (void *)cbh.mOnCaptureProgressed);
1460 } else if (cbh.mIsLogicalCameraCallback) {
1461 msg->setPointer(kCallbackFpKey,
1462 (void *)cbh.mOnLogicalCameraCaptureCompleted);
1463 msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1464 } else {
1465 msg->setPointer(kCallbackFpKey,
1466 (void *)cbh.mOnCaptureCompleted);
1467 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001468 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001469 }
1470
1471 if (!isPartialResult) {
1472 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1473 dev->checkAndFireSequenceCompleteLocked();
1474 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001475
1476 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001477}
1478
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001479binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001480CameraDevice::ServiceCallback::onPrepared(int) {
1481 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001482 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001483}
1484
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001485binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001486CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1487 // onRequestQueueEmpty not yet implemented in NDK
1488 return binder::Status::ok();
1489}
1490
1491binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001492CameraDevice::ServiceCallback::onRepeatingRequestError(
1493 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001494 binder::Status ret = binder::Status::ok();
1495
1496 sp<CameraDevice> dev = mDevice.promote();
1497 if (dev == nullptr) {
1498 return ret; // device has been closed
1499 }
1500
1501 Mutex::Autolock _l(dev->mDeviceLock);
1502
1503 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001504 if (stoppedSequenceId == repeatingSequenceId) {
1505 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1506 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001507
1508 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1509
1510 return ret;
1511}
1512
Jayant Chowdhary6df26072018-11-06 23:55:12 -08001513} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001514} // namespace android