1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #define LOG_TAG "CameraOpenerJni"
19 #define LOG_NDEBUG 0
20 
21 #include <android/log.h>
22 #include <log/log.h>
23 
24 #include <chrono>
25 #include <condition_variable>
26 #include <memory>
27 #include <mutex>
28 #include <thread>
29 
30 #include "camera/NdkCameraManager.h"
31 #include "media/NdkImage.h"
32 #include "media/NdkImageReader.h"
33 
34 namespace {
35 
36 template <typename T, void (*free_ptr)(T*)>
37 class Auto : public std::unique_ptr<T, void (*)(T*)> {
38 public:
Auto()39     Auto() : std::unique_ptr<T, void (*)(T*)>(nullptr, free_ptr) {}
Auto(T * t)40     Auto(T* t) : std::unique_ptr<T, void (*)(T*)>(t, free_ptr) {}
41 };
42 
43 class CameraOpenerJni {
44 public:
CameraOpenerJni()45     CameraOpenerJni()
46           : mCameraManager(ACameraManager_create()),
47             mCameraDeviceListener(*this),
48             mCameraDeviceCb(&mCameraDeviceListener, CameraDeviceListener::onDisconnectedStatic,
49                             CameraDeviceListener::onErrorStatic),
50             mImgReaderAnw(nullptr),
51             mImgReaderListener(),
52             mImgReaderCb(&mImgReaderListener, ImageReaderListener::signalImageStatic),
53             mCaptureSessionListener(),
54             mCaptureSessionCb(&mCaptureSessionListener, CaptureSessionListener::onClosed,
55                               CaptureSessionListener::onReady, CaptureSessionListener::onActive),
56             mCaptureResultListener(*this),
57             mCaptureResultCb(&mCaptureResultListener, CaptureResultListener::onCaptureStart,
58                              CaptureResultListener::onCaptureProgressed,
59                              CaptureResultListener::onCaptureCompletedStatic,
60                              CaptureResultListener::onCaptureFailedStatic,
61                              CaptureResultListener::onCaptureSequenceCompleted,
62                              CaptureResultListener::onCaptureSequenceAborted,
63                              CaptureResultListener::onCaptureBufferLost) {}
64 
hasCamera()65     bool hasCamera() {
66         ACameraIdList* cameraIdList = nullptr;
67         auto rc = ACameraManager_getCameraIdList(mCameraManager.get(), &cameraIdList);
68         if (rc != ACAMERA_OK) {
69             ALOGE("Get camera id list failed: ret %d", rc);
70             return false;
71         }
72         jboolean result = cameraIdList->numCameras > 0;
73         mCameraIdList.reset(cameraIdList);
74         return result;
75     }
76 
openCamera()77     int openCamera() {
78         const char* cameraId = mCameraIdList->cameraIds[0];
79 
80         ACameraDevice* device = nullptr;
81         auto rc = ACameraManager_openCamera(mCameraManager.get(), cameraId, &mCameraDeviceCb,
82                                             &device);
83         if (rc != ACAMERA_OK) {
84             ALOGE("Open camera failed: ret %d", rc);
85             return rc;
86         }
87 
88         mCameraDevice.reset(device);
89 
90         return ACAMERA_OK;
91     }
92 
openCameraStream(bool shouldRepeat)93     int openCameraStream(bool shouldRepeat) {
94         const char* cameraId = mCameraIdList->cameraIds[0];
95         ACameraMetadata* chars = nullptr;
96 
97         auto rc = ACameraManager_getCameraCharacteristics(mCameraManager.get(), cameraId, &chars);
98         if (rc != ACAMERA_OK || chars == nullptr) {
99             ALOGE("Get camera %s characteristics failure. ret %d, chars %p", cameraId, rc, chars);
100             return rc;
101         }
102 
103         mCameraCharacteristics.reset(chars);
104         int width = 0, height = 0;
105         rc = getPreviewSize(width, height);
106         if (rc != ACAMERA_OK) {
107             return rc;
108         }
109 
110         media_status_t mediaRc = createImageReader(width, height);
111         if (mediaRc != AMEDIA_OK) {
112             return mediaRc;
113         }
114 
115         rc = createCaptureSessionOutputContainer();
116         if (rc != ACAMERA_OK) {
117             return rc;
118         }
119 
120         rc = ACameraDevice_isSessionConfigurationSupported(mCameraDevice.get(),
121                                                            mOutputContainer.get());
122         if (rc != ACAMERA_OK) {
123             ALOGE("isSessionConfigurationSupported returned %d, device %p outputContainer %p", rc,
124                   mCameraDevice.get(), mOutputContainer.get());
125             return rc;
126         }
127 
128         ACameraCaptureSession* captureSession = nullptr;
129         rc = ACameraDevice_createCaptureSessionWithSessionParameters(mCameraDevice.get(),
130                                                                      mOutputContainer.get(),
131                                                                      /*sessionParameters=*/nullptr,
132                                                                      &mCaptureSessionCb,
133                                                                      &captureSession);
134         if (rc != ACAMERA_OK || captureSession == nullptr) {
135             ALOGE("Create session for camera %s failed. ret %d session %p", cameraId, rc,
136                   captureSession);
137             if (rc == ACAMERA_OK) {
138                 rc = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
139             }
140             return rc;
141         }
142 
143         mCaptureSession.reset(captureSession);
144 
145         rc = createCaptureRequest(shouldRepeat ? TEMPLATE_PREVIEW : TEMPLATE_STILL_CAPTURE);
146         if (rc != ACAMERA_OK) {
147             return rc;
148         }
149 
150         ACaptureRequest* requests[] = {mCaptureRequest.get()};
151 
152         if (shouldRepeat) {
153             rc = ACameraCaptureSession_setRepeatingRequest(mCaptureSession.get(), &mCaptureResultCb,
154                                                            /*numRequests=*/1, requests,
155                                                            /*captureSequenceId=*/nullptr);
156             if (rc != ACAMERA_OK) {
157                 ALOGE("%s: Failed to setRepeatingRequest %d", __FUNCTION__, rc);
158                 return rc;
159             }
160         } else {
161             rc = ACameraCaptureSession_capture(mCaptureSession.get(), &mCaptureResultCb,
162                                                /*numRequests=*/1, requests,
163                                                /*captureSequenceId=*/nullptr);
164             if (rc != ACAMERA_OK) {
165                 ALOGE("%s: Failed to capture %d", __FUNCTION__, rc);
166                 return rc;
167             }
168         }
169 
170         {
171             std::unique_lock<std::mutex> l(mMutex);
172             if (!mFirstCaptureCompleted && !mStoppedRepeating) {
173                 ALOGV("%s: %p waiting for first capture", __FUNCTION__, this);
174                 auto timeout = std::chrono::seconds(10);
175                 if (!mStateChanged.wait_for(l, timeout, [this]() {
176                         ALOGV("%s: wakeup mFirstCaptureCompleted %d mStoppedRepeating %d",
177                               __FUNCTION__, mFirstCaptureCompleted, mStoppedRepeating);
178                         return mFirstCaptureCompleted || mStoppedRepeating;
179                     })) {
180                     ALOGE("Timed out waiting for capture to complete.");
181                     return ACAMERA_ERROR_UNKNOWN;
182                 }
183             }
184 
185             if (mStoppedRepeating) {
186                 if (mErrorCode != 0) {
187                     ALOGE("%s: Stopped repeating (error %d)", __FUNCTION__, mErrorCode);
188                     return mErrorCode;
189                 } else {
190                     ALOGE("%s: Stopped repeating for unknown reason", __FUNCTION__);
191                     return ACAMERA_ERROR_UNKNOWN;
192                 }
193             }
194         }
195 
196         ALOGV("%s: exit", __FUNCTION__);
197         return ACAMERA_OK;
198     }
199 
waitStopRepeating()200     int waitStopRepeating() {
201         std::unique_lock<std::mutex> l(mMutex);
202         if (!mStoppedRepeating) {
203             auto timeout = std::chrono::seconds(30);
204             if (!mStateChanged.wait_for(l, timeout, [this]() {
205                     ALOGV("%s: wakeup %d", __FUNCTION__, mStoppedRepeating);
206                     return mStoppedRepeating;
207                 })) {
208                 ALOGE("Timed out waiting for stream to stop.");
209                 return ACAMERA_ERROR_UNKNOWN;
210             }
211         }
212         return mErrorCode;
213     }
214 
stopRepeating()215     int stopRepeating() {
216         ALOGV("Enter %s", __FUNCTION__);
217         int rc = ACAMERA_OK;
218         {
219             std::unique_lock<std::mutex> l(mMutex);
220             ALOGV("%s: mStoppedRepeating %d", __FUNCTION__, mStoppedRepeating);
221             if (!mStoppedRepeating) {
222                 mStoppedRepeating = true;
223                 rc = ACameraCaptureSession_stopRepeating(mCaptureSession.get());
224             }
225         }
226 
227         ALOGV("%s: notifying", __FUNCTION__);
228         mStateChanged.notify_all();
229         return rc;
230     }
231 
signalStoppedRepeating(int errorCode)232     void signalStoppedRepeating(int errorCode) {
233         {
234             std::lock_guard<std::mutex> l(mMutex);
235             mStoppedRepeating = true;
236             if (mErrorCode == 0) {
237                 mErrorCode = errorCode;
238             }
239         }
240 
241         ALOGV("%s: notifying", __FUNCTION__);
242         mStateChanged.notify_all();
243     }
244 
onCaptureCompleted()245     void onCaptureCompleted() {
246         {
247             std::lock_guard<std::mutex> l(mMutex);
248             mFirstCaptureCompleted = true;
249         }
250 
251         ALOGV("%s: %p notifying", __FUNCTION__, this);
252         mStateChanged.notify_all();
253     }
254 
onCaptureFailed(ACameraCaptureFailure * failure)255     void onCaptureFailed(ACameraCaptureFailure* failure) {
256         if (failure == nullptr) {
257             ALOGE("%s: null failure", __FUNCTION__);
258             return;
259         }
260         ALOGV("%s: frameNumber %" PRId64 " reason %d sequenceId %d wasImageCaptured %d",
261               __FUNCTION__, failure->frameNumber, failure->reason, failure->sequenceId,
262               failure->wasImageCaptured);
263     }
264 
checkNullObj(void * obj,const char * func)265     static bool checkNullObj(void* obj, const char* func) {
266         if (obj == nullptr) {
267             ALOGE("%s: null obj", func);
268             return true;
269         }
270         return false;
271     }
272 
273     class CameraDeviceListener {
274     public:
CameraDeviceListener(CameraOpenerJni & parent)275         CameraDeviceListener(CameraOpenerJni& parent) : mParent(parent) {}
276 
onDisconnectedStatic(void * obj,ACameraDevice * device)277         static void onDisconnectedStatic(void* obj, ACameraDevice* device) {
278             if (checkNullObj(obj, __FUNCTION__)) return;
279             reinterpret_cast<CameraDeviceListener*>(obj)->onDisconnected(device);
280         }
281 
onErrorStatic(void * obj,ACameraDevice * device,int errorCode)282         static void onErrorStatic(void* obj, ACameraDevice* device, int errorCode) {
283             if (checkNullObj(obj, __FUNCTION__)) return;
284             reinterpret_cast<CameraDeviceListener*>(obj)->onError(device, errorCode);
285         }
286 
closeDevice(ACameraDevice * device)287         static void closeDevice(ACameraDevice* device) {
288             auto rc = ACameraDevice_close(device);
289             if (rc != ACAMERA_OK) {
290                 ALOGE("Close camera failed: ret %d", rc);
291             }
292         }
293 
onDisconnected(ACameraDevice *)294         void onDisconnected(ACameraDevice* /*device*/) {
295             ALOGV("%s", __FUNCTION__);
296             mParent.signalStoppedRepeating(0);
297         }
298 
onError(ACameraDevice *,int errorCode)299         void onError(ACameraDevice* /*device*/, int errorCode) {
300             ALOGV("%s: %d", __FUNCTION__, errorCode);
301             mParent.signalStoppedRepeating(errorCode);
302         }
303 
304     private:
305         CameraOpenerJni& mParent;
306     };
307 
308     class ImageReaderListener {
309     public:
signalImageStatic(void * obj,AImageReader * reader)310         static void signalImageStatic(void* obj, AImageReader* reader) {
311             if (checkNullObj(obj, __FUNCTION__)) return;
312             reinterpret_cast<ImageReaderListener*>(obj)->signalImage(reader);
313         }
314 
signalImage(AImageReader * reader)315         void signalImage(AImageReader* reader) {
316             AImage* img = nullptr;
317             media_status_t rc = AImageReader_acquireNextImage(reader, &img);
318             if (rc != AMEDIA_OK || img == nullptr) {
319                 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p", __FUNCTION__,
320                       reader, rc, img);
321                 return;
322             }
323             AImage_delete(img);
324         }
325     };
326 
327     class CaptureSessionListener {
328     public:
onClosed(void * obj,ACameraCaptureSession * session)329         static void onClosed([[maybe_unused]] void* obj, ACameraCaptureSession* session) {
330             ALOGV("%s: %p", __FUNCTION__, session);
331         }
332 
onReady(void * obj,ACameraCaptureSession * session)333         static void onReady([[maybe_unused]] void* obj, ACameraCaptureSession* session) {
334             ALOGV("%s: %p", __FUNCTION__, session);
335         }
336 
onActive(void * obj,ACameraCaptureSession * session)337         static void onActive([[maybe_unused]] void* obj, ACameraCaptureSession* session) {
338             ALOGV("%s: %p", __FUNCTION__, session);
339         }
340     };
341 
342     class CaptureResultListener {
343     public:
CaptureResultListener(CameraOpenerJni & parent)344         CaptureResultListener(CameraOpenerJni& parent) : mParent(parent) {}
345 
onCaptureStart(void *,ACameraCaptureSession *,const ACaptureRequest *,int64_t)346         static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
347                                    const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
348             ALOGV("%s", __FUNCTION__);
349         }
350 
onCaptureProgressed(void *,ACameraCaptureSession *,ACaptureRequest *,const ACameraMetadata *)351         static void onCaptureProgressed(void* /*obj*/, ACameraCaptureSession* /*session*/,
352                                         ACaptureRequest* /*request*/,
353                                         const ACameraMetadata* /*result*/) {
354             ALOGV("%s", __FUNCTION__);
355         }
356 
onCaptureCompletedStatic(void * obj,ACameraCaptureSession *,ACaptureRequest *,const ACameraMetadata *)357         static void onCaptureCompletedStatic(void* obj, ACameraCaptureSession* /*session*/,
358                                              ACaptureRequest* /*request*/,
359                                              const ACameraMetadata* /*result*/) {
360             ALOGV("%s", __FUNCTION__);
361             if (checkNullObj(obj, __FUNCTION__)) return;
362             reinterpret_cast<CaptureResultListener*>(obj)->onCaptureCompleted();
363         }
364 
onCaptureFailedStatic(void * obj,ACameraCaptureSession *,ACaptureRequest *,ACameraCaptureFailure * failure)365         static void onCaptureFailedStatic(void* obj, ACameraCaptureSession* /*session*/,
366                                           ACaptureRequest* /*request*/,
367                                           ACameraCaptureFailure* failure) {
368             ALOGV("%s", __FUNCTION__);
369             if (checkNullObj(obj, __FUNCTION__)) return;
370             reinterpret_cast<CaptureResultListener*>(obj)->onCaptureFailed(failure);
371         }
372 
onCaptureSequenceCompleted(void *,ACameraCaptureSession *,int,int64_t frameNumber)373         static void onCaptureSequenceCompleted(void* /*obj*/, ACameraCaptureSession* /*session*/,
374                                                int /*sequenceId*/, int64_t frameNumber) {
375             ALOGV("%s: frameNumber %" PRId64, __FUNCTION__, frameNumber);
376         }
377 
onCaptureSequenceAborted(void *,ACameraCaptureSession *,int)378         static void onCaptureSequenceAborted(void* /*obj*/, ACameraCaptureSession* /*session*/,
379                                              int /*sequenceId*/) {
380             ALOGV("%s", __FUNCTION__);
381         }
382 
onCaptureBufferLost(void *,ACameraCaptureSession *,ACaptureRequest *,ANativeWindow *,int64_t frameNumber)383         static void onCaptureBufferLost(void* /*obj*/, ACameraCaptureSession* /*session*/,
384                                         ACaptureRequest* /*request*/, ANativeWindow* /*window*/,
385                                         int64_t frameNumber) {
386             ALOGV("%s: frameNumber %" PRId64, __FUNCTION__, frameNumber);
387         }
388 
onCaptureCompleted()389         void onCaptureCompleted() { mParent.onCaptureCompleted(); }
390 
onCaptureFailed(ACameraCaptureFailure * failure)391         void onCaptureFailed(ACameraCaptureFailure* failure) { mParent.onCaptureFailed(failure); }
392 
393     private:
394         CameraOpenerJni& mParent;
395     };
396 
397 private:
getPreviewSize(int & w,int & h)398     camera_status_t getPreviewSize(int& w, int& h) {
399         ACameraMetadata_const_entry entry;
400         auto rc = ACameraMetadata_getConstEntry(mCameraCharacteristics.get(),
401                                                 ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
402                                                 &entry);
403         if (rc != ACAMERA_OK) {
404             ALOGE("Failed to get available stream configurations: %d", rc);
405             return rc;
406         }
407 
408         for (uint32_t i = 0; i < entry.count; i += 4) {
409             if (entry.data.i32[i] == AIMAGE_FORMAT_JPEG &&
410                 entry.data.i32[i + 3] == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
411                 w = entry.data.i32[i + 1];
412                 h = entry.data.i32[i + 2];
413                 return ACAMERA_OK;
414             }
415         }
416 
417         ALOGE("Could not find preview size for JPEG format");
418         return ACAMERA_ERROR_METADATA_NOT_FOUND;
419     }
420 
createImageReader(int width,int height)421     media_status_t createImageReader(int width, int height) {
422         AImageReader* reader = nullptr;
423 
424         auto rc = AImageReader_new(width, height, AIMAGE_FORMAT_JPEG, /*maxImages=*/1, &reader);
425         if (rc != AMEDIA_OK) {
426             ALOGE("Failed to create image reader: %d", rc);
427             return rc;
428         }
429         if (reader == nullptr) {
430             ALOGE("Null image reader created.");
431             return AMEDIA_ERROR_UNKNOWN;
432         }
433 
434         mImgReader.reset(reader);
435         rc = AImageReader_setImageListener(reader, &mImgReaderCb);
436         if (rc != AMEDIA_OK) {
437             ALOGE("Set AImageReader listener failed. ret %d", rc);
438             return rc;
439         }
440 
441         rc = AImageReader_getWindow(reader, &mImgReaderAnw);
442         if (rc != AMEDIA_OK) {
443             ALOGE("AImageReader_getWindow failed. ret %d", rc);
444             return rc;
445         }
446         if (mImgReaderAnw == nullptr) {
447             ALOGE("Null ANW from AImageReader!");
448             return AMEDIA_ERROR_UNKNOWN;
449         }
450 
451         return AMEDIA_OK;
452     }
453 
createCaptureSessionOutputContainer()454     camera_status_t createCaptureSessionOutputContainer() {
455         ACaptureSessionOutputContainer* outputContainer = nullptr;
456         auto rc = ACaptureSessionOutputContainer_create(&outputContainer);
457         if (rc != ACAMERA_OK) {
458             ALOGE("Create capture session output container failed. ret %d", rc);
459             return rc;
460         }
461 
462         mOutputContainer.reset(outputContainer);
463 
464         ACaptureSessionOutput* output = nullptr;
465         rc = ACaptureSessionOutput_create(mImgReaderAnw, &output);
466         if (rc != ACAMERA_OK || output == nullptr) {
467             ALOGE("Session image reader output create fail! ret %d output %p", rc, output);
468             if (rc == ACAMERA_OK) {
469                 rc = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
470             }
471             return rc;
472         }
473 
474         mOutput.reset(output);
475 
476         rc = ACaptureSessionOutputContainer_add(outputContainer, output);
477         if (rc != ACAMERA_OK) {
478             ALOGE("Session image reader output add failed! ret %d", rc);
479             return rc;
480         }
481 
482         return ACAMERA_OK;
483     }
484 
createCaptureRequest(ACameraDevice_request_template requestTemplate)485     camera_status_t createCaptureRequest(ACameraDevice_request_template requestTemplate) {
486         ACaptureRequest* request = nullptr;
487         auto rc =
488                 ACameraDevice_createCaptureRequest(mCameraDevice.get(), requestTemplate, &request);
489         if (rc != ACAMERA_OK) {
490             ALOGE("Create capture request failed. ret %d", rc);
491             return rc;
492         }
493 
494         mCaptureRequest.reset(request);
495 
496         ACameraOutputTarget* outputTarget = nullptr;
497         rc = ACameraOutputTarget_create(mImgReaderAnw, &outputTarget);
498         if (rc != ACAMERA_OK) {
499             ALOGE("Create request reader output target failed. ret %d", rc);
500             return rc;
501         }
502 
503         mOutputTarget.reset(outputTarget);
504 
505         rc = ACaptureRequest_addTarget(request, outputTarget);
506         if (rc != ACAMERA_OK) {
507             ALOGE("Add capture request output failed. ret %d", rc);
508             return rc;
509         }
510 
511         return ACAMERA_OK;
512     }
513 
514     Auto<ACameraManager, ACameraManager_delete> mCameraManager;
515     Auto<ACameraIdList, ACameraManager_deleteCameraIdList> mCameraIdList;
516     CameraDeviceListener mCameraDeviceListener;
517     ACameraDevice_StateCallbacks mCameraDeviceCb;
518     Auto<ACameraDevice, CameraDeviceListener::closeDevice> mCameraDevice;
519     Auto<ACameraMetadata, ACameraMetadata_free> mCameraCharacteristics;
520     Auto<AImageReader, AImageReader_delete> mImgReader;
521     ANativeWindow* mImgReaderAnw;
522     ImageReaderListener mImgReaderListener;
523     AImageReader_ImageListener mImgReaderCb;
524     Auto<ACaptureSessionOutputContainer, ACaptureSessionOutputContainer_free> mOutputContainer;
525     Auto<ACaptureSessionOutput, ACaptureSessionOutput_free> mOutput;
526     Auto<ACameraCaptureSession, ACameraCaptureSession_close> mCaptureSession;
527     CaptureSessionListener mCaptureSessionListener;
528     ACameraCaptureSession_stateCallbacks mCaptureSessionCb;
529     Auto<ACaptureRequest, ACaptureRequest_free> mCaptureRequest;
530     Auto<ACameraOutputTarget, ACameraOutputTarget_free> mOutputTarget;
531     CaptureResultListener mCaptureResultListener;
532     ACameraCaptureSession_captureCallbacks mCaptureResultCb;
533     std::mutex mMutex;
534     std::condition_variable mStateChanged;
535     bool mFirstCaptureCompleted = false;
536     bool mStoppedRepeating = false;
537     int mErrorCode = 0;
538 };
539 
540 static std::unique_ptr<CameraOpenerJni> sThis = nullptr;
541 
checkNullThis(const char * func)542 static bool checkNullThis(const char* func) {
543     if (sThis == nullptr) {
544         ALOGE("%s: sThis is null", func);
545         return true;
546     }
547     return false;
548 }
549 
550 } // namespace
551 
552 extern "C" {
553 
Java_android_security_cts_camera_open_CameraOpener_nativeInit()554 void Java_android_security_cts_camera_open_CameraOpener_nativeInit() {
555     ALOGV("Enter %s", __FUNCTION__);
556     sThis = std::make_unique<CameraOpenerJni>();
557 }
558 
Java_android_security_cts_camera_open_CameraOpener_nativeCleanup()559 void Java_android_security_cts_camera_open_CameraOpener_nativeCleanup() {
560     ALOGV("Enter %s", __FUNCTION__);
561     sThis = nullptr;
562 }
563 
Java_android_security_cts_camera_open_CameraOpener_nativeHasCamera()564 jboolean Java_android_security_cts_camera_open_CameraOpener_nativeHasCamera() {
565     if (checkNullThis(__FUNCTION__)) return false;
566     return sThis->hasCamera();
567 }
568 
Java_android_security_cts_camera_open_CameraOpener_nativeOpenCamera()569 jint Java_android_security_cts_camera_open_CameraOpener_nativeOpenCamera() {
570     if (checkNullThis(__FUNCTION__)) return ACAMERA_ERROR_UNKNOWN;
571     return sThis->openCamera();
572 }
573 
Java_android_security_cts_camera_open_CameraOpener_nativeOpenCameraStream(jboolean shouldRepeat)574 jint Java_android_security_cts_camera_open_CameraOpener_nativeOpenCameraStream(
575         jboolean shouldRepeat) {
576     if (checkNullThis(__FUNCTION__)) return ACAMERA_ERROR_UNKNOWN;
577     return sThis->openCameraStream(shouldRepeat);
578 }
579 
Java_android_security_cts_camera_open_CameraOpener_nativeWaitStopRepeating()580 jint Java_android_security_cts_camera_open_CameraOpener_nativeWaitStopRepeating() {
581     if (checkNullThis(__FUNCTION__)) return ACAMERA_ERROR_UNKNOWN;
582     return sThis->waitStopRepeating();
583 }
584 
Java_android_security_cts_camera_open_CameraOpener_nativeStopRepeating()585 jint Java_android_security_cts_camera_open_CameraOpener_nativeStopRepeating() {
586     if (checkNullThis(__FUNCTION__)) return ACAMERA_ERROR_UNKNOWN;
587     return sThis->stopRepeating();
588 }
589 }
590