1 /*
2 *
3 * Copyright 2019, 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 #include <jni.h>
19 #include <localization/ConfirmationUITranslations.h>
20 #include <teeui/example/teeui.h>
21
22 /*
23 * JTypeTraits provides hints for JArray on how to access and free the array elements and how
24 * to get the array size. The traits allow JArray to be used with jbyteArray, jintArray,
25 * and jstring.
26 */
27 template <typename T> struct JTypeTraits;
28
29 template <> struct JTypeTraits<jintArray> {
30 using element_type = jint;
31 using array_type = jintArray;
32
33 static constexpr element_type* (JNIEnv::*const getArrayElements)(array_type, jboolean*) =
34 &JNIEnv::GetIntArrayElements;
35 static constexpr void (JNIEnv::*const releaseArrayElements)(array_type, element_type*, jint) =
36 &JNIEnv::ReleaseIntArrayElements;
37 static constexpr jsize (JNIEnv::*const getArrayLength)(jarray) = &JNIEnv::GetArrayLength;
38 };
39
40 template <> struct JTypeTraits<jbyteArray> {
41 using element_type = jbyte;
42 using array_type = jbyteArray;
43
44 static constexpr element_type* (JNIEnv::*const getArrayElements)(array_type, jboolean*) =
45 &JNIEnv::GetByteArrayElements;
46 static constexpr void (JNIEnv::*const releaseArrayElements)(array_type, element_type*, jint) =
47 &JNIEnv::ReleaseByteArrayElements;
48 static constexpr jsize (JNIEnv::*const getArrayLength)(jarray) = &JNIEnv::GetArrayLength;
49 };
50
51 template <> struct JTypeTraits<jstring> {
52 using element_type = const char;
53 using array_type = jstring;
54
55 static constexpr element_type* (JNIEnv::*const getArrayElements)(array_type, jboolean*) =
56 &JNIEnv::GetStringUTFChars;
57 static constexpr void (JNIEnv::*const releaseArrayElements)(array_type, element_type*) =
58 &JNIEnv::ReleaseStringUTFChars;
59 static constexpr jsize (JNIEnv::*const getArrayLength)(array_type) =
60 &JNIEnv::GetStringUTFLength;
61 };
62
63 /*
64 * JArray can wrap various types of primitive Java arrays through a common typical C++ interface.
65 * It tracks ownership. It can only be moved but not copied. It provides iterators through begin()
66 * and end() so that it can be used in range for loops.
67 */
68 template <typename T> class JArray {
69 private:
70 JNIEnv* env_;
71 using element_type = typename JTypeTraits<T>::element_type;
72 using array_type = typename JTypeTraits<T>::array_type;
73 array_type jarray_;
74 element_type* buffer_;
75
76 public:
JArray(JNIEnv * env,array_type jarray)77 JArray(JNIEnv* env, array_type jarray) : env_(env), jarray_(jarray), buffer_(nullptr) {
78 if (env_ == nullptr) return;
79 buffer_ = (env_->*JTypeTraits<T>::getArrayElements)(jarray, nullptr);
80 }
81 JArray(const JArray&) = delete;
JArray(JArray && rhs)82 JArray(JArray&& rhs) : env_(rhs.env_), jarray_(rhs.jarray_), buffer_(rhs.buffer_) {
83 rhs.env_ = nullptr;
84 rhs.buffer_ = nullptr;
85 }
86 ~JArray();
87
88 JArray& operator=(const JArray&) = delete;
operator =(JArray && rhs)89 JArray& operator=(JArray&& rhs) {
90 if (&rhs != this) {
91 env_ = rhs.env_;
92 jarray_ = rhs.jarray_;
93 buffer_ = rhs.buffer_;
94 rhs.env_ = nullptr;
95 rhs.buffer_ = nullptr;
96 }
97 return *this;
98 }
99
operator bool() const100 operator bool() const { return buffer_ != nullptr; }
operator [](size_t offset) const101 const jint& operator[](size_t offset) const { return buffer_[offset]; }
operator [](size_t offset)102 element_type& operator[](size_t offset) { return buffer_[offset]; }
size() const103 size_t size() const { return (env_->*JTypeTraits<T>::getArrayLength)(jarray_); }
begin()104 element_type* begin() { return buffer_; }
end()105 element_type* end() { return buffer_ + size(); }
begin() const106 const element_type* begin() const { return buffer_; }
end() const107 const element_type* end() const { return buffer_ + size(); }
108 };
109
~JArray()110 template <typename T> JArray<T>::~JArray() {
111 if (env_ == nullptr) return;
112 if (buffer_ == nullptr) return;
113 (env_->*JTypeTraits<T>::releaseArrayElements)(jarray_, buffer_, 0);
114 }
115
~JArray()116 template <> JArray<jstring>::~JArray() {
117 if (env_ == nullptr) return;
118 if (buffer_ == nullptr) return;
119 (env_->*JTypeTraits<jstring>::releaseArrayElements)(jarray_, buffer_);
120 }
121
122 using JIntArray = JArray<jintArray>;
123 using JByteArray = JArray<jbyteArray>;
124 using JString = JArray<jstring>;
125
126 /*
127 * Class: com_android_framebufferizer_NativeRenderer
128 * Method: setDeviceInfo
129 * Signature: (Lcom/android/framebufferizer/utils/DeviceInfo;ZZ)I
130 */
Java_com_android_framebufferizer_NativeRenderer_setDeviceInfo(JNIEnv * env,jclass,jobject jDeviceInfo,jboolean magnified,jboolean inverted)131 extern "C" JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_setDeviceInfo(
132 JNIEnv* env, jclass, jobject jDeviceInfo, jboolean magnified, jboolean inverted) {
133 jclass cDeviceInfo = env->FindClass("Lcom/android/framebufferizer/utils/DeviceInfo;");
134 jmethodID method = env->GetMethodID(cDeviceInfo, "getWidthPx", "()I");
135 DeviceInfo device_info;
136 device_info.width_ = env->CallIntMethod(jDeviceInfo, method);
137 method = env->GetMethodID(cDeviceInfo, "getHeightPx", "()I");
138 device_info.height_ = env->CallIntMethod(jDeviceInfo, method);
139 method = env->GetMethodID(cDeviceInfo, "getDp2px", "()D");
140 device_info.dp2px_ = env->CallDoubleMethod(jDeviceInfo, method);
141 method = env->GetMethodID(cDeviceInfo, "getMm2px", "()D");
142 device_info.mm2px_ = env->CallDoubleMethod(jDeviceInfo, method);
143 method = env->GetMethodID(cDeviceInfo, "getPowerButtonTopMm", "()D");
144 device_info.powerButtonTopMm_ = env->CallDoubleMethod(jDeviceInfo, method);
145 method = env->GetMethodID(cDeviceInfo, "getPowerButtonBottomMm", "()D");
146 device_info.powerButtonBottomMm_ = env->CallDoubleMethod(jDeviceInfo, method);
147 method = env->GetMethodID(cDeviceInfo, "getVolUpButtonTopMm", "()D");
148 device_info.volUpButtonTopMm_ = env->CallDoubleMethod(jDeviceInfo, method);
149 method = env->GetMethodID(cDeviceInfo, "getVolUpButtonBottomMm", "()D");
150 device_info.volUpButtonBottomMm_ = env->CallDoubleMethod(jDeviceInfo, method);
151 return setDeviceInfo(device_info, magnified, inverted);
152 }
153
154 /*
155 * Class: com_android_framebufferizer_NativeRenderer
156 * Method: renderBuffer
157 * Signature: (IIIII[I)I
158 */
Java_com_android_framebufferizer_NativeRenderer_renderBuffer(JNIEnv * env,jclass,jint x,jint y,jint width,jint height,jint lineStride,jintArray jbuffer)159 extern "C" JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_renderBuffer(
160 JNIEnv* env, jclass, jint x, jint y, jint width, jint height, jint lineStride,
161 jintArray jbuffer) {
162 JIntArray buffer(env, jbuffer);
163 if (!buffer) return 1;
164 return renderUIIntoBuffer((uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height,
165 (uint32_t)lineStride, (uint32_t*)buffer.begin(), buffer.size());
166 }
167 /*
168 * Class: com_android_confirmationui_Translation_selectLangID
169 * Method: selectLangID
170 * Signature: (Ljava/lang/String;)V
171 */
172 extern "C" JNIEXPORT void JNICALL
Java_com_android_framebufferizer_NativeRenderer_setLanguage(JNIEnv * env,jclass,jstring jlang_id)173 Java_com_android_framebufferizer_NativeRenderer_setLanguage(JNIEnv* env, jclass, jstring jlang_id) {
174 jboolean isCopy = false;
175 const char* lang_id = (env)->GetStringUTFChars(jlang_id, &isCopy);
176 selectLanguage(lang_id);
177 (env)->ReleaseStringUTFChars(jlang_id, lang_id);
178 }
179 /*
180 * Class: com_android_confirmationui_Translation_selectLangID
181 * Method: selectLangID
182 * Signature: ()[Ljava/lang/String;
183 */
184 extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_android_framebufferizer_NativeRenderer_getLanguageIdList(JNIEnv * env,jclass)185 Java_com_android_framebufferizer_NativeRenderer_getLanguageIdList(JNIEnv* env, jclass) {
186 jobjectArray language_ids;
187 languages lang_list = ConfirmationUITranslations_get_languages();
188 const char* const* native_data = lang_list.list;
189 size_t list_size = lang_list.size;
190
191 language_ids = (jobjectArray)env->NewObjectArray(list_size, env->FindClass("java/lang/String"),
192 env->NewStringUTF(""));
193
194 for (size_t i = 0; i < list_size; i++)
195 env->SetObjectArrayElement(language_ids, i, env->NewStringUTF(native_data[i]));
196
197 return language_ids;
198 }
199 /*
200 * Class: com_android_framebufferizer_NativeRenderer
201 * Method: setConfimationMessage
202 * Signature: (Ljava/lang/String;)V
203 */
204 extern "C" JNIEXPORT void JNICALL
Java_com_android_framebufferizer_NativeRenderer_setConfimationMessage(JNIEnv * env,jclass,jstring jConfirmationMessage)205 Java_com_android_framebufferizer_NativeRenderer_setConfimationMessage(
206 JNIEnv* env, jclass, jstring jConfirmationMessage) {
207 JString confirmationMessage(env, jConfirmationMessage);
208 setConfirmationMessage(confirmationMessage.begin());
209 }
210