xref: /aosp_15_r20/frameworks/av/camera/ndk/impl/ACameraDevice.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ACameraDevice"
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <vector>
21*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/ICameraService.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <gui/Surface.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <camera/StringUtils.h>
25*ec779b8eSAndroid Build Coastguard Worker #include "ACameraDevice.h"
26*ec779b8eSAndroid Build Coastguard Worker #include "ACameraMetadata.h"
27*ec779b8eSAndroid Build Coastguard Worker #include "ACaptureRequest.h"
28*ec779b8eSAndroid Build Coastguard Worker #include "ACameraCaptureSession.h"
29*ec779b8eSAndroid Build Coastguard Worker #include <com_android_internal_camera_flags.h>
30*ec779b8eSAndroid Build Coastguard Worker 
31*ec779b8eSAndroid Build Coastguard Worker namespace flags = com::android::internal::camera::flags;
32*ec779b8eSAndroid Build Coastguard Worker 
~ACameraDevice()33*ec779b8eSAndroid Build Coastguard Worker ACameraDevice::~ACameraDevice() {
34*ec779b8eSAndroid Build Coastguard Worker     mDevice->stopLooperAndDisconnect();
35*ec779b8eSAndroid Build Coastguard Worker }
36*ec779b8eSAndroid Build Coastguard Worker 
37*ec779b8eSAndroid Build Coastguard Worker namespace android {
38*ec779b8eSAndroid Build Coastguard Worker namespace acam {
39*ec779b8eSAndroid Build Coastguard Worker 
40*ec779b8eSAndroid Build Coastguard Worker using android::hardware::common::fmq::MQDescriptor;
41*ec779b8eSAndroid Build Coastguard Worker 
42*ec779b8eSAndroid Build Coastguard Worker // Static member definitions
43*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kContextKey        = "Context";
44*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kDeviceKey         = "Device";
45*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kErrorCodeKey      = "ErrorCode";
46*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kCallbackFpKey     = "Callback";
47*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kSessionSpKey      = "SessionSp";
48*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kCaptureRequestKey = "CaptureRequest";
49*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kTimeStampKey      = "TimeStamp";
50*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kCaptureResultKey  = "CaptureResult";
51*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kPhysicalCaptureResultKey = "PhysicalCaptureResult";
52*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kCaptureFailureKey = "CaptureFailure";
53*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kSequenceIdKey     = "SequenceId";
54*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kFrameNumberKey    = "FrameNumber";
55*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kAnwKey            = "Anw";
56*ec779b8eSAndroid Build Coastguard Worker const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
57*ec779b8eSAndroid Build Coastguard Worker 
58*ec779b8eSAndroid Build Coastguard Worker /**
59*ec779b8eSAndroid Build Coastguard Worker  * CameraDevice Implementation
60*ec779b8eSAndroid Build Coastguard Worker  */
CameraDevice(const char * id,ACameraDevice_StateCallbacks * cb,sp<ACameraMetadata> chars,ACameraDevice * wrapper,bool sharedMode)61*ec779b8eSAndroid Build Coastguard Worker CameraDevice::CameraDevice(
62*ec779b8eSAndroid Build Coastguard Worker         const char* id,
63*ec779b8eSAndroid Build Coastguard Worker         ACameraDevice_StateCallbacks* cb,
64*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraMetadata> chars,
65*ec779b8eSAndroid Build Coastguard Worker         ACameraDevice* wrapper, bool sharedMode) :
66*ec779b8eSAndroid Build Coastguard Worker         mCameraId(id),
67*ec779b8eSAndroid Build Coastguard Worker         mAppCallbacks(*cb),
68*ec779b8eSAndroid Build Coastguard Worker         mChars(chars),
69*ec779b8eSAndroid Build Coastguard Worker         mServiceCallback(new ServiceCallback(this)),
70*ec779b8eSAndroid Build Coastguard Worker         mWrapper(wrapper),
71*ec779b8eSAndroid Build Coastguard Worker         mSharedMode(sharedMode),
72*ec779b8eSAndroid Build Coastguard Worker         mInError(false),
73*ec779b8eSAndroid Build Coastguard Worker         mError(ACAMERA_OK),
74*ec779b8eSAndroid Build Coastguard Worker         mIdle(true),
75*ec779b8eSAndroid Build Coastguard Worker         mCurrentSession(nullptr) {
76*ec779b8eSAndroid Build Coastguard Worker     mClosing = false;
77*ec779b8eSAndroid Build Coastguard Worker     // Setup looper thread to perfrom device callbacks to app
78*ec779b8eSAndroid Build Coastguard Worker     mCbLooper = new ALooper;
79*ec779b8eSAndroid Build Coastguard Worker     mCbLooper->setName("C2N-dev-looper");
80*ec779b8eSAndroid Build Coastguard Worker     status_t err = mCbLooper->start(
81*ec779b8eSAndroid Build Coastguard Worker             /*runOnCallingThread*/false,
82*ec779b8eSAndroid Build Coastguard Worker             /*canCallJava*/       true,
83*ec779b8eSAndroid Build Coastguard Worker             PRIORITY_DEFAULT);
84*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
85*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Unable to start camera device callback looper: %s (%d)",
86*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, strerror(-err), err);
87*ec779b8eSAndroid Build Coastguard Worker         setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
88*ec779b8eSAndroid Build Coastguard Worker     }
89*ec779b8eSAndroid Build Coastguard Worker     mHandler = new CallbackHandler(id);
90*ec779b8eSAndroid Build Coastguard Worker     mCbLooper->registerHandler(mHandler);
91*ec779b8eSAndroid Build Coastguard Worker 
92*ec779b8eSAndroid Build Coastguard Worker     const CameraMetadata& metadata = mChars->getInternalData();
93*ec779b8eSAndroid Build Coastguard Worker     camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
94*ec779b8eSAndroid Build Coastguard Worker     if (entry.count != 1) {
95*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
96*ec779b8eSAndroid Build Coastguard Worker         mPartialResultCount = 1;
97*ec779b8eSAndroid Build Coastguard Worker     } else {
98*ec779b8eSAndroid Build Coastguard Worker         mPartialResultCount = entry.data.i32[0];
99*ec779b8eSAndroid Build Coastguard Worker     }
100*ec779b8eSAndroid Build Coastguard Worker 
101*ec779b8eSAndroid Build Coastguard Worker     entry = metadata.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
102*ec779b8eSAndroid Build Coastguard Worker     if (entry.count != 2) {
103*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: bad count %zu for shading map size", __FUNCTION__, entry.count);
104*ec779b8eSAndroid Build Coastguard Worker         mShadingMapSize[0] = 0;
105*ec779b8eSAndroid Build Coastguard Worker         mShadingMapSize[1] = 0;
106*ec779b8eSAndroid Build Coastguard Worker     } else {
107*ec779b8eSAndroid Build Coastguard Worker         mShadingMapSize[0] = entry.data.i32[0];
108*ec779b8eSAndroid Build Coastguard Worker         mShadingMapSize[1] = entry.data.i32[1];
109*ec779b8eSAndroid Build Coastguard Worker     }
110*ec779b8eSAndroid Build Coastguard Worker 
111*ec779b8eSAndroid Build Coastguard Worker     size_t physicalIdCnt = 0;
112*ec779b8eSAndroid Build Coastguard Worker     const char*const* physicalCameraIds;
113*ec779b8eSAndroid Build Coastguard Worker     if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
114*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < physicalIdCnt; i++) {
115*ec779b8eSAndroid Build Coastguard Worker             mPhysicalIds.push_back(physicalCameraIds[i]);
116*ec779b8eSAndroid Build Coastguard Worker         }
117*ec779b8eSAndroid Build Coastguard Worker     }
118*ec779b8eSAndroid Build Coastguard Worker }
119*ec779b8eSAndroid Build Coastguard Worker 
~CameraDevice()120*ec779b8eSAndroid Build Coastguard Worker CameraDevice::~CameraDevice() { }
121*ec779b8eSAndroid Build Coastguard Worker 
122*ec779b8eSAndroid Build Coastguard Worker void
postSessionMsgAndCleanup(sp<AMessage> & msg)123*ec779b8eSAndroid Build Coastguard Worker CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
124*ec779b8eSAndroid Build Coastguard Worker     msg->post();
125*ec779b8eSAndroid Build Coastguard Worker     msg.clear();
126*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> cleanupMsg = new AMessage(kWhatCleanUpSessions, mHandler);
127*ec779b8eSAndroid Build Coastguard Worker     cleanupMsg->post();
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker 
130*ec779b8eSAndroid Build Coastguard Worker // TODO: cached created request?
131*ec779b8eSAndroid Build Coastguard Worker camera_status_t
createCaptureRequest(ACameraDevice_request_template templateId,const ACameraIdList * physicalIdList,ACaptureRequest ** request) const132*ec779b8eSAndroid Build Coastguard Worker CameraDevice::createCaptureRequest(
133*ec779b8eSAndroid Build Coastguard Worker         ACameraDevice_request_template templateId,
134*ec779b8eSAndroid Build Coastguard Worker         const ACameraIdList* physicalIdList,
135*ec779b8eSAndroid Build Coastguard Worker         ACaptureRequest** request) const {
136*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mDeviceLock);
137*ec779b8eSAndroid Build Coastguard Worker 
138*ec779b8eSAndroid Build Coastguard Worker     if (physicalIdList != nullptr) {
139*ec779b8eSAndroid Build Coastguard Worker         if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
140*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
141*ec779b8eSAndroid Build Coastguard Worker                     __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
142*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_INVALID_PARAMETER;
143*ec779b8eSAndroid Build Coastguard Worker         }
144*ec779b8eSAndroid Build Coastguard Worker         for (auto i = 0; i < physicalIdList->numCameras; i++) {
145*ec779b8eSAndroid Build Coastguard Worker             if (physicalIdList->cameraIds[i] == nullptr) {
146*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: physicalId is null!", __FUNCTION__);
147*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_PARAMETER;
148*ec779b8eSAndroid Build Coastguard Worker             }
149*ec779b8eSAndroid Build Coastguard Worker             if (mPhysicalIds.end() == std::find(
150*ec779b8eSAndroid Build Coastguard Worker                     mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
151*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
152*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_PARAMETER;
153*ec779b8eSAndroid Build Coastguard Worker             }
154*ec779b8eSAndroid Build Coastguard Worker         }
155*ec779b8eSAndroid Build Coastguard Worker     }
156*ec779b8eSAndroid Build Coastguard Worker 
157*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
158*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
159*ec779b8eSAndroid Build Coastguard Worker         return ret;
160*ec779b8eSAndroid Build Coastguard Worker     }
161*ec779b8eSAndroid Build Coastguard Worker     if (mRemote == nullptr) {
162*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
163*ec779b8eSAndroid Build Coastguard Worker     }
164*ec779b8eSAndroid Build Coastguard Worker     CameraMetadata rawRequest;
165*ec779b8eSAndroid Build Coastguard Worker     binder::Status remoteRet = mRemote->createDefaultRequest(templateId, &rawRequest);
166*ec779b8eSAndroid Build Coastguard Worker     if (remoteRet.serviceSpecificErrorCode() ==
167*ec779b8eSAndroid Build Coastguard Worker             hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
168*ec779b8eSAndroid Build Coastguard Worker         ALOGW("Create capture request failed! template %d is not supported on this device",
169*ec779b8eSAndroid Build Coastguard Worker             templateId);
170*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
171*ec779b8eSAndroid Build Coastguard Worker     } else if (!remoteRet.isOk()) {
172*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Create capture request failed: %s", remoteRet.toString8().c_str());
173*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNKNOWN;
174*ec779b8eSAndroid Build Coastguard Worker     }
175*ec779b8eSAndroid Build Coastguard Worker     ACaptureRequest* outReq = new ACaptureRequest();
176*ec779b8eSAndroid Build Coastguard Worker     outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
177*ec779b8eSAndroid Build Coastguard Worker     if (physicalIdList != nullptr) {
178*ec779b8eSAndroid Build Coastguard Worker         for (auto i = 0; i < physicalIdList->numCameras; i++) {
179*ec779b8eSAndroid Build Coastguard Worker             outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
180*ec779b8eSAndroid Build Coastguard Worker                     new ACameraMetadata(*(outReq->settings)));
181*ec779b8eSAndroid Build Coastguard Worker         }
182*ec779b8eSAndroid Build Coastguard Worker     }
183*ec779b8eSAndroid Build Coastguard Worker     outReq->targets  = new ACameraOutputTargets();
184*ec779b8eSAndroid Build Coastguard Worker     *request = outReq;
185*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
186*ec779b8eSAndroid Build Coastguard Worker }
187*ec779b8eSAndroid Build Coastguard Worker 
188*ec779b8eSAndroid Build Coastguard Worker camera_status_t
createCaptureSession(const ACaptureSessionOutputContainer * outputs,const ACaptureRequest * sessionParameters,const ACameraCaptureSession_stateCallbacks * callbacks,ACameraCaptureSession ** session)189*ec779b8eSAndroid Build Coastguard Worker CameraDevice::createCaptureSession(
190*ec779b8eSAndroid Build Coastguard Worker         const ACaptureSessionOutputContainer*       outputs,
191*ec779b8eSAndroid Build Coastguard Worker         const ACaptureRequest* sessionParameters,
192*ec779b8eSAndroid Build Coastguard Worker         const ACameraCaptureSession_stateCallbacks* callbacks,
193*ec779b8eSAndroid Build Coastguard Worker         /*out*/ACameraCaptureSession** session) {
194*ec779b8eSAndroid Build Coastguard Worker     nsecs_t startTimeNs = systemTime();
195*ec779b8eSAndroid Build Coastguard Worker     sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
196*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mDeviceLock);
197*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
198*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
199*ec779b8eSAndroid Build Coastguard Worker         return ret;
200*ec779b8eSAndroid Build Coastguard Worker     }
201*ec779b8eSAndroid Build Coastguard Worker 
202*ec779b8eSAndroid Build Coastguard Worker     if (currentSession != nullptr) {
203*ec779b8eSAndroid Build Coastguard Worker         currentSession->closeByDevice();
204*ec779b8eSAndroid Build Coastguard Worker         stopRepeatingLocked();
205*ec779b8eSAndroid Build Coastguard Worker     }
206*ec779b8eSAndroid Build Coastguard Worker 
207*ec779b8eSAndroid Build Coastguard Worker     // Create new session
208*ec779b8eSAndroid Build Coastguard Worker     ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
209*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
210*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Fail to create new session. cannot configure streams");
211*ec779b8eSAndroid Build Coastguard Worker         return ret;
212*ec779b8eSAndroid Build Coastguard Worker     }
213*ec779b8eSAndroid Build Coastguard Worker 
214*ec779b8eSAndroid Build Coastguard Worker     ACameraCaptureSession* newSession = new ACameraCaptureSession(
215*ec779b8eSAndroid Build Coastguard Worker             mNextSessionId++, outputs, callbacks, this);
216*ec779b8eSAndroid Build Coastguard Worker 
217*ec779b8eSAndroid Build Coastguard Worker     // set new session as current session
218*ec779b8eSAndroid Build Coastguard Worker     newSession->incStrong((void *) ACameraDevice_createCaptureSession);
219*ec779b8eSAndroid Build Coastguard Worker     mCurrentSession = newSession;
220*ec779b8eSAndroid Build Coastguard Worker     mFlushing = false;
221*ec779b8eSAndroid Build Coastguard Worker     *session = newSession;
222*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
223*ec779b8eSAndroid Build Coastguard Worker }
224*ec779b8eSAndroid Build Coastguard Worker 
isSessionConfigurationSupported(const ACaptureSessionOutputContainer * sessionOutputContainer) const225*ec779b8eSAndroid Build Coastguard Worker camera_status_t CameraDevice::isSessionConfigurationSupported(
226*ec779b8eSAndroid Build Coastguard Worker         const ACaptureSessionOutputContainer* sessionOutputContainer) const {
227*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mDeviceLock);
228*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
229*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
230*ec779b8eSAndroid Build Coastguard Worker         return ret;
231*ec779b8eSAndroid Build Coastguard Worker     }
232*ec779b8eSAndroid Build Coastguard Worker 
233*ec779b8eSAndroid Build Coastguard Worker     SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
234*ec779b8eSAndroid Build Coastguard Worker             -1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
235*ec779b8eSAndroid Build Coastguard Worker     for (const auto& output : sessionOutputContainer->mOutputs) {
236*ec779b8eSAndroid Build Coastguard Worker         sp<SurfaceType> surface(nullptr);
237*ec779b8eSAndroid Build Coastguard Worker         ret = getSurfacefromAnw(output.mWindow, surface);
238*ec779b8eSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
239*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Camera device %s failed to extract graphic producer from native window",
240*ec779b8eSAndroid Build Coastguard Worker                     getId());
241*ec779b8eSAndroid Build Coastguard Worker             return ret;
242*ec779b8eSAndroid Build Coastguard Worker         }
243*ec779b8eSAndroid Build Coastguard Worker 
244*ec779b8eSAndroid Build Coastguard Worker         ParcelableSurfaceType pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
245*ec779b8eSAndroid Build Coastguard Worker         OutputConfiguration outConfig(pSurface, output.mRotation, output.mPhysicalCameraId,
246*ec779b8eSAndroid Build Coastguard Worker                 OutputConfiguration::INVALID_SET_ID, true);
247*ec779b8eSAndroid Build Coastguard Worker 
248*ec779b8eSAndroid Build Coastguard Worker         for (auto& anw : output.mSharedWindows) {
249*ec779b8eSAndroid Build Coastguard Worker             ret = getSurfacefromAnw(anw, surface);
250*ec779b8eSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
251*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s failed to extract graphic producer from native window",
252*ec779b8eSAndroid Build Coastguard Worker                         getId());
253*ec779b8eSAndroid Build Coastguard Worker                 return ret;
254*ec779b8eSAndroid Build Coastguard Worker             }
255*ec779b8eSAndroid Build Coastguard Worker             pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
256*ec779b8eSAndroid Build Coastguard Worker             outConfig.addSurface(pSurface);
257*ec779b8eSAndroid Build Coastguard Worker         }
258*ec779b8eSAndroid Build Coastguard Worker 
259*ec779b8eSAndroid Build Coastguard Worker         sessionConfiguration.addOutputConfiguration(outConfig);
260*ec779b8eSAndroid Build Coastguard Worker     }
261*ec779b8eSAndroid Build Coastguard Worker 
262*ec779b8eSAndroid Build Coastguard Worker     bool supported = false;
263*ec779b8eSAndroid Build Coastguard Worker     binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
264*ec779b8eSAndroid Build Coastguard Worker             sessionConfiguration, &supported);
265*ec779b8eSAndroid Build Coastguard Worker     if (remoteRet.serviceSpecificErrorCode() ==
266*ec779b8eSAndroid Build Coastguard Worker             hardware::ICameraService::ERROR_INVALID_OPERATION) {
267*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
268*ec779b8eSAndroid Build Coastguard Worker     } else if (!remoteRet.isOk()) {
269*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNKNOWN;
270*ec779b8eSAndroid Build Coastguard Worker     } else {
271*ec779b8eSAndroid Build Coastguard Worker         return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
272*ec779b8eSAndroid Build Coastguard Worker     }
273*ec779b8eSAndroid Build Coastguard Worker }
274*ec779b8eSAndroid Build Coastguard Worker 
updateOutputConfigurationLocked(ACaptureSessionOutput * output)275*ec779b8eSAndroid Build Coastguard Worker camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
276*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
277*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
278*ec779b8eSAndroid Build Coastguard Worker         return ret;
279*ec779b8eSAndroid Build Coastguard Worker     }
280*ec779b8eSAndroid Build Coastguard Worker 
281*ec779b8eSAndroid Build Coastguard Worker     if (output == nullptr) {
282*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
283*ec779b8eSAndroid Build Coastguard Worker     }
284*ec779b8eSAndroid Build Coastguard Worker 
285*ec779b8eSAndroid Build Coastguard Worker     if (!output->mIsShared) {
286*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Error output configuration is not shared");
287*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_OPERATION;
288*ec779b8eSAndroid Build Coastguard Worker     }
289*ec779b8eSAndroid Build Coastguard Worker 
290*ec779b8eSAndroid Build Coastguard Worker     int32_t streamId = -1;
291*ec779b8eSAndroid Build Coastguard Worker     for (auto& kvPair : mConfiguredOutputs) {
292*ec779b8eSAndroid Build Coastguard Worker         if (kvPair.second.first == output->mWindow) {
293*ec779b8eSAndroid Build Coastguard Worker             streamId = kvPair.first;
294*ec779b8eSAndroid Build Coastguard Worker             break;
295*ec779b8eSAndroid Build Coastguard Worker         }
296*ec779b8eSAndroid Build Coastguard Worker     }
297*ec779b8eSAndroid Build Coastguard Worker     if (streamId < 0) {
298*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Error: Invalid output configuration");
299*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
300*ec779b8eSAndroid Build Coastguard Worker     }
301*ec779b8eSAndroid Build Coastguard Worker 
302*ec779b8eSAndroid Build Coastguard Worker     sp<SurfaceType> surface(nullptr);
303*ec779b8eSAndroid Build Coastguard Worker     ret = getSurfacefromAnw(output->mWindow, surface);
304*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
305*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s failed to extract graphic producer from native window",
306*ec779b8eSAndroid Build Coastguard Worker                 getId());
307*ec779b8eSAndroid Build Coastguard Worker         return ret;
308*ec779b8eSAndroid Build Coastguard Worker     }
309*ec779b8eSAndroid Build Coastguard Worker 
310*ec779b8eSAndroid Build Coastguard Worker     ParcelableSurfaceType pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
311*ec779b8eSAndroid Build Coastguard Worker     OutputConfiguration outConfig(pSurface, output->mRotation, output->mPhysicalCameraId,
312*ec779b8eSAndroid Build Coastguard Worker                                   OutputConfiguration::INVALID_SET_ID, true);
313*ec779b8eSAndroid Build Coastguard Worker 
314*ec779b8eSAndroid Build Coastguard Worker     for (auto& anw : output->mSharedWindows) {
315*ec779b8eSAndroid Build Coastguard Worker         ret = getSurfacefromAnw(anw, surface);
316*ec779b8eSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
317*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Camera device %s failed to extract graphic producer from native window",
318*ec779b8eSAndroid Build Coastguard Worker                     getId());
319*ec779b8eSAndroid Build Coastguard Worker             return ret;
320*ec779b8eSAndroid Build Coastguard Worker         }
321*ec779b8eSAndroid Build Coastguard Worker         pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
322*ec779b8eSAndroid Build Coastguard Worker         outConfig.addSurface(pSurface);
323*ec779b8eSAndroid Build Coastguard Worker     }
324*ec779b8eSAndroid Build Coastguard Worker 
325*ec779b8eSAndroid Build Coastguard Worker     auto remoteRet = mRemote->updateOutputConfiguration(streamId, outConfig);
326*ec779b8eSAndroid Build Coastguard Worker     if (!remoteRet.isOk()) {
327*ec779b8eSAndroid Build Coastguard Worker         switch (remoteRet.serviceSpecificErrorCode()) {
328*ec779b8eSAndroid Build Coastguard Worker             case hardware::ICameraService::ERROR_INVALID_OPERATION:
329*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s invalid operation: %s", getId(),
330*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
331*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_OPERATION;
332*ec779b8eSAndroid Build Coastguard Worker                 break;
333*ec779b8eSAndroid Build Coastguard Worker             case hardware::ICameraService::ERROR_ALREADY_EXISTS:
334*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s output surface already exists: %s", getId(),
335*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
336*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_PARAMETER;
337*ec779b8eSAndroid Build Coastguard Worker                 break;
338*ec779b8eSAndroid Build Coastguard Worker             case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
339*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s invalid input argument: %s", getId(),
340*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
341*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_PARAMETER;
342*ec779b8eSAndroid Build Coastguard Worker                 break;
343*ec779b8eSAndroid Build Coastguard Worker             default:
344*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s failed to add shared output: %s", getId(),
345*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
346*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_UNKNOWN;
347*ec779b8eSAndroid Build Coastguard Worker         }
348*ec779b8eSAndroid Build Coastguard Worker     }
349*ec779b8eSAndroid Build Coastguard Worker     mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);
350*ec779b8eSAndroid Build Coastguard Worker 
351*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
352*ec779b8eSAndroid Build Coastguard Worker }
353*ec779b8eSAndroid Build Coastguard Worker 
prepareLocked(ANativeWindow * window)354*ec779b8eSAndroid Build Coastguard Worker camera_status_t CameraDevice::prepareLocked(ANativeWindow *window) {
355*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
356*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
357*ec779b8eSAndroid Build Coastguard Worker         return ret;
358*ec779b8eSAndroid Build Coastguard Worker     }
359*ec779b8eSAndroid Build Coastguard Worker 
360*ec779b8eSAndroid Build Coastguard Worker     if (window == nullptr) {
361*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
362*ec779b8eSAndroid Build Coastguard Worker     }
363*ec779b8eSAndroid Build Coastguard Worker 
364*ec779b8eSAndroid Build Coastguard Worker     int32_t streamId = -1;
365*ec779b8eSAndroid Build Coastguard Worker     for (auto& kvPair : mConfiguredOutputs) {
366*ec779b8eSAndroid Build Coastguard Worker         if (window == kvPair.second.first) {
367*ec779b8eSAndroid Build Coastguard Worker             streamId = kvPair.first;
368*ec779b8eSAndroid Build Coastguard Worker             break;
369*ec779b8eSAndroid Build Coastguard Worker         }
370*ec779b8eSAndroid Build Coastguard Worker     }
371*ec779b8eSAndroid Build Coastguard Worker     if (streamId < 0) {
372*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Error: Invalid output configuration");
373*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
374*ec779b8eSAndroid Build Coastguard Worker     }
375*ec779b8eSAndroid Build Coastguard Worker     auto remoteRet = mRemote->prepare(streamId);
376*ec779b8eSAndroid Build Coastguard Worker     if (!remoteRet.isOk()) {
377*ec779b8eSAndroid Build Coastguard Worker         // TODO:(b/259735869) Do this check for all other binder calls in the
378*ec779b8eSAndroid Build Coastguard Worker         // ndk as well.
379*ec779b8eSAndroid Build Coastguard Worker         if (remoteRet.exceptionCode() != EX_SERVICE_SPECIFIC) {
380*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
381*ec779b8eSAndroid Build Coastguard Worker                     remoteRet.toString8().c_str());
382*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
383*ec779b8eSAndroid Build Coastguard Worker 
384*ec779b8eSAndroid Build Coastguard Worker         }
385*ec779b8eSAndroid Build Coastguard Worker         switch (remoteRet.serviceSpecificErrorCode()) {
386*ec779b8eSAndroid Build Coastguard Worker             case hardware::ICameraService::ERROR_INVALID_OPERATION:
387*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s invalid operation: %s", getId(),
388*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
389*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_OPERATION;
390*ec779b8eSAndroid Build Coastguard Worker                 break;
391*ec779b8eSAndroid Build Coastguard Worker             case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
392*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s invalid input argument: %s", getId(),
393*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
394*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_PARAMETER;
395*ec779b8eSAndroid Build Coastguard Worker                 break;
396*ec779b8eSAndroid Build Coastguard Worker             default:
397*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
398*ec779b8eSAndroid Build Coastguard Worker                         remoteRet.toString8().c_str());
399*ec779b8eSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_UNKNOWN;
400*ec779b8eSAndroid Build Coastguard Worker         }
401*ec779b8eSAndroid Build Coastguard Worker     }
402*ec779b8eSAndroid Build Coastguard Worker 
403*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
404*ec779b8eSAndroid Build Coastguard Worker }
405*ec779b8eSAndroid Build Coastguard Worker 
406*ec779b8eSAndroid Build Coastguard Worker camera_status_t
allocateCaptureRequest(const ACaptureRequest * request,sp<CaptureRequest> & outReq)407*ec779b8eSAndroid Build Coastguard Worker CameraDevice::allocateCaptureRequest(
408*ec779b8eSAndroid Build Coastguard Worker         const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
409*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret;
410*ec779b8eSAndroid Build Coastguard Worker     sp<CaptureRequest> req(new CaptureRequest());
411*ec779b8eSAndroid Build Coastguard Worker     req->mPhysicalCameraSettings.push_back({getId(),
412*ec779b8eSAndroid Build Coastguard Worker             request->settings->getInternalData()});
413*ec779b8eSAndroid Build Coastguard Worker     for (auto& entry : request->physicalSettings) {
414*ec779b8eSAndroid Build Coastguard Worker         req->mPhysicalCameraSettings.push_back({entry.first,
415*ec779b8eSAndroid Build Coastguard Worker                 entry.second->getInternalData()});
416*ec779b8eSAndroid Build Coastguard Worker     }
417*ec779b8eSAndroid Build Coastguard Worker     req->mIsReprocess = false; // NDK does not support reprocessing yet
418*ec779b8eSAndroid Build Coastguard Worker     req->mContext = request->context;
419*ec779b8eSAndroid Build Coastguard Worker     req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
420*ec779b8eSAndroid Build Coastguard Worker 
421*ec779b8eSAndroid Build Coastguard Worker     for (auto outputTarget : request->targets->mOutputs) {
422*ec779b8eSAndroid Build Coastguard Worker         ANativeWindow* anw = outputTarget.mWindow;
423*ec779b8eSAndroid Build Coastguard Worker         sp<Surface> surface;
424*ec779b8eSAndroid Build Coastguard Worker         ret = getSurfaceFromANativeWindow(anw, surface);
425*ec779b8eSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
426*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Bad output target in capture request! ret %d", ret);
427*ec779b8eSAndroid Build Coastguard Worker             return ret;
428*ec779b8eSAndroid Build Coastguard Worker         }
429*ec779b8eSAndroid Build Coastguard Worker         req->mSurfaceList.push_back(surface);
430*ec779b8eSAndroid Build Coastguard Worker 
431*ec779b8eSAndroid Build Coastguard Worker         bool found = false;
432*ec779b8eSAndroid Build Coastguard Worker         // lookup stream/surface ID
433*ec779b8eSAndroid Build Coastguard Worker         for (const auto& kvPair : mConfiguredOutputs) {
434*ec779b8eSAndroid Build Coastguard Worker             int streamId = kvPair.first;
435*ec779b8eSAndroid Build Coastguard Worker             const OutputConfiguration& outConfig = kvPair.second.second;
436*ec779b8eSAndroid Build Coastguard Worker             const auto& surfaces = outConfig.getSurfaces();
437*ec779b8eSAndroid Build Coastguard Worker             for (int surfaceId = 0; surfaceId < (int)surfaces.size(); surfaceId++) {
438*ec779b8eSAndroid Build Coastguard Worker                 if (surfaces[surfaceId] == flagtools::surfaceToSurfaceType(surface)) {
439*ec779b8eSAndroid Build Coastguard Worker                     found = true;
440*ec779b8eSAndroid Build Coastguard Worker                     req->mStreamIdxList.push_back(streamId);
441*ec779b8eSAndroid Build Coastguard Worker                     req->mSurfaceIdxList.push_back(surfaceId);
442*ec779b8eSAndroid Build Coastguard Worker                     break;
443*ec779b8eSAndroid Build Coastguard Worker                 }
444*ec779b8eSAndroid Build Coastguard Worker             }
445*ec779b8eSAndroid Build Coastguard Worker             if (found) {
446*ec779b8eSAndroid Build Coastguard Worker                 break;
447*ec779b8eSAndroid Build Coastguard Worker             }
448*ec779b8eSAndroid Build Coastguard Worker         }
449*ec779b8eSAndroid Build Coastguard Worker         if (!found) {
450*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Unconfigured output target %p in capture request!", anw);
451*ec779b8eSAndroid Build Coastguard Worker             return ret;
452*ec779b8eSAndroid Build Coastguard Worker         }
453*ec779b8eSAndroid Build Coastguard Worker     }
454*ec779b8eSAndroid Build Coastguard Worker 
455*ec779b8eSAndroid Build Coastguard Worker     outReq = req;
456*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
457*ec779b8eSAndroid Build Coastguard Worker }
458*ec779b8eSAndroid Build Coastguard Worker 
459*ec779b8eSAndroid Build Coastguard Worker ACaptureRequest*
allocateACaptureRequest(sp<CaptureRequest> & req,const std::string & deviceId)460*ec779b8eSAndroid Build Coastguard Worker CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
461*ec779b8eSAndroid Build Coastguard Worker     ACaptureRequest* pRequest = new ACaptureRequest();
462*ec779b8eSAndroid Build Coastguard Worker     for (auto& entry : req->mPhysicalCameraSettings) {
463*ec779b8eSAndroid Build Coastguard Worker         CameraMetadata clone = entry.settings;
464*ec779b8eSAndroid Build Coastguard Worker         if (entry.id == deviceId) {
465*ec779b8eSAndroid Build Coastguard Worker             pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
466*ec779b8eSAndroid Build Coastguard Worker         } else {
467*ec779b8eSAndroid Build Coastguard Worker             pRequest->physicalSettings.emplace(entry.id,
468*ec779b8eSAndroid Build Coastguard Worker                     new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
469*ec779b8eSAndroid Build Coastguard Worker         }
470*ec779b8eSAndroid Build Coastguard Worker     }
471*ec779b8eSAndroid Build Coastguard Worker     pRequest->targets  = new ACameraOutputTargets();
472*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
473*ec779b8eSAndroid Build Coastguard Worker         ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
474*ec779b8eSAndroid Build Coastguard Worker         ACameraOutputTarget outputTarget(anw);
475*ec779b8eSAndroid Build Coastguard Worker         pRequest->targets->mOutputs.insert(outputTarget);
476*ec779b8eSAndroid Build Coastguard Worker     }
477*ec779b8eSAndroid Build Coastguard Worker     pRequest->context = req->mContext;
478*ec779b8eSAndroid Build Coastguard Worker     return pRequest;
479*ec779b8eSAndroid Build Coastguard Worker }
480*ec779b8eSAndroid Build Coastguard Worker 
481*ec779b8eSAndroid Build Coastguard Worker void
freeACaptureRequest(ACaptureRequest * req)482*ec779b8eSAndroid Build Coastguard Worker CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
483*ec779b8eSAndroid Build Coastguard Worker     if (req == nullptr) {
484*ec779b8eSAndroid Build Coastguard Worker         return;
485*ec779b8eSAndroid Build Coastguard Worker     }
486*ec779b8eSAndroid Build Coastguard Worker     req->settings.clear();
487*ec779b8eSAndroid Build Coastguard Worker     req->physicalSettings.clear();
488*ec779b8eSAndroid Build Coastguard Worker     delete req->targets;
489*ec779b8eSAndroid Build Coastguard Worker     delete req;
490*ec779b8eSAndroid Build Coastguard Worker }
491*ec779b8eSAndroid Build Coastguard Worker 
492*ec779b8eSAndroid Build Coastguard Worker void
notifySessionEndOfLifeLocked(ACameraCaptureSession * session)493*ec779b8eSAndroid Build Coastguard Worker CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) {
494*ec779b8eSAndroid Build Coastguard Worker     if (isClosed()) {
495*ec779b8eSAndroid Build Coastguard Worker         // Device is closing already. do nothing
496*ec779b8eSAndroid Build Coastguard Worker         return;
497*ec779b8eSAndroid Build Coastguard Worker     }
498*ec779b8eSAndroid Build Coastguard Worker 
499*ec779b8eSAndroid Build Coastguard Worker     if (mCurrentSession != session) {
500*ec779b8eSAndroid Build Coastguard Worker         // Session has been replaced by other seesion or device is closed
501*ec779b8eSAndroid Build Coastguard Worker         return;
502*ec779b8eSAndroid Build Coastguard Worker     }
503*ec779b8eSAndroid Build Coastguard Worker     mCurrentSession = nullptr;
504*ec779b8eSAndroid Build Coastguard Worker 
505*ec779b8eSAndroid Build Coastguard Worker     // Should not happen
506*ec779b8eSAndroid Build Coastguard Worker     if (!session->mIsClosed) {
507*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Error: unclosed session %p reaches end of life!", session);
508*ec779b8eSAndroid Build Coastguard Worker         setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
509*ec779b8eSAndroid Build Coastguard Worker         return;
510*ec779b8eSAndroid Build Coastguard Worker     }
511*ec779b8eSAndroid Build Coastguard Worker 
512*ec779b8eSAndroid Build Coastguard Worker     // No new session, unconfigure now
513*ec779b8eSAndroid Build Coastguard Worker     // Note: The unconfiguration of session won't be accounted for session
514*ec779b8eSAndroid Build Coastguard Worker     // latency because a stream configuration with 0 streams won't ever become
515*ec779b8eSAndroid Build Coastguard Worker     // active.
516*ec779b8eSAndroid Build Coastguard Worker     nsecs_t startTimeNs = systemTime();
517*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
518*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
519*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
520*ec779b8eSAndroid Build Coastguard Worker     }
521*ec779b8eSAndroid Build Coastguard Worker }
522*ec779b8eSAndroid Build Coastguard Worker 
523*ec779b8eSAndroid Build Coastguard Worker void
disconnectLocked(sp<ACameraCaptureSession> & session)524*ec779b8eSAndroid Build Coastguard Worker CameraDevice::disconnectLocked(sp<ACameraCaptureSession>& session) {
525*ec779b8eSAndroid Build Coastguard Worker     if (mClosing.exchange(true)) {
526*ec779b8eSAndroid Build Coastguard Worker         // Already closing, just return
527*ec779b8eSAndroid Build Coastguard Worker         ALOGW("Camera device %s is already closing.", getId());
528*ec779b8eSAndroid Build Coastguard Worker         return;
529*ec779b8eSAndroid Build Coastguard Worker     }
530*ec779b8eSAndroid Build Coastguard Worker 
531*ec779b8eSAndroid Build Coastguard Worker     if (mRemote != nullptr) {
532*ec779b8eSAndroid Build Coastguard Worker         mRemote->disconnect();
533*ec779b8eSAndroid Build Coastguard Worker     }
534*ec779b8eSAndroid Build Coastguard Worker     mRemote = nullptr;
535*ec779b8eSAndroid Build Coastguard Worker 
536*ec779b8eSAndroid Build Coastguard Worker     if (session != nullptr) {
537*ec779b8eSAndroid Build Coastguard Worker         session->closeByDevice();
538*ec779b8eSAndroid Build Coastguard Worker     }
539*ec779b8eSAndroid Build Coastguard Worker }
540*ec779b8eSAndroid Build Coastguard Worker 
541*ec779b8eSAndroid Build Coastguard Worker camera_status_t
stopRepeatingLocked()542*ec779b8eSAndroid Build Coastguard Worker CameraDevice::stopRepeatingLocked() {
543*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
544*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
545*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
546*ec779b8eSAndroid Build Coastguard Worker         return ret;
547*ec779b8eSAndroid Build Coastguard Worker     }
548*ec779b8eSAndroid Build Coastguard Worker     if (mRepeatingSequenceId != REQUEST_ID_NONE) {
549*ec779b8eSAndroid Build Coastguard Worker         int repeatingSequenceId = mRepeatingSequenceId;
550*ec779b8eSAndroid Build Coastguard Worker         mRepeatingSequenceId = REQUEST_ID_NONE;
551*ec779b8eSAndroid Build Coastguard Worker 
552*ec779b8eSAndroid Build Coastguard Worker         int64_t lastFrameNumber;
553*ec779b8eSAndroid Build Coastguard Worker         binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
554*ec779b8eSAndroid Build Coastguard Worker         if (remoteRet.serviceSpecificErrorCode() ==
555*ec779b8eSAndroid Build Coastguard Worker                 hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
556*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Repeating request is already stopped.");
557*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_OK;
558*ec779b8eSAndroid Build Coastguard Worker         } else if (!remoteRet.isOk()) {
559*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().c_str());
560*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
561*ec779b8eSAndroid Build Coastguard Worker         }
562*ec779b8eSAndroid Build Coastguard Worker         checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
563*ec779b8eSAndroid Build Coastguard Worker     }
564*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
565*ec779b8eSAndroid Build Coastguard Worker }
566*ec779b8eSAndroid Build Coastguard Worker 
567*ec779b8eSAndroid Build Coastguard Worker camera_status_t
flushLocked(ACameraCaptureSession * session)568*ec779b8eSAndroid Build Coastguard Worker CameraDevice::flushLocked(ACameraCaptureSession* session) {
569*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
570*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
571*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
572*ec779b8eSAndroid Build Coastguard Worker         return ret;
573*ec779b8eSAndroid Build Coastguard Worker     }
574*ec779b8eSAndroid Build Coastguard Worker 
575*ec779b8eSAndroid Build Coastguard Worker     // This should never happen because creating a new session will close
576*ec779b8eSAndroid Build Coastguard Worker     // previous one and thus reject any API call from previous session.
577*ec779b8eSAndroid Build Coastguard Worker     // But still good to check here in case something unexpected happen.
578*ec779b8eSAndroid Build Coastguard Worker     if (mCurrentSession != session) {
579*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera %s session %p is not current active session!", getId(), session);
580*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_OPERATION;
581*ec779b8eSAndroid Build Coastguard Worker     }
582*ec779b8eSAndroid Build Coastguard Worker 
583*ec779b8eSAndroid Build Coastguard Worker     if (mFlushing) {
584*ec779b8eSAndroid Build Coastguard Worker         ALOGW("Camera %s is already aborting captures", getId());
585*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_OK;
586*ec779b8eSAndroid Build Coastguard Worker     }
587*ec779b8eSAndroid Build Coastguard Worker 
588*ec779b8eSAndroid Build Coastguard Worker     mFlushing = true;
589*ec779b8eSAndroid Build Coastguard Worker 
590*ec779b8eSAndroid Build Coastguard Worker     // Send onActive callback to guarantee there is always active->ready transition
591*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
592*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kContextKey, session->mUserSessionCallback.context);
593*ec779b8eSAndroid Build Coastguard Worker     msg->setObject(kSessionSpKey, session);
594*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
595*ec779b8eSAndroid Build Coastguard Worker     postSessionMsgAndCleanup(msg);
596*ec779b8eSAndroid Build Coastguard Worker 
597*ec779b8eSAndroid Build Coastguard Worker     // If device is already idling, send callback and exit early
598*ec779b8eSAndroid Build Coastguard Worker     if (mIdle) {
599*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
600*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, session->mUserSessionCallback.context);
601*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, session);
602*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
603*ec779b8eSAndroid Build Coastguard Worker         postSessionMsgAndCleanup(msg);
604*ec779b8eSAndroid Build Coastguard Worker         mFlushing = false;
605*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_OK;
606*ec779b8eSAndroid Build Coastguard Worker     }
607*ec779b8eSAndroid Build Coastguard Worker 
608*ec779b8eSAndroid Build Coastguard Worker     int64_t lastFrameNumber;
609*ec779b8eSAndroid Build Coastguard Worker     binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
610*ec779b8eSAndroid Build Coastguard Worker     if (!remoteRet.isOk()) {
611*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().c_str());
612*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNKNOWN;
613*ec779b8eSAndroid Build Coastguard Worker     }
614*ec779b8eSAndroid Build Coastguard Worker     if (mRepeatingSequenceId != REQUEST_ID_NONE) {
615*ec779b8eSAndroid Build Coastguard Worker         checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
616*ec779b8eSAndroid Build Coastguard Worker     }
617*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
618*ec779b8eSAndroid Build Coastguard Worker }
619*ec779b8eSAndroid Build Coastguard Worker 
620*ec779b8eSAndroid Build Coastguard Worker camera_status_t
waitUntilIdleLocked()621*ec779b8eSAndroid Build Coastguard Worker CameraDevice::waitUntilIdleLocked() {
622*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
623*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
624*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Wait until camera %s idle failed! ret %d", getId(), ret);
625*ec779b8eSAndroid Build Coastguard Worker         return ret;
626*ec779b8eSAndroid Build Coastguard Worker     }
627*ec779b8eSAndroid Build Coastguard Worker 
628*ec779b8eSAndroid Build Coastguard Worker     if (mRepeatingSequenceId != REQUEST_ID_NONE) {
629*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s won't go to idle when there is repeating request!", getId());
630*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_OPERATION;
631*ec779b8eSAndroid Build Coastguard Worker     }
632*ec779b8eSAndroid Build Coastguard Worker 
633*ec779b8eSAndroid Build Coastguard Worker     binder::Status remoteRet = mRemote->waitUntilIdle();
634*ec779b8eSAndroid Build Coastguard Worker     if (!remoteRet.isOk()) {
635*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().c_str());
636*ec779b8eSAndroid Build Coastguard Worker         // TODO: define a function to convert status_t -> camera_status_t
637*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNKNOWN;
638*ec779b8eSAndroid Build Coastguard Worker     }
639*ec779b8eSAndroid Build Coastguard Worker 
640*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
641*ec779b8eSAndroid Build Coastguard Worker }
642*ec779b8eSAndroid Build Coastguard Worker 
getSurfacefromAnw(ANativeWindow * anw,sp<SurfaceType> & out)643*ec779b8eSAndroid Build Coastguard Worker camera_status_t CameraDevice::getSurfacefromAnw(ANativeWindow* anw, sp<SurfaceType>& out) {
644*ec779b8eSAndroid Build Coastguard Worker     sp<Surface> surface;
645*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
646*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
647*ec779b8eSAndroid Build Coastguard Worker         return ret;
648*ec779b8eSAndroid Build Coastguard Worker     }
649*ec779b8eSAndroid Build Coastguard Worker     out = flagtools::surfaceToSurfaceType(surface);
650*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
651*ec779b8eSAndroid Build Coastguard Worker }
652*ec779b8eSAndroid Build Coastguard Worker 
653*ec779b8eSAndroid Build Coastguard Worker camera_status_t
getSurfaceFromANativeWindow(ANativeWindow * anw,sp<Surface> & out)654*ec779b8eSAndroid Build Coastguard Worker CameraDevice::getSurfaceFromANativeWindow(
655*ec779b8eSAndroid Build Coastguard Worker         ANativeWindow* anw, sp<Surface>& out) {
656*ec779b8eSAndroid Build Coastguard Worker     if (anw == nullptr) {
657*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Error: output ANativeWindow is null");
658*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
659*ec779b8eSAndroid Build Coastguard Worker     }
660*ec779b8eSAndroid Build Coastguard Worker     int value;
661*ec779b8eSAndroid Build Coastguard Worker     int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
662*ec779b8eSAndroid Build Coastguard Worker     if (err != OK || value != NATIVE_WINDOW_SURFACE) {
663*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Error: ANativeWindow is not backed by Surface!");
664*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
665*ec779b8eSAndroid Build Coastguard Worker     }
666*ec779b8eSAndroid Build Coastguard Worker     sp<Surface> surface(static_cast<Surface*>(anw));
667*ec779b8eSAndroid Build Coastguard Worker     out = surface;
668*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
669*ec779b8eSAndroid Build Coastguard Worker }
670*ec779b8eSAndroid Build Coastguard Worker 
671*ec779b8eSAndroid Build Coastguard Worker camera_status_t
configureStreamsLocked(const ACaptureSessionOutputContainer * outputs,const ACaptureRequest * sessionParameters,nsecs_t startTimeNs)672*ec779b8eSAndroid Build Coastguard Worker CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
673*ec779b8eSAndroid Build Coastguard Worker         const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
674*ec779b8eSAndroid Build Coastguard Worker     ACaptureSessionOutputContainer emptyOutput;
675*ec779b8eSAndroid Build Coastguard Worker     if (outputs == nullptr) {
676*ec779b8eSAndroid Build Coastguard Worker         outputs = &emptyOutput;
677*ec779b8eSAndroid Build Coastguard Worker     }
678*ec779b8eSAndroid Build Coastguard Worker 
679*ec779b8eSAndroid Build Coastguard Worker     camera_status_t ret = checkCameraClosedOrErrorLocked();
680*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
681*ec779b8eSAndroid Build Coastguard Worker         return ret;
682*ec779b8eSAndroid Build Coastguard Worker     }
683*ec779b8eSAndroid Build Coastguard Worker 
684*ec779b8eSAndroid Build Coastguard Worker     std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
685*ec779b8eSAndroid Build Coastguard Worker     for (const auto& outConfig : outputs->mOutputs) {
686*ec779b8eSAndroid Build Coastguard Worker         ANativeWindow* anw = outConfig.mWindow;
687*ec779b8eSAndroid Build Coastguard Worker         sp<SurfaceType> surface(nullptr);
688*ec779b8eSAndroid Build Coastguard Worker         ret = getSurfacefromAnw(anw, surface);
689*ec779b8eSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
690*ec779b8eSAndroid Build Coastguard Worker             return ret;
691*ec779b8eSAndroid Build Coastguard Worker         }
692*ec779b8eSAndroid Build Coastguard Worker         ParcelableSurfaceType pSurface = flagtools::convertSurfaceTypeToParcelable(surface);
693*ec779b8eSAndroid Build Coastguard Worker         outputSet.insert(std::make_pair(
694*ec779b8eSAndroid Build Coastguard Worker                 anw,
695*ec779b8eSAndroid Build Coastguard Worker                 OutputConfiguration(pSurface, outConfig.mRotation, outConfig.mPhysicalCameraId,
696*ec779b8eSAndroid Build Coastguard Worker                                     OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
697*ec779b8eSAndroid Build Coastguard Worker     }
698*ec779b8eSAndroid Build Coastguard Worker     auto addSet = outputSet;
699*ec779b8eSAndroid Build Coastguard Worker     std::vector<int> deleteList;
700*ec779b8eSAndroid Build Coastguard Worker 
701*ec779b8eSAndroid Build Coastguard Worker     // Determine which streams need to be created, which to be deleted
702*ec779b8eSAndroid Build Coastguard Worker     for (auto& kvPair : mConfiguredOutputs) {
703*ec779b8eSAndroid Build Coastguard Worker         int streamId = kvPair.first;
704*ec779b8eSAndroid Build Coastguard Worker         auto& outputPair = kvPair.second;
705*ec779b8eSAndroid Build Coastguard Worker         if (outputSet.count(outputPair) == 0) {
706*ec779b8eSAndroid Build Coastguard Worker             deleteList.push_back(streamId); // Need to delete a no longer needed stream
707*ec779b8eSAndroid Build Coastguard Worker         } else {
708*ec779b8eSAndroid Build Coastguard Worker             addSet.erase(outputPair);        // No need to add already existing stream
709*ec779b8eSAndroid Build Coastguard Worker         }
710*ec779b8eSAndroid Build Coastguard Worker     }
711*ec779b8eSAndroid Build Coastguard Worker 
712*ec779b8eSAndroid Build Coastguard Worker     ret = stopRepeatingLocked();
713*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
714*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s stop repeating failed, ret %d", getId(), ret);
715*ec779b8eSAndroid Build Coastguard Worker         return ret;
716*ec779b8eSAndroid Build Coastguard Worker     }
717*ec779b8eSAndroid Build Coastguard Worker 
718*ec779b8eSAndroid Build Coastguard Worker     ret = waitUntilIdleLocked();
719*ec779b8eSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
720*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s wait until idle failed, ret %d", getId(), ret);
721*ec779b8eSAndroid Build Coastguard Worker         return ret;
722*ec779b8eSAndroid Build Coastguard Worker     }
723*ec779b8eSAndroid Build Coastguard Worker 
724*ec779b8eSAndroid Build Coastguard Worker     // Send onReady to previous session
725*ec779b8eSAndroid Build Coastguard Worker     // CurrentSession will be updated after configureStreamLocked, so here
726*ec779b8eSAndroid Build Coastguard Worker     // mCurrentSession is the session to be replaced by a new session
727*ec779b8eSAndroid Build Coastguard Worker     if (!mIdle && mCurrentSession != nullptr) {
728*ec779b8eSAndroid Build Coastguard Worker         if (mBusySession != mCurrentSession) {
729*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Current session != busy session");
730*ec779b8eSAndroid Build Coastguard Worker             setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
731*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_CAMERA_DEVICE;
732*ec779b8eSAndroid Build Coastguard Worker         }
733*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
734*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, mBusySession->mUserSessionCallback.context);
735*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, mBusySession);
736*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kCallbackFpKey, (void*) mBusySession->mUserSessionCallback.onReady);
737*ec779b8eSAndroid Build Coastguard Worker         mBusySession.clear();
738*ec779b8eSAndroid Build Coastguard Worker         postSessionMsgAndCleanup(msg);
739*ec779b8eSAndroid Build Coastguard Worker     }
740*ec779b8eSAndroid Build Coastguard Worker     mIdle = true;
741*ec779b8eSAndroid Build Coastguard Worker 
742*ec779b8eSAndroid Build Coastguard Worker     binder::Status remoteRet = mRemote->beginConfigure();
743*ec779b8eSAndroid Build Coastguard Worker     if (!remoteRet.isOk()) {
744*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().c_str());
745*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNKNOWN;
746*ec779b8eSAndroid Build Coastguard Worker     }
747*ec779b8eSAndroid Build Coastguard Worker 
748*ec779b8eSAndroid Build Coastguard Worker     // delete to-be-deleted streams
749*ec779b8eSAndroid Build Coastguard Worker     for (auto streamId : deleteList) {
750*ec779b8eSAndroid Build Coastguard Worker         remoteRet = mRemote->deleteStream(streamId);
751*ec779b8eSAndroid Build Coastguard Worker         if (!remoteRet.isOk()) {
752*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
753*ec779b8eSAndroid Build Coastguard Worker                     remoteRet.toString8().c_str());
754*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
755*ec779b8eSAndroid Build Coastguard Worker         }
756*ec779b8eSAndroid Build Coastguard Worker         mConfiguredOutputs.erase(streamId);
757*ec779b8eSAndroid Build Coastguard Worker     }
758*ec779b8eSAndroid Build Coastguard Worker 
759*ec779b8eSAndroid Build Coastguard Worker     // add new streams
760*ec779b8eSAndroid Build Coastguard Worker     for (const auto& outputPair : addSet) {
761*ec779b8eSAndroid Build Coastguard Worker         int streamId;
762*ec779b8eSAndroid Build Coastguard Worker         remoteRet = mRemote->createStream(outputPair.second, &streamId);
763*ec779b8eSAndroid Build Coastguard Worker         if (!remoteRet.isOk()) {
764*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Camera device %s failed to create stream: %s", getId(),
765*ec779b8eSAndroid Build Coastguard Worker                     remoteRet.toString8().c_str());
766*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
767*ec779b8eSAndroid Build Coastguard Worker         }
768*ec779b8eSAndroid Build Coastguard Worker         mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
769*ec779b8eSAndroid Build Coastguard Worker     }
770*ec779b8eSAndroid Build Coastguard Worker 
771*ec779b8eSAndroid Build Coastguard Worker     CameraMetadata params;
772*ec779b8eSAndroid Build Coastguard Worker     if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) {
773*ec779b8eSAndroid Build Coastguard Worker         params.append(sessionParameters->settings->getInternalData());
774*ec779b8eSAndroid Build Coastguard Worker     }
775*ec779b8eSAndroid Build Coastguard Worker     std::vector<int> offlineStreamIds;
776*ec779b8eSAndroid Build Coastguard Worker     remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
777*ec779b8eSAndroid Build Coastguard Worker             ns2ms(startTimeNs), &offlineStreamIds);
778*ec779b8eSAndroid Build Coastguard Worker     if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
779*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
780*ec779b8eSAndroid Build Coastguard Worker                 remoteRet.toString8().c_str());
781*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
782*ec779b8eSAndroid Build Coastguard Worker     } else if (!remoteRet.isOk()) {
783*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().c_str());
784*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_UNKNOWN;
785*ec779b8eSAndroid Build Coastguard Worker     }
786*ec779b8eSAndroid Build Coastguard Worker 
787*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
788*ec779b8eSAndroid Build Coastguard Worker }
789*ec779b8eSAndroid Build Coastguard Worker 
790*ec779b8eSAndroid Build Coastguard Worker void
setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote)791*ec779b8eSAndroid Build Coastguard Worker CameraDevice::setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote) {
792*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mDeviceLock);
793*ec779b8eSAndroid Build Coastguard Worker     mRemote = remote;
794*ec779b8eSAndroid Build Coastguard Worker }
795*ec779b8eSAndroid Build Coastguard Worker 
setDeviceMetadataQueues()796*ec779b8eSAndroid Build Coastguard Worker bool CameraDevice::setDeviceMetadataQueues() {
797*ec779b8eSAndroid Build Coastguard Worker     if (mRemote == nullptr) {
798*ec779b8eSAndroid Build Coastguard Worker         ALOGE("mRemote must not be null while trying to fetch metadata queues");
799*ec779b8eSAndroid Build Coastguard Worker         return false;
800*ec779b8eSAndroid Build Coastguard Worker     }
801*ec779b8eSAndroid Build Coastguard Worker     MQDescriptor<int8_t, SynchronizedReadWrite> resMqDescriptor;
802*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = mRemote->getCaptureResultMetadataQueue(&resMqDescriptor);
803*ec779b8eSAndroid Build Coastguard Worker     if (!ret.isOk()) {
804*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Transaction error trying to get capture result metadata queue");
805*ec779b8eSAndroid Build Coastguard Worker         return false;
806*ec779b8eSAndroid Build Coastguard Worker     }
807*ec779b8eSAndroid Build Coastguard Worker     mCaptureResultMetadataQueue = std::make_unique<ResultMetadataQueue>(resMqDescriptor);
808*ec779b8eSAndroid Build Coastguard Worker     if (!mCaptureResultMetadataQueue->isValid()) {
809*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Empty fmq from cameraserver");
810*ec779b8eSAndroid Build Coastguard Worker         mCaptureResultMetadataQueue = nullptr;
811*ec779b8eSAndroid Build Coastguard Worker         return false;
812*ec779b8eSAndroid Build Coastguard Worker     }
813*ec779b8eSAndroid Build Coastguard Worker 
814*ec779b8eSAndroid Build Coastguard Worker     return true;
815*ec779b8eSAndroid Build Coastguard Worker }
816*ec779b8eSAndroid Build Coastguard Worker 
817*ec779b8eSAndroid Build Coastguard Worker camera_status_t
checkCameraClosedOrErrorLocked() const818*ec779b8eSAndroid Build Coastguard Worker CameraDevice::checkCameraClosedOrErrorLocked() const {
819*ec779b8eSAndroid Build Coastguard Worker     if (mRemote == nullptr) {
820*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: camera device already closed", __FUNCTION__);
821*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
822*ec779b8eSAndroid Build Coastguard Worker     }
823*ec779b8eSAndroid Build Coastguard Worker     if (mInError) {// triggered by onDeviceError
824*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: camera device has encountered a serious error", __FUNCTION__);
825*ec779b8eSAndroid Build Coastguard Worker         return mError;
826*ec779b8eSAndroid Build Coastguard Worker     }
827*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
828*ec779b8eSAndroid Build Coastguard Worker }
829*ec779b8eSAndroid Build Coastguard Worker 
830*ec779b8eSAndroid Build Coastguard Worker void
setCameraDeviceErrorLocked(camera_status_t error)831*ec779b8eSAndroid Build Coastguard Worker CameraDevice::setCameraDeviceErrorLocked(camera_status_t error) {
832*ec779b8eSAndroid Build Coastguard Worker     mInError = true;
833*ec779b8eSAndroid Build Coastguard Worker     mError = error;
834*ec779b8eSAndroid Build Coastguard Worker     return;
835*ec779b8eSAndroid Build Coastguard Worker }
836*ec779b8eSAndroid Build Coastguard Worker 
837*ec779b8eSAndroid Build Coastguard Worker void
updateTracker(int64_t frameNumber,bool isError)838*ec779b8eSAndroid Build Coastguard Worker CameraDevice::FrameNumberTracker::updateTracker(int64_t frameNumber, bool isError) {
839*ec779b8eSAndroid Build Coastguard Worker     ALOGV("updateTracker frame %" PRId64 " isError %d", frameNumber, isError);
840*ec779b8eSAndroid Build Coastguard Worker     if (isError) {
841*ec779b8eSAndroid Build Coastguard Worker         mFutureErrorSet.insert(frameNumber);
842*ec779b8eSAndroid Build Coastguard Worker     } else if (frameNumber <= mCompletedFrameNumber) {
843*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Frame number %" PRId64 " decreased! current fn %" PRId64,
844*ec779b8eSAndroid Build Coastguard Worker                 frameNumber, mCompletedFrameNumber);
845*ec779b8eSAndroid Build Coastguard Worker         return;
846*ec779b8eSAndroid Build Coastguard Worker     } else {
847*ec779b8eSAndroid Build Coastguard Worker         if (frameNumber != mCompletedFrameNumber + 1) {
848*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Frame number out of order. Expect %" PRId64 " but get %" PRId64,
849*ec779b8eSAndroid Build Coastguard Worker                     mCompletedFrameNumber + 1, frameNumber);
850*ec779b8eSAndroid Build Coastguard Worker             // Do not assert as in java implementation
851*ec779b8eSAndroid Build Coastguard Worker         }
852*ec779b8eSAndroid Build Coastguard Worker         mCompletedFrameNumber = frameNumber;
853*ec779b8eSAndroid Build Coastguard Worker     }
854*ec779b8eSAndroid Build Coastguard Worker     update();
855*ec779b8eSAndroid Build Coastguard Worker }
856*ec779b8eSAndroid Build Coastguard Worker 
857*ec779b8eSAndroid Build Coastguard Worker void
update()858*ec779b8eSAndroid Build Coastguard Worker CameraDevice::FrameNumberTracker::update() {
859*ec779b8eSAndroid Build Coastguard Worker     for (auto it = mFutureErrorSet.begin(); it != mFutureErrorSet.end();) {
860*ec779b8eSAndroid Build Coastguard Worker         int64_t errorFrameNumber = *it;
861*ec779b8eSAndroid Build Coastguard Worker         if (errorFrameNumber == mCompletedFrameNumber + 1) {
862*ec779b8eSAndroid Build Coastguard Worker             mCompletedFrameNumber++;
863*ec779b8eSAndroid Build Coastguard Worker             it = mFutureErrorSet.erase(it);
864*ec779b8eSAndroid Build Coastguard Worker         } else if (errorFrameNumber <= mCompletedFrameNumber) {
865*ec779b8eSAndroid Build Coastguard Worker             // This should not happen, but deal with it anyway
866*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Completd frame number passed through current frame number!");
867*ec779b8eSAndroid Build Coastguard Worker             // erase the old error since it's no longer useful
868*ec779b8eSAndroid Build Coastguard Worker             it = mFutureErrorSet.erase(it);
869*ec779b8eSAndroid Build Coastguard Worker         } else {
870*ec779b8eSAndroid Build Coastguard Worker             // Normal requests hasn't catched up error frames, just break
871*ec779b8eSAndroid Build Coastguard Worker             break;
872*ec779b8eSAndroid Build Coastguard Worker         }
873*ec779b8eSAndroid Build Coastguard Worker     }
874*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Update complete frame %" PRId64, mCompletedFrameNumber);
875*ec779b8eSAndroid Build Coastguard Worker }
876*ec779b8eSAndroid Build Coastguard Worker 
877*ec779b8eSAndroid Build Coastguard Worker void
onCaptureErrorLocked(int32_t errorCode,const CaptureResultExtras & resultExtras)878*ec779b8eSAndroid Build Coastguard Worker CameraDevice::onCaptureErrorLocked(
879*ec779b8eSAndroid Build Coastguard Worker         int32_t errorCode,
880*ec779b8eSAndroid Build Coastguard Worker         const CaptureResultExtras& resultExtras) {
881*ec779b8eSAndroid Build Coastguard Worker     int sequenceId = resultExtras.requestId;
882*ec779b8eSAndroid Build Coastguard Worker     int64_t frameNumber = resultExtras.frameNumber;
883*ec779b8eSAndroid Build Coastguard Worker     int32_t burstId = resultExtras.burstId;
884*ec779b8eSAndroid Build Coastguard Worker     auto it = mSequenceCallbackMap.find(sequenceId);
885*ec779b8eSAndroid Build Coastguard Worker     if (it == mSequenceCallbackMap.end()) {
886*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Error: capture sequence index %d not found!",
887*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, sequenceId);
888*ec779b8eSAndroid Build Coastguard Worker         setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
889*ec779b8eSAndroid Build Coastguard Worker         return;
890*ec779b8eSAndroid Build Coastguard Worker     }
891*ec779b8eSAndroid Build Coastguard Worker 
892*ec779b8eSAndroid Build Coastguard Worker     CallbackHolder cbh = (*it).second;
893*ec779b8eSAndroid Build Coastguard Worker     sp<ACameraCaptureSession> session = cbh.mSession;
894*ec779b8eSAndroid Build Coastguard Worker     if ((size_t) burstId >= cbh.mRequests.size()) {
895*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Error: request index %d out of bound (size %zu)",
896*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, burstId, cbh.mRequests.size());
897*ec779b8eSAndroid Build Coastguard Worker         setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
898*ec779b8eSAndroid Build Coastguard Worker         return;
899*ec779b8eSAndroid Build Coastguard Worker     }
900*ec779b8eSAndroid Build Coastguard Worker     sp<CaptureRequest> request = cbh.mRequests[burstId];
901*ec779b8eSAndroid Build Coastguard Worker 
902*ec779b8eSAndroid Build Coastguard Worker     // Handle buffer error
903*ec779b8eSAndroid Build Coastguard Worker     if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER) {
904*ec779b8eSAndroid Build Coastguard Worker         int32_t streamId = resultExtras.errorStreamId;
905*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallback_bufferLost onBufferLost =
906*ec779b8eSAndroid Build Coastguard Worker                 cbh.mOnCaptureBufferLost;
907*ec779b8eSAndroid Build Coastguard Worker         auto outputPairIt = mConfiguredOutputs.find(streamId);
908*ec779b8eSAndroid Build Coastguard Worker         if (outputPairIt == mConfiguredOutputs.end()) {
909*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: Error: stream id %d does not exist", __FUNCTION__, streamId);
910*ec779b8eSAndroid Build Coastguard Worker             setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
911*ec779b8eSAndroid Build Coastguard Worker             return;
912*ec779b8eSAndroid Build Coastguard Worker         }
913*ec779b8eSAndroid Build Coastguard Worker 
914*ec779b8eSAndroid Build Coastguard Worker         const auto& outSurfaces = outputPairIt->second.second.getSurfaces();
915*ec779b8eSAndroid Build Coastguard Worker         for (const auto& outSurface : outSurfaces) {
916*ec779b8eSAndroid Build Coastguard Worker             for (const auto& surface : request->mSurfaceList) {
917*ec779b8eSAndroid Build Coastguard Worker                 if ( outSurface == surface
918*ec779b8eSAndroid Build Coastguard Worker #if not WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
919*ec779b8eSAndroid Build Coastguard Worker                                 ->getIGraphicBufferProducer()
920*ec779b8eSAndroid Build Coastguard Worker #endif
921*ec779b8eSAndroid Build Coastguard Worker                                             ) {
922*ec779b8eSAndroid Build Coastguard Worker                     ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
923*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
924*ec779b8eSAndroid Build Coastguard Worker                             getId(), anw, frameNumber);
925*ec779b8eSAndroid Build Coastguard Worker 
926*ec779b8eSAndroid Build Coastguard Worker                     sp<AMessage> msg = new AMessage(kWhatCaptureBufferLost, mHandler);
927*ec779b8eSAndroid Build Coastguard Worker                     msg->setPointer(kContextKey, cbh.mContext);
928*ec779b8eSAndroid Build Coastguard Worker                     msg->setObject(kSessionSpKey, session);
929*ec779b8eSAndroid Build Coastguard Worker                     msg->setPointer(kCallbackFpKey, (void*) onBufferLost);
930*ec779b8eSAndroid Build Coastguard Worker                     msg->setObject(kCaptureRequestKey, request);
931*ec779b8eSAndroid Build Coastguard Worker                     msg->setPointer(kAnwKey, (void*) anw);
932*ec779b8eSAndroid Build Coastguard Worker                     msg->setInt64(kFrameNumberKey, frameNumber);
933*ec779b8eSAndroid Build Coastguard Worker                     postSessionMsgAndCleanup(msg);
934*ec779b8eSAndroid Build Coastguard Worker                 }
935*ec779b8eSAndroid Build Coastguard Worker             }
936*ec779b8eSAndroid Build Coastguard Worker         }
937*ec779b8eSAndroid Build Coastguard Worker     } else { // Handle other capture failures
938*ec779b8eSAndroid Build Coastguard Worker         // Fire capture failure callback if there is one registered
939*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallback_failed onError = cbh.mOnCaptureFailed;
940*ec779b8eSAndroid Build Coastguard Worker         sp<CameraCaptureFailure> failure(new CameraCaptureFailure());
941*ec779b8eSAndroid Build Coastguard Worker         failure->frameNumber = frameNumber;
942*ec779b8eSAndroid Build Coastguard Worker         // TODO: refine this when implementing flush
943*ec779b8eSAndroid Build Coastguard Worker         failure->reason      = CAPTURE_FAILURE_REASON_ERROR;
944*ec779b8eSAndroid Build Coastguard Worker         failure->sequenceId  = sequenceId;
945*ec779b8eSAndroid Build Coastguard Worker         failure->wasImageCaptured = (errorCode ==
946*ec779b8eSAndroid Build Coastguard Worker                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
947*ec779b8eSAndroid Build Coastguard Worker 
948*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
949*ec779b8eSAndroid Build Coastguard Worker                 kWhatCaptureFail, mHandler);
950*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, cbh.mContext);
951*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, session);
952*ec779b8eSAndroid Build Coastguard Worker         if (cbh.mIsLogicalCameraCallback) {
953*ec779b8eSAndroid Build Coastguard Worker             if (resultExtras.errorPhysicalCameraId.size() > 0) {
954*ec779b8eSAndroid Build Coastguard Worker                 String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
955*ec779b8eSAndroid Build Coastguard Worker                 msg->setString(kFailingPhysicalCameraId, cameraId.c_str(), cameraId.size());
956*ec779b8eSAndroid Build Coastguard Worker             }
957*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
958*ec779b8eSAndroid Build Coastguard Worker         } else {
959*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey, (void*) onError);
960*ec779b8eSAndroid Build Coastguard Worker         }
961*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kCaptureRequestKey, request);
962*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kCaptureFailureKey, failure);
963*ec779b8eSAndroid Build Coastguard Worker         postSessionMsgAndCleanup(msg);
964*ec779b8eSAndroid Build Coastguard Worker 
965*ec779b8eSAndroid Build Coastguard Worker         // Update tracker
966*ec779b8eSAndroid Build Coastguard Worker         mFrameNumberTracker.updateTracker(frameNumber, /*isError*/true);
967*ec779b8eSAndroid Build Coastguard Worker         checkAndFireSequenceCompleteLocked();
968*ec779b8eSAndroid Build Coastguard Worker     }
969*ec779b8eSAndroid Build Coastguard Worker     return;
970*ec779b8eSAndroid Build Coastguard Worker }
971*ec779b8eSAndroid Build Coastguard Worker 
stopLooperAndDisconnect()972*ec779b8eSAndroid Build Coastguard Worker void CameraDevice::stopLooperAndDisconnect() {
973*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mDeviceLock);
974*ec779b8eSAndroid Build Coastguard Worker     sp<ACameraCaptureSession> session = mCurrentSession.promote();
975*ec779b8eSAndroid Build Coastguard Worker     if (!isClosed()) {
976*ec779b8eSAndroid Build Coastguard Worker         disconnectLocked(session);
977*ec779b8eSAndroid Build Coastguard Worker     }
978*ec779b8eSAndroid Build Coastguard Worker     mCurrentSession = nullptr;
979*ec779b8eSAndroid Build Coastguard Worker 
980*ec779b8eSAndroid Build Coastguard Worker     if (mCbLooper != nullptr) {
981*ec779b8eSAndroid Build Coastguard Worker       mCbLooper->unregisterHandler(mHandler->id());
982*ec779b8eSAndroid Build Coastguard Worker       mCbLooper->stop();
983*ec779b8eSAndroid Build Coastguard Worker     }
984*ec779b8eSAndroid Build Coastguard Worker     mCbLooper.clear();
985*ec779b8eSAndroid Build Coastguard Worker     mHandler.clear();
986*ec779b8eSAndroid Build Coastguard Worker }
987*ec779b8eSAndroid Build Coastguard Worker 
CallbackHandler(const char * id)988*ec779b8eSAndroid Build Coastguard Worker CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
989*ec779b8eSAndroid Build Coastguard Worker }
990*ec779b8eSAndroid Build Coastguard Worker 
onMessageReceived(const sp<AMessage> & msg)991*ec779b8eSAndroid Build Coastguard Worker void CameraDevice::CallbackHandler::onMessageReceived(
992*ec779b8eSAndroid Build Coastguard Worker         const sp<AMessage> &msg) {
993*ec779b8eSAndroid Build Coastguard Worker     switch (msg->what()) {
994*ec779b8eSAndroid Build Coastguard Worker         case kWhatOnDisconnected:
995*ec779b8eSAndroid Build Coastguard Worker         case kWhatOnError:
996*ec779b8eSAndroid Build Coastguard Worker         case kWhatSessionStateCb:
997*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureStart:
998*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureStart2:
999*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureResult:
1000*ec779b8eSAndroid Build Coastguard Worker         case kWhatLogicalCaptureResult:
1001*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureFail:
1002*ec779b8eSAndroid Build Coastguard Worker         case kWhatLogicalCaptureFail:
1003*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureSeqEnd:
1004*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureSeqAbort:
1005*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureBufferLost:
1006*ec779b8eSAndroid Build Coastguard Worker         case kWhatPreparedCb:
1007*ec779b8eSAndroid Build Coastguard Worker         case kWhatClientSharedAccessPriorityChanged:
1008*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
1009*ec779b8eSAndroid Build Coastguard Worker             break;
1010*ec779b8eSAndroid Build Coastguard Worker         case kWhatCleanUpSessions:
1011*ec779b8eSAndroid Build Coastguard Worker             mCachedSessions.clear();
1012*ec779b8eSAndroid Build Coastguard Worker             return;
1013*ec779b8eSAndroid Build Coastguard Worker         default:
1014*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s:Error: unknown device callback %d", __FUNCTION__, msg->what());
1015*ec779b8eSAndroid Build Coastguard Worker             return;
1016*ec779b8eSAndroid Build Coastguard Worker     }
1017*ec779b8eSAndroid Build Coastguard Worker     // Check the common part of all message
1018*ec779b8eSAndroid Build Coastguard Worker     void* context;
1019*ec779b8eSAndroid Build Coastguard Worker     bool found = msg->findPointer(kContextKey, &context);
1020*ec779b8eSAndroid Build Coastguard Worker     if (!found) {
1021*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Cannot find callback context!", __FUNCTION__);
1022*ec779b8eSAndroid Build Coastguard Worker         return;
1023*ec779b8eSAndroid Build Coastguard Worker     }
1024*ec779b8eSAndroid Build Coastguard Worker     switch (msg->what()) {
1025*ec779b8eSAndroid Build Coastguard Worker         case kWhatOnDisconnected:
1026*ec779b8eSAndroid Build Coastguard Worker         {
1027*ec779b8eSAndroid Build Coastguard Worker             ACameraDevice* dev;
1028*ec779b8eSAndroid Build Coastguard Worker             found = msg->findPointer(kDeviceKey, (void**) &dev);
1029*ec779b8eSAndroid Build Coastguard Worker             if (!found || dev == nullptr) {
1030*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1031*ec779b8eSAndroid Build Coastguard Worker                 return;
1032*ec779b8eSAndroid Build Coastguard Worker             }
1033*ec779b8eSAndroid Build Coastguard Worker             ACameraDevice_StateCallback onDisconnected;
1034*ec779b8eSAndroid Build Coastguard Worker             found = msg->findPointer(kCallbackFpKey, (void**) &onDisconnected);
1035*ec779b8eSAndroid Build Coastguard Worker             if (!found) {
1036*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find onDisconnected!", __FUNCTION__);
1037*ec779b8eSAndroid Build Coastguard Worker                 return;
1038*ec779b8eSAndroid Build Coastguard Worker             }
1039*ec779b8eSAndroid Build Coastguard Worker             if (onDisconnected == nullptr) {
1040*ec779b8eSAndroid Build Coastguard Worker                 return;
1041*ec779b8eSAndroid Build Coastguard Worker             }
1042*ec779b8eSAndroid Build Coastguard Worker             (*onDisconnected)(context, dev);
1043*ec779b8eSAndroid Build Coastguard Worker             break;
1044*ec779b8eSAndroid Build Coastguard Worker         }
1045*ec779b8eSAndroid Build Coastguard Worker 
1046*ec779b8eSAndroid Build Coastguard Worker         case kWhatClientSharedAccessPriorityChanged:
1047*ec779b8eSAndroid Build Coastguard Worker         {
1048*ec779b8eSAndroid Build Coastguard Worker             if (!flags::camera_multi_client()) {
1049*ec779b8eSAndroid Build Coastguard Worker                 break;
1050*ec779b8eSAndroid Build Coastguard Worker             }
1051*ec779b8eSAndroid Build Coastguard Worker             ACameraDevice* dev;
1052*ec779b8eSAndroid Build Coastguard Worker             found = msg->findPointer(kDeviceKey, (void**) &dev);
1053*ec779b8eSAndroid Build Coastguard Worker             if (!found || dev == nullptr) {
1054*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1055*ec779b8eSAndroid Build Coastguard Worker                 return;
1056*ec779b8eSAndroid Build Coastguard Worker             }
1057*ec779b8eSAndroid Build Coastguard Worker             ACameraDevice_ClientSharedAccessPriorityChangedCallback
1058*ec779b8eSAndroid Build Coastguard Worker                     onClientSharedAccessPriorityChanged;
1059*ec779b8eSAndroid Build Coastguard Worker             found = msg->findPointer(kCallbackFpKey, (void**) &onClientSharedAccessPriorityChanged);
1060*ec779b8eSAndroid Build Coastguard Worker             if (!found) {
1061*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find onClientSharedAccessPriorityChanged!", __FUNCTION__);
1062*ec779b8eSAndroid Build Coastguard Worker                 return;
1063*ec779b8eSAndroid Build Coastguard Worker             }
1064*ec779b8eSAndroid Build Coastguard Worker             if (onClientSharedAccessPriorityChanged == nullptr) {
1065*ec779b8eSAndroid Build Coastguard Worker                 return;
1066*ec779b8eSAndroid Build Coastguard Worker             }
1067*ec779b8eSAndroid Build Coastguard Worker             (*onClientSharedAccessPriorityChanged)(context, dev, dev->isPrimaryClient());
1068*ec779b8eSAndroid Build Coastguard Worker             break;
1069*ec779b8eSAndroid Build Coastguard Worker         }
1070*ec779b8eSAndroid Build Coastguard Worker 
1071*ec779b8eSAndroid Build Coastguard Worker         case kWhatOnError:
1072*ec779b8eSAndroid Build Coastguard Worker         {
1073*ec779b8eSAndroid Build Coastguard Worker             ACameraDevice* dev;
1074*ec779b8eSAndroid Build Coastguard Worker             found = msg->findPointer(kDeviceKey, (void**) &dev);
1075*ec779b8eSAndroid Build Coastguard Worker             if (!found || dev == nullptr) {
1076*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find device pointer!", __FUNCTION__);
1077*ec779b8eSAndroid Build Coastguard Worker                 return;
1078*ec779b8eSAndroid Build Coastguard Worker             }
1079*ec779b8eSAndroid Build Coastguard Worker             ACameraDevice_ErrorStateCallback onError;
1080*ec779b8eSAndroid Build Coastguard Worker             found = msg->findPointer(kCallbackFpKey, (void**) &onError);
1081*ec779b8eSAndroid Build Coastguard Worker             if (!found) {
1082*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find onError!", __FUNCTION__);
1083*ec779b8eSAndroid Build Coastguard Worker                 return;
1084*ec779b8eSAndroid Build Coastguard Worker             }
1085*ec779b8eSAndroid Build Coastguard Worker             int errorCode;
1086*ec779b8eSAndroid Build Coastguard Worker             found = msg->findInt32(kErrorCodeKey, &errorCode);
1087*ec779b8eSAndroid Build Coastguard Worker             if (!found) {
1088*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find error code!", __FUNCTION__);
1089*ec779b8eSAndroid Build Coastguard Worker                 return;
1090*ec779b8eSAndroid Build Coastguard Worker             }
1091*ec779b8eSAndroid Build Coastguard Worker             if (onError == nullptr) {
1092*ec779b8eSAndroid Build Coastguard Worker                 return;
1093*ec779b8eSAndroid Build Coastguard Worker             }
1094*ec779b8eSAndroid Build Coastguard Worker             (*onError)(context, dev, errorCode);
1095*ec779b8eSAndroid Build Coastguard Worker             break;
1096*ec779b8eSAndroid Build Coastguard Worker         }
1097*ec779b8eSAndroid Build Coastguard Worker         case kWhatSessionStateCb:
1098*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureStart:
1099*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureStart2:
1100*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureResult:
1101*ec779b8eSAndroid Build Coastguard Worker         case kWhatLogicalCaptureResult:
1102*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureFail:
1103*ec779b8eSAndroid Build Coastguard Worker         case kWhatLogicalCaptureFail:
1104*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureSeqEnd:
1105*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureSeqAbort:
1106*ec779b8eSAndroid Build Coastguard Worker         case kWhatCaptureBufferLost:
1107*ec779b8eSAndroid Build Coastguard Worker         case kWhatPreparedCb:
1108*ec779b8eSAndroid Build Coastguard Worker         {
1109*ec779b8eSAndroid Build Coastguard Worker             sp<RefBase> obj;
1110*ec779b8eSAndroid Build Coastguard Worker             found = msg->findObject(kSessionSpKey, &obj);
1111*ec779b8eSAndroid Build Coastguard Worker             if (!found || obj == nullptr) {
1112*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Cannot find session pointer!", __FUNCTION__);
1113*ec779b8eSAndroid Build Coastguard Worker                 return;
1114*ec779b8eSAndroid Build Coastguard Worker             }
1115*ec779b8eSAndroid Build Coastguard Worker             sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
1116*ec779b8eSAndroid Build Coastguard Worker             mCachedSessions.push(session);
1117*ec779b8eSAndroid Build Coastguard Worker             sp<CaptureRequest> requestSp = nullptr;
1118*ec779b8eSAndroid Build Coastguard Worker             switch (msg->what()) {
1119*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureStart:
1120*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureStart2:
1121*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureResult:
1122*ec779b8eSAndroid Build Coastguard Worker                 case kWhatLogicalCaptureResult:
1123*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureFail:
1124*ec779b8eSAndroid Build Coastguard Worker                 case kWhatLogicalCaptureFail:
1125*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureBufferLost:
1126*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findObject(kCaptureRequestKey, &obj);
1127*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1128*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture request!", __FUNCTION__);
1129*ec779b8eSAndroid Build Coastguard Worker                         return;
1130*ec779b8eSAndroid Build Coastguard Worker                     }
1131*ec779b8eSAndroid Build Coastguard Worker                     requestSp = static_cast<CaptureRequest*>(obj.get());
1132*ec779b8eSAndroid Build Coastguard Worker                     break;
1133*ec779b8eSAndroid Build Coastguard Worker             }
1134*ec779b8eSAndroid Build Coastguard Worker 
1135*ec779b8eSAndroid Build Coastguard Worker             switch (msg->what()) {
1136*ec779b8eSAndroid Build Coastguard Worker                 case kWhatSessionStateCb:
1137*ec779b8eSAndroid Build Coastguard Worker                 {
1138*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_stateCallback onState;
1139*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onState);
1140*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1141*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find state callback!", __FUNCTION__);
1142*ec779b8eSAndroid Build Coastguard Worker                         return;
1143*ec779b8eSAndroid Build Coastguard Worker                     }
1144*ec779b8eSAndroid Build Coastguard Worker                     if (onState == nullptr) {
1145*ec779b8eSAndroid Build Coastguard Worker                         return;
1146*ec779b8eSAndroid Build Coastguard Worker                     }
1147*ec779b8eSAndroid Build Coastguard Worker                     (*onState)(context, session.get());
1148*ec779b8eSAndroid Build Coastguard Worker                     break;
1149*ec779b8eSAndroid Build Coastguard Worker                 }
1150*ec779b8eSAndroid Build Coastguard Worker                 case kWhatPreparedCb:
1151*ec779b8eSAndroid Build Coastguard Worker                 {
1152*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_prepareCallback onWindowPrepared;
1153*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onWindowPrepared);
1154*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1155*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find window prepared callback!", __FUNCTION__);
1156*ec779b8eSAndroid Build Coastguard Worker                         return;
1157*ec779b8eSAndroid Build Coastguard Worker                     }
1158*ec779b8eSAndroid Build Coastguard Worker                     if (onWindowPrepared == nullptr) {
1159*ec779b8eSAndroid Build Coastguard Worker                         return;
1160*ec779b8eSAndroid Build Coastguard Worker                     }
1161*ec779b8eSAndroid Build Coastguard Worker                     ANativeWindow* anw;
1162*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kAnwKey, (void**) &anw);
1163*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1164*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find ANativeWindow: %d!", __FUNCTION__, __LINE__);
1165*ec779b8eSAndroid Build Coastguard Worker                         return;
1166*ec779b8eSAndroid Build Coastguard Worker                     }
1167*ec779b8eSAndroid Build Coastguard Worker                     (*onWindowPrepared)(context, anw, session.get());
1168*ec779b8eSAndroid Build Coastguard Worker                     break;
1169*ec779b8eSAndroid Build Coastguard Worker                 }
1170*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureStart:
1171*ec779b8eSAndroid Build Coastguard Worker                 {
1172*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_start onStart;
1173*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onStart);
1174*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1175*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture start callback!", __FUNCTION__);
1176*ec779b8eSAndroid Build Coastguard Worker                         return;
1177*ec779b8eSAndroid Build Coastguard Worker                     }
1178*ec779b8eSAndroid Build Coastguard Worker                     if (onStart == nullptr) {
1179*ec779b8eSAndroid Build Coastguard Worker                         return;
1180*ec779b8eSAndroid Build Coastguard Worker                     }
1181*ec779b8eSAndroid Build Coastguard Worker                     int64_t timestamp;
1182*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt64(kTimeStampKey, &timestamp);
1183*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1184*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1185*ec779b8eSAndroid Build Coastguard Worker                         return;
1186*ec779b8eSAndroid Build Coastguard Worker                     }
1187*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1188*ec779b8eSAndroid Build Coastguard Worker                     (*onStart)(context, session.get(), request, timestamp);
1189*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1190*ec779b8eSAndroid Build Coastguard Worker                     break;
1191*ec779b8eSAndroid Build Coastguard Worker                 }
1192*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureStart2:
1193*ec779b8eSAndroid Build Coastguard Worker                 {
1194*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_startV2 onStart2;
1195*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
1196*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1197*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
1198*ec779b8eSAndroid Build Coastguard Worker                         return;
1199*ec779b8eSAndroid Build Coastguard Worker                     }
1200*ec779b8eSAndroid Build Coastguard Worker                     if (onStart2 == nullptr) {
1201*ec779b8eSAndroid Build Coastguard Worker                         return;
1202*ec779b8eSAndroid Build Coastguard Worker                     }
1203*ec779b8eSAndroid Build Coastguard Worker                     int64_t timestamp;
1204*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt64(kTimeStampKey, &timestamp);
1205*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1206*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
1207*ec779b8eSAndroid Build Coastguard Worker                         return;
1208*ec779b8eSAndroid Build Coastguard Worker                     }
1209*ec779b8eSAndroid Build Coastguard Worker                     int64_t frameNumber;
1210*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt64(kFrameNumberKey, &frameNumber);
1211*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1212*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1213*ec779b8eSAndroid Build Coastguard Worker                         return;
1214*ec779b8eSAndroid Build Coastguard Worker                     }
1215*ec779b8eSAndroid Build Coastguard Worker 
1216*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1217*ec779b8eSAndroid Build Coastguard Worker                     (*onStart2)(context, session.get(), request, timestamp, frameNumber);
1218*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1219*ec779b8eSAndroid Build Coastguard Worker                     break;
1220*ec779b8eSAndroid Build Coastguard Worker                 }
1221*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureResult:
1222*ec779b8eSAndroid Build Coastguard Worker                 {
1223*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_result onResult;
1224*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1225*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1226*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture result callback!", __FUNCTION__);
1227*ec779b8eSAndroid Build Coastguard Worker                         return;
1228*ec779b8eSAndroid Build Coastguard Worker                     }
1229*ec779b8eSAndroid Build Coastguard Worker                     if (onResult == nullptr) {
1230*ec779b8eSAndroid Build Coastguard Worker                         return;
1231*ec779b8eSAndroid Build Coastguard Worker                     }
1232*ec779b8eSAndroid Build Coastguard Worker 
1233*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findObject(kCaptureResultKey, &obj);
1234*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1235*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1236*ec779b8eSAndroid Build Coastguard Worker                         return;
1237*ec779b8eSAndroid Build Coastguard Worker                     }
1238*ec779b8eSAndroid Build Coastguard Worker                     sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1239*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1240*ec779b8eSAndroid Build Coastguard Worker                     (*onResult)(context, session.get(), request, result.get());
1241*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1242*ec779b8eSAndroid Build Coastguard Worker                     break;
1243*ec779b8eSAndroid Build Coastguard Worker                 }
1244*ec779b8eSAndroid Build Coastguard Worker                 case kWhatLogicalCaptureResult:
1245*ec779b8eSAndroid Build Coastguard Worker                 {
1246*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_logicalCamera_captureCallback_result onResult;
1247*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onResult);
1248*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1249*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find logicalCamera capture result callback!",
1250*ec779b8eSAndroid Build Coastguard Worker                                 __FUNCTION__);
1251*ec779b8eSAndroid Build Coastguard Worker                         return;
1252*ec779b8eSAndroid Build Coastguard Worker                     }
1253*ec779b8eSAndroid Build Coastguard Worker                     if (onResult == nullptr) {
1254*ec779b8eSAndroid Build Coastguard Worker                         return;
1255*ec779b8eSAndroid Build Coastguard Worker                     }
1256*ec779b8eSAndroid Build Coastguard Worker 
1257*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findObject(kCaptureResultKey, &obj);
1258*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1259*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture result!", __FUNCTION__);
1260*ec779b8eSAndroid Build Coastguard Worker                         return;
1261*ec779b8eSAndroid Build Coastguard Worker                     }
1262*ec779b8eSAndroid Build Coastguard Worker                     sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
1263*ec779b8eSAndroid Build Coastguard Worker 
1264*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findObject(kPhysicalCaptureResultKey, &obj);
1265*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1266*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find physical capture result!", __FUNCTION__);
1267*ec779b8eSAndroid Build Coastguard Worker                         return;
1268*ec779b8eSAndroid Build Coastguard Worker                     }
1269*ec779b8eSAndroid Build Coastguard Worker                     sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1270*ec779b8eSAndroid Build Coastguard Worker                             static_cast<ACameraPhysicalCaptureResultInfo*>(obj.get()));
1271*ec779b8eSAndroid Build Coastguard Worker                     std::vector<PhysicalCaptureResultInfo>& physicalResultInfo =
1272*ec779b8eSAndroid Build Coastguard Worker                             physicalResult->mPhysicalResultInfo;
1273*ec779b8eSAndroid Build Coastguard Worker 
1274*ec779b8eSAndroid Build Coastguard Worker                     std::vector<std::string> physicalCameraIds;
1275*ec779b8eSAndroid Build Coastguard Worker                     std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
1276*ec779b8eSAndroid Build Coastguard Worker                     for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1277*ec779b8eSAndroid Build Coastguard Worker                         String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
1278*ec779b8eSAndroid Build Coastguard Worker                         physicalCameraIds.push_back(physicalId8.c_str());
1279*ec779b8eSAndroid Build Coastguard Worker 
1280*ec779b8eSAndroid Build Coastguard Worker                         CameraMetadata clone =
1281*ec779b8eSAndroid Build Coastguard Worker                                 physicalResultInfo[i].
1282*ec779b8eSAndroid Build Coastguard Worker                                         mCameraMetadataInfo.get<CameraMetadataInfo::metadata>();
1283*ec779b8eSAndroid Build Coastguard Worker                         clone.update(ANDROID_SYNC_FRAME_NUMBER,
1284*ec779b8eSAndroid Build Coastguard Worker                                 &physicalResult->mFrameNumber, /*data_count*/1);
1285*ec779b8eSAndroid Build Coastguard Worker                         sp<ACameraMetadata> metadata =
1286*ec779b8eSAndroid Build Coastguard Worker                                 new ACameraMetadata(clone.release(), ACameraMetadata::ACM_RESULT);
1287*ec779b8eSAndroid Build Coastguard Worker                         physicalMetadataCopy.push_back(metadata);
1288*ec779b8eSAndroid Build Coastguard Worker                     }
1289*ec779b8eSAndroid Build Coastguard Worker 
1290*ec779b8eSAndroid Build Coastguard Worker                     std::vector<const char*> physicalCameraIdPtrs;
1291*ec779b8eSAndroid Build Coastguard Worker                     std::vector<const ACameraMetadata*> physicalMetadataCopyPtrs;
1292*ec779b8eSAndroid Build Coastguard Worker                     for (size_t i = 0; i < physicalResultInfo.size(); i++) {
1293*ec779b8eSAndroid Build Coastguard Worker                         physicalCameraIdPtrs.push_back(physicalCameraIds[i].c_str());
1294*ec779b8eSAndroid Build Coastguard Worker                         physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
1295*ec779b8eSAndroid Build Coastguard Worker                     }
1296*ec779b8eSAndroid Build Coastguard Worker 
1297*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1298*ec779b8eSAndroid Build Coastguard Worker                     (*onResult)(context, session.get(), request, result.get(),
1299*ec779b8eSAndroid Build Coastguard Worker                             physicalResultInfo.size(), physicalCameraIdPtrs.data(),
1300*ec779b8eSAndroid Build Coastguard Worker                             physicalMetadataCopyPtrs.data());
1301*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1302*ec779b8eSAndroid Build Coastguard Worker                     break;
1303*ec779b8eSAndroid Build Coastguard Worker                 }
1304*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureFail:
1305*ec779b8eSAndroid Build Coastguard Worker                 {
1306*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_failed onFail;
1307*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1308*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1309*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1310*ec779b8eSAndroid Build Coastguard Worker                         return;
1311*ec779b8eSAndroid Build Coastguard Worker                     }
1312*ec779b8eSAndroid Build Coastguard Worker                     if (onFail == nullptr) {
1313*ec779b8eSAndroid Build Coastguard Worker                         return;
1314*ec779b8eSAndroid Build Coastguard Worker                     }
1315*ec779b8eSAndroid Build Coastguard Worker 
1316*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findObject(kCaptureFailureKey, &obj);
1317*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1318*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1319*ec779b8eSAndroid Build Coastguard Worker                         return;
1320*ec779b8eSAndroid Build Coastguard Worker                     }
1321*ec779b8eSAndroid Build Coastguard Worker                     sp<CameraCaptureFailure> failureSp(
1322*ec779b8eSAndroid Build Coastguard Worker                             static_cast<CameraCaptureFailure*>(obj.get()));
1323*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureFailure* failure =
1324*ec779b8eSAndroid Build Coastguard Worker                             static_cast<ACameraCaptureFailure*>(failureSp.get());
1325*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1326*ec779b8eSAndroid Build Coastguard Worker                     (*onFail)(context, session.get(), request, failure);
1327*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1328*ec779b8eSAndroid Build Coastguard Worker                     break;
1329*ec779b8eSAndroid Build Coastguard Worker                 }
1330*ec779b8eSAndroid Build Coastguard Worker                 case kWhatLogicalCaptureFail:
1331*ec779b8eSAndroid Build Coastguard Worker                 {
1332*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
1333*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
1334*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1335*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
1336*ec779b8eSAndroid Build Coastguard Worker                         return;
1337*ec779b8eSAndroid Build Coastguard Worker                     }
1338*ec779b8eSAndroid Build Coastguard Worker                     if (onFail == nullptr) {
1339*ec779b8eSAndroid Build Coastguard Worker                         return;
1340*ec779b8eSAndroid Build Coastguard Worker                     }
1341*ec779b8eSAndroid Build Coastguard Worker 
1342*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findObject(kCaptureFailureKey, &obj);
1343*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1344*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
1345*ec779b8eSAndroid Build Coastguard Worker                         return;
1346*ec779b8eSAndroid Build Coastguard Worker                     }
1347*ec779b8eSAndroid Build Coastguard Worker                     sp<CameraCaptureFailure> failureSp(
1348*ec779b8eSAndroid Build Coastguard Worker                             static_cast<CameraCaptureFailure*>(obj.get()));
1349*ec779b8eSAndroid Build Coastguard Worker                     ALogicalCameraCaptureFailure failure;
1350*ec779b8eSAndroid Build Coastguard Worker                     AString physicalCameraId;
1351*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
1352*ec779b8eSAndroid Build Coastguard Worker                     if (found && !physicalCameraId.empty()) {
1353*ec779b8eSAndroid Build Coastguard Worker                         failure.physicalCameraId = physicalCameraId.c_str();
1354*ec779b8eSAndroid Build Coastguard Worker                     } else {
1355*ec779b8eSAndroid Build Coastguard Worker                         failure.physicalCameraId = nullptr;
1356*ec779b8eSAndroid Build Coastguard Worker                     }
1357*ec779b8eSAndroid Build Coastguard Worker                     failure.captureFailure = *failureSp;
1358*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1359*ec779b8eSAndroid Build Coastguard Worker                     (*onFail)(context, session.get(), request, &failure);
1360*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1361*ec779b8eSAndroid Build Coastguard Worker                     break;
1362*ec779b8eSAndroid Build Coastguard Worker                 }
1363*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureSeqEnd:
1364*ec779b8eSAndroid Build Coastguard Worker                 {
1365*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
1366*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onSeqEnd);
1367*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1368*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1369*ec779b8eSAndroid Build Coastguard Worker                         return;
1370*ec779b8eSAndroid Build Coastguard Worker                     }
1371*ec779b8eSAndroid Build Coastguard Worker                     if (onSeqEnd == nullptr) {
1372*ec779b8eSAndroid Build Coastguard Worker                         return;
1373*ec779b8eSAndroid Build Coastguard Worker                     }
1374*ec779b8eSAndroid Build Coastguard Worker                     int seqId;
1375*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt32(kSequenceIdKey, &seqId);
1376*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1377*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1378*ec779b8eSAndroid Build Coastguard Worker                         return;
1379*ec779b8eSAndroid Build Coastguard Worker                     }
1380*ec779b8eSAndroid Build Coastguard Worker                     int64_t frameNumber;
1381*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt64(kFrameNumberKey, &frameNumber);
1382*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1383*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1384*ec779b8eSAndroid Build Coastguard Worker                         return;
1385*ec779b8eSAndroid Build Coastguard Worker                     }
1386*ec779b8eSAndroid Build Coastguard Worker                     (*onSeqEnd)(context, session.get(), seqId, frameNumber);
1387*ec779b8eSAndroid Build Coastguard Worker                     break;
1388*ec779b8eSAndroid Build Coastguard Worker                 }
1389*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureSeqAbort:
1390*ec779b8eSAndroid Build Coastguard Worker                 {
1391*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_sequenceAbort onSeqAbort;
1392*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onSeqAbort);
1393*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1394*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find sequence end callback!", __FUNCTION__);
1395*ec779b8eSAndroid Build Coastguard Worker                         return;
1396*ec779b8eSAndroid Build Coastguard Worker                     }
1397*ec779b8eSAndroid Build Coastguard Worker                     if (onSeqAbort == nullptr) {
1398*ec779b8eSAndroid Build Coastguard Worker                         return;
1399*ec779b8eSAndroid Build Coastguard Worker                     }
1400*ec779b8eSAndroid Build Coastguard Worker                     int seqId;
1401*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt32(kSequenceIdKey, &seqId);
1402*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1403*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1404*ec779b8eSAndroid Build Coastguard Worker                         return;
1405*ec779b8eSAndroid Build Coastguard Worker                     }
1406*ec779b8eSAndroid Build Coastguard Worker                     (*onSeqAbort)(context, session.get(), seqId);
1407*ec779b8eSAndroid Build Coastguard Worker                     break;
1408*ec779b8eSAndroid Build Coastguard Worker                 }
1409*ec779b8eSAndroid Build Coastguard Worker                 case kWhatCaptureBufferLost:
1410*ec779b8eSAndroid Build Coastguard Worker                 {
1411*ec779b8eSAndroid Build Coastguard Worker                     ACameraCaptureSession_captureCallback_bufferLost onBufferLost;
1412*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kCallbackFpKey, (void**) &onBufferLost);
1413*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1414*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find buffer lost callback!", __FUNCTION__);
1415*ec779b8eSAndroid Build Coastguard Worker                         return;
1416*ec779b8eSAndroid Build Coastguard Worker                     }
1417*ec779b8eSAndroid Build Coastguard Worker                     if (onBufferLost == nullptr) {
1418*ec779b8eSAndroid Build Coastguard Worker                         return;
1419*ec779b8eSAndroid Build Coastguard Worker                     }
1420*ec779b8eSAndroid Build Coastguard Worker 
1421*ec779b8eSAndroid Build Coastguard Worker                     ANativeWindow* anw;
1422*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findPointer(kAnwKey, (void**) &anw);
1423*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1424*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find ANativeWindow!", __FUNCTION__);
1425*ec779b8eSAndroid Build Coastguard Worker                         return;
1426*ec779b8eSAndroid Build Coastguard Worker                     }
1427*ec779b8eSAndroid Build Coastguard Worker 
1428*ec779b8eSAndroid Build Coastguard Worker                     int64_t frameNumber;
1429*ec779b8eSAndroid Build Coastguard Worker                     found = msg->findInt64(kFrameNumberKey, &frameNumber);
1430*ec779b8eSAndroid Build Coastguard Worker                     if (!found) {
1431*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: Cannot find frame number!", __FUNCTION__);
1432*ec779b8eSAndroid Build Coastguard Worker                         return;
1433*ec779b8eSAndroid Build Coastguard Worker                     }
1434*ec779b8eSAndroid Build Coastguard Worker 
1435*ec779b8eSAndroid Build Coastguard Worker                     ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
1436*ec779b8eSAndroid Build Coastguard Worker                     (*onBufferLost)(context, session.get(), request, anw, frameNumber);
1437*ec779b8eSAndroid Build Coastguard Worker                     freeACaptureRequest(request);
1438*ec779b8eSAndroid Build Coastguard Worker                     break;
1439*ec779b8eSAndroid Build Coastguard Worker                 }
1440*ec779b8eSAndroid Build Coastguard Worker             }
1441*ec779b8eSAndroid Build Coastguard Worker             break;
1442*ec779b8eSAndroid Build Coastguard Worker         }
1443*ec779b8eSAndroid Build Coastguard Worker     }
1444*ec779b8eSAndroid Build Coastguard Worker }
1445*ec779b8eSAndroid Build Coastguard Worker 
CallbackHolder(sp<ACameraCaptureSession> session,const Vector<sp<CaptureRequest>> & requests,bool isRepeating,ACameraCaptureSession_captureCallbacks * cbs)1446*ec779b8eSAndroid Build Coastguard Worker CameraDevice::CallbackHolder::CallbackHolder(
1447*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraCaptureSession>          session,
1448*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<CaptureRequest> >& requests,
1449*ec779b8eSAndroid Build Coastguard Worker         bool                               isRepeating,
1450*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallbacks* cbs) :
1451*ec779b8eSAndroid Build Coastguard Worker         mSession(session), mRequests(requests),
1452*ec779b8eSAndroid Build Coastguard Worker         mIsRepeating(isRepeating),
1453*ec779b8eSAndroid Build Coastguard Worker         mIsLogicalCameraCallback(false),
1454*ec779b8eSAndroid Build Coastguard Worker         mIs2Callback(false) {
1455*ec779b8eSAndroid Build Coastguard Worker     initCaptureCallbacks(cbs);
1456*ec779b8eSAndroid Build Coastguard Worker 
1457*ec779b8eSAndroid Build Coastguard Worker     if (cbs != nullptr) {
1458*ec779b8eSAndroid Build Coastguard Worker         mOnCaptureCompleted = cbs->onCaptureCompleted;
1459*ec779b8eSAndroid Build Coastguard Worker         mOnCaptureFailed = cbs->onCaptureFailed;
1460*ec779b8eSAndroid Build Coastguard Worker     }
1461*ec779b8eSAndroid Build Coastguard Worker }
1462*ec779b8eSAndroid Build Coastguard Worker 
CallbackHolder(sp<ACameraCaptureSession> session,const Vector<sp<CaptureRequest>> & requests,bool isRepeating,ACameraCaptureSession_logicalCamera_captureCallbacks * lcbs)1463*ec779b8eSAndroid Build Coastguard Worker CameraDevice::CallbackHolder::CallbackHolder(
1464*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraCaptureSession>          session,
1465*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<CaptureRequest> >& requests,
1466*ec779b8eSAndroid Build Coastguard Worker         bool                               isRepeating,
1467*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
1468*ec779b8eSAndroid Build Coastguard Worker         mSession(session), mRequests(requests),
1469*ec779b8eSAndroid Build Coastguard Worker         mIsRepeating(isRepeating),
1470*ec779b8eSAndroid Build Coastguard Worker         mIsLogicalCameraCallback(true),
1471*ec779b8eSAndroid Build Coastguard Worker         mIs2Callback(false) {
1472*ec779b8eSAndroid Build Coastguard Worker     initCaptureCallbacks(lcbs);
1473*ec779b8eSAndroid Build Coastguard Worker 
1474*ec779b8eSAndroid Build Coastguard Worker     if (lcbs != nullptr) {
1475*ec779b8eSAndroid Build Coastguard Worker         mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1476*ec779b8eSAndroid Build Coastguard Worker         mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
1477*ec779b8eSAndroid Build Coastguard Worker     }
1478*ec779b8eSAndroid Build Coastguard Worker }
1479*ec779b8eSAndroid Build Coastguard Worker 
CallbackHolder(sp<ACameraCaptureSession> session,const Vector<sp<CaptureRequest>> & requests,bool isRepeating,ACameraCaptureSession_captureCallbacksV2 * cbs)1480*ec779b8eSAndroid Build Coastguard Worker CameraDevice::CallbackHolder::CallbackHolder(
1481*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraCaptureSession>          session,
1482*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<CaptureRequest> >& requests,
1483*ec779b8eSAndroid Build Coastguard Worker         bool                               isRepeating,
1484*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallbacksV2* cbs) :
1485*ec779b8eSAndroid Build Coastguard Worker         mSession(session), mRequests(requests),
1486*ec779b8eSAndroid Build Coastguard Worker         mIsRepeating(isRepeating),
1487*ec779b8eSAndroid Build Coastguard Worker         mIsLogicalCameraCallback(false),
1488*ec779b8eSAndroid Build Coastguard Worker         mIs2Callback(true) {
1489*ec779b8eSAndroid Build Coastguard Worker     initCaptureCallbacksV2(cbs);
1490*ec779b8eSAndroid Build Coastguard Worker 
1491*ec779b8eSAndroid Build Coastguard Worker     if (cbs != nullptr) {
1492*ec779b8eSAndroid Build Coastguard Worker         mOnCaptureCompleted = cbs->onCaptureCompleted;
1493*ec779b8eSAndroid Build Coastguard Worker         mOnCaptureFailed = cbs->onCaptureFailed;
1494*ec779b8eSAndroid Build Coastguard Worker     }
1495*ec779b8eSAndroid Build Coastguard Worker }
1496*ec779b8eSAndroid Build Coastguard Worker 
CallbackHolder(sp<ACameraCaptureSession> session,const Vector<sp<CaptureRequest>> & requests,bool isRepeating,ACameraCaptureSession_logicalCamera_captureCallbacksV2 * lcbs)1497*ec779b8eSAndroid Build Coastguard Worker CameraDevice::CallbackHolder::CallbackHolder(
1498*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraCaptureSession>          session,
1499*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<CaptureRequest> >& requests,
1500*ec779b8eSAndroid Build Coastguard Worker         bool                               isRepeating,
1501*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
1502*ec779b8eSAndroid Build Coastguard Worker         mSession(session), mRequests(requests),
1503*ec779b8eSAndroid Build Coastguard Worker         mIsRepeating(isRepeating),
1504*ec779b8eSAndroid Build Coastguard Worker         mIsLogicalCameraCallback(true),
1505*ec779b8eSAndroid Build Coastguard Worker         mIs2Callback(true) {
1506*ec779b8eSAndroid Build Coastguard Worker     initCaptureCallbacksV2(lcbs);
1507*ec779b8eSAndroid Build Coastguard Worker 
1508*ec779b8eSAndroid Build Coastguard Worker     if (lcbs != nullptr) {
1509*ec779b8eSAndroid Build Coastguard Worker         mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
1510*ec779b8eSAndroid Build Coastguard Worker         mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
1511*ec779b8eSAndroid Build Coastguard Worker     }
1512*ec779b8eSAndroid Build Coastguard Worker }
1513*ec779b8eSAndroid Build Coastguard Worker 
1514*ec779b8eSAndroid Build Coastguard Worker void
checkRepeatingSequenceCompleteLocked(const int sequenceId,const int64_t lastFrameNumber)1515*ec779b8eSAndroid Build Coastguard Worker CameraDevice::checkRepeatingSequenceCompleteLocked(
1516*ec779b8eSAndroid Build Coastguard Worker     const int sequenceId, const int64_t lastFrameNumber) {
1517*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Repeating seqId %d lastFrameNumer %" PRId64, sequenceId, lastFrameNumber);
1518*ec779b8eSAndroid Build Coastguard Worker     if (lastFrameNumber == NO_FRAMES_CAPTURED) {
1519*ec779b8eSAndroid Build Coastguard Worker         if (mSequenceCallbackMap.count(sequenceId) == 0) {
1520*ec779b8eSAndroid Build Coastguard Worker             ALOGW("No callback found for sequenceId %d", sequenceId);
1521*ec779b8eSAndroid Build Coastguard Worker             return;
1522*ec779b8eSAndroid Build Coastguard Worker         }
1523*ec779b8eSAndroid Build Coastguard Worker         // remove callback holder from callback map
1524*ec779b8eSAndroid Build Coastguard Worker         auto cbIt = mSequenceCallbackMap.find(sequenceId);
1525*ec779b8eSAndroid Build Coastguard Worker         CallbackHolder cbh = cbIt->second;
1526*ec779b8eSAndroid Build Coastguard Worker         mSequenceCallbackMap.erase(cbIt);
1527*ec779b8eSAndroid Build Coastguard Worker         // send seq aborted callback
1528*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(kWhatCaptureSeqAbort, mHandler);
1529*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, cbh.mContext);
1530*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, cbh.mSession);
1531*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceAborted);
1532*ec779b8eSAndroid Build Coastguard Worker         msg->setInt32(kSequenceIdKey, sequenceId);
1533*ec779b8eSAndroid Build Coastguard Worker         postSessionMsgAndCleanup(msg);
1534*ec779b8eSAndroid Build Coastguard Worker     } else {
1535*ec779b8eSAndroid Build Coastguard Worker         // Use mSequenceLastFrameNumberMap to track
1536*ec779b8eSAndroid Build Coastguard Worker         mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
1537*ec779b8eSAndroid Build Coastguard Worker 
1538*ec779b8eSAndroid Build Coastguard Worker         // Last frame might have arrived. Check now
1539*ec779b8eSAndroid Build Coastguard Worker         checkAndFireSequenceCompleteLocked();
1540*ec779b8eSAndroid Build Coastguard Worker     }
1541*ec779b8eSAndroid Build Coastguard Worker }
1542*ec779b8eSAndroid Build Coastguard Worker 
1543*ec779b8eSAndroid Build Coastguard Worker void
checkAndFireSequenceCompleteLocked()1544*ec779b8eSAndroid Build Coastguard Worker CameraDevice::checkAndFireSequenceCompleteLocked() {
1545*ec779b8eSAndroid Build Coastguard Worker     int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
1546*ec779b8eSAndroid Build Coastguard Worker     auto it = mSequenceLastFrameNumberMap.begin();
1547*ec779b8eSAndroid Build Coastguard Worker     while (it != mSequenceLastFrameNumberMap.end()) {
1548*ec779b8eSAndroid Build Coastguard Worker         int sequenceId = it->first;
1549*ec779b8eSAndroid Build Coastguard Worker         int64_t lastFrameNumber = it->second.lastFrameNumber;
1550*ec779b8eSAndroid Build Coastguard Worker 
1551*ec779b8eSAndroid Build Coastguard Worker         if (mRemote == nullptr) {
1552*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Camera %s closed while checking sequence complete", getId());
1553*ec779b8eSAndroid Build Coastguard Worker             return;
1554*ec779b8eSAndroid Build Coastguard Worker         }
1555*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
1556*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
1557*ec779b8eSAndroid Build Coastguard Worker         if (!it->second.isSequenceCompleted) {
1558*ec779b8eSAndroid Build Coastguard Worker             // Check if there is callback for this sequence
1559*ec779b8eSAndroid Build Coastguard Worker             // This should not happen because we always register callback (with nullptr inside)
1560*ec779b8eSAndroid Build Coastguard Worker             if (mSequenceCallbackMap.count(sequenceId) == 0) {
1561*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("No callback found for sequenceId %d", sequenceId);
1562*ec779b8eSAndroid Build Coastguard Worker             }
1563*ec779b8eSAndroid Build Coastguard Worker 
1564*ec779b8eSAndroid Build Coastguard Worker             if (lastFrameNumber <= completedFrameNumber) {
1565*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
1566*ec779b8eSAndroid Build Coastguard Worker                 it->second.isSequenceCompleted = true;
1567*ec779b8eSAndroid Build Coastguard Worker             }
1568*ec779b8eSAndroid Build Coastguard Worker 
1569*ec779b8eSAndroid Build Coastguard Worker         }
1570*ec779b8eSAndroid Build Coastguard Worker 
1571*ec779b8eSAndroid Build Coastguard Worker         if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
1572*ec779b8eSAndroid Build Coastguard Worker             sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
1573*ec779b8eSAndroid Build Coastguard Worker 
1574*ec779b8eSAndroid Build Coastguard Worker             it = mSequenceLastFrameNumberMap.erase(it);
1575*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1576*ec779b8eSAndroid Build Coastguard Worker         } else {
1577*ec779b8eSAndroid Build Coastguard Worker             ++it;
1578*ec779b8eSAndroid Build Coastguard Worker         }
1579*ec779b8eSAndroid Build Coastguard Worker     }
1580*ec779b8eSAndroid Build Coastguard Worker }
1581*ec779b8eSAndroid Build Coastguard Worker 
1582*ec779b8eSAndroid Build Coastguard Worker void
removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber)1583*ec779b8eSAndroid Build Coastguard Worker CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
1584*ec779b8eSAndroid Build Coastguard Worker     auto it = mSequenceLastFrameNumberMap.begin();
1585*ec779b8eSAndroid Build Coastguard Worker     while (it != mSequenceLastFrameNumberMap.end()) {
1586*ec779b8eSAndroid Build Coastguard Worker         int sequenceId = it->first;
1587*ec779b8eSAndroid Build Coastguard Worker         int64_t lastFrameNumber = it->second.lastFrameNumber;
1588*ec779b8eSAndroid Build Coastguard Worker 
1589*ec779b8eSAndroid Build Coastguard Worker         if (mRemote == nullptr) {
1590*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Camera %s closed while checking sequence complete", getId());
1591*ec779b8eSAndroid Build Coastguard Worker             return;
1592*ec779b8eSAndroid Build Coastguard Worker         }
1593*ec779b8eSAndroid Build Coastguard Worker 
1594*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s: seq %d's last frame number %" PRId64
1595*ec779b8eSAndroid Build Coastguard Worker                 ", completed inflight frame number %" PRId64,
1596*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, sequenceId, lastFrameNumber,
1597*ec779b8eSAndroid Build Coastguard Worker                 lastCompletedRegularFrameNumber);
1598*ec779b8eSAndroid Build Coastguard Worker         if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
1599*ec779b8eSAndroid Build Coastguard Worker             if (it->second.isSequenceCompleted) {
1600*ec779b8eSAndroid Build Coastguard Worker                 sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
1601*ec779b8eSAndroid Build Coastguard Worker 
1602*ec779b8eSAndroid Build Coastguard Worker                 it = mSequenceLastFrameNumberMap.erase(it);
1603*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
1604*ec779b8eSAndroid Build Coastguard Worker             } else {
1605*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
1606*ec779b8eSAndroid Build Coastguard Worker                 it->second.isInflightCompleted = true;
1607*ec779b8eSAndroid Build Coastguard Worker                 ++it;
1608*ec779b8eSAndroid Build Coastguard Worker             }
1609*ec779b8eSAndroid Build Coastguard Worker         } else {
1610*ec779b8eSAndroid Build Coastguard Worker             ++it;
1611*ec779b8eSAndroid Build Coastguard Worker         }
1612*ec779b8eSAndroid Build Coastguard Worker     }
1613*ec779b8eSAndroid Build Coastguard Worker }
1614*ec779b8eSAndroid Build Coastguard Worker 
1615*ec779b8eSAndroid Build Coastguard Worker /**
1616*ec779b8eSAndroid Build Coastguard Worker   * Camera service callback implementation
1617*ec779b8eSAndroid Build Coastguard Worker   */
1618*ec779b8eSAndroid Build Coastguard Worker binder::Status
onDeviceError(int32_t errorCode,const CaptureResultExtras & resultExtras)1619*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onDeviceError(
1620*ec779b8eSAndroid Build Coastguard Worker         int32_t errorCode,
1621*ec779b8eSAndroid Build Coastguard Worker         const CaptureResultExtras& resultExtras) {
1622*ec779b8eSAndroid Build Coastguard Worker     ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
1623*ec779b8eSAndroid Build Coastguard Worker             errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
1624*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1625*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1626*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1627*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1628*ec779b8eSAndroid Build Coastguard Worker     }
1629*ec779b8eSAndroid Build Coastguard Worker 
1630*ec779b8eSAndroid Build Coastguard Worker     sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
1631*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1632*ec779b8eSAndroid Build Coastguard Worker     if (dev->mRemote == nullptr) {
1633*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1634*ec779b8eSAndroid Build Coastguard Worker     }
1635*ec779b8eSAndroid Build Coastguard Worker     switch (errorCode) {
1636*ec779b8eSAndroid Build Coastguard Worker         case ERROR_CAMERA_DISCONNECTED:
1637*ec779b8eSAndroid Build Coastguard Worker         {
1638*ec779b8eSAndroid Build Coastguard Worker             // Camera is disconnected, close the session and expect no more callbacks
1639*ec779b8eSAndroid Build Coastguard Worker             if (session != nullptr) {
1640*ec779b8eSAndroid Build Coastguard Worker                 session->closeByDevice();
1641*ec779b8eSAndroid Build Coastguard Worker             }
1642*ec779b8eSAndroid Build Coastguard Worker             dev->mCurrentSession = nullptr;
1643*ec779b8eSAndroid Build Coastguard Worker             sp<AMessage> msg = new AMessage(kWhatOnDisconnected, dev->mHandler);
1644*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1645*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
1646*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onDisconnected);
1647*ec779b8eSAndroid Build Coastguard Worker             msg->post();
1648*ec779b8eSAndroid Build Coastguard Worker             break;
1649*ec779b8eSAndroid Build Coastguard Worker         }
1650*ec779b8eSAndroid Build Coastguard Worker         default:
1651*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Unknown error from camera device: %d", errorCode);
1652*ec779b8eSAndroid Build Coastguard Worker             [[fallthrough]];
1653*ec779b8eSAndroid Build Coastguard Worker         case ERROR_CAMERA_DEVICE:
1654*ec779b8eSAndroid Build Coastguard Worker         case ERROR_CAMERA_SERVICE:
1655*ec779b8eSAndroid Build Coastguard Worker         {
1656*ec779b8eSAndroid Build Coastguard Worker             int32_t errorVal = ::ERROR_CAMERA_DEVICE;
1657*ec779b8eSAndroid Build Coastguard Worker             // We keep this switch since this block might be encountered with
1658*ec779b8eSAndroid Build Coastguard Worker             // more than just 2 states. The default fallthrough could have us
1659*ec779b8eSAndroid Build Coastguard Worker             // handling more unmatched error cases.
1660*ec779b8eSAndroid Build Coastguard Worker             switch (errorCode) {
1661*ec779b8eSAndroid Build Coastguard Worker                 case ERROR_CAMERA_DEVICE:
1662*ec779b8eSAndroid Build Coastguard Worker                     dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
1663*ec779b8eSAndroid Build Coastguard Worker                     break;
1664*ec779b8eSAndroid Build Coastguard Worker                 case ERROR_CAMERA_SERVICE:
1665*ec779b8eSAndroid Build Coastguard Worker                     dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1666*ec779b8eSAndroid Build Coastguard Worker                     errorVal = ::ERROR_CAMERA_SERVICE;
1667*ec779b8eSAndroid Build Coastguard Worker                     break;
1668*ec779b8eSAndroid Build Coastguard Worker                 default:
1669*ec779b8eSAndroid Build Coastguard Worker                     dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_UNKNOWN);
1670*ec779b8eSAndroid Build Coastguard Worker                     break;
1671*ec779b8eSAndroid Build Coastguard Worker             }
1672*ec779b8eSAndroid Build Coastguard Worker             sp<AMessage> msg = new AMessage(kWhatOnError, dev->mHandler);
1673*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1674*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
1675*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onError);
1676*ec779b8eSAndroid Build Coastguard Worker             msg->setInt32(kErrorCodeKey, errorVal);
1677*ec779b8eSAndroid Build Coastguard Worker             msg->post();
1678*ec779b8eSAndroid Build Coastguard Worker             break;
1679*ec779b8eSAndroid Build Coastguard Worker         }
1680*ec779b8eSAndroid Build Coastguard Worker         case ERROR_CAMERA_REQUEST:
1681*ec779b8eSAndroid Build Coastguard Worker         case ERROR_CAMERA_RESULT:
1682*ec779b8eSAndroid Build Coastguard Worker         case ERROR_CAMERA_BUFFER:
1683*ec779b8eSAndroid Build Coastguard Worker             dev->onCaptureErrorLocked(errorCode, resultExtras);
1684*ec779b8eSAndroid Build Coastguard Worker             break;
1685*ec779b8eSAndroid Build Coastguard Worker     }
1686*ec779b8eSAndroid Build Coastguard Worker     return ret;
1687*ec779b8eSAndroid Build Coastguard Worker }
1688*ec779b8eSAndroid Build Coastguard Worker 
1689*ec779b8eSAndroid Build Coastguard Worker binder::Status
onClientSharedAccessPriorityChanged(bool primaryClient)1690*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onClientSharedAccessPriorityChanged(bool primaryClient) {
1691*ec779b8eSAndroid Build Coastguard Worker     ALOGV("onClientSharedAccessPriorityChanged received. primaryClient = %d", primaryClient);
1692*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1693*ec779b8eSAndroid Build Coastguard Worker     if (!flags::camera_multi_client()) {
1694*ec779b8eSAndroid Build Coastguard Worker         return ret;
1695*ec779b8eSAndroid Build Coastguard Worker     }
1696*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1697*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1698*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1699*ec779b8eSAndroid Build Coastguard Worker     }
1700*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1701*ec779b8eSAndroid Build Coastguard Worker     if (dev->isClosed() || dev->mRemote == nullptr) {
1702*ec779b8eSAndroid Build Coastguard Worker         return ret;
1703*ec779b8eSAndroid Build Coastguard Worker     }
1704*ec779b8eSAndroid Build Coastguard Worker     dev->setPrimaryClient(primaryClient);
1705*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> msg = new AMessage(kWhatClientSharedAccessPriorityChanged, dev->mHandler);
1706*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kContextKey, dev->mAppCallbacks.context);
1707*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kDeviceKey, (void*) dev->getWrapper());
1708*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kCallbackFpKey, (void*) dev->mAppCallbacks.onClientSharedAccessPriorityChanged);
1709*ec779b8eSAndroid Build Coastguard Worker     msg->post();
1710*ec779b8eSAndroid Build Coastguard Worker 
1711*ec779b8eSAndroid Build Coastguard Worker     return binder::Status::ok();
1712*ec779b8eSAndroid Build Coastguard Worker }
1713*ec779b8eSAndroid Build Coastguard Worker 
1714*ec779b8eSAndroid Build Coastguard Worker binder::Status
onDeviceIdle()1715*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onDeviceIdle() {
1716*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Camera is now idle");
1717*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1718*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1719*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1720*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1721*ec779b8eSAndroid Build Coastguard Worker     }
1722*ec779b8eSAndroid Build Coastguard Worker 
1723*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1724*ec779b8eSAndroid Build Coastguard Worker     if (dev->isClosed() || dev->mRemote == nullptr) {
1725*ec779b8eSAndroid Build Coastguard Worker         return ret;
1726*ec779b8eSAndroid Build Coastguard Worker     }
1727*ec779b8eSAndroid Build Coastguard Worker 
1728*ec779b8eSAndroid Build Coastguard Worker     dev->removeCompletedCallbackHolderLocked(
1729*ec779b8eSAndroid Build Coastguard Worker              std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
1730*ec779b8eSAndroid Build Coastguard Worker 
1731*ec779b8eSAndroid Build Coastguard Worker     if (dev->mIdle) {
1732*ec779b8eSAndroid Build Coastguard Worker         // Already in idle state. Possibly other thread did waitUntilIdle
1733*ec779b8eSAndroid Build Coastguard Worker         return ret;
1734*ec779b8eSAndroid Build Coastguard Worker     }
1735*ec779b8eSAndroid Build Coastguard Worker 
1736*ec779b8eSAndroid Build Coastguard Worker     if (dev->mCurrentSession != nullptr) {
1737*ec779b8eSAndroid Build Coastguard Worker         ALOGE("onDeviceIdle sending state cb");
1738*ec779b8eSAndroid Build Coastguard Worker         if (dev->mBusySession != dev->mCurrentSession) {
1739*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Current session != busy session");
1740*ec779b8eSAndroid Build Coastguard Worker             dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
1741*ec779b8eSAndroid Build Coastguard Worker             return ret;
1742*ec779b8eSAndroid Build Coastguard Worker         }
1743*ec779b8eSAndroid Build Coastguard Worker 
1744*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(kWhatSessionStateCb, dev->mHandler);
1745*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, dev->mBusySession->mUserSessionCallback.context);
1746*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, dev->mBusySession);
1747*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kCallbackFpKey, (void*) dev->mBusySession->mUserSessionCallback.onReady);
1748*ec779b8eSAndroid Build Coastguard Worker         // Make sure we clear the sp first so the session destructor can
1749*ec779b8eSAndroid Build Coastguard Worker         // only happen on handler thread (where we don't hold device/session lock)
1750*ec779b8eSAndroid Build Coastguard Worker         dev->mBusySession.clear();
1751*ec779b8eSAndroid Build Coastguard Worker         dev->postSessionMsgAndCleanup(msg);
1752*ec779b8eSAndroid Build Coastguard Worker     }
1753*ec779b8eSAndroid Build Coastguard Worker     dev->mIdle = true;
1754*ec779b8eSAndroid Build Coastguard Worker     dev->mFlushing = false;
1755*ec779b8eSAndroid Build Coastguard Worker     return ret;
1756*ec779b8eSAndroid Build Coastguard Worker }
1757*ec779b8eSAndroid Build Coastguard Worker 
1758*ec779b8eSAndroid Build Coastguard Worker binder::Status
onCaptureStarted(const CaptureResultExtras & resultExtras,int64_t timestamp)1759*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onCaptureStarted(
1760*ec779b8eSAndroid Build Coastguard Worker         const CaptureResultExtras& resultExtras,
1761*ec779b8eSAndroid Build Coastguard Worker         int64_t timestamp) {
1762*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1763*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1764*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1765*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1766*ec779b8eSAndroid Build Coastguard Worker     }
1767*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1768*ec779b8eSAndroid Build Coastguard Worker     if (dev->isClosed() || dev->mRemote == nullptr) {
1769*ec779b8eSAndroid Build Coastguard Worker         return ret;
1770*ec779b8eSAndroid Build Coastguard Worker     }
1771*ec779b8eSAndroid Build Coastguard Worker 
1772*ec779b8eSAndroid Build Coastguard Worker     dev->removeCompletedCallbackHolderLocked(
1773*ec779b8eSAndroid Build Coastguard Worker             resultExtras.lastCompletedRegularFrameNumber);
1774*ec779b8eSAndroid Build Coastguard Worker 
1775*ec779b8eSAndroid Build Coastguard Worker     int sequenceId = resultExtras.requestId;
1776*ec779b8eSAndroid Build Coastguard Worker     int32_t burstId = resultExtras.burstId;
1777*ec779b8eSAndroid Build Coastguard Worker     int64_t frameNumber = resultExtras.frameNumber;
1778*ec779b8eSAndroid Build Coastguard Worker 
1779*ec779b8eSAndroid Build Coastguard Worker     auto it = dev->mSequenceCallbackMap.find(sequenceId);
1780*ec779b8eSAndroid Build Coastguard Worker     if (it != dev->mSequenceCallbackMap.end()) {
1781*ec779b8eSAndroid Build Coastguard Worker         CallbackHolder cbh = (*it).second;
1782*ec779b8eSAndroid Build Coastguard Worker         bool v2Callback = cbh.mIs2Callback;
1783*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
1784*ec779b8eSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
1785*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraCaptureSession> session = cbh.mSession;
1786*ec779b8eSAndroid Build Coastguard Worker         if ((size_t) burstId >= cbh.mRequests.size()) {
1787*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: Error: request index %d out of bound (size %zu)",
1788*ec779b8eSAndroid Build Coastguard Worker                     __FUNCTION__, burstId, cbh.mRequests.size());
1789*ec779b8eSAndroid Build Coastguard Worker             dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1790*ec779b8eSAndroid Build Coastguard Worker         }
1791*ec779b8eSAndroid Build Coastguard Worker         sp<CaptureRequest> request = cbh.mRequests[burstId];
1792*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = nullptr;
1793*ec779b8eSAndroid Build Coastguard Worker         if (v2Callback) {
1794*ec779b8eSAndroid Build Coastguard Worker             msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
1795*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey, (void*) onStart2);
1796*ec779b8eSAndroid Build Coastguard Worker         } else {
1797*ec779b8eSAndroid Build Coastguard Worker             msg = new AMessage(kWhatCaptureStart, dev->mHandler);
1798*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey, (void *)onStart);
1799*ec779b8eSAndroid Build Coastguard Worker         }
1800*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, cbh.mContext);
1801*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, session);
1802*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kCaptureRequestKey, request);
1803*ec779b8eSAndroid Build Coastguard Worker         msg->setInt64(kTimeStampKey, timestamp);
1804*ec779b8eSAndroid Build Coastguard Worker         msg->setInt64(kFrameNumberKey, frameNumber);
1805*ec779b8eSAndroid Build Coastguard Worker         dev->postSessionMsgAndCleanup(msg);
1806*ec779b8eSAndroid Build Coastguard Worker     }
1807*ec779b8eSAndroid Build Coastguard Worker     return ret;
1808*ec779b8eSAndroid Build Coastguard Worker }
1809*ec779b8eSAndroid Build Coastguard Worker 
1810*ec779b8eSAndroid Build Coastguard Worker binder::Status
onResultReceived(const CameraMetadataInfo & resultMetadata,const CaptureResultExtras & resultExtras,const std::vector<PhysicalCaptureResultInfo> & physicalResultInfos)1811*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onResultReceived(
1812*ec779b8eSAndroid Build Coastguard Worker         const CameraMetadataInfo &resultMetadata,
1813*ec779b8eSAndroid Build Coastguard Worker         const CaptureResultExtras& resultExtras,
1814*ec779b8eSAndroid Build Coastguard Worker         const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
1815*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1816*ec779b8eSAndroid Build Coastguard Worker 
1817*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1818*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1819*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1820*ec779b8eSAndroid Build Coastguard Worker     }
1821*ec779b8eSAndroid Build Coastguard Worker 
1822*ec779b8eSAndroid Build Coastguard Worker     int sequenceId = resultExtras.requestId;
1823*ec779b8eSAndroid Build Coastguard Worker     int64_t frameNumber = resultExtras.frameNumber;
1824*ec779b8eSAndroid Build Coastguard Worker     int32_t burstId = resultExtras.burstId;
1825*ec779b8eSAndroid Build Coastguard Worker     bool    isPartialResult = (resultExtras.partialResultCount < dev->mPartialResultCount);
1826*ec779b8eSAndroid Build Coastguard Worker     if (!isPartialResult) {
1827*ec779b8eSAndroid Build Coastguard Worker         ALOGV("SeqId %d frame %" PRId64 " result arrive.", sequenceId, frameNumber);
1828*ec779b8eSAndroid Build Coastguard Worker     }
1829*ec779b8eSAndroid Build Coastguard Worker 
1830*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1831*ec779b8eSAndroid Build Coastguard Worker     if (dev->mRemote == nullptr) {
1832*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been disconnected
1833*ec779b8eSAndroid Build Coastguard Worker     }
1834*ec779b8eSAndroid Build Coastguard Worker 
1835*ec779b8eSAndroid Build Coastguard Worker     if (dev->isClosed()) {
1836*ec779b8eSAndroid Build Coastguard Worker         if (!isPartialResult) {
1837*ec779b8eSAndroid Build Coastguard Worker             dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1838*ec779b8eSAndroid Build Coastguard Worker         }
1839*ec779b8eSAndroid Build Coastguard Worker         // early return to avoid callback sent to closed devices
1840*ec779b8eSAndroid Build Coastguard Worker         return ret;
1841*ec779b8eSAndroid Build Coastguard Worker     }
1842*ec779b8eSAndroid Build Coastguard Worker 
1843*ec779b8eSAndroid Build Coastguard Worker     CameraMetadata metadataCopy;
1844*ec779b8eSAndroid Build Coastguard Worker     camera_status_t status = readOneResultMetadata(resultMetadata,
1845*ec779b8eSAndroid Build Coastguard Worker             dev->mCaptureResultMetadataQueue.get(), &metadataCopy);
1846*ec779b8eSAndroid Build Coastguard Worker     if (status != ACAMERA_OK) {
1847*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: result metadata couldn't be converted", __FUNCTION__);
1848*ec779b8eSAndroid Build Coastguard Worker         return ret;
1849*ec779b8eSAndroid Build Coastguard Worker     }
1850*ec779b8eSAndroid Build Coastguard Worker     metadataCopy.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, dev->mShadingMapSize, /*data_count*/2);
1851*ec779b8eSAndroid Build Coastguard Worker     metadataCopy.update(ANDROID_SYNC_FRAME_NUMBER, &frameNumber, /*data_count*/1);
1852*ec779b8eSAndroid Build Coastguard Worker 
1853*ec779b8eSAndroid Build Coastguard Worker     auto it = dev->mSequenceCallbackMap.find(sequenceId);
1854*ec779b8eSAndroid Build Coastguard Worker     if (it != dev->mSequenceCallbackMap.end()) {
1855*ec779b8eSAndroid Build Coastguard Worker         CallbackHolder cbh = (*it).second;
1856*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraCaptureSession> session = cbh.mSession;
1857*ec779b8eSAndroid Build Coastguard Worker         if ((size_t) burstId >= cbh.mRequests.size()) {
1858*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: Error: request index %d out of bound (size %zu)",
1859*ec779b8eSAndroid Build Coastguard Worker                     __FUNCTION__, burstId, cbh.mRequests.size());
1860*ec779b8eSAndroid Build Coastguard Worker             dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
1861*ec779b8eSAndroid Build Coastguard Worker         }
1862*ec779b8eSAndroid Build Coastguard Worker         sp<CaptureRequest> request = cbh.mRequests[burstId];
1863*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraMetadata> result(new ACameraMetadata(
1864*ec779b8eSAndroid Build Coastguard Worker                 metadataCopy.release(), ACameraMetadata::ACM_RESULT));
1865*ec779b8eSAndroid Build Coastguard Worker 
1866*ec779b8eSAndroid Build Coastguard Worker         std::vector<PhysicalCaptureResultInfo> localPhysicalResult;
1867*ec779b8eSAndroid Build Coastguard Worker         localPhysicalResult.resize(physicalResultInfos.size());
1868*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < physicalResultInfos.size(); i++) {
1869*ec779b8eSAndroid Build Coastguard Worker             CameraMetadata physicalMetadata;
1870*ec779b8eSAndroid Build Coastguard Worker             localPhysicalResult[i].mPhysicalCameraId = physicalResultInfos[i].mPhysicalCameraId;
1871*ec779b8eSAndroid Build Coastguard Worker             status = readOneResultMetadata(physicalResultInfos[i].mCameraMetadataInfo,
1872*ec779b8eSAndroid Build Coastguard Worker                     dev->mCaptureResultMetadataQueue.get(),
1873*ec779b8eSAndroid Build Coastguard Worker                     &physicalMetadata);
1874*ec779b8eSAndroid Build Coastguard Worker             if (status != ACAMERA_OK) {
1875*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: physical camera result metadata couldn't be converted", __FUNCTION__);
1876*ec779b8eSAndroid Build Coastguard Worker                 return ret;
1877*ec779b8eSAndroid Build Coastguard Worker             }
1878*ec779b8eSAndroid Build Coastguard Worker             localPhysicalResult[i].mCameraMetadataInfo.set<CameraMetadataInfo::metadata>(
1879*ec779b8eSAndroid Build Coastguard Worker                     std::move(physicalMetadata));
1880*ec779b8eSAndroid Build Coastguard Worker         }
1881*ec779b8eSAndroid Build Coastguard Worker         sp<ACameraPhysicalCaptureResultInfo> physicalResult(
1882*ec779b8eSAndroid Build Coastguard Worker                 new ACameraPhysicalCaptureResultInfo(localPhysicalResult, frameNumber));
1883*ec779b8eSAndroid Build Coastguard Worker 
1884*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(
1885*ec779b8eSAndroid Build Coastguard Worker                 cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureResult : kWhatCaptureResult,
1886*ec779b8eSAndroid Build Coastguard Worker                 dev->mHandler);
1887*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, cbh.mContext);
1888*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, session);
1889*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kCaptureRequestKey, request);
1890*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kCaptureResultKey, result);
1891*ec779b8eSAndroid Build Coastguard Worker         if (isPartialResult) {
1892*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey,
1893*ec779b8eSAndroid Build Coastguard Worker                     (void *)cbh.mOnCaptureProgressed);
1894*ec779b8eSAndroid Build Coastguard Worker         } else if (cbh.mIsLogicalCameraCallback) {
1895*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey,
1896*ec779b8eSAndroid Build Coastguard Worker                     (void *)cbh.mOnLogicalCameraCaptureCompleted);
1897*ec779b8eSAndroid Build Coastguard Worker             msg->setObject(kPhysicalCaptureResultKey, physicalResult);
1898*ec779b8eSAndroid Build Coastguard Worker         } else {
1899*ec779b8eSAndroid Build Coastguard Worker             msg->setPointer(kCallbackFpKey,
1900*ec779b8eSAndroid Build Coastguard Worker                     (void *)cbh.mOnCaptureCompleted);
1901*ec779b8eSAndroid Build Coastguard Worker         }
1902*ec779b8eSAndroid Build Coastguard Worker         dev->postSessionMsgAndCleanup(msg);
1903*ec779b8eSAndroid Build Coastguard Worker     }
1904*ec779b8eSAndroid Build Coastguard Worker 
1905*ec779b8eSAndroid Build Coastguard Worker     if (!isPartialResult) {
1906*ec779b8eSAndroid Build Coastguard Worker         dev->mFrameNumberTracker.updateTracker(frameNumber, /*isError*/false);
1907*ec779b8eSAndroid Build Coastguard Worker         dev->checkAndFireSequenceCompleteLocked();
1908*ec779b8eSAndroid Build Coastguard Worker     }
1909*ec779b8eSAndroid Build Coastguard Worker 
1910*ec779b8eSAndroid Build Coastguard Worker     return ret;
1911*ec779b8eSAndroid Build Coastguard Worker }
1912*ec779b8eSAndroid Build Coastguard Worker 
1913*ec779b8eSAndroid Build Coastguard Worker binder::Status
onPrepared(int streamId)1914*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onPrepared(int streamId) {
1915*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: callback for stream id %d", __FUNCTION__, streamId);
1916*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1917*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1918*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1919*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1920*ec779b8eSAndroid Build Coastguard Worker     }
1921*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1922*ec779b8eSAndroid Build Coastguard Worker     if (dev->isClosed() || dev->mRemote == nullptr) {
1923*ec779b8eSAndroid Build Coastguard Worker         return ret;
1924*ec779b8eSAndroid Build Coastguard Worker     }
1925*ec779b8eSAndroid Build Coastguard Worker     auto it = dev->mConfiguredOutputs.find(streamId);
1926*ec779b8eSAndroid Build Coastguard Worker     if (it == dev->mConfiguredOutputs.end()) {
1927*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: stream id %d does not exist", __FUNCTION__ , streamId);
1928*ec779b8eSAndroid Build Coastguard Worker         return ret;
1929*ec779b8eSAndroid Build Coastguard Worker     }
1930*ec779b8eSAndroid Build Coastguard Worker     sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
1931*ec779b8eSAndroid Build Coastguard Worker     if (session == nullptr) {
1932*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Session is dead already", __FUNCTION__ );
1933*ec779b8eSAndroid Build Coastguard Worker         return ret;
1934*ec779b8eSAndroid Build Coastguard Worker     }
1935*ec779b8eSAndroid Build Coastguard Worker     // We've found the window corresponding to the surface id.
1936*ec779b8eSAndroid Build Coastguard Worker     ANativeWindow *window = it->second.first;
1937*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> msg = new AMessage(kWhatPreparedCb, dev->mHandler);
1938*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kContextKey, session->mPreparedCb.context);
1939*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kAnwKey, window);
1940*ec779b8eSAndroid Build Coastguard Worker     msg->setObject(kSessionSpKey, session);
1941*ec779b8eSAndroid Build Coastguard Worker     msg->setPointer(kCallbackFpKey, (void *)session->mPreparedCb.onWindowPrepared);
1942*ec779b8eSAndroid Build Coastguard Worker     dev->postSessionMsgAndCleanup(msg);
1943*ec779b8eSAndroid Build Coastguard Worker 
1944*ec779b8eSAndroid Build Coastguard Worker     return binder::Status::ok();
1945*ec779b8eSAndroid Build Coastguard Worker }
1946*ec779b8eSAndroid Build Coastguard Worker 
1947*ec779b8eSAndroid Build Coastguard Worker binder::Status
onRequestQueueEmpty()1948*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onRequestQueueEmpty() {
1949*ec779b8eSAndroid Build Coastguard Worker     // onRequestQueueEmpty not yet implemented in NDK
1950*ec779b8eSAndroid Build Coastguard Worker     return binder::Status::ok();
1951*ec779b8eSAndroid Build Coastguard Worker }
1952*ec779b8eSAndroid Build Coastguard Worker 
1953*ec779b8eSAndroid Build Coastguard Worker binder::Status
onRepeatingRequestError(int64_t lastFrameNumber,int32_t stoppedSequenceId)1954*ec779b8eSAndroid Build Coastguard Worker CameraDevice::ServiceCallback::onRepeatingRequestError(
1955*ec779b8eSAndroid Build Coastguard Worker         int64_t lastFrameNumber, int32_t stoppedSequenceId) {
1956*ec779b8eSAndroid Build Coastguard Worker     binder::Status ret = binder::Status::ok();
1957*ec779b8eSAndroid Build Coastguard Worker 
1958*ec779b8eSAndroid Build Coastguard Worker     sp<CameraDevice> dev = mDevice.promote();
1959*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
1960*ec779b8eSAndroid Build Coastguard Worker         return ret; // device has been closed
1961*ec779b8eSAndroid Build Coastguard Worker     }
1962*ec779b8eSAndroid Build Coastguard Worker 
1963*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(dev->mDeviceLock);
1964*ec779b8eSAndroid Build Coastguard Worker 
1965*ec779b8eSAndroid Build Coastguard Worker     int repeatingSequenceId = dev->mRepeatingSequenceId;
1966*ec779b8eSAndroid Build Coastguard Worker     if (stoppedSequenceId == repeatingSequenceId) {
1967*ec779b8eSAndroid Build Coastguard Worker         dev->mRepeatingSequenceId = REQUEST_ID_NONE;
1968*ec779b8eSAndroid Build Coastguard Worker     }
1969*ec779b8eSAndroid Build Coastguard Worker 
1970*ec779b8eSAndroid Build Coastguard Worker     dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
1971*ec779b8eSAndroid Build Coastguard Worker 
1972*ec779b8eSAndroid Build Coastguard Worker     return ret;
1973*ec779b8eSAndroid Build Coastguard Worker }
1974*ec779b8eSAndroid Build Coastguard Worker 
1975*ec779b8eSAndroid Build Coastguard Worker void
sendCaptureSequenceCompletedLocked(int sequenceId,int64_t lastFrameNumber)1976*ec779b8eSAndroid Build Coastguard Worker CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
1977*ec779b8eSAndroid Build Coastguard Worker     auto cbIt = mSequenceCallbackMap.find(sequenceId);
1978*ec779b8eSAndroid Build Coastguard Worker     if (cbIt != mSequenceCallbackMap.end()) {
1979*ec779b8eSAndroid Build Coastguard Worker         CallbackHolder cbh = cbIt->second;
1980*ec779b8eSAndroid Build Coastguard Worker         mSequenceCallbackMap.erase(cbIt);
1981*ec779b8eSAndroid Build Coastguard Worker 
1982*ec779b8eSAndroid Build Coastguard Worker         // send seq complete callback
1983*ec779b8eSAndroid Build Coastguard Worker         sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
1984*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kContextKey, cbh.mContext);
1985*ec779b8eSAndroid Build Coastguard Worker         msg->setObject(kSessionSpKey, cbh.mSession);
1986*ec779b8eSAndroid Build Coastguard Worker         msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
1987*ec779b8eSAndroid Build Coastguard Worker         msg->setInt32(kSequenceIdKey, sequenceId);
1988*ec779b8eSAndroid Build Coastguard Worker         msg->setInt64(kFrameNumberKey, lastFrameNumber);
1989*ec779b8eSAndroid Build Coastguard Worker 
1990*ec779b8eSAndroid Build Coastguard Worker         // Clear the session sp before we send out the message
1991*ec779b8eSAndroid Build Coastguard Worker         // This will guarantee the rare case where the message is processed
1992*ec779b8eSAndroid Build Coastguard Worker         // before cbh goes out of scope and causing we call the session
1993*ec779b8eSAndroid Build Coastguard Worker         // destructor while holding device lock
1994*ec779b8eSAndroid Build Coastguard Worker         cbh.mSession.clear();
1995*ec779b8eSAndroid Build Coastguard Worker         postSessionMsgAndCleanup(msg);
1996*ec779b8eSAndroid Build Coastguard Worker     } else {
1997*ec779b8eSAndroid Build Coastguard Worker         // Check if there is callback for this sequence
1998*ec779b8eSAndroid Build Coastguard Worker         // This should not happen because we always register callback (with nullptr inside)
1999*ec779b8eSAndroid Build Coastguard Worker         ALOGW("No callback found for sequenceId %d", sequenceId);
2000*ec779b8eSAndroid Build Coastguard Worker     }
2001*ec779b8eSAndroid Build Coastguard Worker }
2002*ec779b8eSAndroid Build Coastguard Worker 
readOneResultMetadata(const CameraMetadataInfo & resultInfo,ResultMetadataQueue * metadataQueue,CameraMetadata * metadata)2003*ec779b8eSAndroid Build Coastguard Worker camera_status_t CameraDevice::ServiceCallback::readOneResultMetadata(
2004*ec779b8eSAndroid Build Coastguard Worker         const CameraMetadataInfo& resultInfo, ResultMetadataQueue* metadataQueue,
2005*ec779b8eSAndroid Build Coastguard Worker         CameraMetadata* metadata) {
2006*ec779b8eSAndroid Build Coastguard Worker     if (metadataQueue == nullptr || metadata == nullptr) {
2007*ec779b8eSAndroid Build Coastguard Worker         return ACAMERA_ERROR_INVALID_PARAMETER;
2008*ec779b8eSAndroid Build Coastguard Worker     }
2009*ec779b8eSAndroid Build Coastguard Worker     if (resultInfo.getTag() == CameraMetadataInfo::fmqSize) {
2010*ec779b8eSAndroid Build Coastguard Worker         int64_t metadataSize = resultInfo.get<CameraMetadataInfo::fmqSize>();
2011*ec779b8eSAndroid Build Coastguard Worker         auto metadataVec = std::make_unique<int8_t []>(metadataSize);
2012*ec779b8eSAndroid Build Coastguard Worker         bool read = metadataQueue->read(reinterpret_cast<int8_t*>(metadataVec.get()), metadataSize);
2013*ec779b8eSAndroid Build Coastguard Worker         if (!read) {
2014*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s capture request settings could't be read from fmq", __FUNCTION__);
2015*ec779b8eSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
2016*ec779b8eSAndroid Build Coastguard Worker         }
2017*ec779b8eSAndroid Build Coastguard Worker         *metadata = CameraMetadata(reinterpret_cast<camera_metadata_t *>(metadataVec.release()));
2018*ec779b8eSAndroid Build Coastguard Worker     } else {
2019*ec779b8eSAndroid Build Coastguard Worker         *metadata =
2020*ec779b8eSAndroid Build Coastguard Worker                 resultInfo.get<CameraMetadataInfo::metadata>();
2021*ec779b8eSAndroid Build Coastguard Worker     }
2022*ec779b8eSAndroid Build Coastguard Worker 
2023*ec779b8eSAndroid Build Coastguard Worker     return ACAMERA_OK;
2024*ec779b8eSAndroid Build Coastguard Worker }
2025*ec779b8eSAndroid Build Coastguard Worker 
2026*ec779b8eSAndroid Build Coastguard Worker } // namespace acam
2027*ec779b8eSAndroid Build Coastguard Worker } // namespace android
2028