blob: 4abd2679be72b68d17d5f41d550d1e33b194a08d [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,
160 const ACameraCaptureSession_stateCallbacks* callbacks,
161 /*out*/ACameraCaptureSession** session) {
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700162 sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800163 Mutex::Autolock _l(mDeviceLock);
164 camera_status_t ret = checkCameraClosedOrErrorLocked();
165 if (ret != ACAMERA_OK) {
166 return ret;
167 }
168
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700169 if (currentSession != nullptr) {
170 currentSession->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800171 stopRepeatingLocked();
172 }
173
174 // Create new session
175 ret = configureStreamsLocked(outputs);
176 if (ret != ACAMERA_OK) {
177 ALOGE("Fail to create new session. cannot configure streams");
178 return ret;
179 }
180
181 ACameraCaptureSession* newSession = new ACameraCaptureSession(
182 mNextSessionId++, outputs, callbacks, this);
183
Yin-Chia Yehead91462016-01-06 16:45:08 -0800184 // set new session as current session
185 newSession->incStrong((void *) ACameraDevice_createCaptureSession);
186 mCurrentSession = newSession;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700187 mFlushing = false;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800188 *session = newSession;
189 return ACAMERA_OK;
190}
191
192camera_status_t
193CameraDevice::captureLocked(
194 sp<ACameraCaptureSession> session,
195 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
196 int numRequests, ACaptureRequest** requests,
197 /*optional*/int* captureSequenceId) {
198 return submitRequestsLocked(
199 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
200}
201
202camera_status_t
203CameraDevice::setRepeatingRequestsLocked(
204 sp<ACameraCaptureSession> session,
205 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
206 int numRequests, ACaptureRequest** requests,
207 /*optional*/int* captureSequenceId) {
208 return submitRequestsLocked(
209 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
210}
211
212camera_status_t
213CameraDevice::submitRequestsLocked(
214 sp<ACameraCaptureSession> session,
215 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
216 int numRequests, ACaptureRequest** requests,
217 /*optional*/int* captureSequenceId,
218 bool isRepeating) {
219 camera_status_t ret = checkCameraClosedOrErrorLocked();
220 if (ret != ACAMERA_OK) {
221 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
222 return ret;
223 }
224
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800225 // Form two vectors of capture request, one for internal tracking
226 std::vector<hardware::camera2::CaptureRequest> requestList;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800227 Vector<sp<CaptureRequest> > requestsV;
228 requestsV.setCapacity(numRequests);
229 for (int i = 0; i < numRequests; i++) {
230 sp<CaptureRequest> req;
231 ret = allocateCaptureRequest(requests[i], req);
232 if (ret != ACAMERA_OK) {
233 ALOGE("Convert capture request to internal format failure! ret %d", ret);
234 return ret;
235 }
236 if (req->mSurfaceList.empty()) {
237 ALOGE("Capture request without output target cannot be submitted!");
238 return ACAMERA_ERROR_INVALID_PARAMETER;
239 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800240 requestList.push_back(*(req.get()));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800241 requestsV.push_back(req);
242 }
243
244 if (isRepeating) {
245 ret = stopRepeatingLocked();
246 if (ret != ACAMERA_OK) {
247 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
248 return ret;
249 }
250 }
251
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800252 binder::Status remoteRet;
253 hardware::camera2::utils::SubmitInfo info;
254 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
255 int sequenceId = info.mRequestId;
256 int64_t lastFrameNumber = info.mLastFrameNumber;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800257 if (sequenceId < 0) {
258 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
259 return ACAMERA_ERROR_UNKNOWN;
260 }
261
262 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
263 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
264
265 if (isRepeating) {
266 // stopRepeating above should have cleanup repeating sequence id
267 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
268 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
269 return ACAMERA_ERROR_CAMERA_DEVICE;
270 }
271 mRepeatingSequenceId = sequenceId;
272 } else {
273 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
274 }
275
276 if (mIdle) {
277 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
278 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
279 msg->setObject(kSessionSpKey, session);
280 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700281 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800282 }
283 mIdle = false;
284 mBusySession = session;
285
286 if (captureSequenceId) {
287 *captureSequenceId = sequenceId;
288 }
289 return ACAMERA_OK;
290}
291
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800292camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
Emilian Peev40ead602017-09-26 15:46:36 +0100293 camera_status_t ret = checkCameraClosedOrErrorLocked();
294 if (ret != ACAMERA_OK) {
295 return ret;
296 }
297
298 if (output == nullptr) {
299 return ACAMERA_ERROR_INVALID_PARAMETER;
300 }
301
302 if (!output->mIsShared) {
303 ALOGE("Error output configuration is not shared");
304 return ACAMERA_ERROR_INVALID_OPERATION;
305 }
306
307 int32_t streamId = -1;
308 for (auto& kvPair : mConfiguredOutputs) {
309 if (kvPair.second.first == output->mWindow) {
310 streamId = kvPair.first;
311 break;
312 }
313 }
314 if (streamId < 0) {
315 ALOGE("Error: Invalid output configuration");
316 return ACAMERA_ERROR_INVALID_PARAMETER;
317 }
318
319 sp<IGraphicBufferProducer> iGBP(nullptr);
320 ret = getIGBPfromAnw(output->mWindow, iGBP);
321 if (ret != ACAMERA_OK) {
322 ALOGE("Camera device %s failed to extract graphic producer from native window",
323 getId());
324 return ret;
325 }
326
327 OutputConfiguration outConfig(iGBP, output->mRotation, OutputConfiguration::INVALID_SET_ID,
328 true);
329
330 for (auto& anw : output->mSharedWindows) {
331 ret = getIGBPfromAnw(anw, iGBP);
332 if (ret != ACAMERA_OK) {
333 ALOGE("Camera device %s failed to extract graphic producer from native window",
334 getId());
335 return ret;
336 }
337 outConfig.addGraphicProducer(iGBP);
338 }
339
340 auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
341 if (!remoteRet.isOk()) {
342 switch (remoteRet.serviceSpecificErrorCode()) {
343 case hardware::ICameraService::ERROR_INVALID_OPERATION:
344 ALOGE("Camera device %s invalid operation: %s", getId(),
345 remoteRet.toString8().string());
346 return ACAMERA_ERROR_INVALID_OPERATION;
347 break;
348 case hardware::ICameraService::ERROR_ALREADY_EXISTS:
349 ALOGE("Camera device %s output surface already exists: %s", getId(),
350 remoteRet.toString8().string());
351 return ACAMERA_ERROR_INVALID_PARAMETER;
352 break;
353 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
354 ALOGE("Camera device %s invalid input argument: %s", getId(),
355 remoteRet.toString8().string());
356 return ACAMERA_ERROR_INVALID_PARAMETER;
357 break;
358 default:
359 ALOGE("Camera device %s failed to add shared output: %s", getId(),
360 remoteRet.toString8().string());
361 return ACAMERA_ERROR_UNKNOWN;
362 }
363 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800364 mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
Emilian Peev40ead602017-09-26 15:46:36 +0100365
366 return ACAMERA_OK;
367}
368
Yin-Chia Yehead91462016-01-06 16:45:08 -0800369camera_status_t
370CameraDevice::allocateCaptureRequest(
371 const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
372 camera_status_t ret;
373 sp<CaptureRequest> req(new CaptureRequest());
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800374 req->mMetadata = request->settings->getInternalData();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800375 req->mIsReprocess = false; // NDK does not support reprocessing yet
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700376 req->mContext = request->context;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800377 req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
Yin-Chia Yehead91462016-01-06 16:45:08 -0800378
379 for (auto outputTarget : request->targets->mOutputs) {
380 ANativeWindow* anw = outputTarget.mWindow;
381 sp<Surface> surface;
382 ret = getSurfaceFromANativeWindow(anw, surface);
383 if (ret != ACAMERA_OK) {
384 ALOGE("Bad output target in capture request! ret %d", ret);
385 return ret;
386 }
387 req->mSurfaceList.push_back(surface);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800388
389 bool found = false;
390 // lookup stream/surface ID
391 for (const auto& kvPair : mConfiguredOutputs) {
392 int streamId = kvPair.first;
393 const OutputConfiguration& outConfig = kvPair.second.second;
394 const auto& gbps = outConfig.getGraphicBufferProducers();
395 for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
396 if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
397 found = true;
398 req->mStreamIdxList.push_back(streamId);
399 req->mSurfaceIdxList.push_back(surfaceId);
400 break;
401 }
402 }
403 if (found) {
404 break;
405 }
406 }
407 if (!found) {
408 ALOGE("Unconfigured output target %p in capture request!", anw);
409 return ret;
410 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800411 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800412
Yin-Chia Yehead91462016-01-06 16:45:08 -0800413 outReq = req;
414 return ACAMERA_OK;
415}
416
417ACaptureRequest*
418CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
419 ACaptureRequest* pRequest = new ACaptureRequest();
420 CameraMetadata clone = req->mMetadata;
421 pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
422 pRequest->targets = new ACameraOutputTargets();
423 for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
424 ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
425 ACameraOutputTarget outputTarget(anw);
426 pRequest->targets->mOutputs.insert(outputTarget);
427 }
Yin-Chia Yehd39b9e32017-10-30 17:39:23 -0700428 pRequest->context = req->mContext;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800429 return pRequest;
430}
431
432void
433CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
434 if (req == nullptr) {
435 return;
436 }
437 delete req->settings;
438 delete req->targets;
439 delete req;
440}
441
442void
443CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
444 if (isClosed()) {
445 // Device is closing already. do nothing
446 return;
447 }
448
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700449 if (mCurrentSession != session) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800450 // Session has been replaced by other seesion or device is closed
451 return;
452 }
453 mCurrentSession = nullptr;
454
455 // Should not happen
456 if (!session->mIsClosed) {
457 ALOGE("Error: unclosed session %p reaches end of life!", session);
458 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
459 return;
460 }
461
462 // No new session, unconfigure now
463 camera_status_t ret = configureStreamsLocked(nullptr);
464 if (ret != ACAMERA_OK) {
465 ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
466 }
467}
468
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800469void
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700470CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800471 if (mClosing.exchange(true)) {
472 // Already closing, just return
473 ALOGW("Camera device %s is already closing.", getId());
474 return;
475 }
476
477 if (mRemote != nullptr) {
478 mRemote->disconnect();
479 }
480 mRemote = nullptr;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800481
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700482 if (session != nullptr) {
483 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -0800484 }
485}
486
487camera_status_t
488CameraDevice::stopRepeatingLocked() {
489 camera_status_t ret = checkCameraClosedOrErrorLocked();
490 if (ret != ACAMERA_OK) {
491 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
492 return ret;
493 }
494 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
495 int repeatingSequenceId = mRepeatingSequenceId;
496 mRepeatingSequenceId = REQUEST_ID_NONE;
497
498 int64_t lastFrameNumber;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800499 binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700500 if (remoteRet.serviceSpecificErrorCode() ==
501 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
502 ALOGV("Repeating request is already stopped.");
503 return ACAMERA_OK;
504 } else if (!remoteRet.isOk()) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800505 ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800506 return ACAMERA_ERROR_UNKNOWN;
507 }
508 checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
509 }
510 return ACAMERA_OK;
511}
512
513camera_status_t
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700514CameraDevice::flushLocked(ACameraCaptureSession* session) {
515 camera_status_t ret = checkCameraClosedOrErrorLocked();
516 if (ret != ACAMERA_OK) {
517 ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
518 return ret;
519 }
520
521 // This should never happen because creating a new session will close
522 // previous one and thus reject any API call from previous session.
523 // But still good to check here in case something unexpected happen.
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700524 if (mCurrentSession != session) {
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700525 ALOGE("Camera %s session %p is not current active session!", getId(), session);
526 return ACAMERA_ERROR_INVALID_OPERATION;
527 }
528
529 if (mFlushing) {
530 ALOGW("Camera %s is already aborting captures", getId());
531 return ACAMERA_OK;
532 }
533
534 mFlushing = true;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700535
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700536 // Send onActive callback to guarantee there is always active->ready transition
537 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
538 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
539 msg->setObject(kSessionSpKey, session);
540 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700541 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700542
543 // If device is already idling, send callback and exit early
544 if (mIdle) {
545 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
546 msg->setPointer(kContextKey, session->mUserSessionCallback.context);
547 msg->setObject(kSessionSpKey, session);
548 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700549 postSessionMsgAndCleanup(msg);
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -0700550 mFlushing = false;
551 return ACAMERA_OK;
552 }
553
554 int64_t lastFrameNumber;
555 binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
556 if (!remoteRet.isOk()) {
557 ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
558 return ACAMERA_ERROR_UNKNOWN;
559 }
560 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
561 checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
562 }
563 return ACAMERA_OK;
564}
565
566camera_status_t
Yin-Chia Yehead91462016-01-06 16:45:08 -0800567CameraDevice::waitUntilIdleLocked() {
568 camera_status_t ret = checkCameraClosedOrErrorLocked();
569 if (ret != ACAMERA_OK) {
570 ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
571 return ret;
572 }
573
574 if (mRepeatingSequenceId != REQUEST_ID_NONE) {
575 ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
576 return ACAMERA_ERROR_INVALID_OPERATION;
577 }
578
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800579 binder::Status remoteRet = mRemote->waitUntilIdle();
580 if (!remoteRet.isOk()) {
581 ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800582 // TODO: define a function to convert status_t -> camera_status_t
583 return ACAMERA_ERROR_UNKNOWN;
584 }
585
586 return ACAMERA_OK;
587}
588
589camera_status_t
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700590CameraDevice::getIGBPfromAnw(
591 ANativeWindow* anw,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800592 sp<IGraphicBufferProducer>& out) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800593 sp<Surface> surface;
594 camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
595 if (ret != ACAMERA_OK) {
596 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800597 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800598 out = surface->getIGraphicBufferProducer();
599 return ACAMERA_OK;
600}
601
602camera_status_t
603CameraDevice::getSurfaceFromANativeWindow(
604 ANativeWindow* anw, sp<Surface>& out) {
605 if (anw == nullptr) {
606 ALOGE("Error: output ANativeWindow is null");
607 return ACAMERA_ERROR_INVALID_PARAMETER;
608 }
609 int value;
610 int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800611 if (err != OK || value != NATIVE_WINDOW_SURFACE) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800612 ALOGE("Error: ANativeWindow is not backed by Surface!");
613 return ACAMERA_ERROR_INVALID_PARAMETER;
614 }
615 sp<Surface> surface(static_cast<Surface*>(anw));
616 out = surface;
617 return ACAMERA_OK;
618}
619
620camera_status_t
621CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) {
622 ACaptureSessionOutputContainer emptyOutput;
623 if (outputs == nullptr) {
624 outputs = &emptyOutput;
625 }
626
Yin-Chia Yehead91462016-01-06 16:45:08 -0800627 camera_status_t ret = checkCameraClosedOrErrorLocked();
628 if (ret != ACAMERA_OK) {
629 return ret;
630 }
631
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700632 std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800633 for (auto outConfig : outputs->mOutputs) {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700634 ANativeWindow* anw = outConfig.mWindow;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800635 sp<IGraphicBufferProducer> iGBP(nullptr);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700636 ret = getIGBPfromAnw(anw, iGBP);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800637 if (ret != ACAMERA_OK) {
638 return ret;
639 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700640 outputSet.insert(std::make_pair(
Emilian Peev40ead602017-09-26 15:46:36 +0100641 anw, OutputConfiguration(iGBP, outConfig.mRotation,
642 OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800643 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700644 auto addSet = outputSet;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800645 std::vector<int> deleteList;
646
647 // Determine which streams need to be created, which to be deleted
648 for (auto& kvPair : mConfiguredOutputs) {
649 int streamId = kvPair.first;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700650 auto& outputPair = kvPair.second;
651 if (outputSet.count(outputPair) == 0) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800652 deleteList.push_back(streamId); // Need to delete a no longer needed stream
653 } else {
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700654 addSet.erase(outputPair); // No need to add already existing stream
Yin-Chia Yehead91462016-01-06 16:45:08 -0800655 }
656 }
657
658 ret = stopRepeatingLocked();
659 if (ret != ACAMERA_OK) {
660 ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
661 return ret;
662 }
663
664 ret = waitUntilIdleLocked();
665 if (ret != ACAMERA_OK) {
666 ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
667 return ret;
668 }
669
670 // Send onReady to previous session
671 // CurrentSession will be updated after configureStreamLocked, so here
672 // mCurrentSession is the session to be replaced by a new session
673 if (!mIdle && mCurrentSession != nullptr) {
674 if (mBusySession != mCurrentSession) {
675 ALOGE("Current session != busy session");
676 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
677 return ACAMERA_ERROR_CAMERA_DEVICE;
678 }
679 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
680 msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
681 msg->setObject(kSessionSpKey, mBusySession);
682 msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
683 mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700684 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800685 }
686 mIdle = true;
687
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800688 binder::Status remoteRet = mRemote->beginConfigure();
689 if (!remoteRet.isOk()) {
690 ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800691 return ACAMERA_ERROR_UNKNOWN;
692 }
693
694 // delete to-be-deleted streams
695 for (auto streamId : deleteList) {
696 remoteRet = mRemote->deleteStream(streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800697 if (!remoteRet.isOk()) {
698 ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
699 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800700 return ACAMERA_ERROR_UNKNOWN;
701 }
702 mConfiguredOutputs.erase(streamId);
703 }
704
705 // add new streams
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700706 for (auto outputPair : addSet) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800707 int streamId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700708 remoteRet = mRemote->createStream(outputPair.second, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800709 if (!remoteRet.isOk()) {
710 ALOGE("Camera device %s failed to create stream: %s", getId(),
711 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800712 return ACAMERA_ERROR_UNKNOWN;
713 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700714 mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
Yin-Chia Yehead91462016-01-06 16:45:08 -0800715 }
716
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800717 remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false);
718 if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
719 ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
720 remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800721 return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800722 } else if (!remoteRet.isOk()) {
723 ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
Yin-Chia Yehead91462016-01-06 16:45:08 -0800724 return ACAMERA_ERROR_UNKNOWN;
725 }
726
727 return ACAMERA_OK;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800728}
729
730void
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800731CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800732 Mutex::Autolock _l(mDeviceLock);
733 mRemote = remote;
734}
735
736camera_status_t
737CameraDevice::checkCameraClosedOrErrorLocked() const {
738 if (mRemote == nullptr) {
739 ALOGE("%s: camera device already closed", __FUNCTION__);
740 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
741 }
742 if (mInError) {// triggered by onDeviceError
743 ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
744 return mError;
745 }
746 return ACAMERA_OK;
747}
748
749void
Yin-Chia Yehead91462016-01-06 16:45:08 -0800750CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
751 mInError = true;
752 mError = error;
753 return;
754}
755
756void
757CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
758 ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
759 if (isError) {
760 mFutureErrorSet.insert(frameNumber);
761 } else if (frameNumber <= mCompletedFrameNumber) {
762 ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
763 frameNumber, mCompletedFrameNumber);
764 return;
765 } else {
766 if (frameNumber != mCompletedFrameNumber + 1) {
767 ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
768 mCompletedFrameNumber + 1, frameNumber);
769 // Do not assert as in java implementation
770 }
771 mCompletedFrameNumber = frameNumber;
772 }
773 update();
774}
775
776void
777CameraDevice::FrameNumberTracker::update() {
778 for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
779 int64_t errorFrameNumber = *it;
780 if (errorFrameNumber == mCompletedFrameNumber + 1) {
781 mCompletedFrameNumber++;
782 it = mFutureErrorSet.erase(it);
783 } else if (errorFrameNumber <= mCompletedFrameNumber) {
784 // This should not happen, but deal with it anyway
785 ALOGE("Completd frame number passed through current frame number!");
786 // erase the old error since it's no longer useful
787 it = mFutureErrorSet.erase(it);
788 } else {
789 // Normal requests hasn't catched up error frames, just break
790 break;
791 }
792 }
793 ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
794}
795
796void
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800797CameraDevice::onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800798 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800799 const CaptureResultExtras& resultExtras) {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800800 int sequenceId = resultExtras.requestId;
801 int64_t frameNumber = resultExtras.frameNumber;
802 int32_t burstId = resultExtras.burstId;
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700803 auto it = mSequenceCallbackMap.find(sequenceId);
804 if (it == mSequenceCallbackMap.end()) {
805 ALOGE("%s: Error: capture sequence index %d not found!",
806 __FUNCTION__, sequenceId);
807 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800808 return;
809 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700810
811 CallbackHolder cbh = (*it).second;
812 sp<ACameraCaptureSession> session = cbh.mSession;
813 if ((size_t) burstId >= cbh.mRequests.size()) {
814 ALOGE("%s: Error: request index %d out of bound (size %zu)",
815 __FUNCTION__, burstId, cbh.mRequests.size());
816 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
817 return;
818 }
819 sp<CaptureRequest> request = cbh.mRequests[burstId];
820
821 // Handle buffer error
822 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
823 int32_t streamId = resultExtras.errorStreamId;
824 ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
825 cbh.mCallbacks.onCaptureBufferLost;
826 auto outputPairIt = mConfiguredOutputs.find(streamId);
827 if (outputPairIt == mConfiguredOutputs.end()) {
828 ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800829 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
830 return;
831 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700832
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800833 const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
834 for (const auto& outGbp : gbps) {
835 for (auto surface : request->mSurfaceList) {
836 if (surface->getIGraphicBufferProducer() == outGbp) {
837 ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
838 ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
839 getId(), anw, frameNumber);
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700840
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800841 sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
842 msg->setPointer(kContextKey, cbh.mCallbacks.context);
843 msg->setObject(kSessionSpKey, session);
844 msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
845 msg->setObject(kCaptureRequestKey, request);
846 msg->setPointer(kAnwKey, (void*) anw);
847 msg->setInt64(kFrameNumberKey, frameNumber);
848 postSessionMsgAndCleanup(msg);
849 }
850 }
851 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700852 } else { // Handle other capture failures
853 // Fire capture failure callback if there is one registered
854 ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800855 sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
856 failure->frameNumber = frameNumber;
857 // TODO: refine this when implementing flush
858 failure->reason = CAPTURE_FAILURE_REASON_ERROR;
859 failure->sequenceId = sequenceId;
860 failure->wasImageCaptured = (errorCode ==
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800861 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800862
863 sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
864 msg->setPointer(kContextKey, cbh.mCallbacks.context);
865 msg->setObject(kSessionSpKey, session);
866 msg->setPointer(kCallbackFpKey, (void*) onError);
867 msg->setObject(kCaptureRequestKey, request);
868 msg->setObject(kCaptureFailureKey, failure);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700869 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800870
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700871 // Update tracker
872 mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
873 checkAndFireSequenceCompleteLocked();
874 }
875 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800876}
877
878void CameraDevice::CallbackHandler::onMessageReceived(
879 const sp<AMessage> &msg) {
880 switch (msg->what()) {
881 case kWhatOnDisconnected:
882 case kWhatOnError:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800883 case kWhatSessionStateCb:
884 case kWhatCaptureStart:
885 case kWhatCaptureResult:
886 case kWhatCaptureFail:
887 case kWhatCaptureSeqEnd:
888 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700889 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800890 ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800891 break;
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700892 case kWhatCleanUpSessions:
893 mCachedSessions.clear();
894 return;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800895 default:
896 ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
897 return;
898 }
899 // Check the common part of all message
900 void* context;
901 bool found = msg->findPointer(kContextKey, &context);
902 if (!found) {
903 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
904 return;
905 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800906 switch (msg->what()) {
907 case kWhatOnDisconnected:
908 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800909 ACameraDevice* dev;
910 found = msg->findPointer(kDeviceKey, (void**) &dev);
911 if (!found || dev == nullptr) {
912 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
913 return;
914 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800915 ACameraDevice_StateCallback onDisconnected;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800916 found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800917 if (!found) {
918 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
919 return;
920 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800921 if (onDisconnected == nullptr) {
922 return;
923 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800924 (*onDisconnected)(context, dev);
925 break;
926 }
927 case kWhatOnError:
928 {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800929 ACameraDevice* dev;
930 found = msg->findPointer(kDeviceKey, (void**) &dev);
931 if (!found || dev == nullptr) {
932 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
933 return;
934 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800935 ACameraDevice_ErrorStateCallback onError;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800936 found = msg->findPointer(kCallbackFpKey, (void**) &onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800937 if (!found) {
938 ALOGE("%s: Cannot find onError!", __FUNCTION__);
939 return;
940 }
941 int errorCode;
942 found = msg->findInt32(kErrorCodeKey, &errorCode);
943 if (!found) {
944 ALOGE("%s: Cannot find error code!", __FUNCTION__);
945 return;
946 }
Yin-Chia Yehead91462016-01-06 16:45:08 -0800947 if (onError == nullptr) {
948 return;
949 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800950 (*onError)(context, dev, errorCode);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800951 break;
952 }
953 case kWhatSessionStateCb:
954 case kWhatCaptureStart:
955 case kWhatCaptureResult:
956 case kWhatCaptureFail:
957 case kWhatCaptureSeqEnd:
958 case kWhatCaptureSeqAbort:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700959 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800960 {
961 sp<RefBase> obj;
962 found = msg->findObject(kSessionSpKey, &obj);
963 if (!found || obj == nullptr) {
964 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
965 return;
966 }
967 sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -0700968 mCachedSessions.push(session);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800969 sp<CaptureRequest> requestSp = nullptr;
970 switch (msg->what()) {
971 case kWhatCaptureStart:
972 case kWhatCaptureResult:
973 case kWhatCaptureFail:
Yin-Chia Yehe081c592016-03-29 18:26:44 -0700974 case kWhatCaptureBufferLost:
Yin-Chia Yehead91462016-01-06 16:45:08 -0800975 found = msg->findObject(kCaptureRequestKey, &obj);
976 if (!found) {
977 ALOGE("%s: Cannot find capture request!", __FUNCTION__);
978 return;
979 }
980 requestSp = static_cast<CaptureRequest*>(obj.get());
981 break;
982 }
983
984 switch (msg->what()) {
985 case kWhatSessionStateCb:
986 {
987 ACameraCaptureSession_stateCallback onState;
988 found = msg->findPointer(kCallbackFpKey, (void**) &onState);
989 if (!found) {
990 ALOGE("%s: Cannot find state callback!", __FUNCTION__);
991 return;
992 }
993 if (onState == nullptr) {
994 return;
995 }
996 (*onState)(context, session.get());
997 break;
998 }
999 case kWhatCaptureStart:
1000 {
1001 ACameraCaptureSession_captureCallback_start onStart;
1002 found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1003 if (!found) {
1004 ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1005 return;
1006 }
1007 if (onStart == nullptr) {
1008 return;
1009 }
1010 int64_t timestamp;
1011 found = msg->findInt64(kTimeStampKey, &timestamp);
1012 if (!found) {
1013 ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1014 return;
1015 }
1016 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1017 (*onStart)(context, session.get(), request, timestamp);
1018 freeACaptureRequest(request);
1019 break;
1020 }
1021 case kWhatCaptureResult:
1022 {
1023 ACameraCaptureSession_captureCallback_result onResult;
1024 found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1025 if (!found) {
1026 ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1027 return;
1028 }
1029 if (onResult == nullptr) {
1030 return;
1031 }
1032
1033 found = msg->findObject(kCaptureResultKey, &obj);
1034 if (!found) {
1035 ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1036 return;
1037 }
1038 sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1039 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1040 (*onResult)(context, session.get(), request, result.get());
1041 freeACaptureRequest(request);
1042 break;
1043 }
1044 case kWhatCaptureFail:
1045 {
1046 ACameraCaptureSession_captureCallback_failed onFail;
1047 found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1048 if (!found) {
1049 ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1050 return;
1051 }
1052 if (onFail == nullptr) {
1053 return;
1054 }
1055
1056 found = msg->findObject(kCaptureFailureKey, &obj);
1057 if (!found) {
1058 ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1059 return;
1060 }
1061 sp<CameraCaptureFailure> failureSp(
1062 static_cast<CameraCaptureFailure*>(obj.get()));
1063 ACameraCaptureFailure* failure =
1064 static_cast<ACameraCaptureFailure*>(failureSp.get());
1065 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1066 (*onFail)(context, session.get(), request, failure);
1067 freeACaptureRequest(request);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001068 break;
1069 }
1070 case kWhatCaptureSeqEnd:
1071 {
1072 ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1073 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1074 if (!found) {
1075 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1076 return;
1077 }
1078 if (onSeqEnd == nullptr) {
1079 return;
1080 }
1081 int seqId;
1082 found = msg->findInt32(kSequenceIdKey, &seqId);
1083 if (!found) {
1084 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1085 return;
1086 }
1087 int64_t frameNumber;
1088 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1089 if (!found) {
1090 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1091 return;
1092 }
1093 (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1094 break;
1095 }
1096 case kWhatCaptureSeqAbort:
1097 {
1098 ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1099 found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1100 if (!found) {
1101 ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1102 return;
1103 }
1104 if (onSeqAbort == nullptr) {
1105 return;
1106 }
1107 int seqId;
1108 found = msg->findInt32(kSequenceIdKey, &seqId);
1109 if (!found) {
1110 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1111 return;
1112 }
1113 (*onSeqAbort)(context, session.get(), seqId);
1114 break;
1115 }
Yin-Chia Yehe081c592016-03-29 18:26:44 -07001116 case kWhatCaptureBufferLost:
1117 {
1118 ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1119 found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1120 if (!found) {
1121 ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1122 return;
1123 }
1124 if (onBufferLost == nullptr) {
1125 return;
1126 }
1127
1128 ANativeWindow* anw;
1129 found = msg->findPointer(kAnwKey, (void**) &anw);
1130 if (!found) {
1131 ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1132 return;
1133 }
1134
1135 int64_t frameNumber;
1136 found = msg->findInt64(kFrameNumberKey, &frameNumber);
1137 if (!found) {
1138 ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1139 return;
1140 }
1141
1142 ACaptureRequest* request = allocateACaptureRequest(requestSp);
1143 (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1144 freeACaptureRequest(request);
1145 break;
1146 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001147 }
1148 break;
1149 }
1150 }
1151}
1152
1153CameraDevice::CallbackHolder::CallbackHolder(
1154 sp<ACameraCaptureSession> session,
1155 const Vector<sp<CaptureRequest> >& requests,
1156 bool isRepeating,
1157 ACameraCaptureSession_captureCallbacks* cbs) :
1158 mSession(session), mRequests(requests),
1159 mIsRepeating(isRepeating), mCallbacks(fillCb(cbs)) {}
1160
1161void
1162CameraDevice::checkRepeatingSequenceCompleteLocked(
1163 const int sequenceId, const int64_t lastFrameNumber) {
1164 ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1165 if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1166 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1167 ALOGW("No callback found for sequenceId %d", sequenceId);
1168 return;
1169 }
1170 // remove callback holder from callback map
1171 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1172 CallbackHolder cbh = cbIt->second;
1173 mSequenceCallbackMap.erase(cbIt);
1174 // send seq aborted callback
1175 sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1176 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1177 msg->setObject(kSessionSpKey, cbh.mSession);
1178 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceAborted);
1179 msg->setInt32(kSequenceIdKey, sequenceId);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001180 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001181 } else {
1182 // Use mSequenceLastFrameNumberMap to track
1183 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1184
1185 // Last frame might have arrived. Check now
1186 checkAndFireSequenceCompleteLocked();
1187 }
1188}
1189
1190void
1191CameraDevice::checkAndFireSequenceCompleteLocked() {
1192 int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1193 //std::map<int, int64_t> mSequenceLastFrameNumberMap;
1194 auto it = mSequenceLastFrameNumberMap.begin();
1195 while (it != mSequenceLastFrameNumberMap.end()) {
1196 int sequenceId = it->first;
1197 int64_t lastFrameNumber = it->second;
1198 bool seqCompleted = false;
1199 bool hasCallback = true;
1200
1201 if (mRemote == nullptr) {
1202 ALOGW("Camera %s closed while checking sequence complete", getId());
1203 return;
1204 }
1205
1206 // Check if there is callback for this sequence
1207 // This should not happen because we always register callback (with nullptr inside)
1208 if (mSequenceCallbackMap.count(sequenceId) == 0) {
1209 ALOGW("No callback found for sequenceId %d", sequenceId);
1210 hasCallback = false;
1211 }
1212
1213 if (lastFrameNumber <= completedFrameNumber) {
1214 ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
1215 sequenceId, lastFrameNumber, completedFrameNumber);
1216 seqCompleted = true;
1217 }
1218
1219 if (seqCompleted && hasCallback) {
1220 // remove callback holder from callback map
1221 auto cbIt = mSequenceCallbackMap.find(sequenceId);
1222 CallbackHolder cbh = cbIt->second;
1223 mSequenceCallbackMap.erase(cbIt);
1224 // send seq complete callback
1225 sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1226 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1227 msg->setObject(kSessionSpKey, cbh.mSession);
1228 msg->setPointer(kCallbackFpKey, (void*) cbh.mCallbacks.onCaptureSequenceCompleted);
1229 msg->setInt32(kSequenceIdKey, sequenceId);
1230 msg->setInt64(kFrameNumberKey, lastFrameNumber);
1231
1232 // Clear the session sp before we send out the message
1233 // This will guarantee the rare case where the message is processed
1234 // before cbh goes out of scope and causing we call the session
1235 // destructor while holding device lock
1236 cbh.mSession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001237 postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001238 }
1239
1240 // No need to track sequence complete if there is no callback registered
1241 if (seqCompleted || !hasCallback) {
1242 it = mSequenceLastFrameNumberMap.erase(it);
1243 } else {
1244 ++it;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001245 }
1246 }
1247}
1248
1249/**
1250 * Camera service callback implementation
1251 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001252binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001253CameraDevice::ServiceCallback::onDeviceError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001254 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001255 const CaptureResultExtras& resultExtras) {
1256 ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1257 errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001258 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001259 sp<CameraDevice> dev = mDevice.promote();
1260 if (dev == 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
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001264 sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001265 Mutex::Autolock _l(dev->mDeviceLock);
1266 if (dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001267 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001268 }
1269 switch (errorCode) {
1270 case ERROR_CAMERA_DISCONNECTED:
1271 {
Yin-Chia Yehead91462016-01-06 16:45:08 -08001272 // Camera is disconnected, close the session and expect no more callbacks
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001273 if (session != nullptr) {
1274 session->closeByDevice();
Yin-Chia Yehead91462016-01-06 16:45:08 -08001275 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001276 dev->mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001277 sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1278 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1279 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001280 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001281 msg->post();
1282 break;
1283 }
1284 default:
1285 ALOGE("Unknown error from camera device: %d", errorCode);
1286 // no break
1287 case ERROR_CAMERA_DEVICE:
1288 case ERROR_CAMERA_SERVICE:
1289 {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001290 switch (errorCode) {
1291 case ERROR_CAMERA_DEVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001292 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001293 break;
1294 case ERROR_CAMERA_SERVICE:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001295 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001296 break;
1297 default:
Yin-Chia Yehead91462016-01-06 16:45:08 -08001298 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001299 break;
1300 }
1301 sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1302 msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1303 msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
Yin-Chia Yehead91462016-01-06 16:45:08 -08001304 msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001305 msg->setInt32(kErrorCodeKey, errorCode);
1306 msg->post();
1307 break;
1308 }
1309 case ERROR_CAMERA_REQUEST:
1310 case ERROR_CAMERA_RESULT:
1311 case ERROR_CAMERA_BUFFER:
1312 dev->onCaptureErrorLocked(errorCode, resultExtras);
1313 break;
1314 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001315 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001316}
1317
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001318binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001319CameraDevice::ServiceCallback::onDeviceIdle() {
1320 ALOGV("Camera is now idle");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001321 binder::Status ret = binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001322 sp<CameraDevice> dev = mDevice.promote();
1323 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001324 return ret; // device has been closed
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001325 }
1326
1327 Mutex::Autolock _l(dev->mDeviceLock);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001328 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001329 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001330 }
Yin-Chia Yehead91462016-01-06 16:45:08 -08001331
1332 if (dev->mIdle) {
1333 // Already in idle state. Possibly other thread did waitUntilIdle
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001334 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001335 }
1336
1337 if (dev->mCurrentSession != nullptr) {
1338 ALOGE("onDeviceIdle sending state cb");
1339 if (dev->mBusySession != dev->mCurrentSession) {
1340 ALOGE("Current session != busy session");
1341 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001342 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001343 }
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001344
Yin-Chia Yehead91462016-01-06 16:45:08 -08001345 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1346 msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1347 msg->setObject(kSessionSpKey, dev->mBusySession);
1348 msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1349 // Make sure we clear the sp first so the session destructor can
1350 // only happen on handler thread (where we don't hold device/session lock)
1351 dev->mBusySession.clear();
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001352 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001353 }
1354 dev->mIdle = true;
Yin-Chia Yeh309d05d2016-03-28 10:15:31 -07001355 dev->mFlushing = false;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001356 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001357}
1358
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001359binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001360CameraDevice::ServiceCallback::onCaptureStarted(
1361 const CaptureResultExtras& resultExtras,
1362 int64_t timestamp) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001363 binder::Status ret = binder::Status::ok();
1364
Yin-Chia Yehead91462016-01-06 16:45:08 -08001365 sp<CameraDevice> dev = mDevice.promote();
1366 if (dev == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001367 return ret; // device has been closed
Yin-Chia Yehead91462016-01-06 16:45:08 -08001368 }
1369 Mutex::Autolock _l(dev->mDeviceLock);
1370 if (dev->isClosed() || dev->mRemote == nullptr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001371 return ret;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001372 }
1373
1374 int sequenceId = resultExtras.requestId;
Yin-Chia Yehead91462016-01-06 16:45:08 -08001375 int32_t burstId = resultExtras.burstId;
1376
1377 auto it = dev->mSequenceCallbackMap.find(sequenceId);
1378 if (it != dev->mSequenceCallbackMap.end()) {
1379 CallbackHolder cbh = (*it).second;
1380 ACameraCaptureSession_captureCallback_start onStart = cbh.mCallbacks.onCaptureStarted;
1381 sp<ACameraCaptureSession> session = cbh.mSession;
1382 if ((size_t) burstId >= cbh.mRequests.size()) {
1383 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1384 __FUNCTION__, burstId, cbh.mRequests.size());
1385 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1386 }
1387 sp<CaptureRequest> request = cbh.mRequests[burstId];
1388 sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1389 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1390 msg->setObject(kSessionSpKey, session);
1391 msg->setPointer(kCallbackFpKey, (void*) onStart);
1392 msg->setObject(kCaptureRequestKey, request);
1393 msg->setInt64(kTimeStampKey, timestamp);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001394 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001395 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001396 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001397}
1398
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001399binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001400CameraDevice::ServiceCallback::onResultReceived(
1401 const CameraMetadata& metadata,
1402 const CaptureResultExtras& resultExtras) {
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;
1438 ACameraCaptureSession_captureCallback_result onResult = isPartialResult ?
1439 cbh.mCallbacks.onCaptureProgressed :
1440 cbh.mCallbacks.onCaptureCompleted;
1441 sp<ACameraCaptureSession> session = cbh.mSession;
1442 if ((size_t) burstId >= cbh.mRequests.size()) {
1443 ALOGE("%s: Error: request index %d out of bound (size %zu)",
1444 __FUNCTION__, burstId, cbh.mRequests.size());
1445 dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1446 }
1447 sp<CaptureRequest> request = cbh.mRequests[burstId];
1448 sp<ACameraMetadata> result(new ACameraMetadata(
1449 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1450
1451 sp<AMessage> msg = new AMessage(kWhatCaptureResult, dev->mHandler);
1452 msg->setPointer(kContextKey, cbh.mCallbacks.context);
1453 msg->setObject(kSessionSpKey, session);
1454 msg->setPointer(kCallbackFpKey, (void*) onResult);
1455 msg->setObject(kCaptureRequestKey, request);
1456 msg->setObject(kCaptureResultKey, result);
Yin-Chia Yeh6e2353b2017-10-24 16:35:20 -07001457 dev->postSessionMsgAndCleanup(msg);
Yin-Chia Yehead91462016-01-06 16:45:08 -08001458 }
1459
1460 if (!isPartialResult) {
1461 dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1462 dev->checkAndFireSequenceCompleteLocked();
1463 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001464
1465 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001466}
1467
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001468binder::Status
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001469CameraDevice::ServiceCallback::onPrepared(int) {
1470 // Prepare not yet implemented in NDK
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001471 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001472}
1473
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001474binder::Status
Shuzhen Wang9d066012016-09-30 11:30:20 -07001475CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1476 // onRequestQueueEmpty not yet implemented in NDK
1477 return binder::Status::ok();
1478}
1479
1480binder::Status
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001481CameraDevice::ServiceCallback::onRepeatingRequestError(
1482 int64_t lastFrameNumber, int32_t stoppedSequenceId) {
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001483 binder::Status ret = binder::Status::ok();
1484
1485 sp<CameraDevice> dev = mDevice.promote();
1486 if (dev == nullptr) {
1487 return ret; // device has been closed
1488 }
1489
1490 Mutex::Autolock _l(dev->mDeviceLock);
1491
1492 int repeatingSequenceId = dev->mRepeatingSequenceId;
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001493 if (stoppedSequenceId == repeatingSequenceId) {
1494 dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1495 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001496
1497 dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1498
1499 return ret;
1500}
1501
1502
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001503} // namespace android