blob: 907debc96ee798f66075371b3e3a9ff214612848 [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>
23#include <camera2/SubmitInfo.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080024#include <gui/Surface.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080025#include "ACameraDevice.h"
26#include "ACameraMetadata.h"
27#include "ACaptureRequest.h"
Yin-Chia Yehead91462016-01-06 16:45:08 -080028#include "ACameraCaptureSession.h"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080029
30using namespace android;
31
32namespace android {
33// Static member definitions
Yin-Chia Yehead91462016-01-06 16:45:08 -080034const char* CameraDevice::kContextKey = "Context";
35const char* CameraDevice::kDeviceKey = "Device";
36const char* CameraDevice::kErrorCodeKey = "ErrorCode";
37const char* CameraDevice::kCallbackFpKey = "Callback";
38const char* CameraDevice::kSessionSpKey = "SessionSp";
39const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
40const char* CameraDevice::kTimeStampKey = "TimeStamp";
41const char* CameraDevice::kCaptureResultKey = "CaptureResult";
42const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
43const char* CameraDevice::kSequenceIdKey = "SequenceId";
44const char* CameraDevice::kFrameNumberKey = "FrameNumber";
Yin-Chia Yehe081c592016-03-29 18:26:44 -070045const char* CameraDevice::kAnwKey = "Anw";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080046
47/**
48 * CameraDevice Implementation
49 */
50CameraDevice::CameraDevice(
51 const char* id,
52 ACameraDevice_StateCallbacks* cb,
53 std::unique_ptr<ACameraMetadata> chars,
54 ACameraDevice* wrapper) :
55 mCameraId(id),
56 mAppCallbacks(*cb),
57 mChars(std::move(chars)),
58 mServiceCallback(new ServiceCallback(this)),
59 mWrapper(wrapper),
60 mInError(false),
61 mError(ACAMERA_OK),
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -070062 mIdle(true),
63 mCurrentSession(nullptr) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 mClosing = false;
65 // Setup looper thread to perfrom device callbacks to app
66 mCbLooper = new ALooper;
67 mCbLooper->setName("C2N-dev-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080068 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080069 /*runOnCallingThread*/false,
70 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -080071 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080072 if (err != OK) {
73 ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
74 __FUNCTION__, strerror(-err), err);
75 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
76 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080077 mHandler = new CallbackHandler();
78 mCbLooper->registerHandler(mHandler);
Yin-Chia Yehead91462016-01-06 16:45:08 -080079
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080080 const CameraMetadata& metadata = mChars->getInternalData();
81 camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
Yin-Chia Yehead91462016-01-06 16:45:08 -080082 if (entry.count != 1) {
83 ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
84 mPartialResultCount = 1;
85 } else {
86 mPartialResultCount = entry.data.i32[0];
87 }
88
89 entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
90 if (entry.count != 2) {
91 ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
92 mShadingMapSize[0] = 0;
93 mShadingMapSize[1] = 0;
94 } else {
95 mShadingMapSize[0] = entry.data.i32[0];
96 mShadingMapSize[1] = entry.data.i32[1];
97 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080098}
99
Yin-Chia Yehead91462016-01-06 16:45:08 -0800100// Device close implementaiton
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800101CameraDevice::~CameraDevice() {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700102 sp<ACameraCaptureSession> session = mCurrentSession.promote();
103 {
104 Mutex::Autolock _l(mDeviceLock);
105 if (!isClosed()) {
106 disconnectLocked(session);
107 }
108 mCurrentSession = nullptr;
109 if (mCbLooper != nullptr) {
110 mCbLooper->unregisterHandler(mHandler->id());
111 mCbLooper->stop();
112 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800113 }
114 mCbLooper.clear();
115 mHandler.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116}
117
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700118void
119CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
120 msg->post();
121 msg.clear();
122 sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
123 cleanupMsg->post();
124}
125
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126// TODO: cached created request?
127camera_status_t
128CameraDevice::createCaptureRequest(
129 ACameraDevice_request_template templateId,
130 ACaptureRequest** request) const {
131 Mutex::Autolock _l(mDeviceLock);
132 camera_status_t ret = checkCameraClosedOrErrorLocked();
133 if (ret != ACAMERA_OK) {
134 return ret;
135 }
136 if (mRemote == nullptr) {
137 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
138 }
139 CameraMetadata rawRequest;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800140 binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
141 if (remoteRet.serviceSpecificErrorCode() ==
142 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800143 ALOGW("Create capture request failed! template %d is not supported on this device",
144 templateId);
Yin-Chia Yeha22528a2016-05-12 14:03:11 -0700145 return ACAMERA_ERROR_INVALID_PARAMETER;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800146 } else if (!remoteRet.isOk()) {
147 ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800148 return ACAMERA_ERROR_UNKNOWN;
149 }
150 ACaptureRequest* outReq = new ACaptureRequest();
151 outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
152 outReq->targets = new ACameraOutputTargets();
153 *request = outReq;
154 return ACAMERA_OK;
155}
156
Yin-Chia Yehead91462016-01-06 16:45:08 -0800157camera_status_t
158CameraDevice::createCaptureSession(
159 const ACaptureSessionOutputContainer* outputs,
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100160 const ACaptureRequest* sessionParameters,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800161 const ACameraCaptureSession_stateCallbacks* callbacks,
162 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700163 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800164 Mutex::Autolock _l(mDeviceLock);
165 camera_status_t ret = checkCameraClosedOrErrorLocked();
166 if (ret != ACAMERA_OK) {
167 return ret;
168 }
169
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700170 if (currentSession != nullptr) {
171 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800172 stopRepeatingLocked();
173 }
174
175 // Create new session
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100176 ret = configureStreamsLocked(outputs, sessionParameters);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800177 if (ret != ACAMERA_OK) {
178 ALOGE("Fail to create new session. cannot configure streams");
179 return ret;
180 }
181
182 ACameraCaptureSession* newSession = new ACameraCaptureSession(
183 mNextSessionId++, outputs, callbacks, this);
184
Yin-Chia Yehead91462016-01-06 16:45:08 -0800185 // set new session as current session
186 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
187 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700188 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800189 *session = newSession;
190 return ACAMERA_OK;
191}
192
193camera_status_t
194CameraDevice::captureLocked(
195 sp<ACameraCaptureSession> session,
196 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
197 int numRequests, ACaptureRequest** requests,
198 /*optional*/int* captureSequenceId) {
199 return submitRequestsLocked(
200 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
201}
202
203camera_status_t
204CameraDevice::setRepeatingRequestsLocked(
205 sp<ACameraCaptureSession> session,
206 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
207 int numRequests, ACaptureRequest** requests,
208 /*optional*/int* captureSequenceId) {
209 return submitRequestsLocked(
210 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
211}
212
213camera_status_t
214CameraDevice::submitRequestsLocked(
215 sp<ACameraCaptureSession> session,
216 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
217 int numRequests, ACaptureRequest** requests,
218 /*optional*/int* captureSequenceId,
219 bool isRepeating) {
220 camera_status_t ret = checkCameraClosedOrErrorLocked();
221 if (ret != ACAMERA_OK) {
222 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
223 return ret;
224 }
225
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800226 // Form two vectors of capture request, one for internal tracking
227 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800228 Vector<sp<CaptureRequest> > requestsV;
229 requestsV.setCapacity(numRequests);
230 for (int i = 0; i < numRequests; i++) {
231 sp<CaptureRequest> req;
232 ret = allocateCaptureRequest(requests[i], req);
233 if (ret != ACAMERA_OK) {
234 ALOGE("Convert capture request to internal format failure! ret %d", ret);
235 return ret;
236 }
237 if (req->mSurfaceList.empty()) {
238 ALOGE("Capture request without output target cannot be submitted!");
239 return ACAMERA_ERROR_INVALID_PARAMETER;
240 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800241 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800242 requestsV.push_back(req);
243 }
244
245 if (isRepeating) {
246 ret = stopRepeatingLocked();
247 if (ret != ACAMERA_OK) {
248 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
249 return ret;
250 }
251 }
252
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800253 binder::Status remoteRet;
254 hardware::camera2::utils::SubmitInfo info;
255 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
256 int sequenceId = info.mRequestId;
257 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800258 if (sequenceId < 0) {
259 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
260 return ACAMERA_ERROR_UNKNOWN;
261 }
262
263 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
264 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
265
266 if (isRepeating) {
267 // stopRepeating above should have cleanup repeating sequence id
268 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
269 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
270 return ACAMERA_ERROR_CAMERA_DEVICE;
271 }
272 mRepeatingSequenceId = sequenceId;
273 } else {
274 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
275 }
276
277 if (mIdle) {
278 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
279 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
280 msg->setObject(kSessionSpKey, session);
281 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700282 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800283 }
284 mIdle = false;
285 mBusySession = session;
286
287 if (captureSequenceId) {
288 *captureSequenceId = sequenceId;
289 }
290 return ACAMERA_OK;
291}
292
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800293camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100294 camera_status_t ret = checkCameraClosedOrErrorLocked();
295 if (ret != ACAMERA_OK) {
296 return ret;
297 }
298
299 if (output == nullptr) {
300 return ACAMERA_ERROR_INVALID_PARAMETER;
301 }
302
303 if (!output->mIsShared) {
304 ALOGE("Error output configuration is not shared");
305 return ACAMERA_ERROR_INVALID_OPERATION;
306 }
307
308 int32_t streamId = -1;
309 for (auto& kvPair : mConfiguredOutputs) {
310 if (kvPair.second.first == output->mWindow) {
311 streamId = kvPair.first;
312 break;
313 }
314 }
315 if (streamId < 0) {
316 ALOGE("Error: Invalid output configuration");
317 return ACAMERA_ERROR_INVALID_PARAMETER;
318 }
319
320 sp<IGraphicBufferProducer> iGBP(nullptr);
321 ret = getIGBPfromAnw(output->mWindow, iGBP);
322 if (ret != ACAMERA_OK) {
323 ALOGE("Camera device %s failed to extract graphic producer from native window",
324 getId());
325 return ret;
326 }
327
328 OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
329 true);
330
331 for (auto& anw : output->mSharedWindows) {
332 ret = getIGBPfromAnw(anw, iGBP);
333 if (ret != ACAMERA_OK) {
334 ALOGE("Camera device %s failed to extract graphic producer from native window",
335 getId());
336 return ret;
337 }
338 outConfig.addGraphicProducer(iGBP);
339 }
340
341 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
342 if (!remoteRet.isOk()) {
343 switch (remoteRet.serviceSpecificErrorCode()) {
344 case hardware::ICameraService::ERROR_INVALID_OPERATION:
345 ALOGE("Camera device %s invalid operation: %s", getId(),
346 remoteRet.toString8().string());
347 return ACAMERA_ERROR_INVALID_OPERATION;
348 break;
349 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
350 ALOGE("Camera device %s output surface already exists: %s", getId(),
351 remoteRet.toString8().string());
352 return ACAMERA_ERROR_INVALID_PARAMETER;
353 break;
354 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
355 ALOGE("Camera device %s invalid input argument: %s", getId(),
356 remoteRet.toString8().string());
357 return ACAMERA_ERROR_INVALID_PARAMETER;
358 break;
359 default:
360 ALOGE("Camera device %s failed to add shared output: %s", getId(),
361 remoteRet.toString8().string());
362 return ACAMERA_ERROR_UNKNOWN;
363 }
364 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800365 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100366
367 return ACAMERA_OK;
368}
369
Yin-Chia Yehead91462016-01-06 16:45:08 -0800370camera_status_t
371CameraDevice::allocateCaptureRequest(
372 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
373 camera_status_t ret;
374 sp<CaptureRequest> req(new CaptureRequest());
Emilian Peevaebbe412018-01-15 13:53:24 +0000375 req->mPhysicalCameraSettings.push_back({std::string(mCameraId.string()),
376 request->settings->getInternalData()});
Yin-Chia Yehead91462016-01-06 16:45:08 -0800377 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700378 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800379 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800380
381 for (auto outputTarget : request->targets->mOutputs) {
382 ANativeWindow* anw = outputTarget.mWindow;
383 sp<Surface> surface;
384 ret = getSurfaceFromANativeWindow(anw, surface);
385 if (ret != ACAMERA_OK) {
386 ALOGE("Bad output target in capture request! ret %d", ret);
387 return ret;
388 }
389 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800390
391 bool found = false;
392 // lookup stream/surface ID
393 for (const auto& kvPair : mConfiguredOutputs) {
394 int streamId = kvPair.first;
395 const OutputConfiguration& outConfig = kvPair.second.second;
396 const auto& gbps = outConfig.getGraphicBufferProducers();
397 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
398 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
399 found = true;
400 req->mStreamIdxList.push_back(streamId);
401 req->mSurfaceIdxList.push_back(surfaceId);
402 break;
403 }
404 }
405 if (found) {
406 break;
407 }
408 }
409 if (!found) {
410 ALOGE("Unconfigured output target %p in capture request!", anw);
411 return ret;
412 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800413 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800414
Yin-Chia Yehead91462016-01-06 16:45:08 -0800415 outReq = req;
416 return ACAMERA_OK;
417}
418
419ACaptureRequest*
420CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
421 ACaptureRequest* pRequest = new ACaptureRequest();
Emilian Peevaebbe412018-01-15 13:53:24 +0000422 CameraMetadata clone = req->mPhysicalCameraSettings.begin()->settings;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800423 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
424 pRequest->targets = new ACameraOutputTargets();
425 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
426 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
427 ACameraOutputTarget outputTarget(anw);
428 pRequest->targets->mOutputs.insert(outputTarget);
429 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700430 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800431 return pRequest;
432}
433
434void
435CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
436 if (req == nullptr) {
437 return;
438 }
439 delete req->settings;
440 delete req->targets;
441 delete req;
442}
443
444void
445CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
446 if (isClosed()) {
447 // Device is closing already. do nothing
448 return;
449 }
450
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700451 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800452 // Session has been replaced by other seesion or device is closed
453 return;
454 }
455 mCurrentSession = nullptr;
456
457 // Should not happen
458 if (!session->mIsClosed) {
459 ALOGE("Error: unclosed session %p reaches end of life!", session);
460 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
461 return;
462 }
463
464 // No new session, unconfigure now
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100465 camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800466 if (ret != ACAMERA_OK) {
467 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
468 }
469}
470
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800471void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700472CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800473 if (mClosing.exchange(true)) {
474 // Already closing, just return
475 ALOGW("Camera device %s is already closing.", getId());
476 return;
477 }
478
479 if (mRemote != nullptr) {
480 mRemote->disconnect();
481 }
482 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800483
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700484 if (session != nullptr) {
485 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800486 }
487}
488
489camera_status_t
490CameraDevice::stopRepeatingLocked() {
491 camera_status_t ret = checkCameraClosedOrErrorLocked();
492 if (ret != ACAMERA_OK) {
493 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
494 return ret;
495 }
496 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
497 int repeatingSequenceId = mRepeatingSequenceId;
498 mRepeatingSequenceId = REQUEST_ID_NONE;
499
500 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800501 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700502 if (remoteRet.serviceSpecificErrorCode() ==
503 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
504 ALOGV("Repeating request is already stopped.");
505 return ACAMERA_OK;
506 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800507 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800508 return ACAMERA_ERROR_UNKNOWN;
509 }
510 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
511 }
512 return ACAMERA_OK;
513}
514
515camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700516CameraDevice::flushLocked(ACameraCaptureSession* session) {
517 camera_status_t ret = checkCameraClosedOrErrorLocked();
518 if (ret != ACAMERA_OK) {
519 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
520 return ret;
521 }
522
523 // This should never happen because creating a new session will close
524 // previous one and thus reject any API call from previous session.
525 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700526 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700527 ALOGE("Camera %s session %p is not current active session!", getId(), session);
528 return ACAMERA_ERROR_INVALID_OPERATION;
529 }
530
531 if (mFlushing) {
532 ALOGW("Camera %s is already aborting captures", getId());
533 return ACAMERA_OK;
534 }
535
536 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700537
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700538 // Send onActive callback to guarantee there is always active->ready transition
539 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
540 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
541 msg->setObject(kSessionSpKey, session);
542 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700543 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700544
545 // If device is already idling, send callback and exit early
546 if (mIdle) {
547 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
548 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
549 msg->setObject(kSessionSpKey, session);
550 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700551 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700552 mFlushing = false;
553 return ACAMERA_OK;
554 }
555
556 int64_t lastFrameNumber;
557 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
558 if (!remoteRet.isOk()) {
559 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
560 return ACAMERA_ERROR_UNKNOWN;
561 }
562 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
563 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
564 }
565 return ACAMERA_OK;
566}
567
568camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800569CameraDevice::waitUntilIdleLocked() {
570 camera_status_t ret = checkCameraClosedOrErrorLocked();
571 if (ret != ACAMERA_OK) {
572 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
573 return ret;
574 }
575
576 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
577 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
578 return ACAMERA_ERROR_INVALID_OPERATION;
579 }
580
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800581 binder::Status remoteRet = mRemote->waitUntilIdle();
582 if (!remoteRet.isOk()) {
583 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800584 // TODO: define a function to convert status_t -> camera_status_t
585 return ACAMERA_ERROR_UNKNOWN;
586 }
587
588 return ACAMERA_OK;
589}
590
591camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700592CameraDevice::getIGBPfromAnw(
593 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800594 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800595 sp<Surface> surface;
596 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
597 if (ret != ACAMERA_OK) {
598 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800599 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800600 out = surface->getIGraphicBufferProducer();
601 return ACAMERA_OK;
602}
603
604camera_status_t
605CameraDevice::getSurfaceFromANativeWindow(
606 ANativeWindow* anw, sp<Surface>& out) {
607 if (anw == nullptr) {
608 ALOGE("Error: output ANativeWindow is null");
609 return ACAMERA_ERROR_INVALID_PARAMETER;
610 }
611 int value;
612 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800613 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800614 ALOGE("Error: ANativeWindow is not backed by Surface!");
615 return ACAMERA_ERROR_INVALID_PARAMETER;
616 }
617 sp<Surface> surface(static_cast<Surface*>(anw));
618 out = surface;
619 return ACAMERA_OK;
620}
621
622camera_status_t
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100623CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
624 const ACaptureRequest* sessionParameters) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800625 ACaptureSessionOutputContainer emptyOutput;
626 if (outputs == nullptr) {
627 outputs = &emptyOutput;
628 }
629
Yin-Chia Yehead91462016-01-06 16:45:08 -0800630 camera_status_t ret = checkCameraClosedOrErrorLocked();
631 if (ret != ACAMERA_OK) {
632 return ret;
633 }
634
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700635 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800636 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700637 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800638 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700639 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800640 if (ret != ACAMERA_OK) {
641 return ret;
642 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700643 outputSet.insert(std::make_pair(
Emilian Peev40ead602017-09-26 15:46:36 +0100644 anw, OutputConfiguration(iGBP, outConfig.mRotation,
645 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800646 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700647 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800648 std::vector<int> deleteList;
649
650 // Determine which streams need to be created, which to be deleted
651 for (auto& kvPair : mConfiguredOutputs) {
652 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700653 auto& outputPair = kvPair.second;
654 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800655 deleteList.push_back(streamId); // Need to delete a no longer needed stream
656 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700657 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800658 }
659 }
660
661 ret = stopRepeatingLocked();
662 if (ret != ACAMERA_OK) {
663 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
664 return ret;
665 }
666
667 ret = waitUntilIdleLocked();
668 if (ret != ACAMERA_OK) {
669 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
670 return ret;
671 }
672
673 // Send onReady to previous session
674 // CurrentSession will be updated after configureStreamLocked, so here
675 // mCurrentSession is the session to be replaced by a new session
676 if (!mIdle && mCurrentSession != nullptr) {
677 if (mBusySession != mCurrentSession) {
678 ALOGE("Current session != busy session");
679 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
680 return ACAMERA_ERROR_CAMERA_DEVICE;
681 }
682 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
683 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
684 msg->setObject(kSessionSpKey, mBusySession);
685 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
686 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700687 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800688 }
689 mIdle = true;
690
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800691 binder::Status remoteRet = mRemote->beginConfigure();
692 if (!remoteRet.isOk()) {
693 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800694 return ACAMERA_ERROR_UNKNOWN;
695 }
696
697 // delete to-be-deleted streams
698 for (auto streamId : deleteList) {
699 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800700 if (!remoteRet.isOk()) {
701 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
702 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800703 return ACAMERA_ERROR_UNKNOWN;
704 }
705 mConfiguredOutputs.erase(streamId);
706 }
707
708 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700709 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800710 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700711 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800712 if (!remoteRet.isOk()) {
713 ALOGE("Camera device %s failed to create stream: %s", getId(),
714 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800715 return ACAMERA_ERROR_UNKNOWN;
716 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700717 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800718 }
719
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100720 CameraMetadata params;
721 if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
722 params.append(sessionParameters->settings->getInternalData());
723 }
724 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800725 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
726 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
727 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800728 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800729 } else if (!remoteRet.isOk()) {
730 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800731 return ACAMERA_ERROR_UNKNOWN;
732 }
733
734 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800735}
736
737void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800738CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800739 Mutex::Autolock _l(mDeviceLock);
740 mRemote = remote;
741}
742
743camera_status_t
744CameraDevice::checkCameraClosedOrErrorLocked() const {
745 if (mRemote == nullptr) {
746 ALOGE("%s: camera device already closed", __FUNCTION__);
747 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
748 }
749 if (mInError) {// triggered by onDeviceError
750 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
751 return mError;
752 }
753 return ACAMERA_OK;
754}
755
756void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800757CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
758 mInError = true;
759 mError = error;
760 return;
761}
762
763void
764CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
765 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
766 if (isError) {
767 mFutureErrorSet.insert(frameNumber);
768 } else if (frameNumber <= mCompletedFrameNumber) {
769 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
770 frameNumber, mCompletedFrameNumber);
771 return;
772 } else {
773 if (frameNumber != mCompletedFrameNumber + 1) {
774 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
775 mCompletedFrameNumber + 1, frameNumber);
776 // Do not assert as in java implementation
777 }
778 mCompletedFrameNumber = frameNumber;
779 }
780 update();
781}
782
783void
784CameraDevice::FrameNumberTracker::update() {
785 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
786 int64_t errorFrameNumber = *it;
787 if (errorFrameNumber == mCompletedFrameNumber + 1) {
788 mCompletedFrameNumber++;
789 it = mFutureErrorSet.erase(it);
790 } else if (errorFrameNumber <= mCompletedFrameNumber) {
791 // This should not happen, but deal with it anyway
792 ALOGE("Completd frame number passed through current frame number!");
793 // erase the old error since it's no longer useful
794 it = mFutureErrorSet.erase(it);
795 } else {
796 // Normal requests hasn't catched up error frames, just break
797 break;
798 }
799 }
800 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
801}
802
803void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800804CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800805 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800806 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800807 int sequenceId = resultExtras.requestId;
808 int64_t frameNumber = resultExtras.frameNumber;
809 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700810 auto it = mSequenceCallbackMap.find(sequenceId);
811 if (it == mSequenceCallbackMap.end()) {
812 ALOGE("%s: Error: capture sequence index %d not found!",
813 __FUNCTION__, sequenceId);
814 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800815 return;
816 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700817
818 CallbackHolder cbh = (*it).second;
819 sp<ACameraCaptureSession> session = cbh.mSession;
820 if ((size_t) burstId >= cbh.mRequests.size()) {
821 ALOGE("%s: Error: request index %d out of bound (size %zu)",
822 __FUNCTION__, burstId, cbh.mRequests.size());
823 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
824 return;
825 }
826 sp<CaptureRequest> request = cbh.mRequests[burstId];
827
828 // Handle buffer error
829 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
830 int32_t streamId = resultExtras.errorStreamId;
831 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
832 cbh.mCallbacks.onCaptureBufferLost;
833 auto outputPairIt = mConfiguredOutputs.find(streamId);
834 if (outputPairIt == mConfiguredOutputs.end()) {
835 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800836 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
837 return;
838 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700839
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800840 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
841 for (const auto& outGbp : gbps) {
842 for (auto surface : request->mSurfaceList) {
843 if (surface->getIGraphicBufferProducer() == outGbp) {
844 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
845 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
846 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700847
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800848 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
849 msg->setPointer(kContextKey, cbh.mCallbacks.context);
850 msg->setObject(kSessionSpKey, session);
851 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
852 msg->setObject(kCaptureRequestKey, request);
853 msg->setPointer(kAnwKey, (void*) anw);
854 msg->setInt64(kFrameNumberKey, frameNumber);
855 postSessionMsgAndCleanup(msg);
856 }
857 }
858 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700859 } else { // Handle other capture failures
860 // Fire capture failure callback if there is one registered
861 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800862 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
863 failure->frameNumber = frameNumber;
864 // TODO: refine this when implementing flush
865 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
866 failure->sequenceId = sequenceId;
867 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800868 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800869
870 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
871 msg->setPointer(kContextKey, cbh.mCallbacks.context);
872 msg->setObject(kSessionSpKey, session);
873 msg->setPointer(kCallbackFpKey, (void*) onError);
874 msg->setObject(kCaptureRequestKey, request);
875 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700876 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800877
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700878 // Update tracker
879 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
880 checkAndFireSequenceCompleteLocked();
881 }
882 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800883}
884
885void CameraDevice::CallbackHandler::onMessageReceived(
886 const sp<AMessage> &msg) {
887 switch (msg->what()) {
888 case kWhatOnDisconnected:
889 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800890 case kWhatSessionStateCb:
891 case kWhatCaptureStart:
892 case kWhatCaptureResult:
893 case kWhatCaptureFail:
894 case kWhatCaptureSeqEnd:
895 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700896 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800897 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800898 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700899 case kWhatCleanUpSessions:
900 mCachedSessions.clear();
901 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800902 default:
903 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
904 return;
905 }
906 // Check the common part of all message
907 void* context;
908 bool found = msg->findPointer(kContextKey, &context);
909 if (!found) {
910 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
911 return;
912 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800913 switch (msg->what()) {
914 case kWhatOnDisconnected:
915 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800916 ACameraDevice* dev;
917 found = msg->findPointer(kDeviceKey, (void**) &dev);
918 if (!found || dev == nullptr) {
919 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
920 return;
921 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800922 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800923 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800924 if (!found) {
925 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
926 return;
927 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800928 if (onDisconnected == nullptr) {
929 return;
930 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800931 (*onDisconnected)(context, dev);
932 break;
933 }
934 case kWhatOnError:
935 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800936 ACameraDevice* dev;
937 found = msg->findPointer(kDeviceKey, (void**) &dev);
938 if (!found || dev == nullptr) {
939 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
940 return;
941 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800942 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800943 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800944 if (!found) {
945 ALOGE("%s: Cannot find onError!", __FUNCTION__);
946 return;
947 }
948 int errorCode;
949 found = msg->findInt32(kErrorCodeKey, &errorCode);
950 if (!found) {
951 ALOGE("%s: Cannot find error code!", __FUNCTION__);
952 return;
953 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800954 if (onError == nullptr) {
955 return;
956 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800957 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800958 break;
959 }
960 case kWhatSessionStateCb:
961 case kWhatCaptureStart:
962 case kWhatCaptureResult:
963 case kWhatCaptureFail:
964 case kWhatCaptureSeqEnd:
965 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700966 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800967 {
968 sp<RefBase> obj;
969 found = msg->findObject(kSessionSpKey, &obj);
970 if (!found || obj == nullptr) {
971 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
972 return;
973 }
974 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700975 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800976 sp<CaptureRequest> requestSp = nullptr;
977 switch (msg->what()) {
978 case kWhatCaptureStart:
979 case kWhatCaptureResult:
980 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700981 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800982 found = msg->findObject(kCaptureRequestKey, &obj);
983 if (!found) {
984 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
985 return;
986 }
987 requestSp = static_cast<CaptureRequest*>(obj.get());
988 break;
989 }
990
991 switch (msg->what()) {
992 case kWhatSessionStateCb:
993 {
994 ACameraCaptureSession_stateCallback onState;
995 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
996 if (!found) {
997 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
998 return;
999 }
1000 if (onState == nullptr) {
1001 return;
1002 }
1003 (*onState)(context, session.get());
1004 break;
1005 }
1006 case kWhatCaptureStart:
1007 {
1008 ACameraCaptureSession_captureCallback_start onStart;
1009 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1010 if (!found) {
1011 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1012 return;
1013 }
1014 if (onStart == nullptr) {
1015 return;
1016 }
1017 int64_t timestamp;
1018 found = msg->findInt64(kTimeStampKey, &timestamp);
1019 if (!found) {
1020 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1021 return;
1022 }
1023 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1024 (*onStart)(context, session.get(), request, timestamp);
1025 freeACaptureRequest(request);
1026 break;
1027 }
1028 case kWhatCaptureResult:
1029 {
1030 ACameraCaptureSession_captureCallback_result onResult;
1031 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1032 if (!found) {
1033 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1034 return;
1035 }
1036 if (onResult == nullptr) {
1037 return;
1038 }
1039
1040 found = msg->findObject(kCaptureResultKey, &obj);
1041 if (!found) {
1042 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1043 return;
1044 }
1045 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1046 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1047 (*onResult)(context, session.get(), request, result.get());
1048 freeACaptureRequest(request);
1049 break;
1050 }
1051 case kWhatCaptureFail:
1052 {
1053 ACameraCaptureSession_captureCallback_failed onFail;
1054 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1055 if (!found) {
1056 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1057 return;
1058 }
1059 if (onFail == nullptr) {
1060 return;
1061 }
1062
1063 found = msg->findObject(kCaptureFailureKey, &obj);
1064 if (!found) {
1065 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1066 return;
1067 }
1068 sp<CameraCaptureFailure> failureSp(
1069 static_cast<CameraCaptureFailure*>(obj.get()));
1070 ACameraCaptureFailure* failure =
1071 static_cast<ACameraCaptureFailure*>(failureSp.get());
1072 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1073 (*onFail)(context, session.get(), request, failure);
1074 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001075 break;
1076 }
1077 case kWhatCaptureSeqEnd:
1078 {
1079 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1080 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1081 if (!found) {
1082 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1083 return;
1084 }
1085 if (onSeqEnd == nullptr) {
1086 return;
1087 }
1088 int seqId;
1089 found = msg->findInt32(kSequenceIdKey, &seqId);
1090 if (!found) {
1091 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1092 return;
1093 }
1094 int64_t frameNumber;
1095 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1096 if (!found) {
1097 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1098 return;
1099 }
1100 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1101 break;
1102 }
1103 case kWhatCaptureSeqAbort:
1104 {
1105 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1106 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1107 if (!found) {
1108 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1109 return;
1110 }
1111 if (onSeqAbort == nullptr) {
1112 return;
1113 }
1114 int seqId;
1115 found = msg->findInt32(kSequenceIdKey, &seqId);
1116 if (!found) {
1117 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1118 return;
1119 }
1120 (*onSeqAbort)(context, session.get(), seqId);
1121 break;
1122 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001123 case kWhatCaptureBufferLost:
1124 {
1125 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1126 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1127 if (!found) {
1128 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1129 return;
1130 }
1131 if (onBufferLost == nullptr) {
1132 return;
1133 }
1134
1135 ANativeWindow* anw;
1136 found = msg->findPointer(kAnwKey, (void**) &anw);
1137 if (!found) {
1138 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1139 return;
1140 }
1141
1142 int64_t frameNumber;
1143 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1144 if (!found) {
1145 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1146 return;
1147 }
1148
1149 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1150 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1151 freeACaptureRequest(request);
1152 break;
1153 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001154 }
1155 break;
1156 }
1157 }
1158}
1159
1160CameraDevice::CallbackHolder::CallbackHolder(
1161 sp<ACameraCaptureSession> session,
1162 const Vector<sp<CaptureRequest> >& requests,
1163 bool isRepeating,
1164 ACameraCaptureSession_captureCallbacks* cbs) :
1165 mSession(session), mRequests(requests),
1166 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1167
1168void
1169CameraDevice::checkRepeatingSequenceCompleteLocked(
1170 const int sequenceId, const int64_t lastFrameNumber) {
1171 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1172 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1173 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1174 ALOGW("No callback found for sequenceId %d", sequenceId);
1175 return;
1176 }
1177 // remove callback holder from callback map
1178 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1179 CallbackHolder cbh = cbIt->second;
1180 mSequenceCallbackMap.erase(cbIt);
1181 // send seq aborted callback
1182 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1183 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1184 msg->setObject(kSessionSpKey, cbh.mSession);
1185 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1186 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001187 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001188 } else {
1189 // Use mSequenceLastFrameNumberMap to track
1190 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1191
1192 // Last frame might have arrived. Check now
1193 checkAndFireSequenceCompleteLocked();
1194 }
1195}
1196
1197void
1198CameraDevice::checkAndFireSequenceCompleteLocked() {
1199 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1200 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1201 auto it = mSequenceLastFrameNumberMap.begin();
1202 while (it != mSequenceLastFrameNumberMap.end()) {
1203 int sequenceId = it->first;
1204 int64_t lastFrameNumber = it->second;
1205 bool seqCompleted = false;
1206 bool hasCallback = true;
1207
1208 if (mRemote == nullptr) {
1209 ALOGW("Camera %s closed while checking sequence complete", getId());
1210 return;
1211 }
1212
1213 // Check if there is callback for this sequence
1214 // This should not happen because we always register callback (with nullptr inside)
1215 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1216 ALOGW("No callback found for sequenceId %d", sequenceId);
1217 hasCallback = false;
1218 }
1219
1220 if (lastFrameNumber <= completedFrameNumber) {
1221 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1222 sequenceId, lastFrameNumber, completedFrameNumber);
1223 seqCompleted = true;
1224 }
1225
1226 if (seqCompleted && hasCallback) {
1227 // remove callback holder from callback map
1228 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1229 CallbackHolder cbh = cbIt->second;
1230 mSequenceCallbackMap.erase(cbIt);
1231 // send seq complete callback
1232 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1233 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1234 msg->setObject(kSessionSpKey, cbh.mSession);
1235 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1236 msg->setInt32(kSequenceIdKey, sequenceId);
1237 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1238
1239 // Clear the session sp before we send out the message
1240 // This will guarantee the rare case where the message is processed
1241 // before cbh goes out of scope and causing we call the session
1242 // destructor while holding device lock
1243 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001244 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001245 }
1246
1247 // No need to track sequence complete if there is no callback registered
1248 if (seqCompleted || !hasCallback) {
1249 it = mSequenceLastFrameNumberMap.erase(it);
1250 } else {
1251 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001252 }
1253 }
1254}
1255
1256/**
1257 * Camera service callback implementation
1258 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001259binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001260CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001261 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001262 const CaptureResultExtras& resultExtras) {
1263 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1264 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001265 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001266 sp<CameraDevice> dev = mDevice.promote();
1267 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001268 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001269 }
1270
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001271 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001272 Mutex::Autolock _l(dev->mDeviceLock);
1273 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001274 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001275 }
1276 switch (errorCode) {
1277 case ERROR_CAMERA_DISCONNECTED:
1278 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001279 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001280 if (session != nullptr) {
1281 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001282 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001283 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001284 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1285 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1286 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001287 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001288 msg->post();
1289 break;
1290 }
1291 default:
1292 ALOGE("Unknown error from camera device: %d", errorCode);
1293 // no break
1294 case ERROR_CAMERA_DEVICE:
1295 case ERROR_CAMERA_SERVICE:
1296 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001297 switch (errorCode) {
1298 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001299 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001300 break;
1301 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001302 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001303 break;
1304 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001305 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001306 break;
1307 }
1308 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1309 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1310 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001311 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001312 msg->setInt32(kErrorCodeKey, errorCode);
1313 msg->post();
1314 break;
1315 }
1316 case ERROR_CAMERA_REQUEST:
1317 case ERROR_CAMERA_RESULT:
1318 case ERROR_CAMERA_BUFFER:
1319 dev->onCaptureErrorLocked(errorCode, resultExtras);
1320 break;
1321 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001322 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001323}
1324
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001325binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001326CameraDevice::ServiceCallback::onDeviceIdle() {
1327 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001328 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001329 sp<CameraDevice> dev = mDevice.promote();
1330 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001331 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001332 }
1333
1334 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001335 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001336 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001337 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001338
1339 if (dev->mIdle) {
1340 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001341 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001342 }
1343
1344 if (dev->mCurrentSession != nullptr) {
1345 ALOGE("onDeviceIdle sending state cb");
1346 if (dev->mBusySession != dev->mCurrentSession) {
1347 ALOGE("Current session != busy session");
1348 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001349 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001350 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001351
Yin-Chia Yehead91462016-01-06 16:45:08 -08001352 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1353 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1354 msg->setObject(kSessionSpKey, dev->mBusySession);
1355 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1356 // Make sure we clear the sp first so the session destructor can
1357 // only happen on handler thread (where we don't hold device/session lock)
1358 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001359 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001360 }
1361 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001362 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001363 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001364}
1365
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001366binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001367CameraDevice::ServiceCallback::onCaptureStarted(
1368 const CaptureResultExtras& resultExtras,
1369 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001370 binder::Status ret = binder::Status::ok();
1371
Yin-Chia Yehead91462016-01-06 16:45:08 -08001372 sp<CameraDevice> dev = mDevice.promote();
1373 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001374 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001375 }
1376 Mutex::Autolock _l(dev->mDeviceLock);
1377 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001378 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001379 }
1380
1381 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001382 int32_t burstId = resultExtras.burstId;
1383
1384 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1385 if (it != dev->mSequenceCallbackMap.end()) {
1386 CallbackHolder cbh = (*it).second;
1387 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1388 sp<ACameraCaptureSession> session = cbh.mSession;
1389 if ((size_t) burstId >= cbh.mRequests.size()) {
1390 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1391 __FUNCTION__, burstId, cbh.mRequests.size());
1392 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1393 }
1394 sp<CaptureRequest> request = cbh.mRequests[burstId];
1395 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1396 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1397 msg->setObject(kSessionSpKey, session);
1398 msg->setPointer(kCallbackFpKey, (void*) onStart);
1399 msg->setObject(kCaptureRequestKey, request);
1400 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001401 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001402 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001403 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001404}
1405
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001406binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001407CameraDevice::ServiceCallback::onResultReceived(
1408 const CameraMetadata& metadata,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001409 const CaptureResultExtras& resultExtras,
1410 const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
1411 (void) physicalResultInfos;
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 int sequenceId = resultExtras.requestId;
1419 int64_t frameNumber = resultExtras.frameNumber;
1420 int32_t burstId = resultExtras.burstId;
1421 bool isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1422
1423 if (!isPartialResult) {
1424 ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1425 }
1426
1427 Mutex::Autolock _l(dev->mDeviceLock);
1428 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001429 return ret; // device has been disconnected
Yin-Chia Yehead91462016-01-06 16:45:08 -08001430 }
1431
1432 if (dev->isClosed()) {
1433 if (!isPartialResult) {
1434 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1435 }
1436 // early return to avoid callback sent to closed devices
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001437 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001438 }
1439
1440 CameraMetadata metadataCopy = metadata;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001441 metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
Yin-Chia Yehff2a4952016-04-02 16:31:57 -07001442 metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001443
1444 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1445 if (it != dev->mSequenceCallbackMap.end()) {
1446 CallbackHolder cbh = (*it).second;
1447 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1448 cbh.mCallbacks.onCaptureProgressed :
1449 cbh.mCallbacks.onCaptureCompleted;
1450 sp<ACameraCaptureSession> session = cbh.mSession;
1451 if ((size_t) burstId >= cbh.mRequests.size()) {
1452 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1453 __FUNCTION__, burstId, cbh.mRequests.size());
1454 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1455 }
1456 sp<CaptureRequest> request = cbh.mRequests[burstId];
1457 sp<ACameraMetadata> result(new ACameraMetadata(
1458 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1459
1460 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1461 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1462 msg->setObject(kSessionSpKey, session);
1463 msg->setPointer(kCallbackFpKey, (void*) onResult);
1464 msg->setObject(kCaptureRequestKey, request);
1465 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001466 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001467 }
1468
1469 if (!isPartialResult) {
1470 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1471 dev->checkAndFireSequenceCompleteLocked();
1472 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001473
1474 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001475}
1476
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001477binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001478CameraDevice::ServiceCallback::onPrepared(int) {
1479 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001480 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001481}
1482
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001483binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001484CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1485 // onRequestQueueEmpty not yet implemented in NDK
1486 return binder::Status::ok();
1487}
1488
1489binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001490CameraDevice::ServiceCallback::onRepeatingRequestError(
1491 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001492 binder::Status ret = binder::Status::ok();
1493
1494 sp<CameraDevice> dev = mDevice.promote();
1495 if (dev == nullptr) {
1496 return ret; // device has been closed
1497 }
1498
1499 Mutex::Autolock _l(dev->mDeviceLock);
1500
1501 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001502 if (stoppedSequenceId == repeatingSequenceId) {
1503 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1504 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001505
1506 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1507
1508 return ret;
1509}
1510
1511
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001512} // namespace android