xref: /aosp_15_r20/cts/tests/camera/libctscamera2jni/native-camera-jni.cpp (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker  *
4*b7c941bbSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*b7c941bbSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*b7c941bbSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*b7c941bbSAndroid Build Coastguard Worker  *
8*b7c941bbSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*b7c941bbSAndroid Build Coastguard Worker  *
10*b7c941bbSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*b7c941bbSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*b7c941bbSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7c941bbSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*b7c941bbSAndroid Build Coastguard Worker  * limitations under the License.
15*b7c941bbSAndroid Build Coastguard Worker  */
16*b7c941bbSAndroid Build Coastguard Worker 
17*b7c941bbSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*b7c941bbSAndroid Build Coastguard Worker #define LOG_TAG "NativeCamera"
19*b7c941bbSAndroid Build Coastguard Worker #include <log/log.h>
20*b7c941bbSAndroid Build Coastguard Worker 
21*b7c941bbSAndroid Build Coastguard Worker #include <chrono>
22*b7c941bbSAndroid Build Coastguard Worker #include <cinttypes>
23*b7c941bbSAndroid Build Coastguard Worker #include <condition_variable>
24*b7c941bbSAndroid Build Coastguard Worker #include <map>
25*b7c941bbSAndroid Build Coastguard Worker #include <mutex>
26*b7c941bbSAndroid Build Coastguard Worker #include <string>
27*b7c941bbSAndroid Build Coastguard Worker #include <vector>
28*b7c941bbSAndroid Build Coastguard Worker #include <unistd.h>
29*b7c941bbSAndroid Build Coastguard Worker #include <assert.h>
30*b7c941bbSAndroid Build Coastguard Worker #include <jni.h>
31*b7c941bbSAndroid Build Coastguard Worker #include <stdio.h>
32*b7c941bbSAndroid Build Coastguard Worker #include <string.h>
33*b7c941bbSAndroid Build Coastguard Worker #include <unordered_map>
34*b7c941bbSAndroid Build Coastguard Worker #include <set>
35*b7c941bbSAndroid Build Coastguard Worker 
36*b7c941bbSAndroid Build Coastguard Worker #include <android/native_window_jni.h>
37*b7c941bbSAndroid Build Coastguard Worker 
38*b7c941bbSAndroid Build Coastguard Worker #include "camera/NdkCameraError.h"
39*b7c941bbSAndroid Build Coastguard Worker #include "camera/NdkCameraManager.h"
40*b7c941bbSAndroid Build Coastguard Worker #include "camera/NdkCameraMetadata.h"
41*b7c941bbSAndroid Build Coastguard Worker #include "camera/NdkCameraDevice.h"
42*b7c941bbSAndroid Build Coastguard Worker #include "camera/NdkCameraCaptureSession.h"
43*b7c941bbSAndroid Build Coastguard Worker #include "media/NdkImage.h"
44*b7c941bbSAndroid Build Coastguard Worker #include "media/NdkImageReader.h"
45*b7c941bbSAndroid Build Coastguard Worker 
46*b7c941bbSAndroid Build Coastguard Worker #include "NdkNameToTag.h"
47*b7c941bbSAndroid Build Coastguard Worker 
48*b7c941bbSAndroid Build Coastguard Worker #define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
49*b7c941bbSAndroid Build Coastguard Worker                             ALOGE("%s", buf);
50*b7c941bbSAndroid Build Coastguard Worker 
51*b7c941bbSAndroid Build Coastguard Worker namespace {
52*b7c941bbSAndroid Build Coastguard Worker     const int MAX_ERROR_STRING_LEN = 512;
53*b7c941bbSAndroid Build Coastguard Worker     char errorString[MAX_ERROR_STRING_LEN];
54*b7c941bbSAndroid Build Coastguard Worker }
55*b7c941bbSAndroid Build Coastguard Worker 
56*b7c941bbSAndroid Build Coastguard Worker template <>
57*b7c941bbSAndroid Build Coastguard Worker struct std::default_delete<ACameraMetadata> {
operator ()std::default_delete58*b7c941bbSAndroid Build Coastguard Worker     inline void operator()(ACameraMetadata* chars) const { ACameraMetadata_free(chars); }
59*b7c941bbSAndroid Build Coastguard Worker };
60*b7c941bbSAndroid Build Coastguard Worker 
61*b7c941bbSAndroid Build Coastguard Worker class CameraServiceListener {
62*b7c941bbSAndroid Build Coastguard Worker   public:
63*b7c941bbSAndroid Build Coastguard Worker     typedef std::set<std::pair<std::string, std::string>> StringPairSet;
64*b7c941bbSAndroid Build Coastguard Worker 
onAvailable(void * obj,const char * cameraId)65*b7c941bbSAndroid Build Coastguard Worker     static void onAvailable(void* obj, const char* cameraId) {
66*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Camera %s onAvailable", cameraId);
67*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
68*b7c941bbSAndroid Build Coastguard Worker             return;
69*b7c941bbSAndroid Build Coastguard Worker         }
70*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
71*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
72*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnAvailableCount++;
73*b7c941bbSAndroid Build Coastguard Worker         thiz->mAvailableMap[cameraId] = true;
74*b7c941bbSAndroid Build Coastguard Worker         return;
75*b7c941bbSAndroid Build Coastguard Worker     }
76*b7c941bbSAndroid Build Coastguard Worker 
onUnavailable(void * obj,const char * cameraId)77*b7c941bbSAndroid Build Coastguard Worker     static void onUnavailable(void* obj, const char* cameraId) {
78*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Camera %s onUnavailable", cameraId);
79*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
80*b7c941bbSAndroid Build Coastguard Worker             return;
81*b7c941bbSAndroid Build Coastguard Worker         }
82*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
83*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
84*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnUnavailableCount++;
85*b7c941bbSAndroid Build Coastguard Worker         thiz->mAvailableMap[cameraId] = false;
86*b7c941bbSAndroid Build Coastguard Worker         return;
87*b7c941bbSAndroid Build Coastguard Worker     }
88*b7c941bbSAndroid Build Coastguard Worker 
89*b7c941bbSAndroid Build Coastguard Worker 
onCameraAccessPrioritiesChanged(void * obj)90*b7c941bbSAndroid Build Coastguard Worker     static void onCameraAccessPrioritiesChanged(void* obj) {
91*b7c941bbSAndroid Build Coastguard Worker         ALOGV("onCameraAccessPrioritiesChanged");
92*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
93*b7c941bbSAndroid Build Coastguard Worker             return;
94*b7c941bbSAndroid Build Coastguard Worker         }
95*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
96*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
97*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnCameraAccessPrioritiesChangedCount++;
98*b7c941bbSAndroid Build Coastguard Worker         return;
99*b7c941bbSAndroid Build Coastguard Worker     }
100*b7c941bbSAndroid Build Coastguard Worker 
onPhysicalCameraAvailable(void * obj,const char * cameraId,const char * physicalCameraId)101*b7c941bbSAndroid Build Coastguard Worker     static void onPhysicalCameraAvailable(void* obj, const char* cameraId,
102*b7c941bbSAndroid Build Coastguard Worker             const char* physicalCameraId) {
103*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Camera %s : %s onAvailable", cameraId, physicalCameraId);
104*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
105*b7c941bbSAndroid Build Coastguard Worker             return;
106*b7c941bbSAndroid Build Coastguard Worker         }
107*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
108*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
109*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnPhysicalCameraAvailableCount++;
110*b7c941bbSAndroid Build Coastguard Worker         return;
111*b7c941bbSAndroid Build Coastguard Worker     }
112*b7c941bbSAndroid Build Coastguard Worker 
onPhysicalCameraUnavailable(void * obj,const char * cameraId,const char * physicalCameraId)113*b7c941bbSAndroid Build Coastguard Worker     static void onPhysicalCameraUnavailable(void* obj, const char* cameraId,
114*b7c941bbSAndroid Build Coastguard Worker             const char* physicalCameraId) {
115*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Camera %s : %s onUnavailable", cameraId, physicalCameraId);
116*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
117*b7c941bbSAndroid Build Coastguard Worker             return;
118*b7c941bbSAndroid Build Coastguard Worker         }
119*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
120*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
121*b7c941bbSAndroid Build Coastguard Worker         thiz->mUnavailablePhysicalCameras.emplace(cameraId, physicalCameraId);
122*b7c941bbSAndroid Build Coastguard Worker         return;
123*b7c941bbSAndroid Build Coastguard Worker     }
124*b7c941bbSAndroid Build Coastguard Worker 
125*b7c941bbSAndroid Build Coastguard Worker 
resetCount()126*b7c941bbSAndroid Build Coastguard Worker     void resetCount() {
127*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
128*b7c941bbSAndroid Build Coastguard Worker         mOnAvailableCount = 0;
129*b7c941bbSAndroid Build Coastguard Worker         mOnUnavailableCount = 0;
130*b7c941bbSAndroid Build Coastguard Worker         mOnCameraAccessPrioritiesChangedCount = 0;
131*b7c941bbSAndroid Build Coastguard Worker         mOnPhysicalCameraAvailableCount = 0;
132*b7c941bbSAndroid Build Coastguard Worker         mUnavailablePhysicalCameras.clear();
133*b7c941bbSAndroid Build Coastguard Worker         return;
134*b7c941bbSAndroid Build Coastguard Worker     }
135*b7c941bbSAndroid Build Coastguard Worker 
getAvailableCount()136*b7c941bbSAndroid Build Coastguard Worker     int getAvailableCount() {
137*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
138*b7c941bbSAndroid Build Coastguard Worker         return mOnAvailableCount;
139*b7c941bbSAndroid Build Coastguard Worker     }
140*b7c941bbSAndroid Build Coastguard Worker 
getUnavailableCount()141*b7c941bbSAndroid Build Coastguard Worker     int getUnavailableCount() {
142*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
143*b7c941bbSAndroid Build Coastguard Worker         return mOnUnavailableCount;
144*b7c941bbSAndroid Build Coastguard Worker     }
145*b7c941bbSAndroid Build Coastguard Worker 
getCameraAccessPrioritiesChangedCount()146*b7c941bbSAndroid Build Coastguard Worker     int getCameraAccessPrioritiesChangedCount() {
147*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
148*b7c941bbSAndroid Build Coastguard Worker         return mOnCameraAccessPrioritiesChangedCount;
149*b7c941bbSAndroid Build Coastguard Worker     }
150*b7c941bbSAndroid Build Coastguard Worker 
getPhysicalCameraAvailableCount()151*b7c941bbSAndroid Build Coastguard Worker     int getPhysicalCameraAvailableCount() {
152*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
153*b7c941bbSAndroid Build Coastguard Worker         return mOnPhysicalCameraAvailableCount;
154*b7c941bbSAndroid Build Coastguard Worker     }
155*b7c941bbSAndroid Build Coastguard Worker 
getUnavailablePhysicalCameras()156*b7c941bbSAndroid Build Coastguard Worker     StringPairSet getUnavailablePhysicalCameras() {
157*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
158*b7c941bbSAndroid Build Coastguard Worker         return mUnavailablePhysicalCameras;
159*b7c941bbSAndroid Build Coastguard Worker     }
160*b7c941bbSAndroid Build Coastguard Worker 
isAvailable(const char * cameraId)161*b7c941bbSAndroid Build Coastguard Worker     bool isAvailable(const char* cameraId) {
162*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
163*b7c941bbSAndroid Build Coastguard Worker         if (mAvailableMap.count(cameraId) == 0) {
164*b7c941bbSAndroid Build Coastguard Worker             return false;
165*b7c941bbSAndroid Build Coastguard Worker         }
166*b7c941bbSAndroid Build Coastguard Worker         return mAvailableMap[cameraId];
167*b7c941bbSAndroid Build Coastguard Worker     }
168*b7c941bbSAndroid Build Coastguard Worker 
169*b7c941bbSAndroid Build Coastguard Worker   private:
170*b7c941bbSAndroid Build Coastguard Worker     std::mutex mMutex;
171*b7c941bbSAndroid Build Coastguard Worker     int mOnAvailableCount = 0;
172*b7c941bbSAndroid Build Coastguard Worker     int mOnUnavailableCount = 0;
173*b7c941bbSAndroid Build Coastguard Worker     int mOnCameraAccessPrioritiesChangedCount = 0;
174*b7c941bbSAndroid Build Coastguard Worker     int mOnPhysicalCameraAvailableCount = 0;
175*b7c941bbSAndroid Build Coastguard Worker     std::map<std::string, bool> mAvailableMap;
176*b7c941bbSAndroid Build Coastguard Worker     StringPairSet mUnavailablePhysicalCameras;
177*b7c941bbSAndroid Build Coastguard Worker };
178*b7c941bbSAndroid Build Coastguard Worker 
179*b7c941bbSAndroid Build Coastguard Worker class CameraDeviceListener {
180*b7c941bbSAndroid Build Coastguard Worker   public:
onDisconnected(void * obj,ACameraDevice * device)181*b7c941bbSAndroid Build Coastguard Worker     static void onDisconnected(void* obj, ACameraDevice* device) {
182*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
183*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
184*b7c941bbSAndroid Build Coastguard Worker             return;
185*b7c941bbSAndroid Build Coastguard Worker         }
186*b7c941bbSAndroid Build Coastguard Worker         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
187*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
188*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnDisconnect++;
189*b7c941bbSAndroid Build Coastguard Worker         return;
190*b7c941bbSAndroid Build Coastguard Worker     }
191*b7c941bbSAndroid Build Coastguard Worker 
onError(void * obj,ACameraDevice * device,int errorCode)192*b7c941bbSAndroid Build Coastguard Worker     static void onError(void* obj, ACameraDevice* device, int errorCode) {
193*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
194*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
195*b7c941bbSAndroid Build Coastguard Worker             return;
196*b7c941bbSAndroid Build Coastguard Worker         }
197*b7c941bbSAndroid Build Coastguard Worker         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
198*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
199*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnError++;
200*b7c941bbSAndroid Build Coastguard Worker         thiz->mLatestError = errorCode;
201*b7c941bbSAndroid Build Coastguard Worker         return;
202*b7c941bbSAndroid Build Coastguard Worker     }
203*b7c941bbSAndroid Build Coastguard Worker 
204*b7c941bbSAndroid Build Coastguard Worker   private:
205*b7c941bbSAndroid Build Coastguard Worker     std::mutex mMutex;
206*b7c941bbSAndroid Build Coastguard Worker     int mOnDisconnect = 0;
207*b7c941bbSAndroid Build Coastguard Worker     int mOnError = 0;
208*b7c941bbSAndroid Build Coastguard Worker     int mLatestError = 0;
209*b7c941bbSAndroid Build Coastguard Worker };
210*b7c941bbSAndroid Build Coastguard Worker 
211*b7c941bbSAndroid Build Coastguard Worker class CaptureSessionListener {
212*b7c941bbSAndroid Build Coastguard Worker 
213*b7c941bbSAndroid Build Coastguard Worker   public:
onClosed(void * obj,ACameraCaptureSession * session)214*b7c941bbSAndroid Build Coastguard Worker     static void onClosed(void* obj, ACameraCaptureSession *session) {
215*b7c941bbSAndroid Build Coastguard Worker         // TODO: might want an API to query cameraId even session is closed?
216*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Session %p is closed!", session);
217*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
218*b7c941bbSAndroid Build Coastguard Worker             return;
219*b7c941bbSAndroid Build Coastguard Worker         }
220*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
221*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
222*b7c941bbSAndroid Build Coastguard Worker         thiz->mIsClosed = true;
223*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnClosed++; // Should never > 1
224*b7c941bbSAndroid Build Coastguard Worker     }
225*b7c941bbSAndroid Build Coastguard Worker 
onReady(void * obj,ACameraCaptureSession * session)226*b7c941bbSAndroid Build Coastguard Worker     static void onReady(void* obj, ACameraCaptureSession *session) {
227*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
228*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
229*b7c941bbSAndroid Build Coastguard Worker             return;
230*b7c941bbSAndroid Build Coastguard Worker         }
231*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
232*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
233*b7c941bbSAndroid Build Coastguard Worker         ACameraDevice* device = nullptr;
234*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
235*b7c941bbSAndroid Build Coastguard Worker         // There will be one onReady fired after session closed
236*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK && !thiz->mIsClosed) {
237*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s Getting camera device from session callback failed!",
238*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__);
239*b7c941bbSAndroid Build Coastguard Worker             thiz->mInError = true;
240*b7c941bbSAndroid Build Coastguard Worker         }
241*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
242*b7c941bbSAndroid Build Coastguard Worker         thiz->mIsIdle = true;
243*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnReady++;
244*b7c941bbSAndroid Build Coastguard Worker     }
245*b7c941bbSAndroid Build Coastguard Worker 
onWindowPrepared(void * obj,ANativeWindow * anw,ACameraCaptureSession * session)246*b7c941bbSAndroid Build Coastguard Worker     static void onWindowPrepared(
247*b7c941bbSAndroid Build Coastguard Worker             void* obj, ANativeWindow* anw, ACameraCaptureSession* session) {
248*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
249*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
250*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s ctx ptr is null ?", __FUNCTION__);
251*b7c941bbSAndroid Build Coastguard Worker             return;
252*b7c941bbSAndroid Build Coastguard Worker         }
253*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
254*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
255*b7c941bbSAndroid Build Coastguard Worker         // Reduce the pending prepared count of anw by 1. If count is  0, remove the key.
256*b7c941bbSAndroid Build Coastguard Worker         if(thiz->mPendingPreparedCbs.find(anw) == thiz->mPendingPreparedCbs.end()) {
257*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: ANW %p was not being prepared at all ?", __FUNCTION__, anw);
258*b7c941bbSAndroid Build Coastguard Worker             return;
259*b7c941bbSAndroid Build Coastguard Worker         }
260*b7c941bbSAndroid Build Coastguard Worker         if (thiz->mPendingPreparedCbs[anw] == 0) {
261*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: ANW %p pending prepared cbs is already 0", __FUNCTION__, anw);
262*b7c941bbSAndroid Build Coastguard Worker             return;
263*b7c941bbSAndroid Build Coastguard Worker         }
264*b7c941bbSAndroid Build Coastguard Worker         thiz->mPendingPreparedCbs[anw]--;
265*b7c941bbSAndroid Build Coastguard Worker         if (thiz->mPendingPreparedCbs[anw] == 0) {
266*b7c941bbSAndroid Build Coastguard Worker             thiz->mPendingPreparedCbs.erase(anw);
267*b7c941bbSAndroid Build Coastguard Worker         }
268*b7c941bbSAndroid Build Coastguard Worker     }
onActive(void * obj,ACameraCaptureSession * session)269*b7c941bbSAndroid Build Coastguard Worker     static void onActive(void* obj, ACameraCaptureSession* session) {
270*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
271*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
272*b7c941bbSAndroid Build Coastguard Worker             return;
273*b7c941bbSAndroid Build Coastguard Worker         }
274*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
275*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
276*b7c941bbSAndroid Build Coastguard Worker         ACameraDevice* device = nullptr;
277*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
278*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
279*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s Getting camera device from session callback failed!",
280*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__);
281*b7c941bbSAndroid Build Coastguard Worker             thiz->mInError = true;
282*b7c941bbSAndroid Build Coastguard Worker         }
283*b7c941bbSAndroid Build Coastguard Worker         ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
284*b7c941bbSAndroid Build Coastguard Worker         thiz->mIsIdle = false;
285*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnActive;
286*b7c941bbSAndroid Build Coastguard Worker     }
gotAllPreparedCallbacksWithErrorLog()287*b7c941bbSAndroid Build Coastguard Worker     bool gotAllPreparedCallbacksWithErrorLog() {
288*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
289*b7c941bbSAndroid Build Coastguard Worker         bool ret = (mPendingPreparedCbs.size() == 0);
290*b7c941bbSAndroid Build Coastguard Worker         if (!ret) {
291*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: mPendingPreparedCbs has the following expected callbacks", __FUNCTION__);
292*b7c941bbSAndroid Build Coastguard Worker             for (auto pair : mPendingPreparedCbs) {
293*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("%s: ANW: %p : pending callbacks %d", __FUNCTION__, pair.first, pair.second);
294*b7c941bbSAndroid Build Coastguard Worker             }
295*b7c941bbSAndroid Build Coastguard Worker         }
296*b7c941bbSAndroid Build Coastguard Worker         return ret;
297*b7c941bbSAndroid Build Coastguard Worker     }
298*b7c941bbSAndroid Build Coastguard Worker 
incPendingPrepared(ANativeWindow * anw)299*b7c941bbSAndroid Build Coastguard Worker     void incPendingPrepared(ANativeWindow *anw) {
300*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
301*b7c941bbSAndroid Build Coastguard Worker         if ((mPendingPreparedCbs.find(anw) == mPendingPreparedCbs.end())) {
302*b7c941bbSAndroid Build Coastguard Worker             mPendingPreparedCbs[anw] = 1;
303*b7c941bbSAndroid Build Coastguard Worker             return;
304*b7c941bbSAndroid Build Coastguard Worker         }
305*b7c941bbSAndroid Build Coastguard Worker         mPendingPreparedCbs[anw]++;
306*b7c941bbSAndroid Build Coastguard Worker     }
isClosed()307*b7c941bbSAndroid Build Coastguard Worker     bool isClosed() {
308*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
309*b7c941bbSAndroid Build Coastguard Worker         return mIsClosed;
310*b7c941bbSAndroid Build Coastguard Worker     }
311*b7c941bbSAndroid Build Coastguard Worker 
isIdle()312*b7c941bbSAndroid Build Coastguard Worker     bool isIdle() {
313*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
314*b7c941bbSAndroid Build Coastguard Worker         return mIsIdle;
315*b7c941bbSAndroid Build Coastguard Worker     }
316*b7c941bbSAndroid Build Coastguard Worker 
isInError()317*b7c941bbSAndroid Build Coastguard Worker     bool isInError() {
318*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
319*b7c941bbSAndroid Build Coastguard Worker         return mInError;
320*b7c941bbSAndroid Build Coastguard Worker     }
321*b7c941bbSAndroid Build Coastguard Worker 
onClosedCount()322*b7c941bbSAndroid Build Coastguard Worker     int onClosedCount()  {
323*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
324*b7c941bbSAndroid Build Coastguard Worker         return mOnClosed;
325*b7c941bbSAndroid Build Coastguard Worker     }
326*b7c941bbSAndroid Build Coastguard Worker 
onReadyCount()327*b7c941bbSAndroid Build Coastguard Worker     int onReadyCount()  {
328*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
329*b7c941bbSAndroid Build Coastguard Worker         return mOnReady;
330*b7c941bbSAndroid Build Coastguard Worker     }
331*b7c941bbSAndroid Build Coastguard Worker 
onActiveCount()332*b7c941bbSAndroid Build Coastguard Worker     int onActiveCount()  {
333*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
334*b7c941bbSAndroid Build Coastguard Worker         return mOnActive;
335*b7c941bbSAndroid Build Coastguard Worker     }
336*b7c941bbSAndroid Build Coastguard Worker 
reset()337*b7c941bbSAndroid Build Coastguard Worker     void reset() {
338*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
339*b7c941bbSAndroid Build Coastguard Worker         mIsClosed = false;
340*b7c941bbSAndroid Build Coastguard Worker         mIsIdle = true;
341*b7c941bbSAndroid Build Coastguard Worker         mInError = false;
342*b7c941bbSAndroid Build Coastguard Worker         mOnClosed = 0;
343*b7c941bbSAndroid Build Coastguard Worker         mOnReady = 0;
344*b7c941bbSAndroid Build Coastguard Worker         mOnActive = 0;
345*b7c941bbSAndroid Build Coastguard Worker     }
346*b7c941bbSAndroid Build Coastguard Worker 
347*b7c941bbSAndroid Build Coastguard Worker   private:
348*b7c941bbSAndroid Build Coastguard Worker     std::mutex mMutex;
349*b7c941bbSAndroid Build Coastguard Worker     bool mIsClosed = false;
350*b7c941bbSAndroid Build Coastguard Worker     bool mIsIdle = true;
351*b7c941bbSAndroid Build Coastguard Worker     bool mInError = false; // should always stay false
352*b7c941bbSAndroid Build Coastguard Worker     int mOnClosed = 0;
353*b7c941bbSAndroid Build Coastguard Worker     int mOnReady = 0;
354*b7c941bbSAndroid Build Coastguard Worker     int mOnActive = 0;
355*b7c941bbSAndroid Build Coastguard Worker     // ANativeWindow -> # expected callbacks
356*b7c941bbSAndroid Build Coastguard Worker     std::unordered_map<ANativeWindow *, int> mPendingPreparedCbs;
357*b7c941bbSAndroid Build Coastguard Worker };
358*b7c941bbSAndroid Build Coastguard Worker 
359*b7c941bbSAndroid Build Coastguard Worker class CaptureResultListener {
360*b7c941bbSAndroid Build Coastguard Worker   public:
~CaptureResultListener()361*b7c941bbSAndroid Build Coastguard Worker     ~CaptureResultListener() {
362*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
363*b7c941bbSAndroid Build Coastguard Worker         clearSavedRequestsLocked();
364*b7c941bbSAndroid Build Coastguard Worker         mCompletedFrameNumbers.clear();
365*b7c941bbSAndroid Build Coastguard Worker         mStartedFrameNumbers.clear();
366*b7c941bbSAndroid Build Coastguard Worker         clearFailedLostFrameNumbersLocked();
367*b7c941bbSAndroid Build Coastguard Worker     }
368*b7c941bbSAndroid Build Coastguard Worker 
onCaptureStart(void *,ACameraCaptureSession *,const ACaptureRequest *,int64_t)369*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
370*b7c941bbSAndroid Build Coastguard Worker             const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
371*b7c941bbSAndroid Build Coastguard Worker         //Not used for now
372*b7c941bbSAndroid Build Coastguard Worker     }
373*b7c941bbSAndroid Build Coastguard Worker 
onCaptureStartV2(void * obj,ACameraCaptureSession *,const ACaptureRequest *,int64_t,int64_t frameNumber)374*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureStartV2(void* obj, ACameraCaptureSession* /*session*/,
375*b7c941bbSAndroid Build Coastguard Worker             const ACaptureRequest* /*request*/, int64_t /*timestamp*/, int64_t frameNumber) {
376*b7c941bbSAndroid Build Coastguard Worker         if ((obj == nullptr) || (frameNumber < 0)) {
377*b7c941bbSAndroid Build Coastguard Worker             return;
378*b7c941bbSAndroid Build Coastguard Worker         }
379*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
380*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
381*b7c941bbSAndroid Build Coastguard Worker 
382*b7c941bbSAndroid Build Coastguard Worker         thiz->mStartedFrameNumbers.insert(frameNumber);
383*b7c941bbSAndroid Build Coastguard Worker         thiz->mStartCondition.notify_one();
384*b7c941bbSAndroid Build Coastguard Worker     }
385*b7c941bbSAndroid Build Coastguard Worker 
onCaptureProgressed(void *,ACameraCaptureSession *,ACaptureRequest *,const ACameraMetadata *)386*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureProgressed(void* /*obj*/, ACameraCaptureSession* /*session*/,
387*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* /*request*/, const ACameraMetadata* /*result*/) {
388*b7c941bbSAndroid Build Coastguard Worker         //Not used for now
389*b7c941bbSAndroid Build Coastguard Worker     }
390*b7c941bbSAndroid Build Coastguard Worker 
onCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result)391*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
392*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* request, const ACameraMetadata* result) {
393*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
394*b7c941bbSAndroid Build Coastguard Worker         if ((obj == nullptr) || (result == nullptr)) {
395*b7c941bbSAndroid Build Coastguard Worker             return;
396*b7c941bbSAndroid Build Coastguard Worker         }
397*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
398*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
399*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
400*b7c941bbSAndroid Build Coastguard Worker         auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
401*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
402*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Sync frame number missing from result!");
403*b7c941bbSAndroid Build Coastguard Worker             return;
404*b7c941bbSAndroid Build Coastguard Worker         }
405*b7c941bbSAndroid Build Coastguard Worker 
406*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata* copy = ACameraMetadata_copy(result);
407*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entryCopy;
408*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
409*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
410*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Sync frame number missing from result copy!");
411*b7c941bbSAndroid Build Coastguard Worker             return;
412*b7c941bbSAndroid Build Coastguard Worker         }
413*b7c941bbSAndroid Build Coastguard Worker 
414*b7c941bbSAndroid Build Coastguard Worker         if (entry.data.i64[0] != entryCopy.data.i64[0]) {
415*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
416*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i64[0], entryCopy.data.i64[0]);
417*b7c941bbSAndroid Build Coastguard Worker             return;
418*b7c941bbSAndroid Build Coastguard Worker         }
419*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(copy);
420*b7c941bbSAndroid Build Coastguard Worker 
421*b7c941bbSAndroid Build Coastguard Worker         if (thiz->mSaveCompletedRequests) {
422*b7c941bbSAndroid Build Coastguard Worker             thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
423*b7c941bbSAndroid Build Coastguard Worker         }
424*b7c941bbSAndroid Build Coastguard Worker 
425*b7c941bbSAndroid Build Coastguard Worker         thiz->mCompletedFrameNumbers.insert(entry.data.i64[0]);
426*b7c941bbSAndroid Build Coastguard Worker         thiz->mResultCondition.notify_one();
427*b7c941bbSAndroid Build Coastguard Worker     }
428*b7c941bbSAndroid Build Coastguard Worker 
onLogicalCameraCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result,size_t physicalResultCount,const char ** physicalCameraIds,const ACameraMetadata ** physicalResults)429*b7c941bbSAndroid Build Coastguard Worker     static void onLogicalCameraCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
430*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* request, const ACameraMetadata* result,
431*b7c941bbSAndroid Build Coastguard Worker             size_t physicalResultCount, const char** physicalCameraIds,
432*b7c941bbSAndroid Build Coastguard Worker             const ACameraMetadata** physicalResults) {
433*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
434*b7c941bbSAndroid Build Coastguard Worker         if ((obj == nullptr) || (result == nullptr)) {
435*b7c941bbSAndroid Build Coastguard Worker             return;
436*b7c941bbSAndroid Build Coastguard Worker         }
437*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
438*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
439*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
440*b7c941bbSAndroid Build Coastguard Worker         auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
441*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
442*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Sync frame number missing from result!");
443*b7c941bbSAndroid Build Coastguard Worker             return;
444*b7c941bbSAndroid Build Coastguard Worker         }
445*b7c941bbSAndroid Build Coastguard Worker 
446*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata* copy = ACameraMetadata_copy(result);
447*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entryCopy;
448*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
449*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
450*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Sync frame number missing from result copy!");
451*b7c941bbSAndroid Build Coastguard Worker             return;
452*b7c941bbSAndroid Build Coastguard Worker         }
453*b7c941bbSAndroid Build Coastguard Worker 
454*b7c941bbSAndroid Build Coastguard Worker         if (entry.data.i64[0] != entryCopy.data.i64[0]) {
455*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
456*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i64[0], entryCopy.data.i64[0]);
457*b7c941bbSAndroid Build Coastguard Worker             return;
458*b7c941bbSAndroid Build Coastguard Worker         }
459*b7c941bbSAndroid Build Coastguard Worker 
460*b7c941bbSAndroid Build Coastguard Worker         if (thiz->mRegisteredPhysicalIds.size() != physicalResultCount) {
461*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Error: Number of registered physical camera Ids %zu is different than received"
462*b7c941bbSAndroid Build Coastguard Worker                     " physical camera Ids %zu", thiz->mRegisteredPhysicalIds.size(),
463*b7c941bbSAndroid Build Coastguard Worker                     physicalResultCount);
464*b7c941bbSAndroid Build Coastguard Worker             return;
465*b7c941bbSAndroid Build Coastguard Worker         }
466*b7c941bbSAndroid Build Coastguard Worker         for (size_t i = 0; i < physicalResultCount; i++) {
467*b7c941bbSAndroid Build Coastguard Worker             if (physicalCameraIds[i] == nullptr) {
468*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("Error: Invalid physical camera id in capture result");
469*b7c941bbSAndroid Build Coastguard Worker                 return;
470*b7c941bbSAndroid Build Coastguard Worker             }
471*b7c941bbSAndroid Build Coastguard Worker             if (physicalResults[i] == nullptr) {
472*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("Error: Invalid physical camera metadata in capture result");
473*b7c941bbSAndroid Build Coastguard Worker                 return;
474*b7c941bbSAndroid Build Coastguard Worker             }
475*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_const_entry physicalEntry;
476*b7c941bbSAndroid Build Coastguard Worker             auto ret = ACameraMetadata_getConstEntry(physicalResults[i], ACAMERA_SYNC_FRAME_NUMBER,
477*b7c941bbSAndroid Build Coastguard Worker                     &physicalEntry);
478*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
479*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("Error: Sync frame number missing from physical camera result metadata!");
480*b7c941bbSAndroid Build Coastguard Worker                 return;
481*b7c941bbSAndroid Build Coastguard Worker             }
482*b7c941bbSAndroid Build Coastguard Worker             if (physicalEntry.data.i64[0] != entryCopy.data.i64[0]) {
483*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("Error: Physical camera sync frame number %" PRId64
484*b7c941bbSAndroid Build Coastguard Worker                         " mismatch result copy %" PRId64,
485*b7c941bbSAndroid Build Coastguard Worker                         physicalEntry.data.i64[0], entryCopy.data.i64[0]);
486*b7c941bbSAndroid Build Coastguard Worker                 return;
487*b7c941bbSAndroid Build Coastguard Worker             }
488*b7c941bbSAndroid Build Coastguard Worker 
489*b7c941bbSAndroid Build Coastguard Worker             auto foundId = std::find(thiz->mRegisteredPhysicalIds.begin(),
490*b7c941bbSAndroid Build Coastguard Worker                     thiz->mRegisteredPhysicalIds.end(), physicalCameraIds[i]);
491*b7c941bbSAndroid Build Coastguard Worker             if (foundId == thiz->mRegisteredPhysicalIds.end()) {
492*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("Error: Returned physical camera Id %s is not registered",
493*b7c941bbSAndroid Build Coastguard Worker                         physicalCameraIds[i]);
494*b7c941bbSAndroid Build Coastguard Worker                 return;
495*b7c941bbSAndroid Build Coastguard Worker             }
496*b7c941bbSAndroid Build Coastguard Worker         }
497*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(copy);
498*b7c941bbSAndroid Build Coastguard Worker 
499*b7c941bbSAndroid Build Coastguard Worker         if (thiz->mSaveCompletedRequests) {
500*b7c941bbSAndroid Build Coastguard Worker             thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
501*b7c941bbSAndroid Build Coastguard Worker         }
502*b7c941bbSAndroid Build Coastguard Worker 
503*b7c941bbSAndroid Build Coastguard Worker         thiz->mCompletedFrameNumbers.insert(entry.data.i64[0]);
504*b7c941bbSAndroid Build Coastguard Worker         thiz->mResultCondition.notify_one();
505*b7c941bbSAndroid Build Coastguard Worker     }
506*b7c941bbSAndroid Build Coastguard Worker 
onCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ACameraCaptureFailure * failure)507*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
508*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* /*request*/, ACameraCaptureFailure* failure) {
509*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
510*b7c941bbSAndroid Build Coastguard Worker         if ((obj == nullptr) || (failure == nullptr)) {
511*b7c941bbSAndroid Build Coastguard Worker             return;
512*b7c941bbSAndroid Build Coastguard Worker         }
513*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
514*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
515*b7c941bbSAndroid Build Coastguard Worker         thiz->mFailedFrameNumbers.insert(failure->frameNumber);
516*b7c941bbSAndroid Build Coastguard Worker         thiz->mResultCondition.notify_one();
517*b7c941bbSAndroid Build Coastguard Worker     }
518*b7c941bbSAndroid Build Coastguard Worker 
onLogicalCameraCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ALogicalCameraCaptureFailure * failure)519*b7c941bbSAndroid Build Coastguard Worker     static void onLogicalCameraCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
520*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* /*request*/, ALogicalCameraCaptureFailure* failure) {
521*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
522*b7c941bbSAndroid Build Coastguard Worker         if ((obj == nullptr) || (failure == nullptr)) {
523*b7c941bbSAndroid Build Coastguard Worker             return;
524*b7c941bbSAndroid Build Coastguard Worker         }
525*b7c941bbSAndroid Build Coastguard Worker         if (failure->physicalCameraId != nullptr) {
526*b7c941bbSAndroid Build Coastguard Worker             ALOGV("%s: physicalCameraId: %s", __FUNCTION__, failure->physicalCameraId);
527*b7c941bbSAndroid Build Coastguard Worker         }
528*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
529*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
530*b7c941bbSAndroid Build Coastguard Worker         thiz->mFailedFrameNumbers.insert(failure->captureFailure.frameNumber);
531*b7c941bbSAndroid Build Coastguard Worker         thiz->mResultCondition.notify_one();
532*b7c941bbSAndroid Build Coastguard Worker     }
533*b7c941bbSAndroid Build Coastguard Worker 
onCaptureSequenceCompleted(void * obj,ACameraCaptureSession *,int sequenceId,int64_t frameNumber)534*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureSequenceCompleted(void* obj, ACameraCaptureSession* /*session*/,
535*b7c941bbSAndroid Build Coastguard Worker             int sequenceId, int64_t frameNumber) {
536*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
537*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
538*b7c941bbSAndroid Build Coastguard Worker             return;
539*b7c941bbSAndroid Build Coastguard Worker         }
540*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
541*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
542*b7c941bbSAndroid Build Coastguard Worker         thiz->mLastSequenceIdCompleted = sequenceId;
543*b7c941bbSAndroid Build Coastguard Worker         thiz->mLastSequenceFrameNumber = frameNumber;
544*b7c941bbSAndroid Build Coastguard Worker         thiz->mResultCondition.notify_one();
545*b7c941bbSAndroid Build Coastguard Worker     }
546*b7c941bbSAndroid Build Coastguard Worker 
onCaptureSequenceAborted(void *,ACameraCaptureSession *,int)547*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureSequenceAborted(void* /*obj*/, ACameraCaptureSession* /*session*/,
548*b7c941bbSAndroid Build Coastguard Worker             int /*sequenceId*/) {
549*b7c941bbSAndroid Build Coastguard Worker         //Not used for now
550*b7c941bbSAndroid Build Coastguard Worker     }
551*b7c941bbSAndroid Build Coastguard Worker 
onCaptureBufferLost(void * obj,ACameraCaptureSession *,ACaptureRequest *,ANativeWindow *,int64_t frameNumber)552*b7c941bbSAndroid Build Coastguard Worker     static void onCaptureBufferLost(void* obj, ACameraCaptureSession* /*session*/,
553*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* /*request*/, ANativeWindow* /*window*/, int64_t frameNumber) {
554*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
555*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
556*b7c941bbSAndroid Build Coastguard Worker             return;
557*b7c941bbSAndroid Build Coastguard Worker         }
558*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
559*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
560*b7c941bbSAndroid Build Coastguard Worker         thiz->mBufferLostFrameNumbers.insert(frameNumber);
561*b7c941bbSAndroid Build Coastguard Worker         thiz->mResultCondition.notify_one();
562*b7c941bbSAndroid Build Coastguard Worker     }
563*b7c941bbSAndroid Build Coastguard Worker 
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)564*b7c941bbSAndroid Build Coastguard Worker     int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
565*b7c941bbSAndroid Build Coastguard Worker         int64_t ret = -1;
566*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
567*b7c941bbSAndroid Build Coastguard Worker 
568*b7c941bbSAndroid Build Coastguard Worker         while (mLastSequenceIdCompleted != sequenceId) {
569*b7c941bbSAndroid Build Coastguard Worker             auto timeout = std::chrono::system_clock::now() +
570*b7c941bbSAndroid Build Coastguard Worker                            std::chrono::seconds(timeoutSec);
571*b7c941bbSAndroid Build Coastguard Worker             if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
572*b7c941bbSAndroid Build Coastguard Worker                 break;
573*b7c941bbSAndroid Build Coastguard Worker             }
574*b7c941bbSAndroid Build Coastguard Worker         }
575*b7c941bbSAndroid Build Coastguard Worker 
576*b7c941bbSAndroid Build Coastguard Worker         if (mLastSequenceIdCompleted == sequenceId) {
577*b7c941bbSAndroid Build Coastguard Worker             ret = mLastSequenceFrameNumber;
578*b7c941bbSAndroid Build Coastguard Worker         }
579*b7c941bbSAndroid Build Coastguard Worker 
580*b7c941bbSAndroid Build Coastguard Worker         return ret;
581*b7c941bbSAndroid Build Coastguard Worker     }
582*b7c941bbSAndroid Build Coastguard Worker 
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)583*b7c941bbSAndroid Build Coastguard Worker     bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
584*b7c941bbSAndroid Build Coastguard Worker         bool ret = false;
585*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
586*b7c941bbSAndroid Build Coastguard Worker 
587*b7c941bbSAndroid Build Coastguard Worker         while ((mCompletedFrameNumbers.find(frameNumber) == mCompletedFrameNumbers.end()) &&
588*b7c941bbSAndroid Build Coastguard Worker                 !checkForFailureOrLossLocked(frameNumber)) {
589*b7c941bbSAndroid Build Coastguard Worker             auto timeout = std::chrono::system_clock::now() +
590*b7c941bbSAndroid Build Coastguard Worker                            std::chrono::seconds(timeoutSec);
591*b7c941bbSAndroid Build Coastguard Worker             if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
592*b7c941bbSAndroid Build Coastguard Worker                 break;
593*b7c941bbSAndroid Build Coastguard Worker             }
594*b7c941bbSAndroid Build Coastguard Worker         }
595*b7c941bbSAndroid Build Coastguard Worker 
596*b7c941bbSAndroid Build Coastguard Worker         if ((mCompletedFrameNumbers.find(frameNumber) != mCompletedFrameNumbers.end()) ||
597*b7c941bbSAndroid Build Coastguard Worker                 checkForFailureOrLossLocked(frameNumber)) {
598*b7c941bbSAndroid Build Coastguard Worker             ret = true;
599*b7c941bbSAndroid Build Coastguard Worker         }
600*b7c941bbSAndroid Build Coastguard Worker 
601*b7c941bbSAndroid Build Coastguard Worker         return ret;
602*b7c941bbSAndroid Build Coastguard Worker     }
603*b7c941bbSAndroid Build Coastguard Worker 
waitForFrameNumberStarted(int64_t frameNumber,uint32_t timeoutSec)604*b7c941bbSAndroid Build Coastguard Worker     bool waitForFrameNumberStarted(int64_t frameNumber, uint32_t timeoutSec) {
605*b7c941bbSAndroid Build Coastguard Worker         bool ret = false;
606*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
607*b7c941bbSAndroid Build Coastguard Worker 
608*b7c941bbSAndroid Build Coastguard Worker         while ((mStartedFrameNumbers.find(frameNumber) == mStartedFrameNumbers.end())) {
609*b7c941bbSAndroid Build Coastguard Worker             auto timeout = std::chrono::system_clock::now() +
610*b7c941bbSAndroid Build Coastguard Worker                            std::chrono::seconds(timeoutSec);
611*b7c941bbSAndroid Build Coastguard Worker             if (std::cv_status::timeout == mStartCondition.wait_until(l, timeout)) {
612*b7c941bbSAndroid Build Coastguard Worker                 break;
613*b7c941bbSAndroid Build Coastguard Worker             }
614*b7c941bbSAndroid Build Coastguard Worker         }
615*b7c941bbSAndroid Build Coastguard Worker 
616*b7c941bbSAndroid Build Coastguard Worker         if ((mStartedFrameNumbers.find(frameNumber) != mStartedFrameNumbers.end())) {
617*b7c941bbSAndroid Build Coastguard Worker             ret = true;
618*b7c941bbSAndroid Build Coastguard Worker         }
619*b7c941bbSAndroid Build Coastguard Worker 
620*b7c941bbSAndroid Build Coastguard Worker         return ret;
621*b7c941bbSAndroid Build Coastguard Worker     }
622*b7c941bbSAndroid Build Coastguard Worker 
setRequestSave(bool enable)623*b7c941bbSAndroid Build Coastguard Worker     void setRequestSave(bool enable) {
624*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
625*b7c941bbSAndroid Build Coastguard Worker         if (!enable) {
626*b7c941bbSAndroid Build Coastguard Worker             clearSavedRequestsLocked();
627*b7c941bbSAndroid Build Coastguard Worker         }
628*b7c941bbSAndroid Build Coastguard Worker         mSaveCompletedRequests = enable;
629*b7c941bbSAndroid Build Coastguard Worker     }
630*b7c941bbSAndroid Build Coastguard Worker 
631*b7c941bbSAndroid Build Coastguard Worker     // The lifecycle of returned ACaptureRequest* is still managed by CaptureResultListener
getCompletedRequests(std::vector<ACaptureRequest * > * out)632*b7c941bbSAndroid Build Coastguard Worker     void getCompletedRequests(std::vector<ACaptureRequest*>* out) {
633*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
634*b7c941bbSAndroid Build Coastguard Worker         *out = mCompletedRequests;
635*b7c941bbSAndroid Build Coastguard Worker     }
636*b7c941bbSAndroid Build Coastguard Worker 
registerPhysicalResults(size_t physicalIdCnt,const char * const * physicalOutputs)637*b7c941bbSAndroid Build Coastguard Worker     void registerPhysicalResults(size_t physicalIdCnt, const char*const* physicalOutputs) {
638*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
639*b7c941bbSAndroid Build Coastguard Worker         mRegisteredPhysicalIds.clear();
640*b7c941bbSAndroid Build Coastguard Worker         for (size_t i = 0; i < physicalIdCnt; i++) {
641*b7c941bbSAndroid Build Coastguard Worker             mRegisteredPhysicalIds.push_back(physicalOutputs[i]);
642*b7c941bbSAndroid Build Coastguard Worker         }
643*b7c941bbSAndroid Build Coastguard Worker     }
644*b7c941bbSAndroid Build Coastguard Worker 
checkForFailureOrLoss(int64_t frameNumber)645*b7c941bbSAndroid Build Coastguard Worker     bool checkForFailureOrLoss(int64_t frameNumber) {
646*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
647*b7c941bbSAndroid Build Coastguard Worker         return checkForFailureOrLossLocked(frameNumber);
648*b7c941bbSAndroid Build Coastguard Worker     }
649*b7c941bbSAndroid Build Coastguard Worker 
reset()650*b7c941bbSAndroid Build Coastguard Worker     void reset() {
651*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
652*b7c941bbSAndroid Build Coastguard Worker         mLastSequenceIdCompleted = -1;
653*b7c941bbSAndroid Build Coastguard Worker         mLastSequenceFrameNumber = -1;
654*b7c941bbSAndroid Build Coastguard Worker         mSaveCompletedRequests = false;
655*b7c941bbSAndroid Build Coastguard Worker         clearSavedRequestsLocked();
656*b7c941bbSAndroid Build Coastguard Worker         mCompletedFrameNumbers.clear();
657*b7c941bbSAndroid Build Coastguard Worker         clearFailedLostFrameNumbersLocked();
658*b7c941bbSAndroid Build Coastguard Worker     }
659*b7c941bbSAndroid Build Coastguard Worker 
660*b7c941bbSAndroid Build Coastguard Worker   private:
661*b7c941bbSAndroid Build Coastguard Worker     std::mutex mMutex;
662*b7c941bbSAndroid Build Coastguard Worker     std::condition_variable mResultCondition;
663*b7c941bbSAndroid Build Coastguard Worker     std::condition_variable mStartCondition;
664*b7c941bbSAndroid Build Coastguard Worker     int mLastSequenceIdCompleted = -1;
665*b7c941bbSAndroid Build Coastguard Worker     int64_t mLastSequenceFrameNumber = -1;
666*b7c941bbSAndroid Build Coastguard Worker     std::set<int64_t> mCompletedFrameNumbers;
667*b7c941bbSAndroid Build Coastguard Worker     std::set<int64_t> mStartedFrameNumbers;
668*b7c941bbSAndroid Build Coastguard Worker     std::set<int64_t> mFailedFrameNumbers, mBufferLostFrameNumbers;
669*b7c941bbSAndroid Build Coastguard Worker     bool    mSaveCompletedRequests = false;
670*b7c941bbSAndroid Build Coastguard Worker     std::vector<ACaptureRequest*> mCompletedRequests;
671*b7c941bbSAndroid Build Coastguard Worker     // Registered physical camera Ids that are being requested upon.
672*b7c941bbSAndroid Build Coastguard Worker     std::vector<std::string> mRegisteredPhysicalIds;
673*b7c941bbSAndroid Build Coastguard Worker 
clearSavedRequestsLocked()674*b7c941bbSAndroid Build Coastguard Worker     void clearSavedRequestsLocked() {
675*b7c941bbSAndroid Build Coastguard Worker         for (ACaptureRequest* req : mCompletedRequests) {
676*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest_free(req);
677*b7c941bbSAndroid Build Coastguard Worker         }
678*b7c941bbSAndroid Build Coastguard Worker         mCompletedRequests.clear();
679*b7c941bbSAndroid Build Coastguard Worker     }
680*b7c941bbSAndroid Build Coastguard Worker 
clearFailedLostFrameNumbersLocked()681*b7c941bbSAndroid Build Coastguard Worker     void clearFailedLostFrameNumbersLocked() {
682*b7c941bbSAndroid Build Coastguard Worker         mFailedFrameNumbers.clear();
683*b7c941bbSAndroid Build Coastguard Worker         mBufferLostFrameNumbers.clear();
684*b7c941bbSAndroid Build Coastguard Worker     }
685*b7c941bbSAndroid Build Coastguard Worker 
checkForFailureOrLossLocked(int64_t frameNumber)686*b7c941bbSAndroid Build Coastguard Worker     bool checkForFailureOrLossLocked(int64_t frameNumber) {
687*b7c941bbSAndroid Build Coastguard Worker         return (mFailedFrameNumbers.find(frameNumber) != mFailedFrameNumbers.end()) ||
688*b7c941bbSAndroid Build Coastguard Worker                 (mBufferLostFrameNumbers.find(frameNumber) != mBufferLostFrameNumbers.end());
689*b7c941bbSAndroid Build Coastguard Worker     }
690*b7c941bbSAndroid Build Coastguard Worker };
691*b7c941bbSAndroid Build Coastguard Worker 
692*b7c941bbSAndroid Build Coastguard Worker class ImageReaderListener {
693*b7c941bbSAndroid Build Coastguard Worker   public:
ImageReaderListener()694*b7c941bbSAndroid Build Coastguard Worker     ImageReaderListener() {
695*b7c941bbSAndroid Build Coastguard Worker         mBufferTs.insert(mLastBufferTs);
696*b7c941bbSAndroid Build Coastguard Worker     }
697*b7c941bbSAndroid Build Coastguard Worker 
698*b7c941bbSAndroid Build Coastguard Worker     // count, acquire, validate, and delete AImage when a new image is available
validateImageCb(void * obj,AImageReader * reader)699*b7c941bbSAndroid Build Coastguard Worker     static void validateImageCb(void* obj, AImageReader* reader) {
700*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
701*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
702*b7c941bbSAndroid Build Coastguard Worker             return;
703*b7c941bbSAndroid Build Coastguard Worker         }
704*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
705*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
706*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnImageAvailableCount++;
707*b7c941bbSAndroid Build Coastguard Worker 
708*b7c941bbSAndroid Build Coastguard Worker         AImage* img = nullptr;
709*b7c941bbSAndroid Build Coastguard Worker         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
710*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK || img == nullptr) {
711*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
712*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__, reader, ret, img);
713*b7c941bbSAndroid Build Coastguard Worker             return;
714*b7c941bbSAndroid Build Coastguard Worker         }
715*b7c941bbSAndroid Build Coastguard Worker 
716*b7c941bbSAndroid Build Coastguard Worker         // TODO: validate image content
717*b7c941bbSAndroid Build Coastguard Worker         int32_t format = -1;
718*b7c941bbSAndroid Build Coastguard Worker         ret = AImage_getFormat(img, &format);
719*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK || format == -1) {
720*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: get format for image %p failed! ret: %d, format %d",
721*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__, img, ret, format);
722*b7c941bbSAndroid Build Coastguard Worker         }
723*b7c941bbSAndroid Build Coastguard Worker 
724*b7c941bbSAndroid Build Coastguard Worker         // Save jpeg to SD card
725*b7c941bbSAndroid Build Coastguard Worker         if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
726*b7c941bbSAndroid Build Coastguard Worker             int32_t numPlanes = 0;
727*b7c941bbSAndroid Build Coastguard Worker             ret = AImage_getNumberOfPlanes(img, &numPlanes);
728*b7c941bbSAndroid Build Coastguard Worker             if (ret != AMEDIA_OK || numPlanes != 1) {
729*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
730*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, img, ret, numPlanes);
731*b7c941bbSAndroid Build Coastguard Worker                 AImage_delete(img);
732*b7c941bbSAndroid Build Coastguard Worker                 return;
733*b7c941bbSAndroid Build Coastguard Worker             }
734*b7c941bbSAndroid Build Coastguard Worker 
735*b7c941bbSAndroid Build Coastguard Worker             int32_t width = -1, height = -1;
736*b7c941bbSAndroid Build Coastguard Worker             ret = AImage_getWidth(img, &width);
737*b7c941bbSAndroid Build Coastguard Worker             if (ret != AMEDIA_OK || width <= 0) {
738*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
739*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, img, ret, width);
740*b7c941bbSAndroid Build Coastguard Worker                 AImage_delete(img);
741*b7c941bbSAndroid Build Coastguard Worker                 return;
742*b7c941bbSAndroid Build Coastguard Worker             }
743*b7c941bbSAndroid Build Coastguard Worker 
744*b7c941bbSAndroid Build Coastguard Worker             ret = AImage_getHeight(img, &height);
745*b7c941bbSAndroid Build Coastguard Worker             if (ret != AMEDIA_OK || height <= 0) {
746*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
747*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, img, ret, height);
748*b7c941bbSAndroid Build Coastguard Worker                 AImage_delete(img);
749*b7c941bbSAndroid Build Coastguard Worker                 return;
750*b7c941bbSAndroid Build Coastguard Worker             }
751*b7c941bbSAndroid Build Coastguard Worker 
752*b7c941bbSAndroid Build Coastguard Worker             uint8_t* data = nullptr;
753*b7c941bbSAndroid Build Coastguard Worker             int dataLength = 0;
754*b7c941bbSAndroid Build Coastguard Worker             ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
755*b7c941bbSAndroid Build Coastguard Worker             if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
756*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
757*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, img, ret, data, dataLength);
758*b7c941bbSAndroid Build Coastguard Worker                 AImage_delete(img);
759*b7c941bbSAndroid Build Coastguard Worker                 return;
760*b7c941bbSAndroid Build Coastguard Worker             }
761*b7c941bbSAndroid Build Coastguard Worker 
762*b7c941bbSAndroid Build Coastguard Worker #if 0
763*b7c941bbSAndroid Build Coastguard Worker             char dumpFilePath[512];
764*b7c941bbSAndroid Build Coastguard Worker             sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
765*b7c941bbSAndroid Build Coastguard Worker             ALOGI("Writing jpeg file to %s", dumpFilePath);
766*b7c941bbSAndroid Build Coastguard Worker             FILE* file = fopen(dumpFilePath,"w+");
767*b7c941bbSAndroid Build Coastguard Worker 
768*b7c941bbSAndroid Build Coastguard Worker             if (file != nullptr) {
769*b7c941bbSAndroid Build Coastguard Worker                 fwrite(data, 1, dataLength, file);
770*b7c941bbSAndroid Build Coastguard Worker                 fflush(file);
771*b7c941bbSAndroid Build Coastguard Worker                 fclose(file);
772*b7c941bbSAndroid Build Coastguard Worker             }
773*b7c941bbSAndroid Build Coastguard Worker #endif
774*b7c941bbSAndroid Build Coastguard Worker         }
775*b7c941bbSAndroid Build Coastguard Worker 
776*b7c941bbSAndroid Build Coastguard Worker         AImage_delete(img);
777*b7c941bbSAndroid Build Coastguard Worker     }
778*b7c941bbSAndroid Build Coastguard Worker 
779*b7c941bbSAndroid Build Coastguard Worker     // count, acquire image but not delete the image
acquireImageCb(void * obj,AImageReader * reader)780*b7c941bbSAndroid Build Coastguard Worker     static void acquireImageCb(void* obj, AImageReader* reader) {
781*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
782*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
783*b7c941bbSAndroid Build Coastguard Worker             return;
784*b7c941bbSAndroid Build Coastguard Worker         }
785*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
786*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
787*b7c941bbSAndroid Build Coastguard Worker         thiz->mOnImageAvailableCount++;
788*b7c941bbSAndroid Build Coastguard Worker 
789*b7c941bbSAndroid Build Coastguard Worker         // Acquire, but not closing.
790*b7c941bbSAndroid Build Coastguard Worker         AImage* img = nullptr;
791*b7c941bbSAndroid Build Coastguard Worker         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
792*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK || img == nullptr) {
793*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
794*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__, reader, ret, img);
795*b7c941bbSAndroid Build Coastguard Worker             return;
796*b7c941bbSAndroid Build Coastguard Worker         }
797*b7c941bbSAndroid Build Coastguard Worker         return;
798*b7c941bbSAndroid Build Coastguard Worker     }
799*b7c941bbSAndroid Build Coastguard Worker 
onImageAvailableCount()800*b7c941bbSAndroid Build Coastguard Worker     int onImageAvailableCount() {
801*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
802*b7c941bbSAndroid Build Coastguard Worker         return mOnImageAvailableCount;
803*b7c941bbSAndroid Build Coastguard Worker     }
804*b7c941bbSAndroid Build Coastguard Worker 
setDumpFilePathBase(const char * path)805*b7c941bbSAndroid Build Coastguard Worker     void setDumpFilePathBase(const char* path) {
806*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mMutex);
807*b7c941bbSAndroid Build Coastguard Worker         mDumpFilePathBase = path;
808*b7c941bbSAndroid Build Coastguard Worker     }
809*b7c941bbSAndroid Build Coastguard Worker 
810*b7c941bbSAndroid Build Coastguard Worker     // acquire image, query the corresponding timestamp but not delete the image
signalImageCb(void * obj,AImageReader * reader)811*b7c941bbSAndroid Build Coastguard Worker     static void signalImageCb(void* obj, AImageReader* reader) {
812*b7c941bbSAndroid Build Coastguard Worker         ALOGV("%s", __FUNCTION__);
813*b7c941bbSAndroid Build Coastguard Worker         if (obj == nullptr) {
814*b7c941bbSAndroid Build Coastguard Worker             return;
815*b7c941bbSAndroid Build Coastguard Worker         }
816*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
817*b7c941bbSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(thiz->mMutex);
818*b7c941bbSAndroid Build Coastguard Worker 
819*b7c941bbSAndroid Build Coastguard Worker         AImage* img = nullptr;
820*b7c941bbSAndroid Build Coastguard Worker         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
821*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK || img == nullptr) {
822*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
823*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__, reader, ret, img);
824*b7c941bbSAndroid Build Coastguard Worker             thiz->mBufferCondition.notify_one();
825*b7c941bbSAndroid Build Coastguard Worker             return;
826*b7c941bbSAndroid Build Coastguard Worker         }
827*b7c941bbSAndroid Build Coastguard Worker 
828*b7c941bbSAndroid Build Coastguard Worker         int64_t currentTs = -1;
829*b7c941bbSAndroid Build Coastguard Worker         ret = AImage_getTimestamp(img, &currentTs);
830*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK || currentTs == -1) {
831*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: acquire image from reader %p failed! ret: %d", __FUNCTION__, reader, ret);
832*b7c941bbSAndroid Build Coastguard Worker             AImage_delete(img);
833*b7c941bbSAndroid Build Coastguard Worker             thiz->mBufferCondition.notify_one();
834*b7c941bbSAndroid Build Coastguard Worker             return;
835*b7c941bbSAndroid Build Coastguard Worker         }
836*b7c941bbSAndroid Build Coastguard Worker 
837*b7c941bbSAndroid Build Coastguard Worker         thiz->mBufferTs.insert(currentTs);
838*b7c941bbSAndroid Build Coastguard Worker         thiz->mBufferCondition.notify_one();
839*b7c941bbSAndroid Build Coastguard Worker         return;
840*b7c941bbSAndroid Build Coastguard Worker     }
841*b7c941bbSAndroid Build Coastguard Worker 
waitForNextBuffer(uint32_t timeoutSec)842*b7c941bbSAndroid Build Coastguard Worker     bool waitForNextBuffer(uint32_t timeoutSec) {
843*b7c941bbSAndroid Build Coastguard Worker         bool ret = false;
844*b7c941bbSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mMutex);
845*b7c941bbSAndroid Build Coastguard Worker 
846*b7c941bbSAndroid Build Coastguard Worker         auto it = mBufferTs.find(mLastBufferTs);
847*b7c941bbSAndroid Build Coastguard Worker         if (it == mBufferTs.end()) {
848*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: Last buffer timestamp: %" PRId64 " not found!", __FUNCTION__, mLastBufferTs);
849*b7c941bbSAndroid Build Coastguard Worker             return false;
850*b7c941bbSAndroid Build Coastguard Worker         }
851*b7c941bbSAndroid Build Coastguard Worker         it++;
852*b7c941bbSAndroid Build Coastguard Worker 
853*b7c941bbSAndroid Build Coastguard Worker         if (it == mBufferTs.end()) {
854*b7c941bbSAndroid Build Coastguard Worker             auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(timeoutSec);
855*b7c941bbSAndroid Build Coastguard Worker             if (std::cv_status::no_timeout == mBufferCondition.wait_until(l, timeout)) {
856*b7c941bbSAndroid Build Coastguard Worker                 it = mBufferTs.find(mLastBufferTs);
857*b7c941bbSAndroid Build Coastguard Worker                 it++;
858*b7c941bbSAndroid Build Coastguard Worker             }
859*b7c941bbSAndroid Build Coastguard Worker         }
860*b7c941bbSAndroid Build Coastguard Worker 
861*b7c941bbSAndroid Build Coastguard Worker         if (it != mBufferTs.end()) {
862*b7c941bbSAndroid Build Coastguard Worker             mLastBufferTs = *it;
863*b7c941bbSAndroid Build Coastguard Worker             ret = true;
864*b7c941bbSAndroid Build Coastguard Worker         }
865*b7c941bbSAndroid Build Coastguard Worker 
866*b7c941bbSAndroid Build Coastguard Worker         return ret;
867*b7c941bbSAndroid Build Coastguard Worker     }
868*b7c941bbSAndroid Build Coastguard Worker 
869*b7c941bbSAndroid Build Coastguard Worker   private:
870*b7c941bbSAndroid Build Coastguard Worker     // TODO: add mReader to make sure each listener is associated to one reader?
871*b7c941bbSAndroid Build Coastguard Worker     std::mutex mMutex;
872*b7c941bbSAndroid Build Coastguard Worker     int mOnImageAvailableCount = 0;
873*b7c941bbSAndroid Build Coastguard Worker     const char* mDumpFilePathBase = nullptr;
874*b7c941bbSAndroid Build Coastguard Worker     std::condition_variable mBufferCondition;
875*b7c941bbSAndroid Build Coastguard Worker     int64_t mLastBufferTs = -1;
876*b7c941bbSAndroid Build Coastguard Worker     std::set<int64_t> mBufferTs;
877*b7c941bbSAndroid Build Coastguard Worker };
878*b7c941bbSAndroid Build Coastguard Worker 
879*b7c941bbSAndroid Build Coastguard Worker class StaticInfo {
880*b7c941bbSAndroid Build Coastguard Worker   public:
StaticInfo(ACameraMetadata * chars)881*b7c941bbSAndroid Build Coastguard Worker     explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
882*b7c941bbSAndroid Build Coastguard Worker 
isColorOutputSupported()883*b7c941bbSAndroid Build Coastguard Worker     bool isColorOutputSupported() {
884*b7c941bbSAndroid Build Coastguard Worker         return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
885*b7c941bbSAndroid Build Coastguard Worker     }
886*b7c941bbSAndroid Build Coastguard Worker 
isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap)887*b7c941bbSAndroid Build Coastguard Worker     bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
888*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
889*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
890*b7c941bbSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.count; i++) {
891*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.u8[i] == cap) {
892*b7c941bbSAndroid Build Coastguard Worker                 return true;
893*b7c941bbSAndroid Build Coastguard Worker             }
894*b7c941bbSAndroid Build Coastguard Worker         }
895*b7c941bbSAndroid Build Coastguard Worker         return false;
896*b7c941bbSAndroid Build Coastguard Worker     }
897*b7c941bbSAndroid Build Coastguard Worker 
getMinFrameDurationFor(int64_t format,int64_t width,int64_t height)898*b7c941bbSAndroid Build Coastguard Worker     int64_t getMinFrameDurationFor(int64_t format, int64_t width, int64_t height) {
899*b7c941bbSAndroid Build Coastguard Worker         int32_t minFrameDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
900*b7c941bbSAndroid Build Coastguard Worker                 ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS :
901*b7c941bbSAndroid Build Coastguard Worker                 (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
902*b7c941bbSAndroid Build Coastguard Worker                 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS :
903*b7c941bbSAndroid Build Coastguard Worker                 ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
904*b7c941bbSAndroid Build Coastguard Worker         return getDurationFor(minFrameDurationTag, format, width, height);
905*b7c941bbSAndroid Build Coastguard Worker     }
906*b7c941bbSAndroid Build Coastguard Worker 
getStallDurationFor(int64_t format,int64_t width,int64_t height)907*b7c941bbSAndroid Build Coastguard Worker     int64_t getStallDurationFor(int64_t format, int64_t width, int64_t height) {
908*b7c941bbSAndroid Build Coastguard Worker         int32_t stallDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
909*b7c941bbSAndroid Build Coastguard Worker                 ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS : (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
910*b7c941bbSAndroid Build Coastguard Worker                 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS :
911*b7c941bbSAndroid Build Coastguard Worker                 ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS;
912*b7c941bbSAndroid Build Coastguard Worker         return getDurationFor(stallDurationTag, format, width, height);
913*b7c941bbSAndroid Build Coastguard Worker     }
914*b7c941bbSAndroid Build Coastguard Worker 
getMaxSizeForFormat(int32_t format,int32_t * width,int32_t * height)915*b7c941bbSAndroid Build Coastguard Worker     bool getMaxSizeForFormat(int32_t format, int32_t *width, int32_t *height) {
916*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
917*b7c941bbSAndroid Build Coastguard Worker 
918*b7c941bbSAndroid Build Coastguard Worker         int32_t streamConfigTag, streamConfigOutputTag;
919*b7c941bbSAndroid Build Coastguard Worker         switch (format) {
920*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_HEIC:
921*b7c941bbSAndroid Build Coastguard Worker                 streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
922*b7c941bbSAndroid Build Coastguard Worker                 streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
923*b7c941bbSAndroid Build Coastguard Worker                 break;
924*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_DEPTH_JPEG:
925*b7c941bbSAndroid Build Coastguard Worker                 streamConfigTag = ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS;
926*b7c941bbSAndroid Build Coastguard Worker                 streamConfigOutputTag =
927*b7c941bbSAndroid Build Coastguard Worker                         ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT;
928*b7c941bbSAndroid Build Coastguard Worker                 break;
929*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_JPEG:
930*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_Y8:
931*b7c941bbSAndroid Build Coastguard Worker             default:
932*b7c941bbSAndroid Build Coastguard Worker                 streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
933*b7c941bbSAndroid Build Coastguard Worker                 streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
934*b7c941bbSAndroid Build Coastguard Worker                 break;
935*b7c941bbSAndroid Build Coastguard Worker         }
936*b7c941bbSAndroid Build Coastguard Worker 
937*b7c941bbSAndroid Build Coastguard Worker         bool supported = false;
938*b7c941bbSAndroid Build Coastguard Worker         camera_status_t status = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
939*b7c941bbSAndroid Build Coastguard Worker         if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
940*b7c941bbSAndroid Build Coastguard Worker             return supported;
941*b7c941bbSAndroid Build Coastguard Worker         }
942*b7c941bbSAndroid Build Coastguard Worker 
943*b7c941bbSAndroid Build Coastguard Worker        int32_t w = 0, h = 0;
944*b7c941bbSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.count; i += 4) {
945*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.i32[i] == format &&
946*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i32[i+3] == streamConfigOutputTag &&
947*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i32[i+1] * entry.data.i32[i+2] > w * h) {
948*b7c941bbSAndroid Build Coastguard Worker                 w = entry.data.i32[i+1];
949*b7c941bbSAndroid Build Coastguard Worker                 h = entry.data.i32[i+2];
950*b7c941bbSAndroid Build Coastguard Worker                 supported = true;
951*b7c941bbSAndroid Build Coastguard Worker             }
952*b7c941bbSAndroid Build Coastguard Worker         }
953*b7c941bbSAndroid Build Coastguard Worker 
954*b7c941bbSAndroid Build Coastguard Worker         if (supported) {
955*b7c941bbSAndroid Build Coastguard Worker             *width = w;
956*b7c941bbSAndroid Build Coastguard Worker             *height = h;
957*b7c941bbSAndroid Build Coastguard Worker         }
958*b7c941bbSAndroid Build Coastguard Worker         return supported;
959*b7c941bbSAndroid Build Coastguard Worker     }
960*b7c941bbSAndroid Build Coastguard Worker 
isSizeSupportedForFormat(int32_t format,int32_t width,int32_t height)961*b7c941bbSAndroid Build Coastguard Worker     bool isSizeSupportedForFormat(int32_t format, int32_t width, int32_t height) {
962*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
963*b7c941bbSAndroid Build Coastguard Worker 
964*b7c941bbSAndroid Build Coastguard Worker         int32_t streamConfigTag, streamConfigOutputTag;
965*b7c941bbSAndroid Build Coastguard Worker         switch (format) {
966*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_HEIC:
967*b7c941bbSAndroid Build Coastguard Worker                 streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
968*b7c941bbSAndroid Build Coastguard Worker                 streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
969*b7c941bbSAndroid Build Coastguard Worker                 break;
970*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_JPEG:
971*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_Y8:
972*b7c941bbSAndroid Build Coastguard Worker             default:
973*b7c941bbSAndroid Build Coastguard Worker                 streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
974*b7c941bbSAndroid Build Coastguard Worker                 streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
975*b7c941bbSAndroid Build Coastguard Worker                 break;
976*b7c941bbSAndroid Build Coastguard Worker         }
977*b7c941bbSAndroid Build Coastguard Worker 
978*b7c941bbSAndroid Build Coastguard Worker         auto ret = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
979*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
980*b7c941bbSAndroid Build Coastguard Worker             return false;
981*b7c941bbSAndroid Build Coastguard Worker         }
982*b7c941bbSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.count; i += 4) {
983*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.i32[i] == format &&
984*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i32[i+3] == streamConfigOutputTag &&
985*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i32[i+1] == width &&
986*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i32[i+2] == height) {
987*b7c941bbSAndroid Build Coastguard Worker                 return true;
988*b7c941bbSAndroid Build Coastguard Worker             }
989*b7c941bbSAndroid Build Coastguard Worker         }
990*b7c941bbSAndroid Build Coastguard Worker         return false;
991*b7c941bbSAndroid Build Coastguard Worker     }
992*b7c941bbSAndroid Build Coastguard Worker   private:
getDurationFor(uint32_t tag,int64_t format,int64_t width,int64_t height)993*b7c941bbSAndroid Build Coastguard Worker     int64_t getDurationFor(uint32_t tag, int64_t format, int64_t width, int64_t height) {
994*b7c941bbSAndroid Build Coastguard Worker         if (tag != ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS &&
995*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS &&
996*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS &&
997*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS &&
998*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS &&
999*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS &&
1000*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS &&
1001*b7c941bbSAndroid Build Coastguard Worker                 tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS) {
1002*b7c941bbSAndroid Build Coastguard Worker             return -1;
1003*b7c941bbSAndroid Build Coastguard Worker         }
1004*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
1005*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_getConstEntry(mChars, tag, &entry);
1006*b7c941bbSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.count; i += 4) {
1007*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.i64[i] == format &&
1008*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i64[i+1] == width &&
1009*b7c941bbSAndroid Build Coastguard Worker                     entry.data.i64[i+2] == height) {
1010*b7c941bbSAndroid Build Coastguard Worker                 return entry.data.i64[i+3];
1011*b7c941bbSAndroid Build Coastguard Worker             }
1012*b7c941bbSAndroid Build Coastguard Worker         }
1013*b7c941bbSAndroid Build Coastguard Worker         return -1;
1014*b7c941bbSAndroid Build Coastguard Worker     }
1015*b7c941bbSAndroid Build Coastguard Worker     const ACameraMetadata* mChars;
1016*b7c941bbSAndroid Build Coastguard Worker };
1017*b7c941bbSAndroid Build Coastguard Worker 
1018*b7c941bbSAndroid Build Coastguard Worker class PreviewTestCase {
1019*b7c941bbSAndroid Build Coastguard Worker   public:
~PreviewTestCase()1020*b7c941bbSAndroid Build Coastguard Worker     ~PreviewTestCase() {
1021*b7c941bbSAndroid Build Coastguard Worker         resetCamera();
1022*b7c941bbSAndroid Build Coastguard Worker         deInit();
1023*b7c941bbSAndroid Build Coastguard Worker         if (mCameraManager) {
1024*b7c941bbSAndroid Build Coastguard Worker             ACameraManager_delete(mCameraManager);
1025*b7c941bbSAndroid Build Coastguard Worker             mCameraManager = nullptr;
1026*b7c941bbSAndroid Build Coastguard Worker         }
1027*b7c941bbSAndroid Build Coastguard Worker     }
1028*b7c941bbSAndroid Build Coastguard Worker 
PreviewTestCase()1029*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase() {
1030*b7c941bbSAndroid Build Coastguard Worker         // create is guaranteed to succeed;
1031*b7c941bbSAndroid Build Coastguard Worker         createManager();
1032*b7c941bbSAndroid Build Coastguard Worker     }
1033*b7c941bbSAndroid Build Coastguard Worker 
1034*b7c941bbSAndroid Build Coastguard Worker     // Free all resources except camera manager
resetCamera()1035*b7c941bbSAndroid Build Coastguard Worker     void resetCamera() {
1036*b7c941bbSAndroid Build Coastguard Worker         mSessionListener.reset();
1037*b7c941bbSAndroid Build Coastguard Worker         mResultListener.reset();
1038*b7c941bbSAndroid Build Coastguard Worker         if (mSession) {
1039*b7c941bbSAndroid Build Coastguard Worker             ACameraCaptureSession_close(mSession);
1040*b7c941bbSAndroid Build Coastguard Worker             mSession = nullptr;
1041*b7c941bbSAndroid Build Coastguard Worker         }
1042*b7c941bbSAndroid Build Coastguard Worker         if (mDevice) {
1043*b7c941bbSAndroid Build Coastguard Worker             ACameraDevice_close(mDevice);
1044*b7c941bbSAndroid Build Coastguard Worker             mDevice = nullptr;
1045*b7c941bbSAndroid Build Coastguard Worker         }
1046*b7c941bbSAndroid Build Coastguard Worker         if (mImgReader) {
1047*b7c941bbSAndroid Build Coastguard Worker             AImageReader_delete(mImgReader);
1048*b7c941bbSAndroid Build Coastguard Worker             // No need to call ANativeWindow_release on imageReaderAnw
1049*b7c941bbSAndroid Build Coastguard Worker             mImgReaderAnw = nullptr;
1050*b7c941bbSAndroid Build Coastguard Worker             mImgReader = nullptr;
1051*b7c941bbSAndroid Build Coastguard Worker         }
1052*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewAnw) {
1053*b7c941bbSAndroid Build Coastguard Worker             ANativeWindow_release(mPreviewAnw);
1054*b7c941bbSAndroid Build Coastguard Worker             mPreviewAnw = nullptr;
1055*b7c941bbSAndroid Build Coastguard Worker         }
1056*b7c941bbSAndroid Build Coastguard Worker         if (mOutputs) {
1057*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutputContainer_free(mOutputs);
1058*b7c941bbSAndroid Build Coastguard Worker             mOutputs = nullptr;
1059*b7c941bbSAndroid Build Coastguard Worker         }
1060*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewOutput) {
1061*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutput_free(mPreviewOutput);
1062*b7c941bbSAndroid Build Coastguard Worker             mPreviewOutput = nullptr;
1063*b7c941bbSAndroid Build Coastguard Worker         }
1064*b7c941bbSAndroid Build Coastguard Worker         if (mImgReaderOutput) {
1065*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutput_free(mImgReaderOutput);
1066*b7c941bbSAndroid Build Coastguard Worker             mImgReaderOutput = nullptr;
1067*b7c941bbSAndroid Build Coastguard Worker         }
1068*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewRequest) {
1069*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest_free(mPreviewRequest);
1070*b7c941bbSAndroid Build Coastguard Worker             mPreviewRequest = nullptr;
1071*b7c941bbSAndroid Build Coastguard Worker         }
1072*b7c941bbSAndroid Build Coastguard Worker         if (mStillRequest) {
1073*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest_free(mStillRequest);
1074*b7c941bbSAndroid Build Coastguard Worker             mStillRequest = nullptr;
1075*b7c941bbSAndroid Build Coastguard Worker         }
1076*b7c941bbSAndroid Build Coastguard Worker         if (mReqPreviewOutput) {
1077*b7c941bbSAndroid Build Coastguard Worker             ACameraOutputTarget_free(mReqPreviewOutput);
1078*b7c941bbSAndroid Build Coastguard Worker             mReqPreviewOutput = nullptr;
1079*b7c941bbSAndroid Build Coastguard Worker         }
1080*b7c941bbSAndroid Build Coastguard Worker         if (mReqImgReaderOutput) {
1081*b7c941bbSAndroid Build Coastguard Worker             ACameraOutputTarget_free(mReqImgReaderOutput);
1082*b7c941bbSAndroid Build Coastguard Worker             mReqImgReaderOutput = nullptr;
1083*b7c941bbSAndroid Build Coastguard Worker         }
1084*b7c941bbSAndroid Build Coastguard Worker 
1085*b7c941bbSAndroid Build Coastguard Worker         mImgReaderInited = false;
1086*b7c941bbSAndroid Build Coastguard Worker         mPreviewInited = false;
1087*b7c941bbSAndroid Build Coastguard Worker     }
1088*b7c941bbSAndroid Build Coastguard Worker 
initWithErrorLog()1089*b7c941bbSAndroid Build Coastguard Worker     camera_status_t initWithErrorLog() {
1090*b7c941bbSAndroid Build Coastguard Worker         return initWithErrorLog(nullptr /*env*/, nullptr /*jOverrideCameraId*/);
1091*b7c941bbSAndroid Build Coastguard Worker     }
1092*b7c941bbSAndroid Build Coastguard Worker 
initWithErrorLog(JNIEnv * env,jstring jOverrideCameraId)1093*b7c941bbSAndroid Build Coastguard Worker     camera_status_t initWithErrorLog(JNIEnv* env, jstring jOverrideCameraId) {
1094*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraManager_getCameraIdList(
1095*b7c941bbSAndroid Build Coastguard Worker                 mCameraManager, &mCameraIdList);
1096*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1097*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
1098*b7c941bbSAndroid Build Coastguard Worker             return ret;
1099*b7c941bbSAndroid Build Coastguard Worker         }
1100*b7c941bbSAndroid Build Coastguard Worker 
1101*b7c941bbSAndroid Build Coastguard Worker         if (env != nullptr && jOverrideCameraId != nullptr) {
1102*b7c941bbSAndroid Build Coastguard Worker             mOverrideCameraId = env->GetStringUTFChars(jOverrideCameraId, 0);
1103*b7c941bbSAndroid Build Coastguard Worker         }
1104*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
1105*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1106*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
1107*b7c941bbSAndroid Build Coastguard Worker             return ret;
1108*b7c941bbSAndroid Build Coastguard Worker         }
1109*b7c941bbSAndroid Build Coastguard Worker         mMgrInited = true;
1110*b7c941bbSAndroid Build Coastguard Worker         mJOverrideCameraId = jOverrideCameraId;
1111*b7c941bbSAndroid Build Coastguard Worker         mJNIEnv = env;
1112*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1113*b7c941bbSAndroid Build Coastguard Worker     }
1114*b7c941bbSAndroid Build Coastguard Worker 
deInit()1115*b7c941bbSAndroid Build Coastguard Worker     camera_status_t deInit () {
1116*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited) {
1117*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_OK;
1118*b7c941bbSAndroid Build Coastguard Worker         }
1119*b7c941bbSAndroid Build Coastguard Worker 
1120*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
1121*b7c941bbSAndroid Build Coastguard Worker                 mCameraManager, &mServiceCb);
1122*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1123*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Unregister availability callback failed: ret %d", ret);
1124*b7c941bbSAndroid Build Coastguard Worker             return ret;
1125*b7c941bbSAndroid Build Coastguard Worker         }
1126*b7c941bbSAndroid Build Coastguard Worker 
1127*b7c941bbSAndroid Build Coastguard Worker         if (mCameraIdList) {
1128*b7c941bbSAndroid Build Coastguard Worker             ACameraManager_deleteCameraIdList(mCameraIdList);
1129*b7c941bbSAndroid Build Coastguard Worker             mCameraIdList = nullptr;
1130*b7c941bbSAndroid Build Coastguard Worker         }
1131*b7c941bbSAndroid Build Coastguard Worker         mMgrInited = false;
1132*b7c941bbSAndroid Build Coastguard Worker         if (mOverrideCameraId != nullptr && mJNIEnv != nullptr) {
1133*b7c941bbSAndroid Build Coastguard Worker             mJNIEnv->ReleaseStringUTFChars(mJOverrideCameraId, mOverrideCameraId);
1134*b7c941bbSAndroid Build Coastguard Worker             mOverrideCameraId = nullptr;
1135*b7c941bbSAndroid Build Coastguard Worker             mJOverrideCameraId = nullptr;
1136*b7c941bbSAndroid Build Coastguard Worker             mJNIEnv = nullptr;
1137*b7c941bbSAndroid Build Coastguard Worker         }
1138*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1139*b7c941bbSAndroid Build Coastguard Worker     }
1140*b7c941bbSAndroid Build Coastguard Worker 
getNumCameras()1141*b7c941bbSAndroid Build Coastguard Worker     int getNumCameras() {
1142*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited || !mCameraIdList) {
1143*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s CameraManager not inited yet.", __FUNCTION__);
1144*b7c941bbSAndroid Build Coastguard Worker             return -1;
1145*b7c941bbSAndroid Build Coastguard Worker         }
1146*b7c941bbSAndroid Build Coastguard Worker         if (mOverrideCameraId != nullptr) {
1147*b7c941bbSAndroid Build Coastguard Worker             return 1;
1148*b7c941bbSAndroid Build Coastguard Worker         }
1149*b7c941bbSAndroid Build Coastguard Worker         return mCameraIdList->numCameras;
1150*b7c941bbSAndroid Build Coastguard Worker     }
1151*b7c941bbSAndroid Build Coastguard Worker 
getCameraId(int idx)1152*b7c941bbSAndroid Build Coastguard Worker     const char* getCameraId(int idx) {
1153*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
1154*b7c941bbSAndroid Build Coastguard Worker             return nullptr;
1155*b7c941bbSAndroid Build Coastguard Worker         }
1156*b7c941bbSAndroid Build Coastguard Worker         if (mOverrideCameraId != nullptr) {
1157*b7c941bbSAndroid Build Coastguard Worker             if (idx >= 1) {
1158*b7c941bbSAndroid Build Coastguard Worker                 return nullptr;
1159*b7c941bbSAndroid Build Coastguard Worker             } else {
1160*b7c941bbSAndroid Build Coastguard Worker                 return mOverrideCameraId;
1161*b7c941bbSAndroid Build Coastguard Worker             }
1162*b7c941bbSAndroid Build Coastguard Worker         }
1163*b7c941bbSAndroid Build Coastguard Worker         return mCameraIdList->cameraIds[idx];
1164*b7c941bbSAndroid Build Coastguard Worker     }
1165*b7c941bbSAndroid Build Coastguard Worker 
1166*b7c941bbSAndroid Build Coastguard Worker     // Caller is responsible to free returned characteristics metadata
getCameraChars(int idx)1167*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* getCameraChars(int idx) {
1168*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
1169*b7c941bbSAndroid Build Coastguard Worker             return nullptr;
1170*b7c941bbSAndroid Build Coastguard Worker         }
1171*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = mCameraIdList->cameraIds[idx];
1172*b7c941bbSAndroid Build Coastguard Worker         if (mOverrideCameraId != nullptr) {
1173*b7c941bbSAndroid Build Coastguard Worker             if (idx >= 1) {
1174*b7c941bbSAndroid Build Coastguard Worker                 return nullptr;
1175*b7c941bbSAndroid Build Coastguard Worker             } else {
1176*b7c941bbSAndroid Build Coastguard Worker                 cameraId = mOverrideCameraId;
1177*b7c941bbSAndroid Build Coastguard Worker             }
1178*b7c941bbSAndroid Build Coastguard Worker         }
1179*b7c941bbSAndroid Build Coastguard Worker 
1180*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata* chars;
1181*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraManager_getCameraCharacteristics(
1182*b7c941bbSAndroid Build Coastguard Worker                 mCameraManager, cameraId, &chars);
1183*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1184*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1185*b7c941bbSAndroid Build Coastguard Worker             return nullptr;
1186*b7c941bbSAndroid Build Coastguard Worker         }
1187*b7c941bbSAndroid Build Coastguard Worker         return chars;
1188*b7c941bbSAndroid Build Coastguard Worker     }
1189*b7c941bbSAndroid Build Coastguard Worker 
1190*b7c941bbSAndroid Build Coastguard Worker     // Caller is responsible to free returned characteristics metadata.
getCameraChars(const char * id)1191*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* getCameraChars(const char* id) {
1192*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited || id == nullptr) {
1193*b7c941bbSAndroid Build Coastguard Worker             return nullptr;
1194*b7c941bbSAndroid Build Coastguard Worker         }
1195*b7c941bbSAndroid Build Coastguard Worker 
1196*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata* chars;
1197*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraManager_getCameraCharacteristics(mCameraManager, id, &chars);
1198*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1199*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1200*b7c941bbSAndroid Build Coastguard Worker             return nullptr;
1201*b7c941bbSAndroid Build Coastguard Worker         }
1202*b7c941bbSAndroid Build Coastguard Worker         return chars;
1203*b7c941bbSAndroid Build Coastguard Worker     }
1204*b7c941bbSAndroid Build Coastguard Worker 
updateOutput(JNIEnv * env,ACaptureSessionOutput * output)1205*b7c941bbSAndroid Build Coastguard Worker     camera_status_t updateOutput(JNIEnv* env, ACaptureSessionOutput *output) {
1206*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr) {
1207*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot update output configuration session %p",
1208*b7c941bbSAndroid Build Coastguard Worker                     mSession);
1209*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1210*b7c941bbSAndroid Build Coastguard Worker         }
1211*b7c941bbSAndroid Build Coastguard Worker 
1212*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_updateSharedOutput(mSession, output);
1213*b7c941bbSAndroid Build Coastguard Worker     }
1214*b7c941bbSAndroid Build Coastguard Worker 
openCamera(const char * cameraId)1215*b7c941bbSAndroid Build Coastguard Worker     camera_status_t openCamera(const char* cameraId) {
1216*b7c941bbSAndroid Build Coastguard Worker         if (mDevice) {
1217*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Cannot open camera before closing previously open one");
1218*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_INVALID_PARAMETER;
1219*b7c941bbSAndroid Build Coastguard Worker         }
1220*b7c941bbSAndroid Build Coastguard Worker         mCameraId = cameraId;
1221*b7c941bbSAndroid Build Coastguard Worker         return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
1222*b7c941bbSAndroid Build Coastguard Worker     }
1223*b7c941bbSAndroid Build Coastguard Worker 
closeCamera()1224*b7c941bbSAndroid Build Coastguard Worker     camera_status_t closeCamera() {
1225*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraDevice_close(mDevice);
1226*b7c941bbSAndroid Build Coastguard Worker         mDevice = nullptr;
1227*b7c941bbSAndroid Build Coastguard Worker         return ret;
1228*b7c941bbSAndroid Build Coastguard Worker     }
1229*b7c941bbSAndroid Build Coastguard Worker 
isCameraAvailable(const char * cameraId)1230*b7c941bbSAndroid Build Coastguard Worker     bool isCameraAvailable(const char* cameraId) {
1231*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited) {
1232*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Camera service listener has not been registered!");
1233*b7c941bbSAndroid Build Coastguard Worker         }
1234*b7c941bbSAndroid Build Coastguard Worker         return mServiceListener.isAvailable(cameraId);
1235*b7c941bbSAndroid Build Coastguard Worker     }
1236*b7c941bbSAndroid Build Coastguard Worker 
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener)1237*b7c941bbSAndroid Build Coastguard Worker     media_status_t initImageReaderWithErrorLog(
1238*b7c941bbSAndroid Build Coastguard Worker             int32_t width, int32_t height, int32_t format, int32_t maxImages,
1239*b7c941bbSAndroid Build Coastguard Worker             AImageReader_ImageListener* listener) {
1240*b7c941bbSAndroid Build Coastguard Worker         if (mImgReader || mImgReaderAnw) {
1241*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
1242*b7c941bbSAndroid Build Coastguard Worker             return AMEDIA_ERROR_UNKNOWN;
1243*b7c941bbSAndroid Build Coastguard Worker         }
1244*b7c941bbSAndroid Build Coastguard Worker 
1245*b7c941bbSAndroid Build Coastguard Worker         media_status_t ret = initImageReaderWithErrorLog(
1246*b7c941bbSAndroid Build Coastguard Worker                 width, height, format, maxImages, listener, &mImgReader,
1247*b7c941bbSAndroid Build Coastguard Worker                 &mImgReaderAnw);
1248*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK) {
1249*b7c941bbSAndroid Build Coastguard Worker             return ret;
1250*b7c941bbSAndroid Build Coastguard Worker         }
1251*b7c941bbSAndroid Build Coastguard Worker 
1252*b7c941bbSAndroid Build Coastguard Worker         mImgReaderInited = true;
1253*b7c941bbSAndroid Build Coastguard Worker         return AMEDIA_OK;
1254*b7c941bbSAndroid Build Coastguard Worker     }
1255*b7c941bbSAndroid Build Coastguard Worker 
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener,AImageReader ** imgReader,ANativeWindow ** imgReaderAnw)1256*b7c941bbSAndroid Build Coastguard Worker     media_status_t initImageReaderWithErrorLog(
1257*b7c941bbSAndroid Build Coastguard Worker             int32_t width, int32_t height, int32_t format, int32_t maxImages,
1258*b7c941bbSAndroid Build Coastguard Worker             AImageReader_ImageListener* listener, AImageReader **imgReader,
1259*b7c941bbSAndroid Build Coastguard Worker             ANativeWindow **imgReaderAnw) {
1260*b7c941bbSAndroid Build Coastguard Worker 
1261*b7c941bbSAndroid Build Coastguard Worker         media_status_t ret = AImageReader_new(
1262*b7c941bbSAndroid Build Coastguard Worker                 width, height, format,
1263*b7c941bbSAndroid Build Coastguard Worker                 maxImages, imgReader);
1264*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK) {
1265*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Create image reader. ret %d", ret);
1266*b7c941bbSAndroid Build Coastguard Worker             return ret;
1267*b7c941bbSAndroid Build Coastguard Worker         }
1268*b7c941bbSAndroid Build Coastguard Worker         if (*imgReader == nullptr) {
1269*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "null image reader created");
1270*b7c941bbSAndroid Build Coastguard Worker             return AMEDIA_ERROR_UNKNOWN;
1271*b7c941bbSAndroid Build Coastguard Worker         }
1272*b7c941bbSAndroid Build Coastguard Worker 
1273*b7c941bbSAndroid Build Coastguard Worker         ret = AImageReader_setImageListener(*imgReader, listener);
1274*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK) {
1275*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
1276*b7c941bbSAndroid Build Coastguard Worker             return ret;
1277*b7c941bbSAndroid Build Coastguard Worker         }
1278*b7c941bbSAndroid Build Coastguard Worker 
1279*b7c941bbSAndroid Build Coastguard Worker         ret = AImageReader_getWindow(*imgReader, imgReaderAnw);
1280*b7c941bbSAndroid Build Coastguard Worker         if (ret != AMEDIA_OK) {
1281*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
1282*b7c941bbSAndroid Build Coastguard Worker             return ret;
1283*b7c941bbSAndroid Build Coastguard Worker         }
1284*b7c941bbSAndroid Build Coastguard Worker         if (*imgReaderAnw == nullptr) {
1285*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from AImageReader!");
1286*b7c941bbSAndroid Build Coastguard Worker             return AMEDIA_ERROR_UNKNOWN;
1287*b7c941bbSAndroid Build Coastguard Worker         }
1288*b7c941bbSAndroid Build Coastguard Worker         return AMEDIA_OK;
1289*b7c941bbSAndroid Build Coastguard Worker     }
1290*b7c941bbSAndroid Build Coastguard Worker 
initPreviewAnw(JNIEnv * env,jobject jSurface)1291*b7c941bbSAndroid Build Coastguard Worker     ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
1292*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewAnw) {
1293*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Cannot init preview twice!");
1294*b7c941bbSAndroid Build Coastguard Worker             return nullptr;
1295*b7c941bbSAndroid Build Coastguard Worker         }
1296*b7c941bbSAndroid Build Coastguard Worker         mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
1297*b7c941bbSAndroid Build Coastguard Worker         mPreviewInited = true;
1298*b7c941bbSAndroid Build Coastguard Worker         return mPreviewAnw;
1299*b7c941bbSAndroid Build Coastguard Worker     }
1300*b7c941bbSAndroid Build Coastguard Worker 
createCaptureSessionWithLog(bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)1301*b7c941bbSAndroid Build Coastguard Worker     camera_status_t createCaptureSessionWithLog(bool isPreviewShared = false,
1302*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest *sessionParameters = nullptr) {
1303*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACaptureSessionOutput*> extraOutputs;
1304*b7c941bbSAndroid Build Coastguard Worker         return createCaptureSessionWithLog(extraOutputs, isPreviewShared, sessionParameters);
1305*b7c941bbSAndroid Build Coastguard Worker     }
1306*b7c941bbSAndroid Build Coastguard Worker 
createCaptureSessionOutputContainer(const std::vector<ACaptureSessionOutput * > extraOutputs,ACaptureSessionOutputContainer ** outputs,bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)1307*b7c941bbSAndroid Build Coastguard Worker     camera_status_t createCaptureSessionOutputContainer(
1308*b7c941bbSAndroid Build Coastguard Worker             const std::vector<ACaptureSessionOutput*> extraOutputs,
1309*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutputContainer** outputs,
1310*b7c941bbSAndroid Build Coastguard Worker             bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr) {
1311*b7c941bbSAndroid Build Coastguard Worker         if (!mMgrInited || (!mImgReaderInited && !mPreviewInited) || !outputs) {
1312*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Cannot create session output container. mgrInit %d "
1313*b7c941bbSAndroid Build Coastguard Worker                     "readerInit %d previewInit %d outputs %p",
1314*b7c941bbSAndroid Build Coastguard Worker                     mMgrInited, mImgReaderInited, mPreviewInited, outputs);
1315*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1316*b7c941bbSAndroid Build Coastguard Worker         }
1317*b7c941bbSAndroid Build Coastguard Worker 
1318*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACaptureSessionOutputContainer_create(outputs);
1319*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1320*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
1321*b7c941bbSAndroid Build Coastguard Worker             return ret;
1322*b7c941bbSAndroid Build Coastguard Worker         }
1323*b7c941bbSAndroid Build Coastguard Worker 
1324*b7c941bbSAndroid Build Coastguard Worker         if (mImgReaderInited) {
1325*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
1326*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
1327*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
1328*b7c941bbSAndroid Build Coastguard Worker                         "Session image reader output create fail! ret %d output %p",
1329*b7c941bbSAndroid Build Coastguard Worker                         ret, mImgReaderOutput);
1330*b7c941bbSAndroid Build Coastguard Worker                 if (ret == ACAMERA_OK) {
1331*b7c941bbSAndroid Build Coastguard Worker                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
1332*b7c941bbSAndroid Build Coastguard Worker                 }
1333*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1334*b7c941bbSAndroid Build Coastguard Worker             }
1335*b7c941bbSAndroid Build Coastguard Worker 
1336*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureSessionOutputContainer_add(*outputs, mImgReaderOutput);
1337*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1338*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
1339*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1340*b7c941bbSAndroid Build Coastguard Worker             }
1341*b7c941bbSAndroid Build Coastguard Worker         }
1342*b7c941bbSAndroid Build Coastguard Worker 
1343*b7c941bbSAndroid Build Coastguard Worker         for (auto extraOutput : extraOutputs) {
1344*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureSessionOutputContainer_add(*outputs, extraOutput);
1345*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1346*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
1347*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1348*b7c941bbSAndroid Build Coastguard Worker             }
1349*b7c941bbSAndroid Build Coastguard Worker         }
1350*b7c941bbSAndroid Build Coastguard Worker 
1351*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewInited) {
1352*b7c941bbSAndroid Build Coastguard Worker             if (isPreviewShared) {
1353*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureSessionSharedOutput_create(mPreviewAnw, &mPreviewOutput);
1354*b7c941bbSAndroid Build Coastguard Worker             } else {
1355*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
1356*b7c941bbSAndroid Build Coastguard Worker             }
1357*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
1358*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
1359*b7c941bbSAndroid Build Coastguard Worker                         "Session preview output create fail! ret %d output %p",
1360*b7c941bbSAndroid Build Coastguard Worker                         ret, mPreviewOutput);
1361*b7c941bbSAndroid Build Coastguard Worker                 if (ret == ACAMERA_OK) {
1362*b7c941bbSAndroid Build Coastguard Worker                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
1363*b7c941bbSAndroid Build Coastguard Worker                 }
1364*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1365*b7c941bbSAndroid Build Coastguard Worker             }
1366*b7c941bbSAndroid Build Coastguard Worker 
1367*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureSessionOutputContainer_add(*outputs, mPreviewOutput);
1368*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1369*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Session preview output add failed! ret %d", ret);
1370*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1371*b7c941bbSAndroid Build Coastguard Worker             }
1372*b7c941bbSAndroid Build Coastguard Worker         }
1373*b7c941bbSAndroid Build Coastguard Worker         return ret;
1374*b7c941bbSAndroid Build Coastguard Worker     }
1375*b7c941bbSAndroid Build Coastguard Worker 
createCaptureSessionWithLog(const std::vector<ACaptureSessionOutput * > extraOutputs,bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr,bool sessionConfigurationDefault=true)1376*b7c941bbSAndroid Build Coastguard Worker     camera_status_t createCaptureSessionWithLog(
1377*b7c941bbSAndroid Build Coastguard Worker             const std::vector<ACaptureSessionOutput*> extraOutputs,
1378*b7c941bbSAndroid Build Coastguard Worker             bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr,
1379*b7c941bbSAndroid Build Coastguard Worker             bool sessionConfigurationDefault = true) {
1380*b7c941bbSAndroid Build Coastguard Worker         if (mSession) {
1381*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Cannot create session before closing existing one");
1382*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1383*b7c941bbSAndroid Build Coastguard Worker         }
1384*b7c941bbSAndroid Build Coastguard Worker 
1385*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = createCaptureSessionOutputContainer(
1386*b7c941bbSAndroid Build Coastguard Worker                 extraOutputs, &mOutputs, isPreviewShared, sessionParameters);
1387*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1388*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Failed to create session output container! ret %d", ret);
1389*b7c941bbSAndroid Build Coastguard Worker             return ret;
1390*b7c941bbSAndroid Build Coastguard Worker         }
1391*b7c941bbSAndroid Build Coastguard Worker 
1392*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
1393*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION &&
1394*b7c941bbSAndroid Build Coastguard Worker                 ret != ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
1395*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "isSessionConfigurationSupported must return either OK "
1396*b7c941bbSAndroid Build Coastguard Worker                     ", UNSUPPORTED_OPERATION, or STREAM_CONFIGURE_FAIL, but returns %d", ret);
1397*b7c941bbSAndroid Build Coastguard Worker             return ret;
1398*b7c941bbSAndroid Build Coastguard Worker         }
1399*b7c941bbSAndroid Build Coastguard Worker 
1400*b7c941bbSAndroid Build Coastguard Worker         // If session configuration is not supported by default, return early
1401*b7c941bbSAndroid Build Coastguard Worker         // when camera device doesn't explicitly claim support.
1402*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK && !sessionConfigurationDefault) {
1403*b7c941bbSAndroid Build Coastguard Worker             return ret;
1404*b7c941bbSAndroid Build Coastguard Worker         }
1405*b7c941bbSAndroid Build Coastguard Worker 
1406*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraDevice_createCaptureSessionWithSessionParameters(
1407*b7c941bbSAndroid Build Coastguard Worker                 mDevice, mOutputs, sessionParameters, &mSessionCb, &mSession);
1408*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK || mSession == nullptr) {
1409*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
1410*b7c941bbSAndroid Build Coastguard Worker                     mCameraId, ret, mSession);
1411*b7c941bbSAndroid Build Coastguard Worker             if (ret == ACAMERA_OK) {
1412*b7c941bbSAndroid Build Coastguard Worker                 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
1413*b7c941bbSAndroid Build Coastguard Worker             }
1414*b7c941bbSAndroid Build Coastguard Worker             return ret;
1415*b7c941bbSAndroid Build Coastguard Worker         }
1416*b7c941bbSAndroid Build Coastguard Worker 
1417*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1418*b7c941bbSAndroid Build Coastguard Worker     }
1419*b7c941bbSAndroid Build Coastguard Worker 
prepareWindow(ANativeWindow * window)1420*b7c941bbSAndroid Build Coastguard Worker     camera_status_t prepareWindow(ANativeWindow *window) {
1421*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr) {
1422*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: Called when session hasn't been configured", __FUNCTION__);
1423*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_INVALID_OPERATION;
1424*b7c941bbSAndroid Build Coastguard Worker         }
1425*b7c941bbSAndroid Build Coastguard Worker         mSessionListener.incPendingPrepared(window);
1426*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_prepareWindow(mSession, window);
1427*b7c941bbSAndroid Build Coastguard Worker     }
1428*b7c941bbSAndroid Build Coastguard Worker 
setWindowPreparedCallback()1429*b7c941bbSAndroid Build Coastguard Worker     camera_status_t setWindowPreparedCallback() {
1430*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr) {
1431*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: Called when session hasn't been configured", __FUNCTION__);
1432*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_INVALID_OPERATION;
1433*b7c941bbSAndroid Build Coastguard Worker         }
1434*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_setWindowPreparedCallback(mSession, &mSessionListener,
1435*b7c941bbSAndroid Build Coastguard Worker                                                                mPreparedCb);
1436*b7c941bbSAndroid Build Coastguard Worker     }
1437*b7c941bbSAndroid Build Coastguard Worker 
gotAllPreparedCallbacksWithErrorLog()1438*b7c941bbSAndroid Build Coastguard Worker     bool gotAllPreparedCallbacksWithErrorLog() {
1439*b7c941bbSAndroid Build Coastguard Worker         return mSessionListener.gotAllPreparedCallbacksWithErrorLog();
1440*b7c941bbSAndroid Build Coastguard Worker     }
closeSession()1441*b7c941bbSAndroid Build Coastguard Worker     void closeSession() {
1442*b7c941bbSAndroid Build Coastguard Worker         if (mSession != nullptr) {
1443*b7c941bbSAndroid Build Coastguard Worker             ACameraCaptureSession_close(mSession);
1444*b7c941bbSAndroid Build Coastguard Worker         }
1445*b7c941bbSAndroid Build Coastguard Worker         if (mOutputs) {
1446*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutputContainer_free(mOutputs);
1447*b7c941bbSAndroid Build Coastguard Worker             mOutputs = nullptr;
1448*b7c941bbSAndroid Build Coastguard Worker         }
1449*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewOutput) {
1450*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutput_free(mPreviewOutput);
1451*b7c941bbSAndroid Build Coastguard Worker             mPreviewOutput = nullptr;
1452*b7c941bbSAndroid Build Coastguard Worker         }
1453*b7c941bbSAndroid Build Coastguard Worker         if (mImgReaderOutput) {
1454*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutput_free(mImgReaderOutput);
1455*b7c941bbSAndroid Build Coastguard Worker             mImgReaderOutput = nullptr;
1456*b7c941bbSAndroid Build Coastguard Worker         }
1457*b7c941bbSAndroid Build Coastguard Worker         mSession = nullptr;
1458*b7c941bbSAndroid Build Coastguard Worker     }
1459*b7c941bbSAndroid Build Coastguard Worker 
createRequestsWithErrorLog()1460*b7c941bbSAndroid Build Coastguard Worker     camera_status_t createRequestsWithErrorLog() {
1461*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACameraOutputTarget*> extraOutputs;
1462*b7c941bbSAndroid Build Coastguard Worker         return createRequestsWithErrorLog(extraOutputs);
1463*b7c941bbSAndroid Build Coastguard Worker     }
1464*b7c941bbSAndroid Build Coastguard Worker 
createRequestsWithErrorLog(const std::vector<ACameraOutputTarget * > extraOutputs,const ACameraIdList * physicalCameraIdList=nullptr)1465*b7c941bbSAndroid Build Coastguard Worker     camera_status_t createRequestsWithErrorLog(
1466*b7c941bbSAndroid Build Coastguard Worker                 const std::vector<ACameraOutputTarget*> extraOutputs,
1467*b7c941bbSAndroid Build Coastguard Worker                 const ACameraIdList* physicalCameraIdList = nullptr) {
1468*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewRequest || mStillRequest) {
1469*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
1470*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1471*b7c941bbSAndroid Build Coastguard Worker         }
1472*b7c941bbSAndroid Build Coastguard Worker 
1473*b7c941bbSAndroid Build Coastguard Worker         if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
1474*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString,
1475*b7c941bbSAndroid Build Coastguard Worker                     "Cannot create request. device %p previewInit %d readeInit %d",
1476*b7c941bbSAndroid Build Coastguard Worker                     mDevice, mPreviewInited, mImgReaderInited);
1477*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1478*b7c941bbSAndroid Build Coastguard Worker         }
1479*b7c941bbSAndroid Build Coastguard Worker 
1480*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret;
1481*b7c941bbSAndroid Build Coastguard Worker         bool usePhysicalSettings = (physicalCameraIdList != nullptr);
1482*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewInited) {
1483*b7c941bbSAndroid Build Coastguard Worker             if (!usePhysicalSettings) {
1484*b7c941bbSAndroid Build Coastguard Worker                 ret = ACameraDevice_createCaptureRequest(
1485*b7c941bbSAndroid Build Coastguard Worker                         mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
1486*b7c941bbSAndroid Build Coastguard Worker             } else {
1487*b7c941bbSAndroid Build Coastguard Worker                 ret = ACameraDevice_createCaptureRequest_withPhysicalIds(
1488*b7c941bbSAndroid Build Coastguard Worker                         mDevice, TEMPLATE_PREVIEW, physicalCameraIdList, &mPreviewRequest);
1489*b7c941bbSAndroid Build Coastguard Worker             }
1490*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1491*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
1492*b7c941bbSAndroid Build Coastguard Worker                         mCameraId, ret);
1493*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1494*b7c941bbSAndroid Build Coastguard Worker             }
1495*b7c941bbSAndroid Build Coastguard Worker 
1496*b7c941bbSAndroid Build Coastguard Worker             if (usePhysicalSettings) {
1497*b7c941bbSAndroid Build Coastguard Worker                 for (int i = 0; i < physicalCameraIdList->numCameras; i++) {
1498*b7c941bbSAndroid Build Coastguard Worker                     // Check physical camera specific metadata functions.
1499*b7c941bbSAndroid Build Coastguard Worker                     uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
1500*b7c941bbSAndroid Build Coastguard Worker                     ret = ACaptureRequest_setEntry_physicalCamera_u8(mPreviewRequest,
1501*b7c941bbSAndroid Build Coastguard Worker                             physicalCameraIdList->cameraIds[i], ACAMERA_CONTROL_AE_MODE,
1502*b7c941bbSAndroid Build Coastguard Worker                             1 /*count*/, &aeMode);
1503*b7c941bbSAndroid Build Coastguard Worker                     if (ret != ACAMERA_OK) {
1504*b7c941bbSAndroid Build Coastguard Worker                         LOG_ERROR(errorString,
1505*b7c941bbSAndroid Build Coastguard Worker                             "Error: Camera %s update AE mode key fail. ret %d",
1506*b7c941bbSAndroid Build Coastguard Worker                             physicalCameraIdList->cameraIds[i], ret);
1507*b7c941bbSAndroid Build Coastguard Worker                         return ret;
1508*b7c941bbSAndroid Build Coastguard Worker                     }
1509*b7c941bbSAndroid Build Coastguard Worker 
1510*b7c941bbSAndroid Build Coastguard Worker                     ACameraMetadata_const_entry entry;
1511*b7c941bbSAndroid Build Coastguard Worker                     ret = ACaptureRequest_getConstEntry_physicalCamera(mPreviewRequest,
1512*b7c941bbSAndroid Build Coastguard Worker                                 physicalCameraIdList->cameraIds[i],
1513*b7c941bbSAndroid Build Coastguard Worker                                 ACAMERA_CONTROL_AE_MODE, &entry);
1514*b7c941bbSAndroid Build Coastguard Worker                     if (ret != ACAMERA_OK) {
1515*b7c941bbSAndroid Build Coastguard Worker                         LOG_ERROR(errorString, "Get AE mode key for physicalCamera %s failed."
1516*b7c941bbSAndroid Build Coastguard Worker                                 " ret %d", physicalCameraIdList->cameraIds[i], ret);
1517*b7c941bbSAndroid Build Coastguard Worker                         return ret;
1518*b7c941bbSAndroid Build Coastguard Worker                     }
1519*b7c941bbSAndroid Build Coastguard Worker                     if (entry.data.u8[0] != aeMode) {
1520*b7c941bbSAndroid Build Coastguard Worker                         LOG_ERROR(errorString,
1521*b7c941bbSAndroid Build Coastguard Worker                             "Error: AE mode key is not updated. expect %d but get %d",
1522*b7c941bbSAndroid Build Coastguard Worker                             aeMode, entry.data.u8[0]);
1523*b7c941bbSAndroid Build Coastguard Worker                         return ACAMERA_ERROR_UNKNOWN;
1524*b7c941bbSAndroid Build Coastguard Worker                     }
1525*b7c941bbSAndroid Build Coastguard Worker                 }
1526*b7c941bbSAndroid Build Coastguard Worker             }
1527*b7c941bbSAndroid Build Coastguard Worker 
1528*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
1529*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1530*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
1531*b7c941bbSAndroid Build Coastguard Worker                         "Camera %s create request preview output target failed. ret %d",
1532*b7c941bbSAndroid Build Coastguard Worker                         mCameraId, ret);
1533*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1534*b7c941bbSAndroid Build Coastguard Worker             }
1535*b7c941bbSAndroid Build Coastguard Worker 
1536*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
1537*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1538*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
1539*b7c941bbSAndroid Build Coastguard Worker                         mCameraId, ret);
1540*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1541*b7c941bbSAndroid Build Coastguard Worker             }
1542*b7c941bbSAndroid Build Coastguard Worker 
1543*b7c941bbSAndroid Build Coastguard Worker             // Add extraOutputs to the request
1544*b7c941bbSAndroid Build Coastguard Worker             for (auto extraOutput : extraOutputs) {
1545*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureRequest_addTarget(mPreviewRequest, extraOutput);
1546*b7c941bbSAndroid Build Coastguard Worker                 if (ret != ACAMERA_OK) {
1547*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString, "Camera %s add extra request output failed. ret %d",
1548*b7c941bbSAndroid Build Coastguard Worker                             mCameraId, ret);
1549*b7c941bbSAndroid Build Coastguard Worker                     return ret;
1550*b7c941bbSAndroid Build Coastguard Worker                 }
1551*b7c941bbSAndroid Build Coastguard Worker             }
1552*b7c941bbSAndroid Build Coastguard Worker         } else {
1553*b7c941bbSAndroid Build Coastguard Worker             ALOGI("Preview not inited. Will not create preview request!");
1554*b7c941bbSAndroid Build Coastguard Worker         }
1555*b7c941bbSAndroid Build Coastguard Worker 
1556*b7c941bbSAndroid Build Coastguard Worker         if (mImgReaderInited) {
1557*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraDevice_createCaptureRequest(
1558*b7c941bbSAndroid Build Coastguard Worker                     mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
1559*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1560*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
1561*b7c941bbSAndroid Build Coastguard Worker                         mCameraId, ret);
1562*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1563*b7c941bbSAndroid Build Coastguard Worker             }
1564*b7c941bbSAndroid Build Coastguard Worker 
1565*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
1566*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1567*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
1568*b7c941bbSAndroid Build Coastguard Worker                         "Camera %s create request reader output target failed. ret %d",
1569*b7c941bbSAndroid Build Coastguard Worker                         mCameraId, ret);
1570*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1571*b7c941bbSAndroid Build Coastguard Worker             }
1572*b7c941bbSAndroid Build Coastguard Worker 
1573*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
1574*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
1575*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
1576*b7c941bbSAndroid Build Coastguard Worker                         mCameraId, ret);
1577*b7c941bbSAndroid Build Coastguard Worker                 return ret;
1578*b7c941bbSAndroid Build Coastguard Worker             }
1579*b7c941bbSAndroid Build Coastguard Worker 
1580*b7c941bbSAndroid Build Coastguard Worker             if (mPreviewInited) {
1581*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
1582*b7c941bbSAndroid Build Coastguard Worker                 if (ret != ACAMERA_OK) {
1583*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString,
1584*b7c941bbSAndroid Build Coastguard Worker                             "Camera %s add still request preview output failed. ret %d",
1585*b7c941bbSAndroid Build Coastguard Worker                             mCameraId, ret);
1586*b7c941bbSAndroid Build Coastguard Worker                     return ret;
1587*b7c941bbSAndroid Build Coastguard Worker                 }
1588*b7c941bbSAndroid Build Coastguard Worker             }
1589*b7c941bbSAndroid Build Coastguard Worker         } else {
1590*b7c941bbSAndroid Build Coastguard Worker             ALOGI("AImageReader not inited. Will not create still request!");
1591*b7c941bbSAndroid Build Coastguard Worker         }
1592*b7c941bbSAndroid Build Coastguard Worker 
1593*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1594*b7c941bbSAndroid Build Coastguard Worker     }
1595*b7c941bbSAndroid Build Coastguard Worker 
1596*b7c941bbSAndroid Build Coastguard Worker     // The output ACaptureRequest* is still managed by testcase class
getStillRequest(ACaptureRequest ** out)1597*b7c941bbSAndroid Build Coastguard Worker     camera_status_t getStillRequest(ACaptureRequest** out) {
1598*b7c941bbSAndroid Build Coastguard Worker         if (mStillRequest == nullptr) {
1599*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Camera %s Still capture request hasn't been created", mCameraId);
1600*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_INVALID_PARAMETER;
1601*b7c941bbSAndroid Build Coastguard Worker         }
1602*b7c941bbSAndroid Build Coastguard Worker         *out = mStillRequest;
1603*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1604*b7c941bbSAndroid Build Coastguard Worker     }
1605*b7c941bbSAndroid Build Coastguard Worker 
getPreviewRequest(ACaptureRequest ** out)1606*b7c941bbSAndroid Build Coastguard Worker     camera_status_t getPreviewRequest(ACaptureRequest** out) {
1607*b7c941bbSAndroid Build Coastguard Worker         if (mPreviewRequest == nullptr) {
1608*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Camera %s Preview capture request hasn't been created", mCameraId);
1609*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_INVALID_PARAMETER;
1610*b7c941bbSAndroid Build Coastguard Worker         }
1611*b7c941bbSAndroid Build Coastguard Worker         *out = mPreviewRequest;
1612*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1613*b7c941bbSAndroid Build Coastguard Worker     }
1614*b7c941bbSAndroid Build Coastguard Worker 
startPreview(int * sequenceId=nullptr,size_t physicalIdCnt=0,const char * const * extraPhysicalOutputs=nullptr,bool v2Callbacks=false)1615*b7c941bbSAndroid Build Coastguard Worker     camera_status_t startPreview(int *sequenceId = nullptr, size_t physicalIdCnt = 0,
1616*b7c941bbSAndroid Build Coastguard Worker             const char*const* extraPhysicalOutputs = nullptr, bool v2Callbacks = false) {
1617*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr || mPreviewRequest == nullptr) {
1618*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot start preview: session %p, preview request %p",
1619*b7c941bbSAndroid Build Coastguard Worker                     mSession, mPreviewRequest);
1620*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1621*b7c941bbSAndroid Build Coastguard Worker         }
1622*b7c941bbSAndroid Build Coastguard Worker         int previewSeqId;
1623*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret;
1624*b7c941bbSAndroid Build Coastguard Worker         if (sequenceId == nullptr) {
1625*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraCaptureSession_setRepeatingRequest(
1626*b7c941bbSAndroid Build Coastguard Worker                    mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
1627*b7c941bbSAndroid Build Coastguard Worker         } else if (physicalIdCnt == 0) {
1628*b7c941bbSAndroid Build Coastguard Worker             if (v2Callbacks) {
1629*b7c941bbSAndroid Build Coastguard Worker                 ret = ACameraCaptureSession_setRepeatingRequestV2(
1630*b7c941bbSAndroid Build Coastguard Worker                       mSession, &mResultCb2, 1, &mPreviewRequest, sequenceId);
1631*b7c941bbSAndroid Build Coastguard Worker             } else {
1632*b7c941bbSAndroid Build Coastguard Worker                 ret = ACameraCaptureSession_setRepeatingRequest(
1633*b7c941bbSAndroid Build Coastguard Worker                       mSession, &mResultCb, 1, &mPreviewRequest, sequenceId);
1634*b7c941bbSAndroid Build Coastguard Worker             }
1635*b7c941bbSAndroid Build Coastguard Worker         } else {
1636*b7c941bbSAndroid Build Coastguard Worker             if (extraPhysicalOutputs == nullptr) {
1637*b7c941bbSAndroid Build Coastguard Worker                 ALOGE("Testcase missing valid physical camera Ids for logical camera");
1638*b7c941bbSAndroid Build Coastguard Worker                 return ACAMERA_ERROR_INVALID_PARAMETER;
1639*b7c941bbSAndroid Build Coastguard Worker             }
1640*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener* resultListener =
1641*b7c941bbSAndroid Build Coastguard Worker                     static_cast<CaptureResultListener*>(mLogicalCameraResultCb.context);
1642*b7c941bbSAndroid Build Coastguard Worker             resultListener->registerPhysicalResults(physicalIdCnt, extraPhysicalOutputs);
1643*b7c941bbSAndroid Build Coastguard Worker             if (v2Callbacks) {
1644*b7c941bbSAndroid Build Coastguard Worker                 ret = ACameraCaptureSession_logicalCamera_setRepeatingRequestV2(
1645*b7c941bbSAndroid Build Coastguard Worker                         mSession, &mLogicalCameraResultCb2, 1, &mPreviewRequest, sequenceId);
1646*b7c941bbSAndroid Build Coastguard Worker             } else {
1647*b7c941bbSAndroid Build Coastguard Worker                 ret = ACameraCaptureSession_logicalCamera_setRepeatingRequest(
1648*b7c941bbSAndroid Build Coastguard Worker                         mSession, &mLogicalCameraResultCb, 1, &mPreviewRequest, sequenceId);
1649*b7c941bbSAndroid Build Coastguard Worker             }
1650*b7c941bbSAndroid Build Coastguard Worker         }
1651*b7c941bbSAndroid Build Coastguard Worker         return ret;
1652*b7c941bbSAndroid Build Coastguard Worker     }
1653*b7c941bbSAndroid Build Coastguard Worker 
startRepeatingRequest(int * sequenceId,ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * resultCb)1654*b7c941bbSAndroid Build Coastguard Worker     camera_status_t startRepeatingRequest(int *sequenceId, ACaptureRequest *request,
1655*b7c941bbSAndroid Build Coastguard Worker             ACameraCaptureSession_captureCallbacks *resultCb) {
1656*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr || request == nullptr || resultCb == nullptr) {
1657*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot start repeating request: session %p, request %p resultCb %p",
1658*b7c941bbSAndroid Build Coastguard Worker                     mSession, request, resultCb);
1659*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1660*b7c941bbSAndroid Build Coastguard Worker         }
1661*b7c941bbSAndroid Build Coastguard Worker 
1662*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_setRepeatingRequest(mSession, resultCb, 1, &request,
1663*b7c941bbSAndroid Build Coastguard Worker                 sequenceId);
1664*b7c941bbSAndroid Build Coastguard Worker     }
1665*b7c941bbSAndroid Build Coastguard Worker 
stopPreview()1666*b7c941bbSAndroid Build Coastguard Worker     camera_status_t stopPreview() {
1667*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr) {
1668*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot stop preview: session %p", mSession);
1669*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1670*b7c941bbSAndroid Build Coastguard Worker         }
1671*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_stopRepeating(mSession);
1672*b7c941bbSAndroid Build Coastguard Worker     }
1673*b7c941bbSAndroid Build Coastguard Worker 
abortCaptures()1674*b7c941bbSAndroid Build Coastguard Worker     camera_status_t abortCaptures() {
1675*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr) {
1676*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot abort session %p", mSession);
1677*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1678*b7c941bbSAndroid Build Coastguard Worker         }
1679*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_abortCaptures(mSession);
1680*b7c941bbSAndroid Build Coastguard Worker     }
1681*b7c941bbSAndroid Build Coastguard Worker 
updateRepeatingRequest(ACaptureRequest * updatedRequest,int * sequenceId=nullptr)1682*b7c941bbSAndroid Build Coastguard Worker     camera_status_t updateRepeatingRequest(ACaptureRequest *updatedRequest,
1683*b7c941bbSAndroid Build Coastguard Worker             int *sequenceId = nullptr) {
1684*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr || updatedRequest == nullptr) {
1685*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot update repeating request: session %p, updated request %p",
1686*b7c941bbSAndroid Build Coastguard Worker                     mSession, updatedRequest);
1687*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1688*b7c941bbSAndroid Build Coastguard Worker         }
1689*b7c941bbSAndroid Build Coastguard Worker 
1690*b7c941bbSAndroid Build Coastguard Worker         int previewSeqId;
1691*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret;
1692*b7c941bbSAndroid Build Coastguard Worker         if (sequenceId == nullptr) {
1693*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraCaptureSession_setRepeatingRequest(
1694*b7c941bbSAndroid Build Coastguard Worker                     mSession, nullptr, 1, &updatedRequest, &previewSeqId);
1695*b7c941bbSAndroid Build Coastguard Worker         } else {
1696*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraCaptureSession_setRepeatingRequest(
1697*b7c941bbSAndroid Build Coastguard Worker                     mSession, &mResultCb, 1, &updatedRequest, sequenceId);
1698*b7c941bbSAndroid Build Coastguard Worker         }
1699*b7c941bbSAndroid Build Coastguard Worker         return ret;
1700*b7c941bbSAndroid Build Coastguard Worker     }
1701*b7c941bbSAndroid Build Coastguard Worker 
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)1702*b7c941bbSAndroid Build Coastguard Worker     int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
1703*b7c941bbSAndroid Build Coastguard Worker         return mResultListener.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
1704*b7c941bbSAndroid Build Coastguard Worker     }
1705*b7c941bbSAndroid Build Coastguard Worker 
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)1706*b7c941bbSAndroid Build Coastguard Worker     bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
1707*b7c941bbSAndroid Build Coastguard Worker         return mResultListener.waitForFrameNumber(frameNumber, timeoutSec);
1708*b7c941bbSAndroid Build Coastguard Worker     }
1709*b7c941bbSAndroid Build Coastguard Worker 
waitForFrameNumberStarted(int64_t frameNumber,uint32_t timeoutSec)1710*b7c941bbSAndroid Build Coastguard Worker     bool waitForFrameNumberStarted(int64_t frameNumber, uint32_t timeoutSec) {
1711*b7c941bbSAndroid Build Coastguard Worker         return mResultListener.waitForFrameNumberStarted(frameNumber, timeoutSec);
1712*b7c941bbSAndroid Build Coastguard Worker     }
1713*b7c941bbSAndroid Build Coastguard Worker 
takePicture()1714*b7c941bbSAndroid Build Coastguard Worker     camera_status_t takePicture() {
1715*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr || mStillRequest == nullptr) {
1716*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot take picture: session %p, still request %p",
1717*b7c941bbSAndroid Build Coastguard Worker                     mSession, mStillRequest);
1718*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1719*b7c941bbSAndroid Build Coastguard Worker         }
1720*b7c941bbSAndroid Build Coastguard Worker         int seqId;
1721*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_capture(
1722*b7c941bbSAndroid Build Coastguard Worker                 mSession, nullptr, 1, &mStillRequest, &seqId);
1723*b7c941bbSAndroid Build Coastguard Worker     }
1724*b7c941bbSAndroid Build Coastguard Worker 
capture(ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * listener,int * seqId)1725*b7c941bbSAndroid Build Coastguard Worker     camera_status_t capture(ACaptureRequest* request,
1726*b7c941bbSAndroid Build Coastguard Worker             ACameraCaptureSession_captureCallbacks* listener,
1727*b7c941bbSAndroid Build Coastguard Worker             /*out*/int* seqId) {
1728*b7c941bbSAndroid Build Coastguard Worker         if (mSession == nullptr || request == nullptr) {
1729*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Testcase cannot capture session: session %p, request %p",
1730*b7c941bbSAndroid Build Coastguard Worker                     mSession, request);
1731*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1732*b7c941bbSAndroid Build Coastguard Worker         }
1733*b7c941bbSAndroid Build Coastguard Worker         return ACameraCaptureSession_capture(
1734*b7c941bbSAndroid Build Coastguard Worker                 mSession, listener, 1, &request, seqId);
1735*b7c941bbSAndroid Build Coastguard Worker     }
1736*b7c941bbSAndroid Build Coastguard Worker 
resetWithErrorLog()1737*b7c941bbSAndroid Build Coastguard Worker     camera_status_t resetWithErrorLog() {
1738*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret;
1739*b7c941bbSAndroid Build Coastguard Worker 
1740*b7c941bbSAndroid Build Coastguard Worker         closeSession();
1741*b7c941bbSAndroid Build Coastguard Worker 
1742*b7c941bbSAndroid Build Coastguard Worker         for (int i = 0; i < 50; i++) {
1743*b7c941bbSAndroid Build Coastguard Worker             usleep(100000); // sleep 100ms
1744*b7c941bbSAndroid Build Coastguard Worker             if (mSessionListener.isClosed()) {
1745*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("Session take ~%d ms to close", i*100);
1746*b7c941bbSAndroid Build Coastguard Worker                 break;
1747*b7c941bbSAndroid Build Coastguard Worker             }
1748*b7c941bbSAndroid Build Coastguard Worker         }
1749*b7c941bbSAndroid Build Coastguard Worker 
1750*b7c941bbSAndroid Build Coastguard Worker         if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
1751*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString,
1752*b7c941bbSAndroid Build Coastguard Worker                     "Session for camera %s close error. isClosde %d close count %d",
1753*b7c941bbSAndroid Build Coastguard Worker                     mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
1754*b7c941bbSAndroid Build Coastguard Worker             return ACAMERA_ERROR_UNKNOWN;
1755*b7c941bbSAndroid Build Coastguard Worker         }
1756*b7c941bbSAndroid Build Coastguard Worker         mSessionListener.reset();
1757*b7c941bbSAndroid Build Coastguard Worker         mResultListener.reset();
1758*b7c941bbSAndroid Build Coastguard Worker 
1759*b7c941bbSAndroid Build Coastguard Worker         ret = closeCamera();
1760*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
1761*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
1762*b7c941bbSAndroid Build Coastguard Worker             return ret;
1763*b7c941bbSAndroid Build Coastguard Worker         }
1764*b7c941bbSAndroid Build Coastguard Worker 
1765*b7c941bbSAndroid Build Coastguard Worker         resetCamera();
1766*b7c941bbSAndroid Build Coastguard Worker         return ACAMERA_OK;
1767*b7c941bbSAndroid Build Coastguard Worker     }
1768*b7c941bbSAndroid Build Coastguard Worker 
getSessionListener()1769*b7c941bbSAndroid Build Coastguard Worker     CaptureSessionListener* getSessionListener() {
1770*b7c941bbSAndroid Build Coastguard Worker         return &mSessionListener;
1771*b7c941bbSAndroid Build Coastguard Worker     }
1772*b7c941bbSAndroid Build Coastguard Worker 
getCameraDevice()1773*b7c941bbSAndroid Build Coastguard Worker     ACameraDevice* getCameraDevice() {
1774*b7c941bbSAndroid Build Coastguard Worker         return mDevice;
1775*b7c941bbSAndroid Build Coastguard Worker     }
1776*b7c941bbSAndroid Build Coastguard Worker 
getPreviewOutput()1777*b7c941bbSAndroid Build Coastguard Worker     ACaptureSessionOutput *getPreviewOutput() {
1778*b7c941bbSAndroid Build Coastguard Worker         return mPreviewOutput;
1779*b7c941bbSAndroid Build Coastguard Worker     }
1780*b7c941bbSAndroid Build Coastguard Worker 
1781*b7c941bbSAndroid Build Coastguard Worker   private:
createManager()1782*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* createManager() {
1783*b7c941bbSAndroid Build Coastguard Worker         if (!mCameraManager) {
1784*b7c941bbSAndroid Build Coastguard Worker             mCameraManager = ACameraManager_create();
1785*b7c941bbSAndroid Build Coastguard Worker         }
1786*b7c941bbSAndroid Build Coastguard Worker         return mCameraManager;
1787*b7c941bbSAndroid Build Coastguard Worker     }
1788*b7c941bbSAndroid Build Coastguard Worker 
1789*b7c941bbSAndroid Build Coastguard Worker     CameraServiceListener mServiceListener;
1790*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_AvailabilityCallbacks mServiceCb {
1791*b7c941bbSAndroid Build Coastguard Worker         &mServiceListener,
1792*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener::onAvailable,
1793*b7c941bbSAndroid Build Coastguard Worker         CameraServiceListener::onUnavailable
1794*b7c941bbSAndroid Build Coastguard Worker     };
1795*b7c941bbSAndroid Build Coastguard Worker     CameraDeviceListener mDeviceListener;
1796*b7c941bbSAndroid Build Coastguard Worker     ACameraDevice_StateCallbacks mDeviceCb {
1797*b7c941bbSAndroid Build Coastguard Worker         &mDeviceListener,
1798*b7c941bbSAndroid Build Coastguard Worker         CameraDeviceListener::onDisconnected,
1799*b7c941bbSAndroid Build Coastguard Worker         CameraDeviceListener::onError
1800*b7c941bbSAndroid Build Coastguard Worker     };
1801*b7c941bbSAndroid Build Coastguard Worker     CaptureSessionListener mSessionListener;
1802*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession_stateCallbacks mSessionCb {
1803*b7c941bbSAndroid Build Coastguard Worker         &mSessionListener,
1804*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener::onClosed,
1805*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener::onReady,
1806*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener::onActive
1807*b7c941bbSAndroid Build Coastguard Worker     };
1808*b7c941bbSAndroid Build Coastguard Worker 
1809*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession_prepareCallback mPreparedCb  = &CaptureSessionListener::onWindowPrepared;
1810*b7c941bbSAndroid Build Coastguard Worker 
1811*b7c941bbSAndroid Build Coastguard Worker     CaptureResultListener mResultListener;
1812*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession_captureCallbacks mResultCb {
1813*b7c941bbSAndroid Build Coastguard Worker         &mResultListener,
1814*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureStart,
1815*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureProgressed,
1816*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureCompleted,
1817*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureFailed,
1818*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceCompleted,
1819*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceAborted,
1820*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureBufferLost
1821*b7c941bbSAndroid Build Coastguard Worker     };
1822*b7c941bbSAndroid Build Coastguard Worker 
1823*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession_captureCallbacksV2 mResultCb2 {
1824*b7c941bbSAndroid Build Coastguard Worker         &mResultListener,
1825*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureStartV2,
1826*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureProgressed,
1827*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureCompleted,
1828*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureFailed,
1829*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceCompleted,
1830*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceAborted,
1831*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureBufferLost
1832*b7c941bbSAndroid Build Coastguard Worker     };
1833*b7c941bbSAndroid Build Coastguard Worker 
1834*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession_logicalCamera_captureCallbacksV2 mLogicalCameraResultCb2 {
1835*b7c941bbSAndroid Build Coastguard Worker         &mResultListener,
1836*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureStartV2,
1837*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureProgressed,
1838*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onLogicalCameraCaptureCompleted,
1839*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onLogicalCameraCaptureFailed,
1840*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceCompleted,
1841*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceAborted,
1842*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureBufferLost
1843*b7c941bbSAndroid Build Coastguard Worker     };
1844*b7c941bbSAndroid Build Coastguard Worker 
1845*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCameraResultCb {
1846*b7c941bbSAndroid Build Coastguard Worker         &mResultListener,
1847*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureStart,
1848*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureProgressed,
1849*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onLogicalCameraCaptureCompleted,
1850*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onLogicalCameraCaptureFailed,
1851*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceCompleted,
1852*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureSequenceAborted,
1853*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener::onCaptureBufferLost
1854*b7c941bbSAndroid Build Coastguard Worker     };
1855*b7c941bbSAndroid Build Coastguard Worker 
1856*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList* mCameraIdList = nullptr;
1857*b7c941bbSAndroid Build Coastguard Worker     ACameraDevice* mDevice = nullptr;
1858*b7c941bbSAndroid Build Coastguard Worker     AImageReader* mImgReader = nullptr;
1859*b7c941bbSAndroid Build Coastguard Worker     ANativeWindow* mImgReaderAnw = nullptr;
1860*b7c941bbSAndroid Build Coastguard Worker     ANativeWindow* mPreviewAnw = nullptr;
1861*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mCameraManager = nullptr;
1862*b7c941bbSAndroid Build Coastguard Worker     ACaptureSessionOutputContainer* mOutputs = nullptr;
1863*b7c941bbSAndroid Build Coastguard Worker     ACaptureSessionOutput* mPreviewOutput = nullptr;
1864*b7c941bbSAndroid Build Coastguard Worker     ACaptureSessionOutput* mImgReaderOutput = nullptr;
1865*b7c941bbSAndroid Build Coastguard Worker     ACameraCaptureSession* mSession = nullptr;
1866*b7c941bbSAndroid Build Coastguard Worker     ACaptureRequest* mPreviewRequest = nullptr;
1867*b7c941bbSAndroid Build Coastguard Worker     ACaptureRequest* mStillRequest = nullptr;
1868*b7c941bbSAndroid Build Coastguard Worker     ACameraOutputTarget* mReqPreviewOutput = nullptr;
1869*b7c941bbSAndroid Build Coastguard Worker     ACameraOutputTarget* mReqImgReaderOutput = nullptr;
1870*b7c941bbSAndroid Build Coastguard Worker     const char* mCameraId;
1871*b7c941bbSAndroid Build Coastguard Worker     JNIEnv* mJNIEnv = nullptr;
1872*b7c941bbSAndroid Build Coastguard Worker     jstring mJOverrideCameraId;
1873*b7c941bbSAndroid Build Coastguard Worker     const char* mOverrideCameraId = nullptr;
1874*b7c941bbSAndroid Build Coastguard Worker 
1875*b7c941bbSAndroid Build Coastguard Worker     bool mMgrInited = false; // cameraId, serviceListener
1876*b7c941bbSAndroid Build Coastguard Worker     bool mImgReaderInited = false;
1877*b7c941bbSAndroid Build Coastguard Worker     bool mPreviewInited = false;
1878*b7c941bbSAndroid Build Coastguard Worker };
1879*b7c941bbSAndroid Build Coastguard Worker 
throwAssertionError(JNIEnv * env,const char * message)1880*b7c941bbSAndroid Build Coastguard Worker jint throwAssertionError(JNIEnv* env, const char* message)
1881*b7c941bbSAndroid Build Coastguard Worker {
1882*b7c941bbSAndroid Build Coastguard Worker     jclass assertionClass;
1883*b7c941bbSAndroid Build Coastguard Worker     const char* className = "junit/framework/AssertionFailedError";
1884*b7c941bbSAndroid Build Coastguard Worker 
1885*b7c941bbSAndroid Build Coastguard Worker     assertionClass = env->FindClass(className);
1886*b7c941bbSAndroid Build Coastguard Worker     if (assertionClass == nullptr) {
1887*b7c941bbSAndroid Build Coastguard Worker         ALOGE("Native throw error: cannot find class %s", className);
1888*b7c941bbSAndroid Build Coastguard Worker         return -1;
1889*b7c941bbSAndroid Build Coastguard Worker     }
1890*b7c941bbSAndroid Build Coastguard Worker     return env->ThrowNew(assertionClass, message);
1891*b7c941bbSAndroid Build Coastguard Worker }
1892*b7c941bbSAndroid Build Coastguard Worker 
1893*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)1894*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1895*b7c941bbSAndroid Build Coastguard Worker testCameraManagerGetAndCloseNative(
1896*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/) {
1897*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
1898*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
1899*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* cameraManager2 = nullptr;
1900*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* cameraManager3 = nullptr;
1901*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* cameraManager4 = nullptr;
1902*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = ACAMERA_OK;
1903*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* cameraManager = ACameraManager_create();
1904*b7c941bbSAndroid Build Coastguard Worker     if (cameraManager == nullptr) {
1905*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
1906*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
1907*b7c941bbSAndroid Build Coastguard Worker     }
1908*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(cameraManager);
1909*b7c941bbSAndroid Build Coastguard Worker     cameraManager = nullptr;
1910*b7c941bbSAndroid Build Coastguard Worker 
1911*b7c941bbSAndroid Build Coastguard Worker     // Test get/close multiple instances
1912*b7c941bbSAndroid Build Coastguard Worker     cameraManager = ACameraManager_create();
1913*b7c941bbSAndroid Build Coastguard Worker     cameraManager2 = ACameraManager_create();
1914*b7c941bbSAndroid Build Coastguard Worker     if (cameraManager2 == nullptr) {
1915*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
1916*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
1917*b7c941bbSAndroid Build Coastguard Worker     }
1918*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(cameraManager);
1919*b7c941bbSAndroid Build Coastguard Worker     cameraManager = nullptr;
1920*b7c941bbSAndroid Build Coastguard Worker     cameraManager3 = ACameraManager_create();
1921*b7c941bbSAndroid Build Coastguard Worker     if (cameraManager3 == nullptr) {
1922*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
1923*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
1924*b7c941bbSAndroid Build Coastguard Worker     }
1925*b7c941bbSAndroid Build Coastguard Worker     cameraManager4 = ACameraManager_create();
1926*b7c941bbSAndroid Build Coastguard Worker         if (cameraManager4 == nullptr) {
1927*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
1928*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
1929*b7c941bbSAndroid Build Coastguard Worker     }
1930*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(cameraManager3);
1931*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(cameraManager2);
1932*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(cameraManager4);
1933*b7c941bbSAndroid Build Coastguard Worker 
1934*b7c941bbSAndroid Build Coastguard Worker     pass = true;
1935*b7c941bbSAndroid Build Coastguard Worker cleanup:
1936*b7c941bbSAndroid Build Coastguard Worker     if (cameraManager) {
1937*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_delete(cameraManager);
1938*b7c941bbSAndroid Build Coastguard Worker     }
1939*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1940*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
1941*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
1942*b7c941bbSAndroid Build Coastguard Worker     }
1943*b7c941bbSAndroid Build Coastguard Worker     return pass;
1944*b7c941bbSAndroid Build Coastguard Worker }
1945*b7c941bbSAndroid Build Coastguard Worker 
1946*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)1947*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1948*b7c941bbSAndroid Build Coastguard Worker testCameraManagerGetCameraIdsNative(
1949*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/) {
1950*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
1951*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
1952*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
1953*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList *cameraIdList = nullptr;
1954*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1955*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1956*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1957*b7c941bbSAndroid Build Coastguard Worker                 ret, cameraIdList);
1958*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
1959*b7c941bbSAndroid Build Coastguard Worker     }
1960*b7c941bbSAndroid Build Coastguard Worker     ALOGI("Number of cameras: %d", cameraIdList->numCameras);
1961*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < cameraIdList->numCameras; i++) {
1962*b7c941bbSAndroid Build Coastguard Worker         ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
1963*b7c941bbSAndroid Build Coastguard Worker     }
1964*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_deleteCameraIdList(cameraIdList);
1965*b7c941bbSAndroid Build Coastguard Worker     cameraIdList = nullptr;
1966*b7c941bbSAndroid Build Coastguard Worker 
1967*b7c941bbSAndroid Build Coastguard Worker     pass = true;
1968*b7c941bbSAndroid Build Coastguard Worker cleanup:
1969*b7c941bbSAndroid Build Coastguard Worker     if (mgr) {
1970*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_delete(mgr);
1971*b7c941bbSAndroid Build Coastguard Worker     }
1972*b7c941bbSAndroid Build Coastguard Worker     if (cameraIdList) {
1973*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_deleteCameraIdList(cameraIdList);
1974*b7c941bbSAndroid Build Coastguard Worker     }
1975*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1976*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
1977*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
1978*b7c941bbSAndroid Build Coastguard Worker     }
1979*b7c941bbSAndroid Build Coastguard Worker     return pass;
1980*b7c941bbSAndroid Build Coastguard Worker }
1981*b7c941bbSAndroid Build Coastguard Worker 
1982*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerExtendedAvailabilityCallbackNative(JNIEnv * env,jclass)1983*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1984*b7c941bbSAndroid Build Coastguard Worker testCameraManagerExtendedAvailabilityCallbackNative(
1985*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/) {
1986*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
1987*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
1988*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
1989*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList *cameraIdList = nullptr;
1990*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1991*b7c941bbSAndroid Build Coastguard Worker     int numCameras = cameraIdList->numCameras;
1992*b7c941bbSAndroid Build Coastguard Worker     CameraServiceListener listener;
1993*b7c941bbSAndroid Build Coastguard Worker     CameraServiceListener::StringPairSet unavailablePhysicalCameras;
1994*b7c941bbSAndroid Build Coastguard Worker     CameraServiceListener::StringPairSet physicalCameraIdPairs;
1995*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_ExtendedAvailabilityCallbacks cbs {
1996*b7c941bbSAndroid Build Coastguard Worker             {
1997*b7c941bbSAndroid Build Coastguard Worker                 &listener,
1998*b7c941bbSAndroid Build Coastguard Worker                 CameraServiceListener::onAvailable,
1999*b7c941bbSAndroid Build Coastguard Worker                 CameraServiceListener::onUnavailable
2000*b7c941bbSAndroid Build Coastguard Worker             },
2001*b7c941bbSAndroid Build Coastguard Worker             CameraServiceListener::onCameraAccessPrioritiesChanged,
2002*b7c941bbSAndroid Build Coastguard Worker             CameraServiceListener::onPhysicalCameraAvailable,
2003*b7c941bbSAndroid Build Coastguard Worker             CameraServiceListener::onPhysicalCameraUnavailable,
2004*b7c941bbSAndroid Build Coastguard Worker             {}
2005*b7c941bbSAndroid Build Coastguard Worker     };
2006*b7c941bbSAndroid Build Coastguard Worker 
2007*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraManager_registerExtendedAvailabilityCallback(mgr, &cbs);
2008*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2009*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Register extended availability callback failed: ret %d", ret);
2010*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2011*b7c941bbSAndroid Build Coastguard Worker     }
2012*b7c941bbSAndroid Build Coastguard Worker     sleep(1); // sleep a second to give some time for callbacks to happen
2013*b7c941bbSAndroid Build Coastguard Worker 
2014*b7c941bbSAndroid Build Coastguard Worker     // Should at least get onAvailable for each camera once
2015*b7c941bbSAndroid Build Coastguard Worker     if (listener.getAvailableCount() < numCameras) {
2016*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
2017*b7c941bbSAndroid Build Coastguard Worker                 numCameras, listener.getAvailableCount());
2018*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2019*b7c941bbSAndroid Build Coastguard Worker     }
2020*b7c941bbSAndroid Build Coastguard Worker 
2021*b7c941bbSAndroid Build Coastguard Worker     {
2022*b7c941bbSAndroid Build Coastguard Worker         int availablePhysicalCamera = listener.getPhysicalCameraAvailableCount();
2023*b7c941bbSAndroid Build Coastguard Worker         if (availablePhysicalCamera > 0) {
2024*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Expect no available callback, but got %d",
2025*b7c941bbSAndroid Build Coastguard Worker                     availablePhysicalCamera);
2026*b7c941bbSAndroid Build Coastguard Worker         }
2027*b7c941bbSAndroid Build Coastguard Worker     }
2028*b7c941bbSAndroid Build Coastguard Worker 
2029*b7c941bbSAndroid Build Coastguard Worker     unavailablePhysicalCameras = listener.getUnavailablePhysicalCameras();
2030*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
2031*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = cameraIdList->cameraIds[i];
2032*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
2033*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2034*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2035*b7c941bbSAndroid Build Coastguard Worker         }
2036*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata* c;
2037*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &c);
2038*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK || c == nullptr) {
2039*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
2040*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2041*b7c941bbSAndroid Build Coastguard Worker         }
2042*b7c941bbSAndroid Build Coastguard Worker         std::unique_ptr<ACameraMetadata> chars(c);
2043*b7c941bbSAndroid Build Coastguard Worker 
2044*b7c941bbSAndroid Build Coastguard Worker         size_t physicalCameraCnt = 0;
2045*b7c941bbSAndroid Build Coastguard Worker         const char *const* physicalCameraIds = nullptr;
2046*b7c941bbSAndroid Build Coastguard Worker         if (!ACameraMetadata_isLogicalMultiCamera(
2047*b7c941bbSAndroid Build Coastguard Worker                 chars.get(), &physicalCameraCnt, &physicalCameraIds)) {
2048*b7c941bbSAndroid Build Coastguard Worker             continue;
2049*b7c941bbSAndroid Build Coastguard Worker         }
2050*b7c941bbSAndroid Build Coastguard Worker         for (size_t j = 0; j < physicalCameraCnt; j++) {
2051*b7c941bbSAndroid Build Coastguard Worker             physicalCameraIdPairs.emplace(cameraId, physicalCameraIds[j]);
2052*b7c941bbSAndroid Build Coastguard Worker         }
2053*b7c941bbSAndroid Build Coastguard Worker     }
2054*b7c941bbSAndroid Build Coastguard Worker     for (const auto& unavailIdPair : unavailablePhysicalCameras) {
2055*b7c941bbSAndroid Build Coastguard Worker         bool validPair = false;
2056*b7c941bbSAndroid Build Coastguard Worker         for (const auto& idPair : physicalCameraIdPairs) {
2057*b7c941bbSAndroid Build Coastguard Worker             if (idPair.first == unavailIdPair.first && idPair.second == unavailIdPair.second) {
2058*b7c941bbSAndroid Build Coastguard Worker                 validPair = true;
2059*b7c941bbSAndroid Build Coastguard Worker                 break;
2060*b7c941bbSAndroid Build Coastguard Worker             }
2061*b7c941bbSAndroid Build Coastguard Worker         }
2062*b7c941bbSAndroid Build Coastguard Worker         if (!validPair) {
2063*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Expect valid unavailable physical cameras, but got %s : %s",
2064*b7c941bbSAndroid Build Coastguard Worker                     unavailIdPair.first.c_str(), unavailIdPair.second.c_str());
2065*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2066*b7c941bbSAndroid Build Coastguard Worker         }
2067*b7c941bbSAndroid Build Coastguard Worker     }
2068*b7c941bbSAndroid Build Coastguard Worker 
2069*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraManager_unregisterExtendedAvailabilityCallback(mgr, &cbs);
2070*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2071*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Unregister extended availability callback failed: ret %d", ret);
2072*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2073*b7c941bbSAndroid Build Coastguard Worker     }
2074*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2075*b7c941bbSAndroid Build Coastguard Worker cleanup:
2076*b7c941bbSAndroid Build Coastguard Worker     if (cameraIdList) {
2077*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_deleteCameraIdList(cameraIdList);
2078*b7c941bbSAndroid Build Coastguard Worker     }
2079*b7c941bbSAndroid Build Coastguard Worker     if (mgr) {
2080*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_delete(mgr);
2081*b7c941bbSAndroid Build Coastguard Worker     }
2082*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2083*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
2084*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
2085*b7c941bbSAndroid Build Coastguard Worker     }
2086*b7c941bbSAndroid Build Coastguard Worker     return pass;
2087*b7c941bbSAndroid Build Coastguard Worker }
2088*b7c941bbSAndroid Build Coastguard Worker 
2089*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)2090*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
2091*b7c941bbSAndroid Build Coastguard Worker testCameraManagerAvailabilityCallbackNative(
2092*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/) {
2093*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
2094*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
2095*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
2096*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList *cameraIdList = nullptr;
2097*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2098*b7c941bbSAndroid Build Coastguard Worker     int numCameras = cameraIdList->numCameras;
2099*b7c941bbSAndroid Build Coastguard Worker     CameraServiceListener listener;
2100*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_AvailabilityCallbacks cbs {
2101*b7c941bbSAndroid Build Coastguard Worker             &listener,
2102*b7c941bbSAndroid Build Coastguard Worker             CameraServiceListener::onAvailable,
2103*b7c941bbSAndroid Build Coastguard Worker             CameraServiceListener::onUnavailable};
2104*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
2105*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2106*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
2107*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2108*b7c941bbSAndroid Build Coastguard Worker     }
2109*b7c941bbSAndroid Build Coastguard Worker     sleep(1); // sleep a second to give some time for callbacks to happen
2110*b7c941bbSAndroid Build Coastguard Worker 
2111*b7c941bbSAndroid Build Coastguard Worker     // Should at least get onAvailable for each camera once
2112*b7c941bbSAndroid Build Coastguard Worker     if (listener.getAvailableCount() < numCameras) {
2113*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
2114*b7c941bbSAndroid Build Coastguard Worker                 numCameras, listener.getAvailableCount());
2115*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2116*b7c941bbSAndroid Build Coastguard Worker     }
2117*b7c941bbSAndroid Build Coastguard Worker 
2118*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
2119*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2120*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
2121*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2122*b7c941bbSAndroid Build Coastguard Worker     }
2123*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2124*b7c941bbSAndroid Build Coastguard Worker cleanup:
2125*b7c941bbSAndroid Build Coastguard Worker     if (cameraIdList) {
2126*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_deleteCameraIdList(cameraIdList);
2127*b7c941bbSAndroid Build Coastguard Worker     }
2128*b7c941bbSAndroid Build Coastguard Worker     if (mgr) {
2129*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_delete(mgr);
2130*b7c941bbSAndroid Build Coastguard Worker     }
2131*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2132*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
2133*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
2134*b7c941bbSAndroid Build Coastguard Worker     }
2135*b7c941bbSAndroid Build Coastguard Worker     return pass;
2136*b7c941bbSAndroid Build Coastguard Worker }
2137*b7c941bbSAndroid Build Coastguard Worker 
2138*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)2139*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
2140*b7c941bbSAndroid Build Coastguard Worker testCameraManagerCharacteristicsNative(
2141*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/) {
2142*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
2143*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
2144*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
2145*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList *cameraIdList = nullptr;
2146*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
2147*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* copy = nullptr;
2148*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
2149*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2150*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
2151*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
2152*b7c941bbSAndroid Build Coastguard Worker                 ret, cameraIdList);
2153*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2154*b7c941bbSAndroid Build Coastguard Worker     }
2155*b7c941bbSAndroid Build Coastguard Worker     numCameras = cameraIdList->numCameras;
2156*b7c941bbSAndroid Build Coastguard Worker 
2157*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
2158*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraManager_getCameraCharacteristics(
2159*b7c941bbSAndroid Build Coastguard Worker                 mgr, cameraIdList->cameraIds[i], &chars);
2160*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2161*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2162*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2163*b7c941bbSAndroid Build Coastguard Worker         }
2164*b7c941bbSAndroid Build Coastguard Worker 
2165*b7c941bbSAndroid Build Coastguard Worker         int32_t numTags = 0;
2166*b7c941bbSAndroid Build Coastguard Worker         const uint32_t* tags = nullptr;
2167*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
2168*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2169*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
2170*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2171*b7c941bbSAndroid Build Coastguard Worker         }
2172*b7c941bbSAndroid Build Coastguard Worker 
2173*b7c941bbSAndroid Build Coastguard Worker         for (int tid = 0; tid < numTags; tid++) {
2174*b7c941bbSAndroid Build Coastguard Worker             uint32_t tagId = tags[tid];
2175*b7c941bbSAndroid Build Coastguard Worker             ALOGV("%s camera characteristics contains key %u", __FUNCTION__, tagId);
2176*b7c941bbSAndroid Build Coastguard Worker             uint32_t sectionId = tagId >> 16;
2177*b7c941bbSAndroid Build Coastguard Worker             if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
2178*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
2179*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2180*b7c941bbSAndroid Build Coastguard Worker             }
2181*b7c941bbSAndroid Build Coastguard Worker         }
2182*b7c941bbSAndroid Build Coastguard Worker 
2183*b7c941bbSAndroid Build Coastguard Worker         for (const auto keyAndTag : ndk_metadata_name_to_tag) {
2184*b7c941bbSAndroid Build Coastguard Worker             uint32_t returnedTag = 0;
2185*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraMetadata_getTagFromName(chars, /*name*/keyAndTag.first, &returnedTag);
2186*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2187*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "ACameraMetadata_getTagFromName() failed: ret %d", ret);
2188*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2189*b7c941bbSAndroid Build Coastguard Worker             }
2190*b7c941bbSAndroid Build Coastguard Worker             if (keyAndTag.second != returnedTag) {
2191*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "ACameraMetadata_getTagFromName returned incorrect tag"
2192*b7c941bbSAndroid Build Coastguard Worker                         "value %u for tag %s, expected value %u", returnedTag, keyAndTag.first,
2193*b7c941bbSAndroid Build Coastguard Worker                         keyAndTag.second);
2194*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2195*b7c941bbSAndroid Build Coastguard Worker             }
2196*b7c941bbSAndroid Build Coastguard Worker         }
2197*b7c941bbSAndroid Build Coastguard Worker 
2198*b7c941bbSAndroid Build Coastguard Worker 
2199*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entry;
2200*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2201*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2202*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
2203*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2204*b7c941bbSAndroid Build Coastguard Worker         }
2205*b7c941bbSAndroid Build Coastguard Worker 
2206*b7c941bbSAndroid Build Coastguard Worker         // Check the entry is actually legit
2207*b7c941bbSAndroid Build Coastguard Worker         if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
2208*b7c941bbSAndroid Build Coastguard Worker                 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
2209*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString,
2210*b7c941bbSAndroid Build Coastguard Worker                     "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
2211*b7c941bbSAndroid Build Coastguard Worker                     "type %d (expected %d), data %p (expected not null)",
2212*b7c941bbSAndroid Build Coastguard Worker                     entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
2213*b7c941bbSAndroid Build Coastguard Worker                     entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
2214*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2215*b7c941bbSAndroid Build Coastguard Worker         }
2216*b7c941bbSAndroid Build Coastguard Worker         // All camera supports BC except depth only cameras
2217*b7c941bbSAndroid Build Coastguard Worker         bool supportBC = false, supportDepth = false;
2218*b7c941bbSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.count; i++) {
2219*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
2220*b7c941bbSAndroid Build Coastguard Worker                 supportBC = true;
2221*b7c941bbSAndroid Build Coastguard Worker             }
2222*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
2223*b7c941bbSAndroid Build Coastguard Worker                 supportDepth = true;
2224*b7c941bbSAndroid Build Coastguard Worker             }
2225*b7c941bbSAndroid Build Coastguard Worker         }
2226*b7c941bbSAndroid Build Coastguard Worker         if (!(supportBC || supportDepth)) {
2227*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
2228*b7c941bbSAndroid Build Coastguard Worker                     cameraIdList->cameraIds[i]);
2229*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2230*b7c941bbSAndroid Build Coastguard Worker         }
2231*b7c941bbSAndroid Build Coastguard Worker 
2232*b7c941bbSAndroid Build Coastguard Worker         // Check copy works
2233*b7c941bbSAndroid Build Coastguard Worker         copy = ACameraMetadata_copy(chars);
2234*b7c941bbSAndroid Build Coastguard Worker 
2235*b7c941bbSAndroid Build Coastguard Worker         // Compare copy with original
2236*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry entryCopy;
2237*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getConstEntry(
2238*b7c941bbSAndroid Build Coastguard Worker                 copy, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entryCopy);
2239*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2240*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
2241*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2242*b7c941bbSAndroid Build Coastguard Worker         }
2243*b7c941bbSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.count; i++) {
2244*b7c941bbSAndroid Build Coastguard Worker             if (entry.data.u8[i] != entryCopy.data.u8[i]) {
2245*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
2246*b7c941bbSAndroid Build Coastguard Worker                     "Copy of available capability key[%d]: %d mismatches original %d",
2247*b7c941bbSAndroid Build Coastguard Worker                     i, entryCopy.data.u8[i], entry.data.u8[i]);
2248*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2249*b7c941bbSAndroid Build Coastguard Worker             }
2250*b7c941bbSAndroid Build Coastguard Worker         }
2251*b7c941bbSAndroid Build Coastguard Worker 
2252*b7c941bbSAndroid Build Coastguard Worker         // Check get unknown value fails
2253*b7c941bbSAndroid Build Coastguard Worker         uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
2254*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
2255*b7c941bbSAndroid Build Coastguard Worker         if (ret == ACAMERA_OK) {
2256*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Error: get unknown tag should fail!");
2257*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2258*b7c941bbSAndroid Build Coastguard Worker         }
2259*b7c941bbSAndroid Build Coastguard Worker 
2260*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
2261*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(copy);
2262*b7c941bbSAndroid Build Coastguard Worker         chars = nullptr;
2263*b7c941bbSAndroid Build Coastguard Worker         copy = nullptr;
2264*b7c941bbSAndroid Build Coastguard Worker     }
2265*b7c941bbSAndroid Build Coastguard Worker 
2266*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2267*b7c941bbSAndroid Build Coastguard Worker cleanup:
2268*b7c941bbSAndroid Build Coastguard Worker     if (chars) {
2269*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
2270*b7c941bbSAndroid Build Coastguard Worker     }
2271*b7c941bbSAndroid Build Coastguard Worker     if (copy) {
2272*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(copy);
2273*b7c941bbSAndroid Build Coastguard Worker     }
2274*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_deleteCameraIdList(cameraIdList);
2275*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(mgr);
2276*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2277*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
2278*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
2279*b7c941bbSAndroid Build Coastguard Worker     }
2280*b7c941bbSAndroid Build Coastguard Worker     return pass;
2281*b7c941bbSAndroid Build Coastguard Worker }
2282*b7c941bbSAndroid Build Coastguard Worker 
2283*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass,jstring jOverrideCameraId)2284*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2285*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceOpenAndCloseNative(
2286*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
2287*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
2288*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
2289*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
2290*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
2291*b7c941bbSAndroid Build Coastguard Worker 
2292*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2293*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2294*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
2295*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2296*b7c941bbSAndroid Build Coastguard Worker     }
2297*b7c941bbSAndroid Build Coastguard Worker 
2298*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
2299*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
2300*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2301*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2302*b7c941bbSAndroid Build Coastguard Worker     }
2303*b7c941bbSAndroid Build Coastguard Worker 
2304*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
2305*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
2306*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
2307*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2308*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2309*b7c941bbSAndroid Build Coastguard Worker         }
2310*b7c941bbSAndroid Build Coastguard Worker 
2311*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
2312*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2313*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2314*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2315*b7c941bbSAndroid Build Coastguard Worker         }
2316*b7c941bbSAndroid Build Coastguard Worker 
2317*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2318*b7c941bbSAndroid Build Coastguard Worker 
2319*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
2320*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2321*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2322*b7c941bbSAndroid Build Coastguard Worker         }
2323*b7c941bbSAndroid Build Coastguard Worker 
2324*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.closeCamera();
2325*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2326*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
2327*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2328*b7c941bbSAndroid Build Coastguard Worker         }
2329*b7c941bbSAndroid Build Coastguard Worker 
2330*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2331*b7c941bbSAndroid Build Coastguard Worker 
2332*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
2333*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2334*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2335*b7c941bbSAndroid Build Coastguard Worker         }
2336*b7c941bbSAndroid Build Coastguard Worker     }
2337*b7c941bbSAndroid Build Coastguard Worker 
2338*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
2339*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2340*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2341*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2342*b7c941bbSAndroid Build Coastguard Worker     }
2343*b7c941bbSAndroid Build Coastguard Worker 
2344*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2345*b7c941bbSAndroid Build Coastguard Worker cleanup:
2346*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2347*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
2348*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
2349*b7c941bbSAndroid Build Coastguard Worker     }
2350*b7c941bbSAndroid Build Coastguard Worker     return pass;
2351*b7c941bbSAndroid Build Coastguard Worker }
2352*b7c941bbSAndroid Build Coastguard Worker 
2353*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass,jstring jOverrideCameraId)2354*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2355*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceCreateCaptureRequestNative(
2356*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
2357*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
2358*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
2359*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
2360*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList* cameraIdList = nullptr;
2361*b7c941bbSAndroid Build Coastguard Worker     ACameraDevice* device = nullptr;
2362*b7c941bbSAndroid Build Coastguard Worker     ACaptureRequest* request = nullptr;
2363*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
2364*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2365*b7c941bbSAndroid Build Coastguard Worker 
2366*b7c941bbSAndroid Build Coastguard Worker     int numCameras = cameraIdList->numCameras;
2367*b7c941bbSAndroid Build Coastguard Worker     const char* overrideCameraId = nullptr;
2368*b7c941bbSAndroid Build Coastguard Worker     if (jOverrideCameraId != nullptr) {
2369*b7c941bbSAndroid Build Coastguard Worker         overrideCameraId = env->GetStringUTFChars(jOverrideCameraId, nullptr);
2370*b7c941bbSAndroid Build Coastguard Worker     }
2371*b7c941bbSAndroid Build Coastguard Worker 
2372*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
2373*b7c941bbSAndroid Build Coastguard Worker         CameraDeviceListener deviceListener;
2374*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = cameraIdList->cameraIds[i];
2375*b7c941bbSAndroid Build Coastguard Worker         if (overrideCameraId != nullptr && strcmp(overrideCameraId, cameraId)) {
2376*b7c941bbSAndroid Build Coastguard Worker             // Skip other cameras if overriding camera id to be tested.
2377*b7c941bbSAndroid Build Coastguard Worker             continue;
2378*b7c941bbSAndroid Build Coastguard Worker         }
2379*b7c941bbSAndroid Build Coastguard Worker         ACameraDevice_StateCallbacks deviceCb {
2380*b7c941bbSAndroid Build Coastguard Worker             &deviceListener,
2381*b7c941bbSAndroid Build Coastguard Worker             CameraDeviceListener::onDisconnected,
2382*b7c941bbSAndroid Build Coastguard Worker             CameraDeviceListener::onError
2383*b7c941bbSAndroid Build Coastguard Worker         };
2384*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
2385*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2386*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2387*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2388*b7c941bbSAndroid Build Coastguard Worker         }
2389*b7c941bbSAndroid Build Coastguard Worker 
2390*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
2391*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK || chars == nullptr) {
2392*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
2393*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret, chars);
2394*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2395*b7c941bbSAndroid Build Coastguard Worker         }
2396*b7c941bbSAndroid Build Coastguard Worker         StaticInfo staticInfo(chars);
2397*b7c941bbSAndroid Build Coastguard Worker 
2398*b7c941bbSAndroid Build Coastguard Worker         for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
2399*b7c941bbSAndroid Build Coastguard Worker             ACameraDevice_request_template templateId =
2400*b7c941bbSAndroid Build Coastguard Worker                     static_cast<ACameraDevice_request_template>(t);
2401*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
2402*b7c941bbSAndroid Build Coastguard Worker             if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
2403*b7c941bbSAndroid Build Coastguard Worker                 // template not supported. skip
2404*b7c941bbSAndroid Build Coastguard Worker                 continue;
2405*b7c941bbSAndroid Build Coastguard Worker             }
2406*b7c941bbSAndroid Build Coastguard Worker 
2407*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2408*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
2409*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2410*b7c941bbSAndroid Build Coastguard Worker             }
2411*b7c941bbSAndroid Build Coastguard Worker 
2412*b7c941bbSAndroid Build Coastguard Worker             int32_t numTags = 0;
2413*b7c941bbSAndroid Build Coastguard Worker             const uint32_t* tags = nullptr;
2414*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
2415*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2416*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
2417*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2418*b7c941bbSAndroid Build Coastguard Worker             }
2419*b7c941bbSAndroid Build Coastguard Worker 
2420*b7c941bbSAndroid Build Coastguard Worker             for (int tid = 0; tid < numTags; tid++) {
2421*b7c941bbSAndroid Build Coastguard Worker                 uint32_t tagId = tags[tid];
2422*b7c941bbSAndroid Build Coastguard Worker                 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
2423*b7c941bbSAndroid Build Coastguard Worker                 uint32_t sectionId = tagId >> 16;
2424*b7c941bbSAndroid Build Coastguard Worker                 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
2425*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
2426*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2427*b7c941bbSAndroid Build Coastguard Worker                 }
2428*b7c941bbSAndroid Build Coastguard Worker             }
2429*b7c941bbSAndroid Build Coastguard Worker 
2430*b7c941bbSAndroid Build Coastguard Worker             void* context = nullptr;
2431*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getUserContext(request, &context);
2432*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2433*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2434*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2435*b7c941bbSAndroid Build Coastguard Worker             }
2436*b7c941bbSAndroid Build Coastguard Worker             if (context != nullptr) {
2437*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Capture request context is not null: %p", context);
2438*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2439*b7c941bbSAndroid Build Coastguard Worker             }
2440*b7c941bbSAndroid Build Coastguard Worker 
2441*b7c941bbSAndroid Build Coastguard Worker             intptr_t magic_num = 0xBEEF;
2442*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
2443*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2444*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
2445*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2446*b7c941bbSAndroid Build Coastguard Worker             }
2447*b7c941bbSAndroid Build Coastguard Worker 
2448*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getUserContext(request, &context);
2449*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2450*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2451*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2452*b7c941bbSAndroid Build Coastguard Worker             }
2453*b7c941bbSAndroid Build Coastguard Worker             if (context != (void*) magic_num) {
2454*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
2455*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2456*b7c941bbSAndroid Build Coastguard Worker             }
2457*b7c941bbSAndroid Build Coastguard Worker 
2458*b7c941bbSAndroid Build Coastguard Worker             // try get/set capture request fields
2459*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_const_entry entry;
2460*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getConstEntry_physicalCamera(request, nullptr,
2461*b7c941bbSAndroid Build Coastguard Worker                     ACAMERA_CONTROL_AE_MODE, &entry);
2462*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2463*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Get AE mode key for null physical id should fail. ret %d",
2464*b7c941bbSAndroid Build Coastguard Worker                         ret);
2465*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2466*b7c941bbSAndroid Build Coastguard Worker             }
2467*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getConstEntry_physicalCamera(request, cameraId,
2468*b7c941bbSAndroid Build Coastguard Worker                     ACAMERA_CONTROL_AE_MODE, &entry);
2469*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2470*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Get AE mode key for physical id should fail. ret %d",
2471*b7c941bbSAndroid Build Coastguard Worker                         ret);
2472*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2473*b7c941bbSAndroid Build Coastguard Worker             }
2474*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
2475*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2476*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2477*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2478*b7c941bbSAndroid Build Coastguard Worker             }
2479*b7c941bbSAndroid Build Coastguard Worker 
2480*b7c941bbSAndroid Build Coastguard Worker             if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
2481*b7c941bbSAndroid Build Coastguard Worker                     entry.count != 1) {
2482*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
2483*b7c941bbSAndroid Build Coastguard Worker                         "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
2484*b7c941bbSAndroid Build Coastguard Worker                         "count %d (expect %d)",
2485*b7c941bbSAndroid Build Coastguard Worker                         entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
2486*b7c941bbSAndroid Build Coastguard Worker                         entry.count, 1);
2487*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2488*b7c941bbSAndroid Build Coastguard Worker             }
2489*b7c941bbSAndroid Build Coastguard Worker             if (t == TEMPLATE_MANUAL) {
2490*b7c941bbSAndroid Build Coastguard Worker                 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
2491*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
2492*b7c941bbSAndroid Build Coastguard Worker                             entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
2493*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2494*b7c941bbSAndroid Build Coastguard Worker                 }
2495*b7c941bbSAndroid Build Coastguard Worker                 // try set AE_MODE_ON
2496*b7c941bbSAndroid Build Coastguard Worker                 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
2497*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2498*b7c941bbSAndroid Build Coastguard Worker                         request, nullptr, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2499*b7c941bbSAndroid Build Coastguard Worker                 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2500*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2501*b7c941bbSAndroid Build Coastguard Worker                             "fail. ret %d", cameraId, ret);
2502*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2503*b7c941bbSAndroid Build Coastguard Worker                 }
2504*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2505*b7c941bbSAndroid Build Coastguard Worker                         request, cameraId, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2506*b7c941bbSAndroid Build Coastguard Worker                 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2507*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2508*b7c941bbSAndroid Build Coastguard Worker                             "fail. ret %d", cameraId, ret);
2509*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2510*b7c941bbSAndroid Build Coastguard Worker                 }
2511*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureRequest_setEntry_u8(
2512*b7c941bbSAndroid Build Coastguard Worker                         request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2513*b7c941bbSAndroid Build Coastguard Worker                 if (ret != ACAMERA_OK) {
2514*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString,
2515*b7c941bbSAndroid Build Coastguard Worker                             "Error: Camera %s template %d: update AE mode key fail. ret %d",
2516*b7c941bbSAndroid Build Coastguard Worker                             cameraId, t, ret);
2517*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2518*b7c941bbSAndroid Build Coastguard Worker                 }
2519*b7c941bbSAndroid Build Coastguard Worker                 ret = ACaptureRequest_getConstEntry(
2520*b7c941bbSAndroid Build Coastguard Worker                         request, ACAMERA_CONTROL_AE_MODE, &entry);
2521*b7c941bbSAndroid Build Coastguard Worker                 if (ret != ACAMERA_OK) {
2522*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2523*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2524*b7c941bbSAndroid Build Coastguard Worker                 }
2525*b7c941bbSAndroid Build Coastguard Worker                 if (entry.data.u8[0] != aeMode) {
2526*b7c941bbSAndroid Build Coastguard Worker                     LOG_ERROR(errorString,
2527*b7c941bbSAndroid Build Coastguard Worker                             "Error: AE mode key is not updated. expect %d but get %d",
2528*b7c941bbSAndroid Build Coastguard Worker                             aeMode, entry.data.u8[0]);
2529*b7c941bbSAndroid Build Coastguard Worker                     goto cleanup;
2530*b7c941bbSAndroid Build Coastguard Worker                 }
2531*b7c941bbSAndroid Build Coastguard Worker             } else {
2532*b7c941bbSAndroid Build Coastguard Worker                 if (staticInfo.isColorOutputSupported()) {
2533*b7c941bbSAndroid Build Coastguard Worker                     if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
2534*b7c941bbSAndroid Build Coastguard Worker                         LOG_ERROR(errorString,
2535*b7c941bbSAndroid Build Coastguard Worker                                 "Error: Template %d has wrong AE mode %d (expect %d)",
2536*b7c941bbSAndroid Build Coastguard Worker                                 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
2537*b7c941bbSAndroid Build Coastguard Worker                         goto cleanup;
2538*b7c941bbSAndroid Build Coastguard Worker                     }
2539*b7c941bbSAndroid Build Coastguard Worker                     // try set AE_MODE_OFF
2540*b7c941bbSAndroid Build Coastguard Worker                     if (staticInfo.isCapabilitySupported(
2541*b7c941bbSAndroid Build Coastguard Worker                             ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
2542*b7c941bbSAndroid Build Coastguard Worker                         uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
2543*b7c941bbSAndroid Build Coastguard Worker                         ret = ACaptureRequest_setEntry_u8(
2544*b7c941bbSAndroid Build Coastguard Worker                                 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2545*b7c941bbSAndroid Build Coastguard Worker                         if (ret != ACAMERA_OK) {
2546*b7c941bbSAndroid Build Coastguard Worker                             LOG_ERROR(errorString,
2547*b7c941bbSAndroid Build Coastguard Worker                                     "Error: Camera %s template %d: update AE mode key fail. ret %d",
2548*b7c941bbSAndroid Build Coastguard Worker                                     cameraId, t, ret);
2549*b7c941bbSAndroid Build Coastguard Worker                             goto cleanup;
2550*b7c941bbSAndroid Build Coastguard Worker                         }
2551*b7c941bbSAndroid Build Coastguard Worker                         ret = ACaptureRequest_getConstEntry(
2552*b7c941bbSAndroid Build Coastguard Worker                                 request, ACAMERA_CONTROL_AE_MODE, &entry);
2553*b7c941bbSAndroid Build Coastguard Worker                         if (ret != ACAMERA_OK) {
2554*b7c941bbSAndroid Build Coastguard Worker                             LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2555*b7c941bbSAndroid Build Coastguard Worker                             goto cleanup;
2556*b7c941bbSAndroid Build Coastguard Worker                         }
2557*b7c941bbSAndroid Build Coastguard Worker                         if (entry.data.u8[0] != aeMode) {
2558*b7c941bbSAndroid Build Coastguard Worker                             LOG_ERROR(errorString,
2559*b7c941bbSAndroid Build Coastguard Worker                                     "Error: AE mode key is not updated. expect %d but get %d",
2560*b7c941bbSAndroid Build Coastguard Worker                                     aeMode, entry.data.u8[0]);
2561*b7c941bbSAndroid Build Coastguard Worker                             goto cleanup;
2562*b7c941bbSAndroid Build Coastguard Worker                         }
2563*b7c941bbSAndroid Build Coastguard Worker                     }
2564*b7c941bbSAndroid Build Coastguard Worker                 }
2565*b7c941bbSAndroid Build Coastguard Worker             }
2566*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest_free(request);
2567*b7c941bbSAndroid Build Coastguard Worker             request = nullptr;
2568*b7c941bbSAndroid Build Coastguard Worker         }
2569*b7c941bbSAndroid Build Coastguard Worker 
2570*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
2571*b7c941bbSAndroid Build Coastguard Worker         chars = nullptr;
2572*b7c941bbSAndroid Build Coastguard Worker         ACameraDevice_close(device);
2573*b7c941bbSAndroid Build Coastguard Worker         device = nullptr;
2574*b7c941bbSAndroid Build Coastguard Worker     }
2575*b7c941bbSAndroid Build Coastguard Worker 
2576*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2577*b7c941bbSAndroid Build Coastguard Worker cleanup:
2578*b7c941bbSAndroid Build Coastguard Worker     if (cameraIdList) {
2579*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_deleteCameraIdList(cameraIdList);
2580*b7c941bbSAndroid Build Coastguard Worker     }
2581*b7c941bbSAndroid Build Coastguard Worker     if (request) {
2582*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest_free(request);
2583*b7c941bbSAndroid Build Coastguard Worker     }
2584*b7c941bbSAndroid Build Coastguard Worker     if (chars) {
2585*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
2586*b7c941bbSAndroid Build Coastguard Worker     }
2587*b7c941bbSAndroid Build Coastguard Worker     if (device) {
2588*b7c941bbSAndroid Build Coastguard Worker         ACameraDevice_close(device);
2589*b7c941bbSAndroid Build Coastguard Worker     }
2590*b7c941bbSAndroid Build Coastguard Worker     if (mgr) {
2591*b7c941bbSAndroid Build Coastguard Worker         ACameraManager_delete(mgr);
2592*b7c941bbSAndroid Build Coastguard Worker     }
2593*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2594*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
2595*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
2596*b7c941bbSAndroid Build Coastguard Worker     }
2597*b7c941bbSAndroid Build Coastguard Worker     return pass;
2598*b7c941bbSAndroid Build Coastguard Worker }
2599*b7c941bbSAndroid Build Coastguard Worker 
2600*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2601*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2602*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceSessionOpenAndCloseNative(
2603*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2604*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
2605*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
2606*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
2607*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
2608*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
2609*b7c941bbSAndroid Build Coastguard Worker 
2610*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2611*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2612*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
2613*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2614*b7c941bbSAndroid Build Coastguard Worker     }
2615*b7c941bbSAndroid Build Coastguard Worker 
2616*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
2617*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
2618*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2619*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2620*b7c941bbSAndroid Build Coastguard Worker     }
2621*b7c941bbSAndroid Build Coastguard Worker 
2622*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
2623*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
2624*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
2625*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2626*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2627*b7c941bbSAndroid Build Coastguard Worker         }
2628*b7c941bbSAndroid Build Coastguard Worker 
2629*b7c941bbSAndroid Build Coastguard Worker         {
2630*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2631*b7c941bbSAndroid Build Coastguard Worker             StaticInfo staticInfo(chars);
2632*b7c941bbSAndroid Build Coastguard Worker             if (!staticInfo.isColorOutputSupported()) {
2633*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("%s: camera %s does not support color output. skipping",
2634*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, cameraId);
2635*b7c941bbSAndroid Build Coastguard Worker                 ACameraMetadata_free(chars);
2636*b7c941bbSAndroid Build Coastguard Worker                 continue;
2637*b7c941bbSAndroid Build Coastguard Worker             }
2638*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
2639*b7c941bbSAndroid Build Coastguard Worker         }
2640*b7c941bbSAndroid Build Coastguard Worker 
2641*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
2642*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2643*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2644*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2645*b7c941bbSAndroid Build Coastguard Worker         }
2646*b7c941bbSAndroid Build Coastguard Worker 
2647*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2648*b7c941bbSAndroid Build Coastguard Worker 
2649*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
2650*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2651*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2652*b7c941bbSAndroid Build Coastguard Worker         }
2653*b7c941bbSAndroid Build Coastguard Worker 
2654*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2655*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
2656*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
2657*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2658*b7c941bbSAndroid Build Coastguard Worker         }
2659*b7c941bbSAndroid Build Coastguard Worker 
2660*b7c941bbSAndroid Build Coastguard Worker         CaptureSessionListener* sessionListener = testCase.getSessionListener();
2661*b7c941bbSAndroid Build Coastguard Worker         if (sessionListener == nullptr) {
2662*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
2663*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2664*b7c941bbSAndroid Build Coastguard Worker         }
2665*b7c941bbSAndroid Build Coastguard Worker 
2666*b7c941bbSAndroid Build Coastguard Worker         // Try open/close session multiple times
2667*b7c941bbSAndroid Build Coastguard Worker         for (int j = 0; j < 5; j++) {
2668*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.createCaptureSessionWithLog();
2669*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
2670*b7c941bbSAndroid Build Coastguard Worker                 // Don't log error here. testcase did it
2671*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2672*b7c941bbSAndroid Build Coastguard Worker             }
2673*b7c941bbSAndroid Build Coastguard Worker 
2674*b7c941bbSAndroid Build Coastguard Worker             usleep(100000); // sleep to give some time for callbacks to happen
2675*b7c941bbSAndroid Build Coastguard Worker 
2676*b7c941bbSAndroid Build Coastguard Worker             if (!sessionListener->isIdle()) {
2677*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
2678*b7c941bbSAndroid Build Coastguard Worker                         cameraId);
2679*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2680*b7c941bbSAndroid Build Coastguard Worker             }
2681*b7c941bbSAndroid Build Coastguard Worker 
2682*b7c941bbSAndroid Build Coastguard Worker             testCase.closeSession();
2683*b7c941bbSAndroid Build Coastguard Worker 
2684*b7c941bbSAndroid Build Coastguard Worker             usleep(100000); // sleep to give some time for callbacks to happen
2685*b7c941bbSAndroid Build Coastguard Worker             if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2686*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
2687*b7c941bbSAndroid Build Coastguard Worker                         "Session for camera %s close error. isClosde %d close count %d",
2688*b7c941bbSAndroid Build Coastguard Worker                         cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2689*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
2690*b7c941bbSAndroid Build Coastguard Worker             }
2691*b7c941bbSAndroid Build Coastguard Worker             sessionListener->reset();
2692*b7c941bbSAndroid Build Coastguard Worker         }
2693*b7c941bbSAndroid Build Coastguard Worker 
2694*b7c941bbSAndroid Build Coastguard Worker         // Try open/close really fast
2695*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog();
2696*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2697*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
2698*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2699*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2700*b7c941bbSAndroid Build Coastguard Worker         }
2701*b7c941bbSAndroid Build Coastguard Worker         testCase.closeSession();
2702*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2703*b7c941bbSAndroid Build Coastguard Worker         if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2704*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString,
2705*b7c941bbSAndroid Build Coastguard Worker                     "Session for camera %s close error. isClosde %d close count %d",
2706*b7c941bbSAndroid Build Coastguard Worker                     cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2707*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2708*b7c941bbSAndroid Build Coastguard Worker         }
2709*b7c941bbSAndroid Build Coastguard Worker 
2710*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
2711*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2712*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
2713*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2714*b7c941bbSAndroid Build Coastguard Worker         }
2715*b7c941bbSAndroid Build Coastguard Worker 
2716*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2717*b7c941bbSAndroid Build Coastguard Worker 
2718*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
2719*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2720*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2721*b7c941bbSAndroid Build Coastguard Worker         }
2722*b7c941bbSAndroid Build Coastguard Worker     }
2723*b7c941bbSAndroid Build Coastguard Worker 
2724*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
2725*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2726*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2727*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2728*b7c941bbSAndroid Build Coastguard Worker     }
2729*b7c941bbSAndroid Build Coastguard Worker 
2730*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2731*b7c941bbSAndroid Build Coastguard Worker cleanup:
2732*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2733*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
2734*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
2735*b7c941bbSAndroid Build Coastguard Worker     }
2736*b7c941bbSAndroid Build Coastguard Worker     return pass;
2737*b7c941bbSAndroid Build Coastguard Worker }
2738*b7c941bbSAndroid Build Coastguard Worker 
2739*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSharedOutputUpdate(JNIEnv * env,jclass,jobject jPreviewSurface,jobject jSharedSurface,jstring jOverrideCameraId)2740*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2741*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceSharedOutputUpdate(
2742*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface,
2743*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
2744*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
2745*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
2746*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
2747*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
2748*b7c941bbSAndroid Build Coastguard Worker     int sequenceId = -1;
2749*b7c941bbSAndroid Build Coastguard Worker     int64_t lastFrameNumber = 0;
2750*b7c941bbSAndroid Build Coastguard Worker     bool frameArrived = false;
2751*b7c941bbSAndroid Build Coastguard Worker     ANativeWindow* previewAnw = nullptr;
2752*b7c941bbSAndroid Build Coastguard Worker     ANativeWindow* sharedAnw = ANativeWindow_fromSurface(env, jSharedSurface);
2753*b7c941bbSAndroid Build Coastguard Worker     ACaptureRequest* updatedRequest = nullptr;
2754*b7c941bbSAndroid Build Coastguard Worker     ACameraOutputTarget* reqPreviewOutput = nullptr;
2755*b7c941bbSAndroid Build Coastguard Worker     ACameraOutputTarget* reqSharedOutput = nullptr;
2756*b7c941bbSAndroid Build Coastguard Worker     ACaptureSessionOutput *previewOutput = nullptr;
2757*b7c941bbSAndroid Build Coastguard Worker     uint32_t timeoutSec = 1;
2758*b7c941bbSAndroid Build Coastguard Worker     uint32_t runPreviewSec = 2;
2759*b7c941bbSAndroid Build Coastguard Worker 
2760*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2761*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2762*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
2763*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2764*b7c941bbSAndroid Build Coastguard Worker     }
2765*b7c941bbSAndroid Build Coastguard Worker 
2766*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
2767*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
2768*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2769*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2770*b7c941bbSAndroid Build Coastguard Worker     }
2771*b7c941bbSAndroid Build Coastguard Worker 
2772*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
2773*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
2774*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
2775*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2776*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2777*b7c941bbSAndroid Build Coastguard Worker         }
2778*b7c941bbSAndroid Build Coastguard Worker 
2779*b7c941bbSAndroid Build Coastguard Worker         {
2780*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2781*b7c941bbSAndroid Build Coastguard Worker             StaticInfo staticInfo(chars);
2782*b7c941bbSAndroid Build Coastguard Worker             if (!staticInfo.isColorOutputSupported()) {
2783*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("%s: camera %s does not support color output. skipping",
2784*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, cameraId);
2785*b7c941bbSAndroid Build Coastguard Worker                 ACameraMetadata_free(chars);
2786*b7c941bbSAndroid Build Coastguard Worker                 continue;
2787*b7c941bbSAndroid Build Coastguard Worker             }
2788*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
2789*b7c941bbSAndroid Build Coastguard Worker         }
2790*b7c941bbSAndroid Build Coastguard Worker 
2791*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
2792*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2793*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2794*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2795*b7c941bbSAndroid Build Coastguard Worker         }
2796*b7c941bbSAndroid Build Coastguard Worker 
2797*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2798*b7c941bbSAndroid Build Coastguard Worker 
2799*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
2800*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2801*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2802*b7c941bbSAndroid Build Coastguard Worker         }
2803*b7c941bbSAndroid Build Coastguard Worker 
2804*b7c941bbSAndroid Build Coastguard Worker         previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2805*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
2806*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
2807*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2808*b7c941bbSAndroid Build Coastguard Worker         }
2809*b7c941bbSAndroid Build Coastguard Worker 
2810*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog(true);
2811*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2812*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
2813*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2814*b7c941bbSAndroid Build Coastguard Worker         }
2815*b7c941bbSAndroid Build Coastguard Worker 
2816*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog();
2817*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2818*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
2819*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2820*b7c941bbSAndroid Build Coastguard Worker         }
2821*b7c941bbSAndroid Build Coastguard Worker 
2822*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startPreview();
2823*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2824*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Start preview failed!");
2825*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2826*b7c941bbSAndroid Build Coastguard Worker         }
2827*b7c941bbSAndroid Build Coastguard Worker 
2828*b7c941bbSAndroid Build Coastguard Worker         sleep(runPreviewSec);
2829*b7c941bbSAndroid Build Coastguard Worker 
2830*b7c941bbSAndroid Build Coastguard Worker         previewOutput = testCase.getPreviewOutput();
2831*b7c941bbSAndroid Build Coastguard Worker         //Try some bad input
2832*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureSessionSharedOutput_add(previewOutput, previewAnw);
2833*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2834*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add should return invalid "
2835*b7c941bbSAndroid Build Coastguard Worker                     "parameter! %d", ret);
2836*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2837*b7c941bbSAndroid Build Coastguard Worker         }
2838*b7c941bbSAndroid Build Coastguard Worker 
2839*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureSessionSharedOutput_remove(previewOutput, previewAnw);
2840*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2841*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove should return invalid "
2842*b7c941bbSAndroid Build Coastguard Worker                     "parameter! %d", ret);
2843*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2844*b7c941bbSAndroid Build Coastguard Worker         }
2845*b7c941bbSAndroid Build Coastguard Worker 
2846*b7c941bbSAndroid Build Coastguard Worker         //Now try with valid input
2847*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureSessionSharedOutput_add(previewOutput, sharedAnw);
2848*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2849*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add failed!")
2850*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2851*b7c941bbSAndroid Build Coastguard Worker         }
2852*b7c941bbSAndroid Build Coastguard Worker 
2853*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.updateOutput(env, previewOutput);
2854*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2855*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Failed to update output configuration!")
2856*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2857*b7c941bbSAndroid Build Coastguard Worker         }
2858*b7c941bbSAndroid Build Coastguard Worker 
2859*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraDevice_createCaptureRequest(
2860*b7c941bbSAndroid Build Coastguard Worker                 testCase.getCameraDevice(), TEMPLATE_PREVIEW, &updatedRequest);
2861*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2862*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
2863*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2864*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2865*b7c941bbSAndroid Build Coastguard Worker         }
2866*b7c941bbSAndroid Build Coastguard Worker 
2867*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraOutputTarget_create(previewAnw, &reqPreviewOutput);
2868*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2869*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString,
2870*b7c941bbSAndroid Build Coastguard Worker                     "Camera %s create request preview output target failed. ret %d",
2871*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2872*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2873*b7c941bbSAndroid Build Coastguard Worker         }
2874*b7c941bbSAndroid Build Coastguard Worker 
2875*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureRequest_addTarget(updatedRequest, reqPreviewOutput);
2876*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2877*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2878*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2879*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2880*b7c941bbSAndroid Build Coastguard Worker         }
2881*b7c941bbSAndroid Build Coastguard Worker 
2882*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraOutputTarget_create(sharedAnw, &reqSharedOutput);
2883*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2884*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString,
2885*b7c941bbSAndroid Build Coastguard Worker                     "Camera %s create request preview output target failed. ret %d",
2886*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2887*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2888*b7c941bbSAndroid Build Coastguard Worker         }
2889*b7c941bbSAndroid Build Coastguard Worker 
2890*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureRequest_addTarget(updatedRequest, reqSharedOutput);
2891*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2892*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2893*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2894*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2895*b7c941bbSAndroid Build Coastguard Worker         }
2896*b7c941bbSAndroid Build Coastguard Worker 
2897*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.updateRepeatingRequest(updatedRequest, &sequenceId);
2898*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2899*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2900*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2901*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2902*b7c941bbSAndroid Build Coastguard Worker         }
2903*b7c941bbSAndroid Build Coastguard Worker 
2904*b7c941bbSAndroid Build Coastguard Worker         sleep(runPreviewSec);
2905*b7c941bbSAndroid Build Coastguard Worker 
2906*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureSessionSharedOutput_remove(previewOutput, sharedAnw);
2907*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2908*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove failed!");
2909*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2910*b7c941bbSAndroid Build Coastguard Worker         }
2911*b7c941bbSAndroid Build Coastguard Worker 
2912*b7c941bbSAndroid Build Coastguard Worker         //Try removing shared output which still has pending camera requests
2913*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.updateOutput(env, previewOutput);
2914*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2915*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "updateOutput should fail!");
2916*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2917*b7c941bbSAndroid Build Coastguard Worker         }
2918*b7c941bbSAndroid Build Coastguard Worker 
2919*b7c941bbSAndroid Build Coastguard Worker         //Remove the shared output correctly by updating the repeating request
2920*b7c941bbSAndroid Build Coastguard Worker         //first
2921*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureRequest_removeTarget(updatedRequest, reqSharedOutput);
2922*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2923*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s remove target output failed. ret %d",
2924*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2925*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2926*b7c941bbSAndroid Build Coastguard Worker         }
2927*b7c941bbSAndroid Build Coastguard Worker 
2928*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.updateRepeatingRequest(updatedRequest);
2929*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2930*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2931*b7c941bbSAndroid Build Coastguard Worker                     cameraId, ret);
2932*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2933*b7c941bbSAndroid Build Coastguard Worker         }
2934*b7c941bbSAndroid Build Coastguard Worker 
2935*b7c941bbSAndroid Build Coastguard Worker         //Then wait for all old requests to flush
2936*b7c941bbSAndroid Build Coastguard Worker         lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
2937*b7c941bbSAndroid Build Coastguard Worker         if (lastFrameNumber < 0) {
2938*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
2939*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
2940*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2941*b7c941bbSAndroid Build Coastguard Worker         }
2942*b7c941bbSAndroid Build Coastguard Worker 
2943*b7c941bbSAndroid Build Coastguard Worker         frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
2944*b7c941bbSAndroid Build Coastguard Worker         if (!frameArrived) {
2945*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
2946*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
2947*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2948*b7c941bbSAndroid Build Coastguard Worker         }
2949*b7c941bbSAndroid Build Coastguard Worker 
2950*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.updateOutput(env, previewOutput);
2951*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2952*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "updateOutput failed!");
2953*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2954*b7c941bbSAndroid Build Coastguard Worker         }
2955*b7c941bbSAndroid Build Coastguard Worker 
2956*b7c941bbSAndroid Build Coastguard Worker         sleep(runPreviewSec);
2957*b7c941bbSAndroid Build Coastguard Worker 
2958*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
2959*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
2960*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
2961*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2962*b7c941bbSAndroid Build Coastguard Worker         }
2963*b7c941bbSAndroid Build Coastguard Worker 
2964*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
2965*b7c941bbSAndroid Build Coastguard Worker 
2966*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
2967*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2968*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
2969*b7c941bbSAndroid Build Coastguard Worker         }
2970*b7c941bbSAndroid Build Coastguard Worker     }
2971*b7c941bbSAndroid Build Coastguard Worker 
2972*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
2973*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
2974*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2975*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
2976*b7c941bbSAndroid Build Coastguard Worker     }
2977*b7c941bbSAndroid Build Coastguard Worker 
2978*b7c941bbSAndroid Build Coastguard Worker     pass = true;
2979*b7c941bbSAndroid Build Coastguard Worker 
2980*b7c941bbSAndroid Build Coastguard Worker cleanup:
2981*b7c941bbSAndroid Build Coastguard Worker 
2982*b7c941bbSAndroid Build Coastguard Worker     if (updatedRequest != nullptr) {
2983*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest_free(updatedRequest);
2984*b7c941bbSAndroid Build Coastguard Worker         updatedRequest = nullptr;
2985*b7c941bbSAndroid Build Coastguard Worker     }
2986*b7c941bbSAndroid Build Coastguard Worker 
2987*b7c941bbSAndroid Build Coastguard Worker     if (reqPreviewOutput != nullptr) {
2988*b7c941bbSAndroid Build Coastguard Worker         ACameraOutputTarget_free(reqPreviewOutput);
2989*b7c941bbSAndroid Build Coastguard Worker         reqPreviewOutput = nullptr;
2990*b7c941bbSAndroid Build Coastguard Worker     }
2991*b7c941bbSAndroid Build Coastguard Worker 
2992*b7c941bbSAndroid Build Coastguard Worker     if (reqSharedOutput != nullptr) {
2993*b7c941bbSAndroid Build Coastguard Worker         ACameraOutputTarget_free(reqSharedOutput);
2994*b7c941bbSAndroid Build Coastguard Worker         reqSharedOutput = nullptr;
2995*b7c941bbSAndroid Build Coastguard Worker     }
2996*b7c941bbSAndroid Build Coastguard Worker 
2997*b7c941bbSAndroid Build Coastguard Worker     if (sharedAnw) {
2998*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow_release(sharedAnw);
2999*b7c941bbSAndroid Build Coastguard Worker         sharedAnw = nullptr;
3000*b7c941bbSAndroid Build Coastguard Worker     }
3001*b7c941bbSAndroid Build Coastguard Worker 
3002*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3003*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
3004*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
3005*b7c941bbSAndroid Build Coastguard Worker     }
3006*b7c941bbSAndroid Build Coastguard Worker     return pass;
3007*b7c941bbSAndroid Build Coastguard Worker }
3008*b7c941bbSAndroid Build Coastguard Worker 
testCameraDeviceSimplePreviewNativeInternal(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId,bool v2Callbacks)3009*b7c941bbSAndroid Build Coastguard Worker bool testCameraDeviceSimplePreviewNativeInternal(
3010*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3011*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId, bool v2Callbacks) {
3012*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
3013*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
3014*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
3015*b7c941bbSAndroid Build Coastguard Worker     const int timeoutSec = 1;
3016*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
3017*b7c941bbSAndroid Build Coastguard Worker 
3018*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3019*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3020*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
3021*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3022*b7c941bbSAndroid Build Coastguard Worker     }
3023*b7c941bbSAndroid Build Coastguard Worker 
3024*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
3025*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
3026*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3027*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3028*b7c941bbSAndroid Build Coastguard Worker     }
3029*b7c941bbSAndroid Build Coastguard Worker 
3030*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
3031*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
3032*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
3033*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3034*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3035*b7c941bbSAndroid Build Coastguard Worker         }
3036*b7c941bbSAndroid Build Coastguard Worker 
3037*b7c941bbSAndroid Build Coastguard Worker         {
3038*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
3039*b7c941bbSAndroid Build Coastguard Worker             StaticInfo staticInfo(chars);
3040*b7c941bbSAndroid Build Coastguard Worker             if (!staticInfo.isColorOutputSupported()) {
3041*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("%s: camera %s does not support color output. skipping",
3042*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, cameraId);
3043*b7c941bbSAndroid Build Coastguard Worker                 ACameraMetadata_free(chars);
3044*b7c941bbSAndroid Build Coastguard Worker                 continue;
3045*b7c941bbSAndroid Build Coastguard Worker             }
3046*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
3047*b7c941bbSAndroid Build Coastguard Worker         }
3048*b7c941bbSAndroid Build Coastguard Worker 
3049*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
3050*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3051*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3052*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3053*b7c941bbSAndroid Build Coastguard Worker         }
3054*b7c941bbSAndroid Build Coastguard Worker 
3055*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3056*b7c941bbSAndroid Build Coastguard Worker 
3057*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
3058*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3059*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3060*b7c941bbSAndroid Build Coastguard Worker         }
3061*b7c941bbSAndroid Build Coastguard Worker 
3062*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3063*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
3064*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
3065*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3066*b7c941bbSAndroid Build Coastguard Worker         }
3067*b7c941bbSAndroid Build Coastguard Worker 
3068*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog();
3069*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3070*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3071*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3072*b7c941bbSAndroid Build Coastguard Worker         }
3073*b7c941bbSAndroid Build Coastguard Worker 
3074*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog();
3075*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3076*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3077*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3078*b7c941bbSAndroid Build Coastguard Worker         }
3079*b7c941bbSAndroid Build Coastguard Worker         int sequenceId = 0;
3080*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startPreview(&sequenceId, 0, nullptr, v2Callbacks);
3081*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3082*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Start preview failed!");
3083*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3084*b7c941bbSAndroid Build Coastguard Worker         }
3085*b7c941bbSAndroid Build Coastguard Worker 
3086*b7c941bbSAndroid Build Coastguard Worker         sleep(3);
3087*b7c941bbSAndroid Build Coastguard Worker 
3088*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.stopPreview();
3089*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3090*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: stopPreview failed", __FUNCTION__);
3091*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "stopPreview failed!");
3092*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3093*b7c941bbSAndroid Build Coastguard Worker         }
3094*b7c941bbSAndroid Build Coastguard Worker 
3095*b7c941bbSAndroid Build Coastguard Worker         //Then wait for all old requests to flush
3096*b7c941bbSAndroid Build Coastguard Worker         int64_t lastFrameNumber =
3097*b7c941bbSAndroid Build Coastguard Worker                 testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
3098*b7c941bbSAndroid Build Coastguard Worker         if (lastFrameNumber < 0) {
3099*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
3100*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
3101*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3102*b7c941bbSAndroid Build Coastguard Worker         }
3103*b7c941bbSAndroid Build Coastguard Worker         if (v2Callbacks) {
3104*b7c941bbSAndroid Build Coastguard Worker               bool frameStarted = testCase.waitForFrameNumberStarted(lastFrameNumber, timeoutSec);
3105*b7c941bbSAndroid Build Coastguard Worker             if (!frameStarted) {
3106*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s timed out waiting on onCaptureStart for last"
3107*b7c941bbSAndroid Build Coastguard Worker                         "frame number!", cameraId);
3108*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3109*b7c941bbSAndroid Build Coastguard Worker             }
3110*b7c941bbSAndroid Build Coastguard Worker 
3111*b7c941bbSAndroid Build Coastguard Worker         }
3112*b7c941bbSAndroid Build Coastguard Worker 
3113*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
3114*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3115*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3116*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3117*b7c941bbSAndroid Build Coastguard Worker         }
3118*b7c941bbSAndroid Build Coastguard Worker 
3119*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3120*b7c941bbSAndroid Build Coastguard Worker 
3121*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
3122*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3123*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3124*b7c941bbSAndroid Build Coastguard Worker         }
3125*b7c941bbSAndroid Build Coastguard Worker     }
3126*b7c941bbSAndroid Build Coastguard Worker 
3127*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
3128*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3129*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3130*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3131*b7c941bbSAndroid Build Coastguard Worker     }
3132*b7c941bbSAndroid Build Coastguard Worker 
3133*b7c941bbSAndroid Build Coastguard Worker     pass = true;
3134*b7c941bbSAndroid Build Coastguard Worker cleanup:
3135*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3136*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
3137*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
3138*b7c941bbSAndroid Build Coastguard Worker     }
3139*b7c941bbSAndroid Build Coastguard Worker     return pass;
3140*b7c941bbSAndroid Build Coastguard Worker }
3141*b7c941bbSAndroid Build Coastguard Worker 
3142*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass clazz,jobject jPreviewSurface,jstring jOverrideCameraId)3143*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3144*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceSimplePreviewNative(
3145*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass clazz, jobject jPreviewSurface,
3146*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3147*b7c941bbSAndroid Build Coastguard Worker     return testCameraDeviceSimplePreviewNativeInternal(env, clazz, jPreviewSurface,
3148*b7c941bbSAndroid Build Coastguard Worker             jOverrideCameraId, /*v2Callbacks*/false);
3149*b7c941bbSAndroid Build Coastguard Worker }
3150*b7c941bbSAndroid Build Coastguard Worker 
3151*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative2(JNIEnv * env,jclass clazz,jobject jPreviewSurface,jstring jOverrideCameraId)3152*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3153*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceSimplePreviewNative2(
3154*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass clazz, jobject jPreviewSurface,
3155*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3156*b7c941bbSAndroid Build Coastguard Worker     return testCameraDeviceSimplePreviewNativeInternal(env, clazz, jPreviewSurface,
3157*b7c941bbSAndroid Build Coastguard Worker             jOverrideCameraId, /*v2Callbacks*/true);
3158*b7c941bbSAndroid Build Coastguard Worker }
3159*b7c941bbSAndroid Build Coastguard Worker 
3160*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDevicePreviewWithSessionParametersNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3161*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3162*b7c941bbSAndroid Build Coastguard Worker testCameraDevicePreviewWithSessionParametersNative(
3163*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3164*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3165*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
3166*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
3167*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
3168*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
3169*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
3170*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
3171*b7c941bbSAndroid Build Coastguard Worker 
3172*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3173*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3174*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
3175*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3176*b7c941bbSAndroid Build Coastguard Worker     }
3177*b7c941bbSAndroid Build Coastguard Worker 
3178*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
3179*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
3180*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3181*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3182*b7c941bbSAndroid Build Coastguard Worker     }
3183*b7c941bbSAndroid Build Coastguard Worker 
3184*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
3185*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
3186*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
3187*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3188*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3189*b7c941bbSAndroid Build Coastguard Worker         }
3190*b7c941bbSAndroid Build Coastguard Worker 
3191*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraManager_getCameraCharacteristics(
3192*b7c941bbSAndroid Build Coastguard Worker                 mgr, cameraId, &chars);
3193*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3194*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
3195*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3196*b7c941bbSAndroid Build Coastguard Worker         }
3197*b7c941bbSAndroid Build Coastguard Worker 
3198*b7c941bbSAndroid Build Coastguard Worker         StaticInfo staticInfo(chars);
3199*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_const_entry sessionParamKeys{};
3200*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS,
3201*b7c941bbSAndroid Build Coastguard Worker                 &sessionParamKeys);
3202*b7c941bbSAndroid Build Coastguard Worker         if ((ret != ACAMERA_OK) || (sessionParamKeys.count == 0) ||
3203*b7c941bbSAndroid Build Coastguard Worker                 !staticInfo.isColorOutputSupported()) {
3204*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
3205*b7c941bbSAndroid Build Coastguard Worker             chars = nullptr;
3206*b7c941bbSAndroid Build Coastguard Worker             continue;
3207*b7c941bbSAndroid Build Coastguard Worker         }
3208*b7c941bbSAndroid Build Coastguard Worker 
3209*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
3210*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3211*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3212*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3213*b7c941bbSAndroid Build Coastguard Worker         }
3214*b7c941bbSAndroid Build Coastguard Worker 
3215*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3216*b7c941bbSAndroid Build Coastguard Worker 
3217*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
3218*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3219*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3220*b7c941bbSAndroid Build Coastguard Worker         }
3221*b7c941bbSAndroid Build Coastguard Worker 
3222*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3223*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
3224*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
3225*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3226*b7c941bbSAndroid Build Coastguard Worker         }
3227*b7c941bbSAndroid Build Coastguard Worker 
3228*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog();
3229*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3230*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3231*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3232*b7c941bbSAndroid Build Coastguard Worker         }
3233*b7c941bbSAndroid Build Coastguard Worker 
3234*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest *previewRequest = nullptr;
3235*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.getPreviewRequest(&previewRequest);
3236*b7c941bbSAndroid Build Coastguard Worker         if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3237*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Preview request query failed!");
3238*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3239*b7c941bbSAndroid Build Coastguard Worker         }
3240*b7c941bbSAndroid Build Coastguard Worker 
3241*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog(/*isPreviewShared*/ false, previewRequest);
3242*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3243*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3244*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3245*b7c941bbSAndroid Build Coastguard Worker         }
3246*b7c941bbSAndroid Build Coastguard Worker 
3247*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startPreview();
3248*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3249*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Start preview failed!");
3250*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3251*b7c941bbSAndroid Build Coastguard Worker         }
3252*b7c941bbSAndroid Build Coastguard Worker 
3253*b7c941bbSAndroid Build Coastguard Worker         sleep(3);
3254*b7c941bbSAndroid Build Coastguard Worker 
3255*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
3256*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3257*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3258*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3259*b7c941bbSAndroid Build Coastguard Worker         }
3260*b7c941bbSAndroid Build Coastguard Worker 
3261*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3262*b7c941bbSAndroid Build Coastguard Worker 
3263*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
3264*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3265*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3266*b7c941bbSAndroid Build Coastguard Worker         }
3267*b7c941bbSAndroid Build Coastguard Worker 
3268*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
3269*b7c941bbSAndroid Build Coastguard Worker         chars = nullptr;
3270*b7c941bbSAndroid Build Coastguard Worker     }
3271*b7c941bbSAndroid Build Coastguard Worker 
3272*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
3273*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3274*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3275*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3276*b7c941bbSAndroid Build Coastguard Worker     }
3277*b7c941bbSAndroid Build Coastguard Worker 
3278*b7c941bbSAndroid Build Coastguard Worker     pass = true;
3279*b7c941bbSAndroid Build Coastguard Worker cleanup:
3280*b7c941bbSAndroid Build Coastguard Worker     if (chars) {
3281*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
3282*b7c941bbSAndroid Build Coastguard Worker     }
3283*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(mgr);
3284*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3285*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
3286*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
3287*b7c941bbSAndroid Build Coastguard Worker     }
3288*b7c941bbSAndroid Build Coastguard Worker     return pass;
3289*b7c941bbSAndroid Build Coastguard Worker }
3290*b7c941bbSAndroid Build Coastguard Worker 
nativeCameraDeviceTestPrepareSurface(JNIEnv * env,jobject jPreviewSurface,jstring jOverrideCameraId)3291*b7c941bbSAndroid Build Coastguard Worker bool nativeCameraDeviceTestPrepareSurface(
3292*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jobject jPreviewSurface,
3293*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3294*b7c941bbSAndroid Build Coastguard Worker     const int NUM_TEST_IMAGES = 10;
3295*b7c941bbSAndroid Build Coastguard Worker     const int TEST_WIDTH  = 640;
3296*b7c941bbSAndroid Build Coastguard Worker     const int TEST_HEIGHT = 480;
3297*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
3298*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
3299*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
3300*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
3301*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
3302*b7c941bbSAndroid Build Coastguard Worker     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3303*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
3304*b7c941bbSAndroid Build Coastguard Worker     int64_t lastFrameNumber = 0;
3305*b7c941bbSAndroid Build Coastguard Worker     bool frameStarted = false;
3306*b7c941bbSAndroid Build Coastguard Worker     bool frameArrived = false;
3307*b7c941bbSAndroid Build Coastguard Worker     uint32_t timeoutSec = 1;
3308*b7c941bbSAndroid Build Coastguard Worker     uint32_t runPreviewSec = 2;
3309*b7c941bbSAndroid Build Coastguard Worker 
3310*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3311*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3312*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
3313*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3314*b7c941bbSAndroid Build Coastguard Worker     }
3315*b7c941bbSAndroid Build Coastguard Worker 
3316*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
3317*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
3318*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
3319*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3320*b7c941bbSAndroid Build Coastguard Worker     }
3321*b7c941bbSAndroid Build Coastguard Worker 
3322*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
3323*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
3324*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
3325*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3326*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3327*b7c941bbSAndroid Build Coastguard Worker         }
3328*b7c941bbSAndroid Build Coastguard Worker 
3329*b7c941bbSAndroid Build Coastguard Worker         chars = testCase.getCameraChars(cameraId);
3330*b7c941bbSAndroid Build Coastguard Worker         if (chars == nullptr) {
3331*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3332*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3333*b7c941bbSAndroid Build Coastguard Worker         }
3334*b7c941bbSAndroid Build Coastguard Worker         StaticInfo staticInfo(chars);
3335*b7c941bbSAndroid Build Coastguard Worker         if (!staticInfo.isColorOutputSupported()) {
3336*b7c941bbSAndroid Build Coastguard Worker             ALOGI("%s: camera %s does not support color output. skipping",
3337*b7c941bbSAndroid Build Coastguard Worker                     __FUNCTION__, cameraId);
3338*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
3339*b7c941bbSAndroid Build Coastguard Worker             chars = nullptr;
3340*b7c941bbSAndroid Build Coastguard Worker             continue;
3341*b7c941bbSAndroid Build Coastguard Worker         }
3342*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
3343*b7c941bbSAndroid Build Coastguard Worker         chars = nullptr;
3344*b7c941bbSAndroid Build Coastguard Worker 
3345*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
3346*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3347*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3348*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3349*b7c941bbSAndroid Build Coastguard Worker         }
3350*b7c941bbSAndroid Build Coastguard Worker 
3351*b7c941bbSAndroid Build Coastguard Worker         usleep(1000000); // sleep to give some time for callbacks to happen
3352*b7c941bbSAndroid Build Coastguard Worker 
3353*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
3354*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3355*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3356*b7c941bbSAndroid Build Coastguard Worker         }
3357*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener readerListener;
3358*b7c941bbSAndroid Build Coastguard Worker         AImageReader* reader = nullptr;
3359*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* readerAnw = nullptr;
3360*b7c941bbSAndroid Build Coastguard Worker         ACaptureSessionOutput* readerSessionOutput = nullptr;
3361*b7c941bbSAndroid Build Coastguard Worker         ACameraOutputTarget* readerOutput = nullptr;
3362*b7c941bbSAndroid Build Coastguard Worker         AImageReader_ImageListener readerCb {
3363*b7c941bbSAndroid Build Coastguard Worker             &readerListener,
3364*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::validateImageCb
3365*b7c941bbSAndroid Build Coastguard Worker         };
3366*b7c941bbSAndroid Build Coastguard Worker 
3367*b7c941bbSAndroid Build Coastguard Worker         mediaRet = testCase.initImageReaderWithErrorLog(
3368*b7c941bbSAndroid Build Coastguard Worker                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
3369*b7c941bbSAndroid Build Coastguard Worker                 &readerCb, &reader, &readerAnw);
3370*b7c941bbSAndroid Build Coastguard Worker         if (mediaRet != AMEDIA_OK) {
3371*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3372*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3373*b7c941bbSAndroid Build Coastguard Worker         }
3374*b7c941bbSAndroid Build Coastguard Worker 
3375*b7c941bbSAndroid Build Coastguard Worker         ret = ACaptureSessionOutput_create(readerAnw,
3376*b7c941bbSAndroid Build Coastguard Worker                 &readerSessionOutput);
3377*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
3378*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3379*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3380*b7c941bbSAndroid Build Coastguard Worker         }
3381*b7c941bbSAndroid Build Coastguard Worker 
3382*b7c941bbSAndroid Build Coastguard Worker         ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
3383*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3384*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3385*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3386*b7c941bbSAndroid Build Coastguard Worker         }
3387*b7c941bbSAndroid Build Coastguard Worker 
3388*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3389*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
3390*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
3391*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3392*b7c941bbSAndroid Build Coastguard Worker         }
3393*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACaptureSessionOutput *> readerSessionOutputs = {readerSessionOutput};
3394*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
3395*b7c941bbSAndroid Build Coastguard Worker                 nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
3396*b7c941bbSAndroid Build Coastguard Worker         if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
3397*b7c941bbSAndroid Build Coastguard Worker                 ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
3398*b7c941bbSAndroid Build Coastguard Worker             // Camera device doesn't support the stream combination, skip the
3399*b7c941bbSAndroid Build Coastguard Worker             // current camera.
3400*b7c941bbSAndroid Build Coastguard Worker             testCase.closeCamera();
3401*b7c941bbSAndroid Build Coastguard Worker             testCase.resetCamera();
3402*b7c941bbSAndroid Build Coastguard Worker             continue;
3403*b7c941bbSAndroid Build Coastguard Worker         } else if (ret != ACAMERA_OK) {
3404*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3405*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3406*b7c941bbSAndroid Build Coastguard Worker         }
3407*b7c941bbSAndroid Build Coastguard Worker         // Set the callback on the created capture session and prepare all the surfaces
3408*b7c941bbSAndroid Build Coastguard Worker         if (testCase.setWindowPreparedCallback() != ACAMERA_OK ||
3409*b7c941bbSAndroid Build Coastguard Worker                 testCase.prepareWindow(previewAnw) != ACAMERA_OK) {
3410*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3411*b7c941bbSAndroid Build Coastguard Worker         }
3412*b7c941bbSAndroid Build Coastguard Worker         if (testCase.prepareWindow(readerAnw) != ACAMERA_OK) {
3413*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3414*b7c941bbSAndroid Build Coastguard Worker         }
3415*b7c941bbSAndroid Build Coastguard Worker         // Wait for some time - we should've gotten onWindowPrepared callbacks for all the
3416*b7c941bbSAndroid Build Coastguard Worker         // ANativeWindows.
3417*b7c941bbSAndroid Build Coastguard Worker         usleep(200000);
3418*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.gotAllPreparedCallbacksWithErrorLog()) {
3419*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3420*b7c941bbSAndroid Build Coastguard Worker         }
3421*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACameraOutputTarget* > readerOutputs = {readerOutput};
3422*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog(readerOutputs);
3423*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3424*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3425*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3426*b7c941bbSAndroid Build Coastguard Worker         }
3427*b7c941bbSAndroid Build Coastguard Worker 
3428*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest *previewRequest = nullptr;
3429*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.getPreviewRequest(&previewRequest);
3430*b7c941bbSAndroid Build Coastguard Worker         if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3431*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Preview request query failed!");
3432*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3433*b7c941bbSAndroid Build Coastguard Worker         }
3434*b7c941bbSAndroid Build Coastguard Worker 
3435*b7c941bbSAndroid Build Coastguard Worker         int sequenceId = 0;
3436*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startPreview(&sequenceId);
3437*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3438*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Start preview failed!");
3439*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3440*b7c941bbSAndroid Build Coastguard Worker         }
3441*b7c941bbSAndroid Build Coastguard Worker 
3442*b7c941bbSAndroid Build Coastguard Worker         sleep(runPreviewSec);
3443*b7c941bbSAndroid Build Coastguard Worker 
3444*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.stopPreview();
3445*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3446*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: stopPreview failed", __FUNCTION__);
3447*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "stopPreview failed!");
3448*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3449*b7c941bbSAndroid Build Coastguard Worker         }
3450*b7c941bbSAndroid Build Coastguard Worker 
3451*b7c941bbSAndroid Build Coastguard Worker         //Then wait for all old requests to flush
3452*b7c941bbSAndroid Build Coastguard Worker         lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
3453*b7c941bbSAndroid Build Coastguard Worker         if (lastFrameNumber < 0) {
3454*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
3455*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
3456*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3457*b7c941bbSAndroid Build Coastguard Worker         }
3458*b7c941bbSAndroid Build Coastguard Worker         frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
3459*b7c941bbSAndroid Build Coastguard Worker         if (!frameArrived) {
3460*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3461*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
3462*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3463*b7c941bbSAndroid Build Coastguard Worker         }
3464*b7c941bbSAndroid Build Coastguard Worker 
3465*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
3466*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3467*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3468*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3469*b7c941bbSAndroid Build Coastguard Worker         }
3470*b7c941bbSAndroid Build Coastguard Worker 
3471*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3472*b7c941bbSAndroid Build Coastguard Worker 
3473*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
3474*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3475*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3476*b7c941bbSAndroid Build Coastguard Worker         }
3477*b7c941bbSAndroid Build Coastguard Worker     }
3478*b7c941bbSAndroid Build Coastguard Worker 
3479*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
3480*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3481*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3482*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3483*b7c941bbSAndroid Build Coastguard Worker     }
3484*b7c941bbSAndroid Build Coastguard Worker 
3485*b7c941bbSAndroid Build Coastguard Worker     pass = true;
3486*b7c941bbSAndroid Build Coastguard Worker cleanup:
3487*b7c941bbSAndroid Build Coastguard Worker     if (chars) {
3488*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
3489*b7c941bbSAndroid Build Coastguard Worker     }
3490*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(mgr);
3491*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3492*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
3493*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
3494*b7c941bbSAndroid Build Coastguard Worker     }
3495*b7c941bbSAndroid Build Coastguard Worker     return pass;
3496*b7c941bbSAndroid Build Coastguard Worker }
3497*b7c941bbSAndroid Build Coastguard Worker 
3498*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDevicePrepareSurface(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3499*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3500*b7c941bbSAndroid Build Coastguard Worker testCameraDevicePrepareSurface(
3501*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3502*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3503*b7c941bbSAndroid Build Coastguard Worker     return nativeCameraDeviceTestPrepareSurface(env,
3504*b7c941bbSAndroid Build Coastguard Worker             jPreviewSurface, jOverrideCameraId);
3505*b7c941bbSAndroid Build Coastguard Worker }
3506*b7c941bbSAndroid Build Coastguard Worker 
nativeCameraDeviceLogicalPhysicalStreaming(JNIEnv * env,jobject jPreviewSurface,bool usePhysicalSettings,jstring jOverrideCameraId,bool v2Callbacks)3507*b7c941bbSAndroid Build Coastguard Worker bool nativeCameraDeviceLogicalPhysicalStreaming(
3508*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings,
3509*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId, bool v2Callbacks) {
3510*b7c941bbSAndroid Build Coastguard Worker     const int NUM_TEST_IMAGES = 10;
3511*b7c941bbSAndroid Build Coastguard Worker     const int TEST_WIDTH  = 640;
3512*b7c941bbSAndroid Build Coastguard Worker     const int TEST_HEIGHT = 480;
3513*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
3514*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
3515*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
3516*b7c941bbSAndroid Build Coastguard Worker     ACameraManager* mgr = ACameraManager_create();
3517*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
3518*b7c941bbSAndroid Build Coastguard Worker     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3519*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
3520*b7c941bbSAndroid Build Coastguard Worker     int64_t lastFrameNumber = 0;
3521*b7c941bbSAndroid Build Coastguard Worker     bool frameStarted = false;
3522*b7c941bbSAndroid Build Coastguard Worker     bool frameArrived = false;
3523*b7c941bbSAndroid Build Coastguard Worker     uint32_t timeoutSec = 1;
3524*b7c941bbSAndroid Build Coastguard Worker     uint32_t runPreviewSec = 2;
3525*b7c941bbSAndroid Build Coastguard Worker 
3526*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3527*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3528*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
3529*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3530*b7c941bbSAndroid Build Coastguard Worker     }
3531*b7c941bbSAndroid Build Coastguard Worker 
3532*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
3533*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
3534*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3535*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3536*b7c941bbSAndroid Build Coastguard Worker     }
3537*b7c941bbSAndroid Build Coastguard Worker 
3538*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
3539*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
3540*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
3541*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3542*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3543*b7c941bbSAndroid Build Coastguard Worker         }
3544*b7c941bbSAndroid Build Coastguard Worker 
3545*b7c941bbSAndroid Build Coastguard Worker         if (chars != nullptr) {
3546*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
3547*b7c941bbSAndroid Build Coastguard Worker             chars = nullptr;
3548*b7c941bbSAndroid Build Coastguard Worker         }
3549*b7c941bbSAndroid Build Coastguard Worker         chars = testCase.getCameraChars(i);
3550*b7c941bbSAndroid Build Coastguard Worker         if (chars == nullptr) {
3551*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3552*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3553*b7c941bbSAndroid Build Coastguard Worker         }
3554*b7c941bbSAndroid Build Coastguard Worker 
3555*b7c941bbSAndroid Build Coastguard Worker         size_t physicalCameraCnt = 0;
3556*b7c941bbSAndroid Build Coastguard Worker         const char *const* physicalCameraIds = nullptr;
3557*b7c941bbSAndroid Build Coastguard Worker         if (!ACameraMetadata_isLogicalMultiCamera(
3558*b7c941bbSAndroid Build Coastguard Worker                 chars, &physicalCameraCnt, &physicalCameraIds)) {
3559*b7c941bbSAndroid Build Coastguard Worker             continue;
3560*b7c941bbSAndroid Build Coastguard Worker         }
3561*b7c941bbSAndroid Build Coastguard Worker         if (physicalCameraCnt < 2) {
3562*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Logical camera device %s only has %zu physical cameras",
3563*b7c941bbSAndroid Build Coastguard Worker                    cameraId, physicalCameraCnt);
3564*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3565*b7c941bbSAndroid Build Coastguard Worker         }
3566*b7c941bbSAndroid Build Coastguard Worker 
3567*b7c941bbSAndroid Build Coastguard Worker         std::vector<const char*> candidateIds;
3568*b7c941bbSAndroid Build Coastguard Worker         for (size_t i = 0; i < physicalCameraCnt && candidateIds.size() < 2; i++) {
3569*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata* physicalChars = testCase.getCameraChars(physicalCameraIds[i]);
3570*b7c941bbSAndroid Build Coastguard Worker             if (physicalChars == nullptr) {
3571*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString,
3572*b7c941bbSAndroid Build Coastguard Worker                         "Get camera %s characteristics failure", physicalCameraIds[i]);
3573*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3574*b7c941bbSAndroid Build Coastguard Worker             }
3575*b7c941bbSAndroid Build Coastguard Worker             StaticInfo info(physicalChars);
3576*b7c941bbSAndroid Build Coastguard Worker             bool testSizeSupported = info.isSizeSupportedForFormat(AIMAGE_FORMAT_YUV_420_888,
3577*b7c941bbSAndroid Build Coastguard Worker                     TEST_WIDTH, TEST_HEIGHT);
3578*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(physicalChars);
3579*b7c941bbSAndroid Build Coastguard Worker             if (!testSizeSupported) {
3580*b7c941bbSAndroid Build Coastguard Worker                 continue;
3581*b7c941bbSAndroid Build Coastguard Worker             }
3582*b7c941bbSAndroid Build Coastguard Worker             candidateIds.push_back(physicalCameraIds[i]);
3583*b7c941bbSAndroid Build Coastguard Worker         }
3584*b7c941bbSAndroid Build Coastguard Worker         if (candidateIds.size() < 2) {
3585*b7c941bbSAndroid Build Coastguard Worker             continue;
3586*b7c941bbSAndroid Build Coastguard Worker         }
3587*b7c941bbSAndroid Build Coastguard Worker 
3588*b7c941bbSAndroid Build Coastguard Worker         // Check physical camera request keys
3589*b7c941bbSAndroid Build Coastguard Worker         if (usePhysicalSettings) {
3590*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_const_entry entry;
3591*b7c941bbSAndroid Build Coastguard Worker             camera_status_t status = ACameraMetadata_getConstEntry(
3592*b7c941bbSAndroid Build Coastguard Worker                     chars, ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &entry);
3593*b7c941bbSAndroid Build Coastguard Worker             if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
3594*b7c941bbSAndroid Build Coastguard Worker                 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
3595*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("%s camera id %s physical request keys not reported, skipping",
3596*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, cameraId);
3597*b7c941bbSAndroid Build Coastguard Worker                 continue;
3598*b7c941bbSAndroid Build Coastguard Worker             } else if (status != ACAMERA_OK) {
3599*b7c941bbSAndroid Build Coastguard Worker                 // Do not log error here. testcase did it.
3600*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3601*b7c941bbSAndroid Build Coastguard Worker             } else if (entry.count == 0) {
3602*b7c941bbSAndroid Build Coastguard Worker                 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
3603*b7c941bbSAndroid Build Coastguard Worker                 continue;
3604*b7c941bbSAndroid Build Coastguard Worker             }
3605*b7c941bbSAndroid Build Coastguard Worker         }
3606*b7c941bbSAndroid Build Coastguard Worker 
3607*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
3608*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3609*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3610*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3611*b7c941bbSAndroid Build Coastguard Worker         }
3612*b7c941bbSAndroid Build Coastguard Worker 
3613*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3614*b7c941bbSAndroid Build Coastguard Worker 
3615*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
3616*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3617*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3618*b7c941bbSAndroid Build Coastguard Worker         }
3619*b7c941bbSAndroid Build Coastguard Worker 
3620*b7c941bbSAndroid Build Coastguard Worker         std::vector<ImageReaderListener> readerListeners(2);
3621*b7c941bbSAndroid Build Coastguard Worker         std::vector<AImageReader_ImageListener> readerCbs;
3622*b7c941bbSAndroid Build Coastguard Worker         std::vector<AImageReader*> readers;
3623*b7c941bbSAndroid Build Coastguard Worker         std::vector<ANativeWindow*> readerAnws;
3624*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACaptureSessionOutput*> readerSessionOutputs;
3625*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACameraOutputTarget*> readerOutputs;
3626*b7c941bbSAndroid Build Coastguard Worker         for (size_t i = 0; i < 2; i++) {
3627*b7c941bbSAndroid Build Coastguard Worker             AImageReader_ImageListener readerCb {
3628*b7c941bbSAndroid Build Coastguard Worker                 &readerListeners[i],
3629*b7c941bbSAndroid Build Coastguard Worker                 ImageReaderListener::validateImageCb
3630*b7c941bbSAndroid Build Coastguard Worker             };
3631*b7c941bbSAndroid Build Coastguard Worker             readerCbs.push_back(readerCb);
3632*b7c941bbSAndroid Build Coastguard Worker 
3633*b7c941bbSAndroid Build Coastguard Worker             AImageReader* reader = nullptr;
3634*b7c941bbSAndroid Build Coastguard Worker             ANativeWindow* readerAnw = nullptr;
3635*b7c941bbSAndroid Build Coastguard Worker             ACaptureSessionOutput* readerSessionOutput = nullptr;
3636*b7c941bbSAndroid Build Coastguard Worker             ACameraOutputTarget* readerOutput = nullptr;
3637*b7c941bbSAndroid Build Coastguard Worker             mediaRet = testCase.initImageReaderWithErrorLog(
3638*b7c941bbSAndroid Build Coastguard Worker                     TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
3639*b7c941bbSAndroid Build Coastguard Worker                     &readerCb, &reader, &readerAnw);
3640*b7c941bbSAndroid Build Coastguard Worker             if (mediaRet != AMEDIA_OK) {
3641*b7c941bbSAndroid Build Coastguard Worker                 // Don't log error here. testcase did it
3642*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3643*b7c941bbSAndroid Build Coastguard Worker             }
3644*b7c941bbSAndroid Build Coastguard Worker 
3645*b7c941bbSAndroid Build Coastguard Worker             camera_status_t ret = ACaptureSessionPhysicalOutput_create(readerAnw,
3646*b7c941bbSAndroid Build Coastguard Worker                     candidateIds[i], &readerSessionOutput);
3647*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
3648*b7c941bbSAndroid Build Coastguard Worker                 if (ret == ACAMERA_OK) {
3649*b7c941bbSAndroid Build Coastguard Worker                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
3650*b7c941bbSAndroid Build Coastguard Worker                 }
3651*b7c941bbSAndroid Build Coastguard Worker                 // Don't log error here. testcase did it
3652*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3653*b7c941bbSAndroid Build Coastguard Worker             }
3654*b7c941bbSAndroid Build Coastguard Worker 
3655*b7c941bbSAndroid Build Coastguard Worker             ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
3656*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
3657*b7c941bbSAndroid Build Coastguard Worker                 // Don't log error here. testcase did it
3658*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3659*b7c941bbSAndroid Build Coastguard Worker             }
3660*b7c941bbSAndroid Build Coastguard Worker 
3661*b7c941bbSAndroid Build Coastguard Worker             readers.push_back(reader);
3662*b7c941bbSAndroid Build Coastguard Worker             readerAnws.push_back(readerAnw);
3663*b7c941bbSAndroid Build Coastguard Worker             readerSessionOutputs.push_back(readerSessionOutput);
3664*b7c941bbSAndroid Build Coastguard Worker             readerOutputs.push_back(readerOutput);
3665*b7c941bbSAndroid Build Coastguard Worker         }
3666*b7c941bbSAndroid Build Coastguard Worker 
3667*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3668*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
3669*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
3670*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3671*b7c941bbSAndroid Build Coastguard Worker         }
3672*b7c941bbSAndroid Build Coastguard Worker 
3673*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
3674*b7c941bbSAndroid Build Coastguard Worker                 nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
3675*b7c941bbSAndroid Build Coastguard Worker         if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
3676*b7c941bbSAndroid Build Coastguard Worker                 ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
3677*b7c941bbSAndroid Build Coastguard Worker             // Camera device doesn't support the stream combination, skip the
3678*b7c941bbSAndroid Build Coastguard Worker             // current camera.
3679*b7c941bbSAndroid Build Coastguard Worker             testCase.closeCamera();
3680*b7c941bbSAndroid Build Coastguard Worker             testCase.resetCamera();
3681*b7c941bbSAndroid Build Coastguard Worker             continue;
3682*b7c941bbSAndroid Build Coastguard Worker         } else if (ret != ACAMERA_OK) {
3683*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3684*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3685*b7c941bbSAndroid Build Coastguard Worker         }
3686*b7c941bbSAndroid Build Coastguard Worker 
3687*b7c941bbSAndroid Build Coastguard Worker         if (usePhysicalSettings) {
3688*b7c941bbSAndroid Build Coastguard Worker             std::vector<const char*> twoNullStr = {nullptr, nullptr};
3689*b7c941bbSAndroid Build Coastguard Worker             ACameraIdList nullCameraIdList = {2, twoNullStr.data()};
3690*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.createRequestsWithErrorLog(readerOutputs, &nullCameraIdList);
3691*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3692*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Null physical camera ids must fail createCaptureRequest. "
3693*b7c941bbSAndroid Build Coastguard Worker                         "ret %d", ret);
3694*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3695*b7c941bbSAndroid Build Coastguard Worker             }
3696*b7c941bbSAndroid Build Coastguard Worker 
3697*b7c941bbSAndroid Build Coastguard Worker             std::string invalidId = "";
3698*b7c941bbSAndroid Build Coastguard Worker             std::vector<const char*> one0LengthStr = {invalidId.c_str()};
3699*b7c941bbSAndroid Build Coastguard Worker             ACameraIdList invalidCameraIdList = {1, one0LengthStr.data()};
3700*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.createRequestsWithErrorLog(readerOutputs, &invalidCameraIdList);
3701*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3702*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "zero-length physical camera ids must fail "
3703*b7c941bbSAndroid Build Coastguard Worker                         "createCaptureRequest. ret %d", ret);
3704*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3705*b7c941bbSAndroid Build Coastguard Worker             }
3706*b7c941bbSAndroid Build Coastguard Worker 
3707*b7c941bbSAndroid Build Coastguard Worker             ACameraIdList physicalCameraIdList = {2, candidateIds.data()};
3708*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.createRequestsWithErrorLog(readerOutputs, &physicalCameraIdList);
3709*b7c941bbSAndroid Build Coastguard Worker         } else {
3710*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.createRequestsWithErrorLog(readerOutputs);
3711*b7c941bbSAndroid Build Coastguard Worker         }
3712*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3713*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3714*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3715*b7c941bbSAndroid Build Coastguard Worker         }
3716*b7c941bbSAndroid Build Coastguard Worker 
3717*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest *previewRequest = nullptr;
3718*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.getPreviewRequest(&previewRequest);
3719*b7c941bbSAndroid Build Coastguard Worker         if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3720*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Preview request query failed!");
3721*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3722*b7c941bbSAndroid Build Coastguard Worker         }
3723*b7c941bbSAndroid Build Coastguard Worker 
3724*b7c941bbSAndroid Build Coastguard Worker         int sequenceId = 0;
3725*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startPreview(&sequenceId, 2, candidateIds.data(), v2Callbacks);
3726*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3727*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Start preview failed!");
3728*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3729*b7c941bbSAndroid Build Coastguard Worker         }
3730*b7c941bbSAndroid Build Coastguard Worker 
3731*b7c941bbSAndroid Build Coastguard Worker         sleep(runPreviewSec);
3732*b7c941bbSAndroid Build Coastguard Worker 
3733*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.stopPreview();
3734*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3735*b7c941bbSAndroid Build Coastguard Worker             ALOGE("%s: stopPreview failed", __FUNCTION__);
3736*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "stopPreview failed!");
3737*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3738*b7c941bbSAndroid Build Coastguard Worker         }
3739*b7c941bbSAndroid Build Coastguard Worker 
3740*b7c941bbSAndroid Build Coastguard Worker         //Then wait for all old requests to flush
3741*b7c941bbSAndroid Build Coastguard Worker         lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
3742*b7c941bbSAndroid Build Coastguard Worker         if (lastFrameNumber < 0) {
3743*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
3744*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
3745*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3746*b7c941bbSAndroid Build Coastguard Worker         }
3747*b7c941bbSAndroid Build Coastguard Worker         if (v2Callbacks) {
3748*b7c941bbSAndroid Build Coastguard Worker               frameStarted = testCase.waitForFrameNumberStarted(lastFrameNumber, timeoutSec);
3749*b7c941bbSAndroid Build Coastguard Worker             if (!frameStarted) {
3750*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s timed out waiting on onCaptureStart for last"
3751*b7c941bbSAndroid Build Coastguard Worker                         "frame number!", cameraId);
3752*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3753*b7c941bbSAndroid Build Coastguard Worker             }
3754*b7c941bbSAndroid Build Coastguard Worker 
3755*b7c941bbSAndroid Build Coastguard Worker         }
3756*b7c941bbSAndroid Build Coastguard Worker 
3757*b7c941bbSAndroid Build Coastguard Worker         frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
3758*b7c941bbSAndroid Build Coastguard Worker         if (!frameArrived) {
3759*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3760*b7c941bbSAndroid Build Coastguard Worker                     cameraId);
3761*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3762*b7c941bbSAndroid Build Coastguard Worker         }
3763*b7c941bbSAndroid Build Coastguard Worker 
3764*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
3765*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3766*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3767*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3768*b7c941bbSAndroid Build Coastguard Worker         }
3769*b7c941bbSAndroid Build Coastguard Worker 
3770*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
3771*b7c941bbSAndroid Build Coastguard Worker 
3772*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
3773*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3774*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3775*b7c941bbSAndroid Build Coastguard Worker         }
3776*b7c941bbSAndroid Build Coastguard Worker     }
3777*b7c941bbSAndroid Build Coastguard Worker 
3778*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
3779*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3780*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3781*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3782*b7c941bbSAndroid Build Coastguard Worker     }
3783*b7c941bbSAndroid Build Coastguard Worker 
3784*b7c941bbSAndroid Build Coastguard Worker     pass = true;
3785*b7c941bbSAndroid Build Coastguard Worker cleanup:
3786*b7c941bbSAndroid Build Coastguard Worker     if (chars) {
3787*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
3788*b7c941bbSAndroid Build Coastguard Worker     }
3789*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_delete(mgr);
3790*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3791*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
3792*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
3793*b7c941bbSAndroid Build Coastguard Worker     }
3794*b7c941bbSAndroid Build Coastguard Worker     return pass;
3795*b7c941bbSAndroid Build Coastguard Worker }
3796*b7c941bbSAndroid Build Coastguard Worker 
3797*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalStreamingNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3798*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3799*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceLogicalPhysicalStreamingNative(
3800*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3801*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3802*b7c941bbSAndroid Build Coastguard Worker     return nativeCameraDeviceLogicalPhysicalStreaming(env,
3803*b7c941bbSAndroid Build Coastguard Worker             jPreviewSurface, false /*usePhysicalSettings*/,
3804*b7c941bbSAndroid Build Coastguard Worker             jOverrideCameraId, /*v2Callbacks*/false);
3805*b7c941bbSAndroid Build Coastguard Worker }
3806*b7c941bbSAndroid Build Coastguard Worker 
3807*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalStreamingNative2(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3808*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3809*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceLogicalPhysicalStreamingNative2(
3810*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3811*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3812*b7c941bbSAndroid Build Coastguard Worker     return nativeCameraDeviceLogicalPhysicalStreaming(env,
3813*b7c941bbSAndroid Build Coastguard Worker             jPreviewSurface, false /*usePhysicalSettings*/,
3814*b7c941bbSAndroid Build Coastguard Worker             jOverrideCameraId, /*v2Callbacks*/true);
3815*b7c941bbSAndroid Build Coastguard Worker }
3816*b7c941bbSAndroid Build Coastguard Worker 
3817*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalSettingsNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3818*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3819*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceLogicalPhysicalSettingsNative(
3820*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3821*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3822*b7c941bbSAndroid Build Coastguard Worker     return nativeCameraDeviceLogicalPhysicalStreaming(env,
3823*b7c941bbSAndroid Build Coastguard Worker             jPreviewSurface, true /*usePhysicalSettings*/,
3824*b7c941bbSAndroid Build Coastguard Worker             jOverrideCameraId, /*v2Callbacks*/false);
3825*b7c941bbSAndroid Build Coastguard Worker }
3826*b7c941bbSAndroid Build Coastguard Worker 
3827*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalSettingsNative2(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3828*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3829*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceLogicalPhysicalSettingsNative2(
3830*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3831*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3832*b7c941bbSAndroid Build Coastguard Worker     return nativeCameraDeviceLogicalPhysicalStreaming(env,
3833*b7c941bbSAndroid Build Coastguard Worker             jPreviewSurface, true /*usePhysicalSettings*/,
3834*b7c941bbSAndroid Build Coastguard Worker             jOverrideCameraId, /*v2Callbacks*/ true);
3835*b7c941bbSAndroid Build Coastguard Worker }
3836*b7c941bbSAndroid Build Coastguard Worker 
nativeImageReaderTestBase(JNIEnv * env,jstring jOutPath,jint format,AImageReader_ImageCallback cb,jstring jOverrideCameraId)3837*b7c941bbSAndroid Build Coastguard Worker bool nativeImageReaderTestBase(
3838*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb,
3839*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
3840*b7c941bbSAndroid Build Coastguard Worker     const int NUM_TEST_IMAGES = 10;
3841*b7c941bbSAndroid Build Coastguard Worker     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3842*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
3843*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
3844*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
3845*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
3846*b7c941bbSAndroid Build Coastguard Worker 
3847*b7c941bbSAndroid Build Coastguard Worker     const char* outPath = (jOutPath == nullptr) ? nullptr :
3848*b7c941bbSAndroid Build Coastguard Worker             env->GetStringUTFChars(jOutPath, nullptr);
3849*b7c941bbSAndroid Build Coastguard Worker     if (outPath != nullptr) {
3850*b7c941bbSAndroid Build Coastguard Worker         ALOGI("%s: out path is %s", __FUNCTION__, outPath);
3851*b7c941bbSAndroid Build Coastguard Worker     }
3852*b7c941bbSAndroid Build Coastguard Worker 
3853*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3854*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
3855*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
3856*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3857*b7c941bbSAndroid Build Coastguard Worker     }
3858*b7c941bbSAndroid Build Coastguard Worker 
3859*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
3860*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
3861*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3862*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
3863*b7c941bbSAndroid Build Coastguard Worker     }
3864*b7c941bbSAndroid Build Coastguard Worker 
3865*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
3866*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
3867*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
3868*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3869*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3870*b7c941bbSAndroid Build Coastguard Worker         }
3871*b7c941bbSAndroid Build Coastguard Worker 
3872*b7c941bbSAndroid Build Coastguard Worker         {
3873*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
3874*b7c941bbSAndroid Build Coastguard Worker             StaticInfo staticInfo(chars);
3875*b7c941bbSAndroid Build Coastguard Worker             if (!staticInfo.isColorOutputSupported()) {
3876*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("%s: camera %s does not support color output. skipping",
3877*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, cameraId);
3878*b7c941bbSAndroid Build Coastguard Worker                 ACameraMetadata_free(chars);
3879*b7c941bbSAndroid Build Coastguard Worker                 continue;
3880*b7c941bbSAndroid Build Coastguard Worker             }
3881*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
3882*b7c941bbSAndroid Build Coastguard Worker         }
3883*b7c941bbSAndroid Build Coastguard Worker 
3884*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
3885*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3886*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3887*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3888*b7c941bbSAndroid Build Coastguard Worker         }
3889*b7c941bbSAndroid Build Coastguard Worker 
3890*b7c941bbSAndroid Build Coastguard Worker         chars = testCase.getCameraChars(i);
3891*b7c941bbSAndroid Build Coastguard Worker         if (chars == nullptr) {
3892*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3893*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3894*b7c941bbSAndroid Build Coastguard Worker         }
3895*b7c941bbSAndroid Build Coastguard Worker         StaticInfo staticInfo(chars);
3896*b7c941bbSAndroid Build Coastguard Worker 
3897*b7c941bbSAndroid Build Coastguard Worker         usleep(200000); // sleep to give some time for callbacks to happen
3898*b7c941bbSAndroid Build Coastguard Worker 
3899*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
3900*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3901*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3902*b7c941bbSAndroid Build Coastguard Worker         }
3903*b7c941bbSAndroid Build Coastguard Worker 
3904*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener readerListener;
3905*b7c941bbSAndroid Build Coastguard Worker         AImageReader_ImageListener readerCb { &readerListener, cb };
3906*b7c941bbSAndroid Build Coastguard Worker         readerListener.setDumpFilePathBase(outPath);
3907*b7c941bbSAndroid Build Coastguard Worker 
3908*b7c941bbSAndroid Build Coastguard Worker         int32_t testWidth, testHeight;
3909*b7c941bbSAndroid Build Coastguard Worker         switch (format) {
3910*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_JPEG:
3911*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_Y8:
3912*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_HEIC:
3913*b7c941bbSAndroid Build Coastguard Worker             case AIMAGE_FORMAT_DEPTH_JPEG:
3914*b7c941bbSAndroid Build Coastguard Worker                 if (!staticInfo.getMaxSizeForFormat(format, &testWidth, &testHeight)) {
3915*b7c941bbSAndroid Build Coastguard Worker                     // No corresponding format support, skip this device.
3916*b7c941bbSAndroid Build Coastguard Worker                     ACameraMetadata_free(chars);
3917*b7c941bbSAndroid Build Coastguard Worker                     chars = nullptr;
3918*b7c941bbSAndroid Build Coastguard Worker                     ret = testCase.closeCamera();
3919*b7c941bbSAndroid Build Coastguard Worker                     if (ret != ACAMERA_OK) {
3920*b7c941bbSAndroid Build Coastguard Worker                         LOG_ERROR(errorString, "Camera %s failed to close. ret %d ", cameraId, ret);
3921*b7c941bbSAndroid Build Coastguard Worker                         goto cleanup;
3922*b7c941bbSAndroid Build Coastguard Worker                     }
3923*b7c941bbSAndroid Build Coastguard Worker 
3924*b7c941bbSAndroid Build Coastguard Worker                     continue;
3925*b7c941bbSAndroid Build Coastguard Worker                 }
3926*b7c941bbSAndroid Build Coastguard Worker                 break;
3927*b7c941bbSAndroid Build Coastguard Worker             default:
3928*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Testcase doesn't yet support format %d", format);
3929*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3930*b7c941bbSAndroid Build Coastguard Worker         }
3931*b7c941bbSAndroid Build Coastguard Worker         mediaRet = testCase.initImageReaderWithErrorLog(
3932*b7c941bbSAndroid Build Coastguard Worker                 testWidth, testHeight, format, NUM_TEST_IMAGES,
3933*b7c941bbSAndroid Build Coastguard Worker                 &readerCb);
3934*b7c941bbSAndroid Build Coastguard Worker         if (mediaRet != AMEDIA_OK) {
3935*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3936*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3937*b7c941bbSAndroid Build Coastguard Worker         }
3938*b7c941bbSAndroid Build Coastguard Worker 
3939*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog();
3940*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3941*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3942*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3943*b7c941bbSAndroid Build Coastguard Worker         }
3944*b7c941bbSAndroid Build Coastguard Worker 
3945*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog();
3946*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
3947*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3948*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3949*b7c941bbSAndroid Build Coastguard Worker         }
3950*b7c941bbSAndroid Build Coastguard Worker 
3951*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener resultListener;
3952*b7c941bbSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallbacks resultCb {
3953*b7c941bbSAndroid Build Coastguard Worker             &resultListener,
3954*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureStart,
3955*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureProgressed,
3956*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureCompleted,
3957*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureFailed,
3958*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureSequenceCompleted,
3959*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureSequenceAborted,
3960*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureBufferLost
3961*b7c941bbSAndroid Build Coastguard Worker         };
3962*b7c941bbSAndroid Build Coastguard Worker         resultListener.setRequestSave(true);
3963*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest* requestTemplate = nullptr;
3964*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.getStillRequest(&requestTemplate);
3965*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3966*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
3967*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3968*b7c941bbSAndroid Build Coastguard Worker         }
3969*b7c941bbSAndroid Build Coastguard Worker 
3970*b7c941bbSAndroid Build Coastguard Worker         // Do some still capture
3971*b7c941bbSAndroid Build Coastguard Worker         int lastSeqId = -1;
3972*b7c941bbSAndroid Build Coastguard Worker         for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
3973*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
3974*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest_setUserContext(req, (void*) capture);
3975*b7c941bbSAndroid Build Coastguard Worker             int seqId;
3976*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.capture(req, &resultCb, &seqId);
3977*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
3978*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
3979*b7c941bbSAndroid Build Coastguard Worker                         cameraId, capture, ret);
3980*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
3981*b7c941bbSAndroid Build Coastguard Worker             }
3982*b7c941bbSAndroid Build Coastguard Worker             if (capture == NUM_TEST_IMAGES - 1) {
3983*b7c941bbSAndroid Build Coastguard Worker                 lastSeqId = seqId;
3984*b7c941bbSAndroid Build Coastguard Worker             }
3985*b7c941bbSAndroid Build Coastguard Worker             ACaptureRequest_free(req);
3986*b7c941bbSAndroid Build Coastguard Worker         }
3987*b7c941bbSAndroid Build Coastguard Worker 
3988*b7c941bbSAndroid Build Coastguard Worker         // wait until last sequence complete
3989*b7c941bbSAndroid Build Coastguard Worker         resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 5);
3990*b7c941bbSAndroid Build Coastguard Worker 
3991*b7c941bbSAndroid Build Coastguard Worker         std::vector<ACaptureRequest*> completedRequests;
3992*b7c941bbSAndroid Build Coastguard Worker         resultListener.getCompletedRequests(&completedRequests);
3993*b7c941bbSAndroid Build Coastguard Worker 
3994*b7c941bbSAndroid Build Coastguard Worker         if (completedRequests.size() != NUM_TEST_IMAGES) {
3995*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
3996*b7c941bbSAndroid Build Coastguard Worker                     cameraId, NUM_TEST_IMAGES, completedRequests.size());
3997*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
3998*b7c941bbSAndroid Build Coastguard Worker         }
3999*b7c941bbSAndroid Build Coastguard Worker 
4000*b7c941bbSAndroid Build Coastguard Worker         for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
4001*b7c941bbSAndroid Build Coastguard Worker             intptr_t userContext = -1;
4002*b7c941bbSAndroid Build Coastguard Worker             ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
4003*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
4004*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
4005*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
4006*b7c941bbSAndroid Build Coastguard Worker             }
4007*b7c941bbSAndroid Build Coastguard Worker 
4008*b7c941bbSAndroid Build Coastguard Worker             if (userContext != i) {
4009*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
4010*b7c941bbSAndroid Build Coastguard Worker                         "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
4011*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
4012*b7c941bbSAndroid Build Coastguard Worker             }
4013*b7c941bbSAndroid Build Coastguard Worker         }
4014*b7c941bbSAndroid Build Coastguard Worker 
4015*b7c941bbSAndroid Build Coastguard Worker         int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
4016*b7c941bbSAndroid Build Coastguard Worker                 format, testWidth, testHeight);
4017*b7c941bbSAndroid Build Coastguard Worker         if (minFrameDurationNs < 0) {
4018*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
4019*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4020*b7c941bbSAndroid Build Coastguard Worker         }
4021*b7c941bbSAndroid Build Coastguard Worker         int64_t stallDurationNs = (format == AIMAGE_FORMAT_Y8) ? 0 :
4022*b7c941bbSAndroid Build Coastguard Worker                 staticInfo.getStallDurationFor(format, testWidth, testHeight);
4023*b7c941bbSAndroid Build Coastguard Worker         if (stallDurationNs < 0) {
4024*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
4025*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4026*b7c941bbSAndroid Build Coastguard Worker         }
4027*b7c941bbSAndroid Build Coastguard Worker 
4028*b7c941bbSAndroid Build Coastguard Worker         int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
4029*b7c941bbSAndroid Build Coastguard Worker         constexpr int64_t waitPerIterationUs = 100000;
4030*b7c941bbSAndroid Build Coastguard Worker         constexpr int64_t usToNs = 1000;
4031*b7c941bbSAndroid Build Coastguard Worker         int totalWaitIteration = 50;
4032*b7c941bbSAndroid Build Coastguard Worker 
4033*b7c941bbSAndroid Build Coastguard Worker         // Allow 1.5x margin
4034*b7c941bbSAndroid Build Coastguard Worker         if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
4035*b7c941bbSAndroid Build Coastguard Worker             totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
4036*b7c941bbSAndroid Build Coastguard Worker         }
4037*b7c941bbSAndroid Build Coastguard Worker 
4038*b7c941bbSAndroid Build Coastguard Worker         // wait until all capture finished
4039*b7c941bbSAndroid Build Coastguard Worker         for (int i = 0; i < totalWaitIteration; i++) {
4040*b7c941bbSAndroid Build Coastguard Worker             usleep(waitPerIterationUs);
4041*b7c941bbSAndroid Build Coastguard Worker             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
4042*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("Session take ~%d ms to capture %d images",
4043*b7c941bbSAndroid Build Coastguard Worker                         i*100, NUM_TEST_IMAGES);
4044*b7c941bbSAndroid Build Coastguard Worker                 break;
4045*b7c941bbSAndroid Build Coastguard Worker             }
4046*b7c941bbSAndroid Build Coastguard Worker         }
4047*b7c941bbSAndroid Build Coastguard Worker 
4048*b7c941bbSAndroid Build Coastguard Worker         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
4049*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
4050*b7c941bbSAndroid Build Coastguard Worker                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
4051*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4052*b7c941bbSAndroid Build Coastguard Worker         }
4053*b7c941bbSAndroid Build Coastguard Worker 
4054*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
4055*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4056*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4057*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4058*b7c941bbSAndroid Build Coastguard Worker         }
4059*b7c941bbSAndroid Build Coastguard Worker 
4060*b7c941bbSAndroid Build Coastguard Worker         usleep(200000); // sleep to give some time for callbacks to happen
4061*b7c941bbSAndroid Build Coastguard Worker 
4062*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
4063*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
4064*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4065*b7c941bbSAndroid Build Coastguard Worker         }
4066*b7c941bbSAndroid Build Coastguard Worker     }
4067*b7c941bbSAndroid Build Coastguard Worker 
4068*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
4069*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4070*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
4071*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
4072*b7c941bbSAndroid Build Coastguard Worker     }
4073*b7c941bbSAndroid Build Coastguard Worker 
4074*b7c941bbSAndroid Build Coastguard Worker     pass = true;
4075*b7c941bbSAndroid Build Coastguard Worker 
4076*b7c941bbSAndroid Build Coastguard Worker cleanup:
4077*b7c941bbSAndroid Build Coastguard Worker     if (outPath != nullptr) {
4078*b7c941bbSAndroid Build Coastguard Worker         env->ReleaseStringUTFChars(jOutPath, outPath);
4079*b7c941bbSAndroid Build Coastguard Worker     }
4080*b7c941bbSAndroid Build Coastguard Worker 
4081*b7c941bbSAndroid Build Coastguard Worker     if (chars != nullptr) {
4082*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
4083*b7c941bbSAndroid Build Coastguard Worker         chars = nullptr;
4084*b7c941bbSAndroid Build Coastguard Worker     }
4085*b7c941bbSAndroid Build Coastguard Worker 
4086*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
4087*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
4088*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
4089*b7c941bbSAndroid Build Coastguard Worker     }
4090*b7c941bbSAndroid Build Coastguard Worker     return pass;
4091*b7c941bbSAndroid Build Coastguard Worker }
4092*b7c941bbSAndroid Build Coastguard Worker 
4093*b7c941bbSAndroid Build Coastguard Worker // Test the camera NDK capture failure path by acquiring the maximum amount of
4094*b7c941bbSAndroid Build Coastguard Worker // ImageReader buffers available. Since there is no circulation of camera
4095*b7c941bbSAndroid Build Coastguard Worker // images, the registered output surface will eventually run out of free buffers
4096*b7c941bbSAndroid Build Coastguard Worker // and start reporting capture errors or lost buffers.
4097*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCaptureFailureNative(JNIEnv * env,jclass,jstring jOverrideCameraId)4098*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
4099*b7c941bbSAndroid Build Coastguard Worker testCameraDeviceCaptureFailureNative(JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
4100*b7c941bbSAndroid Build Coastguard Worker     const size_t NUM_TEST_IMAGES = 10;
4101*b7c941bbSAndroid Build Coastguard Worker     const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
4102*b7c941bbSAndroid Build Coastguard Worker     const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
4103*b7c941bbSAndroid Build Coastguard Worker     const size_t TEST_WIDTH  = 640;
4104*b7c941bbSAndroid Build Coastguard Worker     const size_t TEST_HEIGHT = 480;
4105*b7c941bbSAndroid Build Coastguard Worker     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
4106*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
4107*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
4108*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
4109*b7c941bbSAndroid Build Coastguard Worker     uint32_t bufferTimeoutSec = 1;
4110*b7c941bbSAndroid Build Coastguard Worker     uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
4111*b7c941bbSAndroid Build Coastguard Worker                               // timeout
4112*b7c941bbSAndroid Build Coastguard Worker 
4113*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
4114*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4115*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
4116*b7c941bbSAndroid Build Coastguard Worker         goto exit;
4117*b7c941bbSAndroid Build Coastguard Worker     }
4118*b7c941bbSAndroid Build Coastguard Worker 
4119*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
4120*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
4121*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
4122*b7c941bbSAndroid Build Coastguard Worker         goto exit;
4123*b7c941bbSAndroid Build Coastguard Worker     }
4124*b7c941bbSAndroid Build Coastguard Worker 
4125*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
4126*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
4127*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
4128*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
4129*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4130*b7c941bbSAndroid Build Coastguard Worker         }
4131*b7c941bbSAndroid Build Coastguard Worker 
4132*b7c941bbSAndroid Build Coastguard Worker         std::unique_ptr<ACameraMetadata> chars(testCase.getCameraChars(i));
4133*b7c941bbSAndroid Build Coastguard Worker         if (chars.get() == nullptr) {
4134*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
4135*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4136*b7c941bbSAndroid Build Coastguard Worker         }
4137*b7c941bbSAndroid Build Coastguard Worker         StaticInfo staticInfo(chars.get());
4138*b7c941bbSAndroid Build Coastguard Worker 
4139*b7c941bbSAndroid Build Coastguard Worker         if (!staticInfo.isColorOutputSupported()) {
4140*b7c941bbSAndroid Build Coastguard Worker             continue;
4141*b7c941bbSAndroid Build Coastguard Worker         }
4142*b7c941bbSAndroid Build Coastguard Worker 
4143*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
4144*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4145*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
4146*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4147*b7c941bbSAndroid Build Coastguard Worker         }
4148*b7c941bbSAndroid Build Coastguard Worker 
4149*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
4150*b7c941bbSAndroid Build Coastguard Worker 
4151*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
4152*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
4153*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4154*b7c941bbSAndroid Build Coastguard Worker         }
4155*b7c941bbSAndroid Build Coastguard Worker 
4156*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener readerListener;
4157*b7c941bbSAndroid Build Coastguard Worker         AImageReader_ImageListener readerCb =
4158*b7c941bbSAndroid Build Coastguard Worker                 { &readerListener, ImageReaderListener::signalImageCb };
4159*b7c941bbSAndroid Build Coastguard Worker         mediaRet = testCase.initImageReaderWithErrorLog(TEST_WIDTH, TEST_HEIGHT,
4160*b7c941bbSAndroid Build Coastguard Worker                 AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES, &readerCb);
4161*b7c941bbSAndroid Build Coastguard Worker         if (mediaRet != AMEDIA_OK) {
4162*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4163*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4164*b7c941bbSAndroid Build Coastguard Worker         }
4165*b7c941bbSAndroid Build Coastguard Worker 
4166*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog();
4167*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4168*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4169*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4170*b7c941bbSAndroid Build Coastguard Worker         }
4171*b7c941bbSAndroid Build Coastguard Worker 
4172*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog();
4173*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4174*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4175*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4176*b7c941bbSAndroid Build Coastguard Worker         }
4177*b7c941bbSAndroid Build Coastguard Worker 
4178*b7c941bbSAndroid Build Coastguard Worker         CaptureResultListener resultListener;
4179*b7c941bbSAndroid Build Coastguard Worker         ACameraCaptureSession_captureCallbacks resultCb {
4180*b7c941bbSAndroid Build Coastguard Worker             &resultListener,
4181*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureStart,
4182*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureProgressed,
4183*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureCompleted,
4184*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureFailed,
4185*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureSequenceCompleted,
4186*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureSequenceAborted,
4187*b7c941bbSAndroid Build Coastguard Worker             CaptureResultListener::onCaptureBufferLost
4188*b7c941bbSAndroid Build Coastguard Worker         };
4189*b7c941bbSAndroid Build Coastguard Worker         ACaptureRequest* requestTemplate = nullptr;
4190*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.getStillRequest(&requestTemplate);
4191*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK || requestTemplate == nullptr) {
4192*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4193*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4194*b7c941bbSAndroid Build Coastguard Worker         }
4195*b7c941bbSAndroid Build Coastguard Worker 
4196*b7c941bbSAndroid Build Coastguard Worker         int seqId;
4197*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startRepeatingRequest(&seqId, requestTemplate, &resultCb);
4198*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4199*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4200*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4201*b7c941bbSAndroid Build Coastguard Worker         }
4202*b7c941bbSAndroid Build Coastguard Worker 
4203*b7c941bbSAndroid Build Coastguard Worker         size_t failedRequestCount;
4204*b7c941bbSAndroid Build Coastguard Worker         int64_t lastFrameNumber;
4205*b7c941bbSAndroid Build Coastguard Worker         int64_t lastFailedRequestNumber = -1;
4206*b7c941bbSAndroid Build Coastguard Worker         failedRequestCount = lastFrameNumber = 0;
4207*b7c941bbSAndroid Build Coastguard Worker         while ((failedRequestCount < NUM_FAILED_FRAMES) && (lastFrameNumber < NUM_TOTAL_FRAMES)) {
4208*b7c941bbSAndroid Build Coastguard Worker             auto frameArrived = resultListener.waitForFrameNumber(lastFrameNumber, timeoutSec);
4209*b7c941bbSAndroid Build Coastguard Worker             if (!frameArrived) {
4210*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
4211*b7c941bbSAndroid Build Coastguard Worker                         cameraId);
4212*b7c941bbSAndroid Build Coastguard Worker                 goto exit;
4213*b7c941bbSAndroid Build Coastguard Worker             }
4214*b7c941bbSAndroid Build Coastguard Worker             readerListener.waitForNextBuffer(bufferTimeoutSec);
4215*b7c941bbSAndroid Build Coastguard Worker             auto failedFrameNumber = resultListener.checkForFailureOrLoss(lastFrameNumber) ?
4216*b7c941bbSAndroid Build Coastguard Worker                     lastFrameNumber : -1;
4217*b7c941bbSAndroid Build Coastguard Worker             if (lastFailedRequestNumber != failedFrameNumber) {
4218*b7c941bbSAndroid Build Coastguard Worker                 if ((lastFailedRequestNumber + 1) == failedFrameNumber) {
4219*b7c941bbSAndroid Build Coastguard Worker                     failedRequestCount++;
4220*b7c941bbSAndroid Build Coastguard Worker                 } else {
4221*b7c941bbSAndroid Build Coastguard Worker                     failedRequestCount = 1;
4222*b7c941bbSAndroid Build Coastguard Worker                 }
4223*b7c941bbSAndroid Build Coastguard Worker                 lastFailedRequestNumber = failedFrameNumber;
4224*b7c941bbSAndroid Build Coastguard Worker             }
4225*b7c941bbSAndroid Build Coastguard Worker             lastFrameNumber++;
4226*b7c941bbSAndroid Build Coastguard Worker         }
4227*b7c941bbSAndroid Build Coastguard Worker 
4228*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.abortCaptures();
4229*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4230*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "abort captures failed!");
4231*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4232*b7c941bbSAndroid Build Coastguard Worker         }
4233*b7c941bbSAndroid Build Coastguard Worker 
4234*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
4235*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4236*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4237*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4238*b7c941bbSAndroid Build Coastguard Worker         }
4239*b7c941bbSAndroid Build Coastguard Worker 
4240*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
4241*b7c941bbSAndroid Build Coastguard Worker 
4242*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
4243*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
4244*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4245*b7c941bbSAndroid Build Coastguard Worker         }
4246*b7c941bbSAndroid Build Coastguard Worker 
4247*b7c941bbSAndroid Build Coastguard Worker         if (failedRequestCount < NUM_FAILED_FRAMES) {
4248*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Unable to receive %zu consecutive capture failures within"
4249*b7c941bbSAndroid Build Coastguard Worker                     " %" PRId64 " capture requests", NUM_FAILED_FRAMES, NUM_TOTAL_FRAMES);
4250*b7c941bbSAndroid Build Coastguard Worker             goto exit;
4251*b7c941bbSAndroid Build Coastguard Worker         }
4252*b7c941bbSAndroid Build Coastguard Worker     }
4253*b7c941bbSAndroid Build Coastguard Worker 
4254*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
4255*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4256*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
4257*b7c941bbSAndroid Build Coastguard Worker         goto exit;
4258*b7c941bbSAndroid Build Coastguard Worker     }
4259*b7c941bbSAndroid Build Coastguard Worker 
4260*b7c941bbSAndroid Build Coastguard Worker     pass = true;
4261*b7c941bbSAndroid Build Coastguard Worker 
4262*b7c941bbSAndroid Build Coastguard Worker exit:
4263*b7c941bbSAndroid Build Coastguard Worker 
4264*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
4265*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
4266*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
4267*b7c941bbSAndroid Build Coastguard Worker     }
4268*b7c941bbSAndroid Build Coastguard Worker 
4269*b7c941bbSAndroid Build Coastguard Worker     return pass;
4270*b7c941bbSAndroid Build Coastguard Worker }
4271*b7c941bbSAndroid Build Coastguard Worker 
4272*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)4273*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeImageReaderTest_\
4274*b7c941bbSAndroid Build Coastguard Worker testJpegNative(
4275*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
4276*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
4277*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4278*b7c941bbSAndroid Build Coastguard Worker     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
4279*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::validateImageCb, jOverrideCameraId);
4280*b7c941bbSAndroid Build Coastguard Worker }
4281*b7c941bbSAndroid Build Coastguard Worker 
4282*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testY8Native(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)4283*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeImageReaderTest_\
4284*b7c941bbSAndroid Build Coastguard Worker testY8Native(
4285*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
4286*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
4287*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4288*b7c941bbSAndroid Build Coastguard Worker     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
4289*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::validateImageCb, jOverrideCameraId);
4290*b7c941bbSAndroid Build Coastguard Worker }
4291*b7c941bbSAndroid Build Coastguard Worker 
4292*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testHeicNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)4293*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeImageReaderTest_\
4294*b7c941bbSAndroid Build Coastguard Worker testHeicNative(
4295*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
4296*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
4297*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4298*b7c941bbSAndroid Build Coastguard Worker     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
4299*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::validateImageCb, jOverrideCameraId);
4300*b7c941bbSAndroid Build Coastguard Worker }
4301*b7c941bbSAndroid Build Coastguard Worker 
4302*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testDepthJpegNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)4303*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeImageReaderTest_\
4304*b7c941bbSAndroid Build Coastguard Worker testDepthJpegNative(
4305*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
4306*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
4307*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4308*b7c941bbSAndroid Build Coastguard Worker     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
4309*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::validateImageCb, jOverrideCameraId);
4310*b7c941bbSAndroid Build Coastguard Worker }
4311*b7c941bbSAndroid Build Coastguard Worker 
4312*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testImageReaderCloseAcquiredImagesNative(JNIEnv * env,jclass,jstring jOverrideCameraId)4313*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeImageReaderTest_\
4314*b7c941bbSAndroid Build Coastguard Worker testImageReaderCloseAcquiredImagesNative(
4315*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/,
4316*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
4317*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4318*b7c941bbSAndroid Build Coastguard Worker     return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
4319*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::acquireImageCb, jOverrideCameraId);
4320*b7c941bbSAndroid Build Coastguard Worker }
4321*b7c941bbSAndroid Build Coastguard Worker 
4322*b7c941bbSAndroid Build Coastguard Worker template <>
4323*b7c941bbSAndroid Build Coastguard Worker struct std::default_delete<ACameraManager> {
operator ()std::default_delete4324*b7c941bbSAndroid Build Coastguard Worker     inline void operator()(ACameraManager* manager) const { ACameraManager_delete(manager); }
4325*b7c941bbSAndroid Build Coastguard Worker };
4326*b7c941bbSAndroid Build Coastguard Worker 
4327*b7c941bbSAndroid Build Coastguard Worker class AvailabilityContext {
4328*b7c941bbSAndroid Build Coastguard Worker     public:
4329*b7c941bbSAndroid Build Coastguard Worker         AvailabilityContext();
4330*b7c941bbSAndroid Build Coastguard Worker         ~AvailabilityContext();
4331*b7c941bbSAndroid Build Coastguard Worker 
4332*b7c941bbSAndroid Build Coastguard Worker         camera_status_t initialize();
4333*b7c941bbSAndroid Build Coastguard Worker         int getAcessCallbackCountAndReset();
4334*b7c941bbSAndroid Build Coastguard Worker 
4335*b7c941bbSAndroid Build Coastguard Worker     private:
4336*b7c941bbSAndroid Build Coastguard Worker         std::unique_ptr<ACameraManager> mCameraManager;
4337*b7c941bbSAndroid Build Coastguard Worker         std::unique_ptr<CameraServiceListener> mServiceListener;
4338*b7c941bbSAndroid Build Coastguard Worker         std::unique_ptr<ACameraManager_ExtendedAvailabilityCallbacks> mServiceCb;
4339*b7c941bbSAndroid Build Coastguard Worker };
4340*b7c941bbSAndroid Build Coastguard Worker 
AvailabilityContext()4341*b7c941bbSAndroid Build Coastguard Worker AvailabilityContext::AvailabilityContext() :
4342*b7c941bbSAndroid Build Coastguard Worker     mCameraManager(ACameraManager_create()),
4343*b7c941bbSAndroid Build Coastguard Worker     mServiceListener(std::make_unique<CameraServiceListener>()),
4344*b7c941bbSAndroid Build Coastguard Worker     mServiceCb(std::make_unique<ACameraManager_ExtendedAvailabilityCallbacks>()) {
4345*b7c941bbSAndroid Build Coastguard Worker         mServiceCb->availabilityCallbacks.context = mServiceListener.get();
4346*b7c941bbSAndroid Build Coastguard Worker         mServiceCb->availabilityCallbacks.onCameraAvailable = CameraServiceListener::onAvailable;
4347*b7c941bbSAndroid Build Coastguard Worker         mServiceCb->availabilityCallbacks.onCameraUnavailable =
4348*b7c941bbSAndroid Build Coastguard Worker                 CameraServiceListener::onUnavailable;
4349*b7c941bbSAndroid Build Coastguard Worker         mServiceCb->onCameraAccessPrioritiesChanged =
4350*b7c941bbSAndroid Build Coastguard Worker                 CameraServiceListener::onCameraAccessPrioritiesChanged;
4351*b7c941bbSAndroid Build Coastguard Worker         mServiceCb->onPhysicalCameraAvailable =
4352*b7c941bbSAndroid Build Coastguard Worker                 CameraServiceListener::onPhysicalCameraAvailable;
4353*b7c941bbSAndroid Build Coastguard Worker         mServiceCb->onPhysicalCameraUnavailable =
4354*b7c941bbSAndroid Build Coastguard Worker                 CameraServiceListener::onPhysicalCameraUnavailable;
4355*b7c941bbSAndroid Build Coastguard Worker }
4356*b7c941bbSAndroid Build Coastguard Worker 
initialize()4357*b7c941bbSAndroid Build Coastguard Worker camera_status_t AvailabilityContext::initialize() {
4358*b7c941bbSAndroid Build Coastguard Worker     auto rc = ACameraManager_registerExtendedAvailabilityCallback(mCameraManager.get(),
4359*b7c941bbSAndroid Build Coastguard Worker             mServiceCb.get());
4360*b7c941bbSAndroid Build Coastguard Worker     if (rc != ACAMERA_OK) {
4361*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Register availability callback failed: rc %d", rc);
4362*b7c941bbSAndroid Build Coastguard Worker         return rc;
4363*b7c941bbSAndroid Build Coastguard Worker     }
4364*b7c941bbSAndroid Build Coastguard Worker 
4365*b7c941bbSAndroid Build Coastguard Worker     ACameraIdList* cameraIdList = nullptr;
4366*b7c941bbSAndroid Build Coastguard Worker     rc = ACameraManager_getCameraIdList(mCameraManager.get(), &cameraIdList);
4367*b7c941bbSAndroid Build Coastguard Worker     if (rc != ACAMERA_OK) {
4368*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Get camera id list failed: ret %d", rc);
4369*b7c941bbSAndroid Build Coastguard Worker         return rc;
4370*b7c941bbSAndroid Build Coastguard Worker     }
4371*b7c941bbSAndroid Build Coastguard Worker     ACameraManager_deleteCameraIdList(cameraIdList);
4372*b7c941bbSAndroid Build Coastguard Worker 
4373*b7c941bbSAndroid Build Coastguard Worker     return rc;
4374*b7c941bbSAndroid Build Coastguard Worker }
4375*b7c941bbSAndroid Build Coastguard Worker 
getAcessCallbackCountAndReset()4376*b7c941bbSAndroid Build Coastguard Worker int AvailabilityContext::getAcessCallbackCountAndReset() {
4377*b7c941bbSAndroid Build Coastguard Worker     auto ret = mServiceListener->getCameraAccessPrioritiesChangedCount();
4378*b7c941bbSAndroid Build Coastguard Worker     mServiceListener->resetCount();
4379*b7c941bbSAndroid Build Coastguard Worker     return ret;
4380*b7c941bbSAndroid Build Coastguard Worker }
4381*b7c941bbSAndroid Build Coastguard Worker 
~AvailabilityContext()4382*b7c941bbSAndroid Build Coastguard Worker AvailabilityContext::~AvailabilityContext() {
4383*b7c941bbSAndroid Build Coastguard Worker     if (mServiceCb != nullptr) {
4384*b7c941bbSAndroid Build Coastguard Worker         camera_status_t ret = ACameraManager_unregisterExtendedAvailabilityCallback(
4385*b7c941bbSAndroid Build Coastguard Worker                 mCameraManager.get(), mServiceCb.get());
4386*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4387*b7c941bbSAndroid Build Coastguard Worker             ALOGE("Unregister availability callback failed: ret %d", ret);
4388*b7c941bbSAndroid Build Coastguard Worker         }
4389*b7c941bbSAndroid Build Coastguard Worker     }
4390*b7c941bbSAndroid Build Coastguard Worker }
4391*b7c941bbSAndroid Build Coastguard Worker 
4392*b7c941bbSAndroid Build Coastguard Worker extern "C" jlong
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_initializeAvailabilityCallbacksNative(JNIEnv * env,jclass)4393*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
4394*b7c941bbSAndroid Build Coastguard Worker initializeAvailabilityCallbacksNative(
4395*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/) {
4396*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4397*b7c941bbSAndroid Build Coastguard Worker 
4398*b7c941bbSAndroid Build Coastguard Worker     AvailabilityContext *ctx = new AvailabilityContext();
4399*b7c941bbSAndroid Build Coastguard Worker 
4400*b7c941bbSAndroid Build Coastguard Worker     auto rc = ctx->initialize();
4401*b7c941bbSAndroid Build Coastguard Worker     if (rc != ACAMERA_OK) {
4402*b7c941bbSAndroid Build Coastguard Worker         delete ctx;
4403*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Availability context initialization failed: %d", rc);
4404*b7c941bbSAndroid Build Coastguard Worker         return 0;
4405*b7c941bbSAndroid Build Coastguard Worker     }
4406*b7c941bbSAndroid Build Coastguard Worker 
4407*b7c941bbSAndroid Build Coastguard Worker     return (jlong) ctx;
4408*b7c941bbSAndroid Build Coastguard Worker }
4409*b7c941bbSAndroid Build Coastguard Worker 
4410*b7c941bbSAndroid Build Coastguard Worker extern "C" jint
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_getAccessCallbacksCountAndResetNative(JNIEnv * env,jclass,jlong context)4411*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
4412*b7c941bbSAndroid Build Coastguard Worker getAccessCallbacksCountAndResetNative(
4413*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jlong context) {
4414*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4415*b7c941bbSAndroid Build Coastguard Worker 
4416*b7c941bbSAndroid Build Coastguard Worker     if (context == 0) {
4417*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Invalid availability context");
4418*b7c941bbSAndroid Build Coastguard Worker         return 0;
4419*b7c941bbSAndroid Build Coastguard Worker     }
4420*b7c941bbSAndroid Build Coastguard Worker 
4421*b7c941bbSAndroid Build Coastguard Worker     AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
4422*b7c941bbSAndroid Build Coastguard Worker     return ctx->getAcessCallbackCountAndReset();
4423*b7c941bbSAndroid Build Coastguard Worker }
4424*b7c941bbSAndroid Build Coastguard Worker 
4425*b7c941bbSAndroid Build Coastguard Worker extern "C" void
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_releaseAvailabilityCallbacksNative(JNIEnv * env,jclass,jlong context)4426*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
4427*b7c941bbSAndroid Build Coastguard Worker releaseAvailabilityCallbacksNative(
4428*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jlong context) {
4429*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4430*b7c941bbSAndroid Build Coastguard Worker 
4431*b7c941bbSAndroid Build Coastguard Worker     if (context == 0) {
4432*b7c941bbSAndroid Build Coastguard Worker         return;
4433*b7c941bbSAndroid Build Coastguard Worker     }
4434*b7c941bbSAndroid Build Coastguard Worker 
4435*b7c941bbSAndroid Build Coastguard Worker     AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
4436*b7c941bbSAndroid Build Coastguard Worker     delete ctx;
4437*b7c941bbSAndroid Build Coastguard Worker }
4438*b7c941bbSAndroid Build Coastguard Worker 
4439*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface,jstring jOverrideCameraId)4440*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
4441*b7c941bbSAndroid Build Coastguard Worker testStillCaptureNative(
4442*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface,
4443*b7c941bbSAndroid Build Coastguard Worker         jstring jOverrideCameraId) {
4444*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4445*b7c941bbSAndroid Build Coastguard Worker     const int NUM_TEST_IMAGES = 10;
4446*b7c941bbSAndroid Build Coastguard Worker     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
4447*b7c941bbSAndroid Build Coastguard Worker     int numCameras = 0;
4448*b7c941bbSAndroid Build Coastguard Worker     bool pass = false;
4449*b7c941bbSAndroid Build Coastguard Worker     PreviewTestCase testCase;
4450*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* chars = nullptr;
4451*b7c941bbSAndroid Build Coastguard Worker 
4452*b7c941bbSAndroid Build Coastguard Worker     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
4453*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
4454*b7c941bbSAndroid Build Coastguard Worker 
4455*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
4456*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4457*b7c941bbSAndroid Build Coastguard Worker         // Don't log error here. testcase did it
4458*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
4459*b7c941bbSAndroid Build Coastguard Worker     }
4460*b7c941bbSAndroid Build Coastguard Worker 
4461*b7c941bbSAndroid Build Coastguard Worker     numCameras = testCase.getNumCameras();
4462*b7c941bbSAndroid Build Coastguard Worker     if (numCameras < 0) {
4463*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
4464*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
4465*b7c941bbSAndroid Build Coastguard Worker     }
4466*b7c941bbSAndroid Build Coastguard Worker 
4467*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < numCameras; i++) {
4468*b7c941bbSAndroid Build Coastguard Worker         const char* cameraId = testCase.getCameraId(i);
4469*b7c941bbSAndroid Build Coastguard Worker         if (cameraId == nullptr) {
4470*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
4471*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4472*b7c941bbSAndroid Build Coastguard Worker         }
4473*b7c941bbSAndroid Build Coastguard Worker 
4474*b7c941bbSAndroid Build Coastguard Worker         {
4475*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
4476*b7c941bbSAndroid Build Coastguard Worker             StaticInfo staticInfo(chars);
4477*b7c941bbSAndroid Build Coastguard Worker             if (!staticInfo.isColorOutputSupported()) {
4478*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("%s: camera %s does not support color output. skipping",
4479*b7c941bbSAndroid Build Coastguard Worker                         __FUNCTION__, cameraId);
4480*b7c941bbSAndroid Build Coastguard Worker                 ACameraMetadata_free(chars);
4481*b7c941bbSAndroid Build Coastguard Worker                 continue;
4482*b7c941bbSAndroid Build Coastguard Worker             }
4483*b7c941bbSAndroid Build Coastguard Worker             ACameraMetadata_free(chars);
4484*b7c941bbSAndroid Build Coastguard Worker         }
4485*b7c941bbSAndroid Build Coastguard Worker 
4486*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.openCamera(cameraId);
4487*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4488*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
4489*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4490*b7c941bbSAndroid Build Coastguard Worker         }
4491*b7c941bbSAndroid Build Coastguard Worker 
4492*b7c941bbSAndroid Build Coastguard Worker         chars = testCase.getCameraChars(i);
4493*b7c941bbSAndroid Build Coastguard Worker         if (chars == nullptr) {
4494*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
4495*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4496*b7c941bbSAndroid Build Coastguard Worker         }
4497*b7c941bbSAndroid Build Coastguard Worker         StaticInfo staticInfo(chars);
4498*b7c941bbSAndroid Build Coastguard Worker 
4499*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
4500*b7c941bbSAndroid Build Coastguard Worker 
4501*b7c941bbSAndroid Build Coastguard Worker         if (testCase.isCameraAvailable(cameraId)) {
4502*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
4503*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4504*b7c941bbSAndroid Build Coastguard Worker         }
4505*b7c941bbSAndroid Build Coastguard Worker 
4506*b7c941bbSAndroid Build Coastguard Worker         ImageReaderListener readerListener;
4507*b7c941bbSAndroid Build Coastguard Worker         AImageReader_ImageListener readerCb {
4508*b7c941bbSAndroid Build Coastguard Worker             &readerListener,
4509*b7c941bbSAndroid Build Coastguard Worker             ImageReaderListener::validateImageCb
4510*b7c941bbSAndroid Build Coastguard Worker         };
4511*b7c941bbSAndroid Build Coastguard Worker         readerListener.setDumpFilePathBase(outPath);
4512*b7c941bbSAndroid Build Coastguard Worker         int32_t testWidth, testHeight;
4513*b7c941bbSAndroid Build Coastguard Worker         if (!staticInfo.getMaxSizeForFormat(AIMAGE_FORMAT_JPEG, &testWidth, &testHeight)) {
4514*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4515*b7c941bbSAndroid Build Coastguard Worker         }
4516*b7c941bbSAndroid Build Coastguard Worker         mediaRet = testCase.initImageReaderWithErrorLog(
4517*b7c941bbSAndroid Build Coastguard Worker                 testWidth, testHeight, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
4518*b7c941bbSAndroid Build Coastguard Worker                 &readerCb);
4519*b7c941bbSAndroid Build Coastguard Worker         if (mediaRet != AMEDIA_OK) {
4520*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4521*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4522*b7c941bbSAndroid Build Coastguard Worker         }
4523*b7c941bbSAndroid Build Coastguard Worker 
4524*b7c941bbSAndroid Build Coastguard Worker         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
4525*b7c941bbSAndroid Build Coastguard Worker         if (previewAnw == nullptr) {
4526*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Null ANW from preview surface!");
4527*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4528*b7c941bbSAndroid Build Coastguard Worker         }
4529*b7c941bbSAndroid Build Coastguard Worker 
4530*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createCaptureSessionWithLog();
4531*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4532*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4533*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4534*b7c941bbSAndroid Build Coastguard Worker         }
4535*b7c941bbSAndroid Build Coastguard Worker 
4536*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.createRequestsWithErrorLog();
4537*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4538*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4539*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4540*b7c941bbSAndroid Build Coastguard Worker         }
4541*b7c941bbSAndroid Build Coastguard Worker 
4542*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.startPreview();
4543*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4544*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Start preview failed!");
4545*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4546*b7c941bbSAndroid Build Coastguard Worker         }
4547*b7c941bbSAndroid Build Coastguard Worker 
4548*b7c941bbSAndroid Build Coastguard Worker         // Let preview run some time
4549*b7c941bbSAndroid Build Coastguard Worker         sleep(3);
4550*b7c941bbSAndroid Build Coastguard Worker 
4551*b7c941bbSAndroid Build Coastguard Worker         // Do some still capture
4552*b7c941bbSAndroid Build Coastguard Worker         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
4553*b7c941bbSAndroid Build Coastguard Worker             ret = testCase.takePicture();
4554*b7c941bbSAndroid Build Coastguard Worker             if (ret != ACAMERA_OK) {
4555*b7c941bbSAndroid Build Coastguard Worker                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
4556*b7c941bbSAndroid Build Coastguard Worker                         cameraId, capture, ret);
4557*b7c941bbSAndroid Build Coastguard Worker                 goto cleanup;
4558*b7c941bbSAndroid Build Coastguard Worker             }
4559*b7c941bbSAndroid Build Coastguard Worker         }
4560*b7c941bbSAndroid Build Coastguard Worker 
4561*b7c941bbSAndroid Build Coastguard Worker         int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
4562*b7c941bbSAndroid Build Coastguard Worker                 AIMAGE_FORMAT_JPEG, testWidth, testHeight);
4563*b7c941bbSAndroid Build Coastguard Worker         if (minFrameDurationNs < 0) {
4564*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
4565*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4566*b7c941bbSAndroid Build Coastguard Worker         }
4567*b7c941bbSAndroid Build Coastguard Worker         int64_t stallDurationNs = staticInfo.getStallDurationFor(
4568*b7c941bbSAndroid Build Coastguard Worker                 AIMAGE_FORMAT_JPEG, testWidth, testHeight);
4569*b7c941bbSAndroid Build Coastguard Worker         if (stallDurationNs < 0) {
4570*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
4571*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4572*b7c941bbSAndroid Build Coastguard Worker         }
4573*b7c941bbSAndroid Build Coastguard Worker 
4574*b7c941bbSAndroid Build Coastguard Worker         int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
4575*b7c941bbSAndroid Build Coastguard Worker         constexpr int64_t waitPerIterationUs = 100000;
4576*b7c941bbSAndroid Build Coastguard Worker         constexpr int64_t usToNs = 1000;
4577*b7c941bbSAndroid Build Coastguard Worker         int totalWaitIteration = 60;
4578*b7c941bbSAndroid Build Coastguard Worker 
4579*b7c941bbSAndroid Build Coastguard Worker         // Allow 1.5x margin
4580*b7c941bbSAndroid Build Coastguard Worker         if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
4581*b7c941bbSAndroid Build Coastguard Worker             totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
4582*b7c941bbSAndroid Build Coastguard Worker         }
4583*b7c941bbSAndroid Build Coastguard Worker 
4584*b7c941bbSAndroid Build Coastguard Worker         // wait until all capture finished
4585*b7c941bbSAndroid Build Coastguard Worker         for (int i = 0; i < totalWaitIteration; i++) {
4586*b7c941bbSAndroid Build Coastguard Worker             usleep(waitPerIterationUs);
4587*b7c941bbSAndroid Build Coastguard Worker             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
4588*b7c941bbSAndroid Build Coastguard Worker                 ALOGI("Session take ~%d ms to capture %d images",
4589*b7c941bbSAndroid Build Coastguard Worker                         i*100, NUM_TEST_IMAGES);
4590*b7c941bbSAndroid Build Coastguard Worker                 break;
4591*b7c941bbSAndroid Build Coastguard Worker             }
4592*b7c941bbSAndroid Build Coastguard Worker         }
4593*b7c941bbSAndroid Build Coastguard Worker 
4594*b7c941bbSAndroid Build Coastguard Worker         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
4595*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
4596*b7c941bbSAndroid Build Coastguard Worker                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
4597*b7c941bbSAndroid Build Coastguard Worker             testCase.resetWithErrorLog();
4598*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4599*b7c941bbSAndroid Build Coastguard Worker         }
4600*b7c941bbSAndroid Build Coastguard Worker 
4601*b7c941bbSAndroid Build Coastguard Worker         ret = testCase.resetWithErrorLog();
4602*b7c941bbSAndroid Build Coastguard Worker         if (ret != ACAMERA_OK) {
4603*b7c941bbSAndroid Build Coastguard Worker             // Don't log error here. testcase did it
4604*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4605*b7c941bbSAndroid Build Coastguard Worker         }
4606*b7c941bbSAndroid Build Coastguard Worker 
4607*b7c941bbSAndroid Build Coastguard Worker         usleep(100000); // sleep to give some time for callbacks to happen
4608*b7c941bbSAndroid Build Coastguard Worker 
4609*b7c941bbSAndroid Build Coastguard Worker         if (!testCase.isCameraAvailable(cameraId)) {
4610*b7c941bbSAndroid Build Coastguard Worker             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
4611*b7c941bbSAndroid Build Coastguard Worker             goto cleanup;
4612*b7c941bbSAndroid Build Coastguard Worker         }
4613*b7c941bbSAndroid Build Coastguard Worker     }
4614*b7c941bbSAndroid Build Coastguard Worker 
4615*b7c941bbSAndroid Build Coastguard Worker     ret = testCase.deInit();
4616*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4617*b7c941bbSAndroid Build Coastguard Worker         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
4618*b7c941bbSAndroid Build Coastguard Worker         goto cleanup;
4619*b7c941bbSAndroid Build Coastguard Worker     }
4620*b7c941bbSAndroid Build Coastguard Worker 
4621*b7c941bbSAndroid Build Coastguard Worker     pass = true;
4622*b7c941bbSAndroid Build Coastguard Worker cleanup:
4623*b7c941bbSAndroid Build Coastguard Worker     env->ReleaseStringUTFChars(jOutPath, outPath);
4624*b7c941bbSAndroid Build Coastguard Worker 
4625*b7c941bbSAndroid Build Coastguard Worker     if (chars != nullptr) {
4626*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(chars);
4627*b7c941bbSAndroid Build Coastguard Worker         chars = nullptr;
4628*b7c941bbSAndroid Build Coastguard Worker     }
4629*b7c941bbSAndroid Build Coastguard Worker 
4630*b7c941bbSAndroid Build Coastguard Worker     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
4631*b7c941bbSAndroid Build Coastguard Worker     if (!pass) {
4632*b7c941bbSAndroid Build Coastguard Worker         throwAssertionError(env, errorString);
4633*b7c941bbSAndroid Build Coastguard Worker     }
4634*b7c941bbSAndroid Build Coastguard Worker     return pass;
4635*b7c941bbSAndroid Build Coastguard Worker }
4636*b7c941bbSAndroid Build Coastguard Worker 
4637*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_validateACameraMetadataFromCameraMetadataCriticalTagsNative(JNIEnv * env,jclass,jobject captureResult,jlong javaTimestamp)4638*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_CaptureResultTest_\
4639*b7c941bbSAndroid Build Coastguard Worker validateACameraMetadataFromCameraMetadataCriticalTagsNative(
4640*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject captureResult,
4641*b7c941bbSAndroid Build Coastguard Worker         jlong javaTimestamp) {
4642*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4643*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* ndkResult =
4644*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_fromCameraMetadata(env, captureResult);
4645*b7c941bbSAndroid Build Coastguard Worker     if (!ndkResult) {
4646*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: "
4647*b7c941bbSAndroid Build Coastguard Worker               "ACameraMetadata_fromCameraMetadata returned nullptr.");
4648*b7c941bbSAndroid Build Coastguard Worker         return false;
4649*b7c941bbSAndroid Build Coastguard Worker     }
4650*b7c941bbSAndroid Build Coastguard Worker 
4651*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret;
4652*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata_const_entry entry;
4653*b7c941bbSAndroid Build Coastguard Worker 
4654*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraMetadata_getConstEntry(ndkResult, ACAMERA_SENSOR_TIMESTAMP,
4655*b7c941bbSAndroid Build Coastguard Worker         &entry);
4656*b7c941bbSAndroid Build Coastguard Worker 
4657*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4658*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: "
4659*b7c941bbSAndroid Build Coastguard Worker               "ACameraMetadata_getConstEntry returned %d.", ret);
4660*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(ndkResult);
4661*b7c941bbSAndroid Build Coastguard Worker         return false;
4662*b7c941bbSAndroid Build Coastguard Worker     }
4663*b7c941bbSAndroid Build Coastguard Worker     if (entry.type != ACAMERA_TYPE_INT64) {
4664*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
4665*b7c941bbSAndroid Build Coastguard Worker               entry.type, ACAMERA_TYPE_INT64);
4666*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(ndkResult);
4667*b7c941bbSAndroid Build Coastguard Worker         return false;
4668*b7c941bbSAndroid Build Coastguard Worker     }
4669*b7c941bbSAndroid Build Coastguard Worker     if (entry.count != 1) {
4670*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
4671*b7c941bbSAndroid Build Coastguard Worker               entry.count, 1);
4672*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(ndkResult);
4673*b7c941bbSAndroid Build Coastguard Worker         return false;
4674*b7c941bbSAndroid Build Coastguard Worker     }
4675*b7c941bbSAndroid Build Coastguard Worker     if (entry.data.i64 == nullptr) {
4676*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: entry.data.i64 is nullptr.");
4677*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(ndkResult);
4678*b7c941bbSAndroid Build Coastguard Worker         return false;
4679*b7c941bbSAndroid Build Coastguard Worker     }
4680*b7c941bbSAndroid Build Coastguard Worker 
4681*b7c941bbSAndroid Build Coastguard Worker     const int64_t javaTimestampI64 = static_cast<int64_t>(javaTimestamp);
4682*b7c941bbSAndroid Build Coastguard Worker     const int64_t ndkTimestampI64 = *(entry.data.i64);
4683*b7c941bbSAndroid Build Coastguard Worker     ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
4684*b7c941bbSAndroid Build Coastguard Worker           javaTimestampI64, ndkTimestampI64);
4685*b7c941bbSAndroid Build Coastguard Worker 
4686*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata_free(ndkResult);
4687*b7c941bbSAndroid Build Coastguard Worker 
4688*b7c941bbSAndroid Build Coastguard Worker     return (javaTimestampI64 == ndkTimestampI64);
4689*b7c941bbSAndroid Build Coastguard Worker }
4690*b7c941bbSAndroid Build Coastguard Worker 
4691*b7c941bbSAndroid Build Coastguard Worker static ACameraMetadata *sStashedMetadata = nullptr;
4692*b7c941bbSAndroid Build Coastguard Worker 
4693*b7c941bbSAndroid Build Coastguard Worker // Test holding on to a ACameraMetadata past a single local JNI call
4694*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_stashACameraMetadataFromCameraMetadataNative(JNIEnv * env,jclass,jobject captureResult)4695*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_CaptureResultTest_\
4696*b7c941bbSAndroid Build Coastguard Worker stashACameraMetadataFromCameraMetadataNative(
4697*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject captureResult) {
4698*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4699*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* ndkResult =
4700*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_fromCameraMetadata(env, captureResult);
4701*b7c941bbSAndroid Build Coastguard Worker     if (ndkResult == nullptr) return false;
4702*b7c941bbSAndroid Build Coastguard Worker     sStashedMetadata = ndkResult;
4703*b7c941bbSAndroid Build Coastguard Worker 
4704*b7c941bbSAndroid Build Coastguard Worker     return true;
4705*b7c941bbSAndroid Build Coastguard Worker }
4706*b7c941bbSAndroid Build Coastguard Worker 
4707*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_validateStashedACameraMetadataFromCameraMetadataNative(JNIEnv * env,jclass,jlong timestamp)4708*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_CaptureResultTest_\
4709*b7c941bbSAndroid Build Coastguard Worker validateStashedACameraMetadataFromCameraMetadataNative(
4710*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jlong timestamp) {
4711*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4712*b7c941bbSAndroid Build Coastguard Worker     if (sStashedMetadata == nullptr) return false;
4713*b7c941bbSAndroid Build Coastguard Worker 
4714*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret;
4715*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata_const_entry entry;
4716*b7c941bbSAndroid Build Coastguard Worker 
4717*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraMetadata_getConstEntry(sStashedMetadata, ACAMERA_SENSOR_TIMESTAMP,
4718*b7c941bbSAndroid Build Coastguard Worker         &entry);
4719*b7c941bbSAndroid Build Coastguard Worker 
4720*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4721*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateStashed failed: "
4722*b7c941bbSAndroid Build Coastguard Worker               "ACameraMetadata_getConstEntry returned %d.", ret);
4723*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(sStashedMetadata);
4724*b7c941bbSAndroid Build Coastguard Worker         sStashedMetadata = nullptr;
4725*b7c941bbSAndroid Build Coastguard Worker         return false;
4726*b7c941bbSAndroid Build Coastguard Worker     }
4727*b7c941bbSAndroid Build Coastguard Worker     if (entry.type != ACAMERA_TYPE_INT64) {
4728*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateStashed failed: entry.type is %u but should be %u.",
4729*b7c941bbSAndroid Build Coastguard Worker               entry.type, ACAMERA_TYPE_INT64);
4730*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(sStashedMetadata);
4731*b7c941bbSAndroid Build Coastguard Worker         sStashedMetadata = nullptr;
4732*b7c941bbSAndroid Build Coastguard Worker         return false;
4733*b7c941bbSAndroid Build Coastguard Worker     }
4734*b7c941bbSAndroid Build Coastguard Worker     if (entry.count != 1) {
4735*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateStashed failed: entry.count is %u but should be %u.",
4736*b7c941bbSAndroid Build Coastguard Worker               entry.count, 1);
4737*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(sStashedMetadata);
4738*b7c941bbSAndroid Build Coastguard Worker         sStashedMetadata = nullptr;
4739*b7c941bbSAndroid Build Coastguard Worker         return false;
4740*b7c941bbSAndroid Build Coastguard Worker     }
4741*b7c941bbSAndroid Build Coastguard Worker     if (entry.data.i64 == nullptr) {
4742*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateStashed failed: entry.data.i64 is nullptr.");
4743*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_free(sStashedMetadata);
4744*b7c941bbSAndroid Build Coastguard Worker         sStashedMetadata = nullptr;
4745*b7c941bbSAndroid Build Coastguard Worker         return false;
4746*b7c941bbSAndroid Build Coastguard Worker     }
4747*b7c941bbSAndroid Build Coastguard Worker 
4748*b7c941bbSAndroid Build Coastguard Worker     const int64_t javaTimestampI64 = static_cast<int64_t>(timestamp);
4749*b7c941bbSAndroid Build Coastguard Worker     const int64_t ndkTimestampI64 = *(entry.data.i64);
4750*b7c941bbSAndroid Build Coastguard Worker 
4751*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata_free(sStashedMetadata);
4752*b7c941bbSAndroid Build Coastguard Worker     sStashedMetadata = nullptr;
4753*b7c941bbSAndroid Build Coastguard Worker     ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
4754*b7c941bbSAndroid Build Coastguard Worker           javaTimestampI64, ndkTimestampI64);
4755*b7c941bbSAndroid Build Coastguard Worker     return (javaTimestampI64 == ndkTimestampI64);
4756*b7c941bbSAndroid Build Coastguard Worker 
4757*b7c941bbSAndroid Build Coastguard Worker }
4758*b7c941bbSAndroid Build Coastguard Worker 
4759*b7c941bbSAndroid Build Coastguard Worker 
4760*b7c941bbSAndroid Build Coastguard Worker 
4761*b7c941bbSAndroid Build Coastguard Worker extern "C" jboolean
Java_android_hardware_camera2_cts_CameraManagerTest_validateACameraMetadataFromCameraMetadataCriticalTagsNative(JNIEnv * env,jclass,jobject cameraCharacteristics,jint javaLensFacing)4762*b7c941bbSAndroid Build Coastguard Worker Java_android_hardware_camera2_cts_CameraManagerTest_\
4763*b7c941bbSAndroid Build Coastguard Worker validateACameraMetadataFromCameraMetadataCriticalTagsNative(
4764*b7c941bbSAndroid Build Coastguard Worker         JNIEnv* env, jclass /*clazz*/, jobject cameraCharacteristics,
4765*b7c941bbSAndroid Build Coastguard Worker         jint javaLensFacing) {
4766*b7c941bbSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
4767*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata* ndkCharacteristics =
4768*b7c941bbSAndroid Build Coastguard Worker         ACameraMetadata_fromCameraMetadata(env, cameraCharacteristics);
4769*b7c941bbSAndroid Build Coastguard Worker     if (!ndkCharacteristics) {
4770*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: "
4771*b7c941bbSAndroid Build Coastguard Worker               "ACameraMetadata_fromCameraMetadata returned nullptr.");
4772*b7c941bbSAndroid Build Coastguard Worker         return false;
4773*b7c941bbSAndroid Build Coastguard Worker     }
4774*b7c941bbSAndroid Build Coastguard Worker 
4775*b7c941bbSAndroid Build Coastguard Worker     camera_status_t ret;
4776*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata_const_entry entry;
4777*b7c941bbSAndroid Build Coastguard Worker 
4778*b7c941bbSAndroid Build Coastguard Worker     ret = ACameraMetadata_getConstEntry(ndkCharacteristics,
4779*b7c941bbSAndroid Build Coastguard Worker         ACAMERA_LENS_FACING, &entry);
4780*b7c941bbSAndroid Build Coastguard Worker     ACameraMetadata_free(ndkCharacteristics);
4781*b7c941bbSAndroid Build Coastguard Worker 
4782*b7c941bbSAndroid Build Coastguard Worker     if (ret != ACAMERA_OK) {
4783*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: "
4784*b7c941bbSAndroid Build Coastguard Worker               "ACameraMetadata_getConstEntry returned %d", ret);
4785*b7c941bbSAndroid Build Coastguard Worker         return false;
4786*b7c941bbSAndroid Build Coastguard Worker     }
4787*b7c941bbSAndroid Build Coastguard Worker     if (entry.type != ACAMERA_TYPE_BYTE) {
4788*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
4789*b7c941bbSAndroid Build Coastguard Worker               entry.type, ACAMERA_TYPE_BYTE);
4790*b7c941bbSAndroid Build Coastguard Worker         return false;
4791*b7c941bbSAndroid Build Coastguard Worker     }
4792*b7c941bbSAndroid Build Coastguard Worker     if (entry.count != 1) {
4793*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
4794*b7c941bbSAndroid Build Coastguard Worker               entry.count, 1);
4795*b7c941bbSAndroid Build Coastguard Worker         return false;
4796*b7c941bbSAndroid Build Coastguard Worker     }
4797*b7c941bbSAndroid Build Coastguard Worker     if (entry.data.u8 == nullptr) {
4798*b7c941bbSAndroid Build Coastguard Worker         ALOGE("validateCriticalTags failed: entry.data.u8 is nullptr.");
4799*b7c941bbSAndroid Build Coastguard Worker         return false;
4800*b7c941bbSAndroid Build Coastguard Worker     }
4801*b7c941bbSAndroid Build Coastguard Worker 
4802*b7c941bbSAndroid Build Coastguard Worker     const uint8_t javaLensFacingU8 = static_cast<uint8_t>(javaLensFacing);
4803*b7c941bbSAndroid Build Coastguard Worker     const uint8_t ndkLensFacingU8 = *(entry.data.u8);
4804*b7c941bbSAndroid Build Coastguard Worker     ALOGV("javaLensFacingU8 = %d, ndkLensFacingU8 = %d",
4805*b7c941bbSAndroid Build Coastguard Worker           javaLensFacingU8, ndkLensFacingU8);
4806*b7c941bbSAndroid Build Coastguard Worker     return (javaLensFacingU8 == ndkLensFacingU8);
4807*b7c941bbSAndroid Build Coastguard Worker }
4808