xref: /aosp_15_r20/frameworks/base/core/jni/android_hardware_camera2_CameraDevice.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
2 **
3 ** Copyright 2024, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 // #define LOG_NDEBUG 0
19 
20 #define ATRACE_TAG ATRACE_TAG_CAMERA
21 
22 #include <memory>
23 #define LOG_TAG "CameraDevice-JNI"
24 #include <utils/Errors.h>
25 #include <utils/Log.h>
26 #include <utils/Trace.h>
27 #include <vector>
28 
29 #include "jni.h"
30 #include <nativehelper/JNIHelp.h>
31 #include "android_os_Parcel.h"
32 #include "core_jni_helpers.h"
33 #include <android/binder_parcel_jni.h>
34 #include <android/hardware/camera2/ICameraDeviceUser.h>
35 #include <aidl/android/hardware/common/fmq/MQDescriptor.h>
36 #include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
37 #include <fmq/AidlMessageQueue.h>
38 #include <camera/CameraMetadata.h>
39 
40 using namespace android;
41 
42 using ::android::AidlMessageQueue;
43 using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
44 
45 class FMQReader {
46     public:
FMQReader(MQDescriptor<int8_t,SynchronizedReadWrite> & resultMQ)47     FMQReader(MQDescriptor<int8_t, SynchronizedReadWrite> &resultMQ) {
48         mCaptureResultMetadataQueue = std::make_shared<ResultMetadataQueue>(resultMQ);
49     }
50     std::shared_ptr<CameraMetadata> readOneResultMetadata(long metadataSize);
51     private:
52     std::shared_ptr<ResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
53 };
54 
readOneResultMetadata(long metadataSize)55 std::shared_ptr<CameraMetadata> FMQReader::readOneResultMetadata(long metadataSize) {
56     ATRACE_CALL();
57     if (metadataSize == 0) {
58         return nullptr;
59     }
60     auto metadataVec = std::make_unique<int8_t []>(metadataSize);
61     bool read = mCaptureResultMetadataQueue->read(metadataVec.get(), metadataSize);
62     if (!read) {
63         ALOGE("%s capture metadata could't be read from fmq", __FUNCTION__);
64         return nullptr;
65     }
66 
67     // Takes ownership of metadataVec, this doesn't copy
68     std::shared_ptr<CameraMetadata> retVal =
69             std::make_shared<CameraMetadata>(
70                     reinterpret_cast<camera_metadata_t *>(metadataVec.release()));
71     return retVal;
72 }
73 
74 extern "C" {
75 
CameraDevice_createFMQReader(JNIEnv * env,jclass thiz,jobject resultParcel)76 static jlong CameraDevice_createFMQReader(JNIEnv *env, jclass thiz,
77         jobject resultParcel) {
78     AParcel *resultAParcel = AParcel_fromJavaParcel(env, resultParcel);
79     if (resultAParcel == nullptr) {
80         ALOGE("%s: Error creating result parcel", __FUNCTION__);
81         return 0;
82     }
83     AParcel_setDataPosition(resultAParcel, 0);
84 
85     MQDescriptor<int8_t, SynchronizedReadWrite> resultMQ;
86     if (resultMQ.readFromParcel(resultAParcel) != OK) {
87         ALOGE("%s: read from result parcel failed", __FUNCTION__);
88         return 0;
89     }
90     return reinterpret_cast<jlong>(new std::shared_ptr<FMQReader>(
91             new FMQReader(resultMQ)));
92 }
93 
FMQReader_getSharedPtr(jlong fmqReaderLongPtr)94 static std::shared_ptr<FMQReader>* FMQReader_getSharedPtr(jlong fmqReaderLongPtr) {
95     return reinterpret_cast<std::shared_ptr<FMQReader>* >(fmqReaderLongPtr);
96 }
97 
CameraDevice_readResultMetadata(JNIEnv * env,jclass thiz,jlong ptr,jlong metadataSize)98 static jlong CameraDevice_readResultMetadata(JNIEnv *env, jclass thiz, jlong ptr,
99         jlong metadataSize) {
100     ALOGV("%s", __FUNCTION__);
101 
102     FMQReader *fmqReader = FMQReader_getSharedPtr(ptr)->get();
103     auto metadataSp = fmqReader->readOneResultMetadata(metadataSize);
104     auto retVal = new std::shared_ptr<CameraMetadata>(metadataSp);
105     return reinterpret_cast<jlong>(retVal);
106 }
107 
CameraDevice_close(JNIEnv * env,jclass thiz,jlong ptr)108 static void CameraDevice_close(JNIEnv *env, jclass thiz, jlong ptr) {
109     ALOGV("%s", __FUNCTION__);
110 
111     auto fmqPtr = FMQReader_getSharedPtr(ptr);
112     if (fmqPtr != nullptr) {
113         delete fmqPtr;
114     }
115 }
116 
117 }
118 
119 //-------------------------------------------------
120 #define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/impl/CameraDeviceImpl"
121 static const JNINativeMethod gCameraDeviceMethods[] = {
122 // static methods
123   { "nativeCreateFMQReader",
124     "(Landroid/os/Parcel;)J",
125     (void *)CameraDevice_createFMQReader},
126   { "nativeReadResultMetadata",
127     "(JJ)J",
128     (void *)CameraDevice_readResultMetadata},
129   { "nativeClose",
130     "(J)V",
131     (void*)CameraDevice_close},
132 // instance methods
133 };
134 
135 
136 // Get all the required offsets in java class and register native functions
register_android_hardware_camera2_CameraDevice(JNIEnv * env)137 int register_android_hardware_camera2_CameraDevice(JNIEnv *env)
138 {
139     // Register native functions
140     return RegisterMethodsOrDie(env,
141             CAMERA_DEVICE_CLASS_NAME,
142             gCameraDeviceMethods,
143             NELEM(gCameraDeviceMethods));
144 }
145 
146 extern "C" {
147 
148 } // extern "C"