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"