• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "sdk/android/native_api/jni/java_types.h"
12 
13 #include <memory>
14 #include <string>
15 #include <utility>
16 
17 #include "sdk/android/generated_external_classes_jni/ArrayList_jni.h"
18 #include "sdk/android/generated_external_classes_jni/Boolean_jni.h"
19 #include "sdk/android/generated_external_classes_jni/Double_jni.h"
20 #include "sdk/android/generated_external_classes_jni/Enum_jni.h"
21 #include "sdk/android/generated_external_classes_jni/Integer_jni.h"
22 #include "sdk/android/generated_external_classes_jni/Iterable_jni.h"
23 #include "sdk/android/generated_external_classes_jni/Iterator_jni.h"
24 #include "sdk/android/generated_external_classes_jni/LinkedHashMap_jni.h"
25 #include "sdk/android/generated_external_classes_jni/Long_jni.h"
26 #include "sdk/android/generated_external_classes_jni/Map_jni.h"
27 #include "sdk/android/generated_native_api_jni/JniHelper_jni.h"
28 
29 namespace webrtc {
30 
Iterable(JNIEnv * jni,const JavaRef<jobject> & iterable)31 Iterable::Iterable(JNIEnv* jni, const JavaRef<jobject>& iterable)
32     : jni_(jni), iterable_(jni, iterable) {}
33 
34 Iterable::Iterable(Iterable&& other) = default;
35 
36 Iterable::~Iterable() = default;
37 
38 // Creates an iterator representing the end of any collection.
39 Iterable::Iterator::Iterator() = default;
40 
41 // Creates an iterator pointing to the beginning of the specified collection.
Iterator(JNIEnv * jni,const JavaRef<jobject> & iterable)42 Iterable::Iterator::Iterator(JNIEnv* jni, const JavaRef<jobject>& iterable)
43     : jni_(jni) {
44   iterator_ = JNI_Iterable::Java_Iterable_iterator(jni, iterable);
45   RTC_CHECK(!iterator_.is_null());
46   // Start at the first element in the collection.
47   ++(*this);
48 }
49 
50 // Move constructor - necessary to be able to return iterator types from
51 // functions.
Iterator(Iterator && other)52 Iterable::Iterator::Iterator(Iterator&& other)
53     : jni_(std::move(other.jni_)),
54       iterator_(std::move(other.iterator_)),
55       value_(std::move(other.value_)) {
56   RTC_DCHECK_RUN_ON(&thread_checker_);
57 }
58 
59 Iterable::Iterator::~Iterator() = default;
60 
61 // Advances the iterator one step.
operator ++()62 Iterable::Iterator& Iterable::Iterator::operator++() {
63   RTC_DCHECK_RUN_ON(&thread_checker_);
64   if (AtEnd()) {
65     // Can't move past the end.
66     return *this;
67   }
68   bool has_next = JNI_Iterator::Java_Iterator_hasNext(jni_, iterator_);
69   if (!has_next) {
70     iterator_ = nullptr;
71     value_ = nullptr;
72     return *this;
73   }
74 
75   value_ = JNI_Iterator::Java_Iterator_next(jni_, iterator_);
76   return *this;
77 }
78 
Remove()79 void Iterable::Iterator::Remove() {
80   JNI_Iterator::Java_Iterator_remove(jni_, iterator_);
81 }
82 
83 // Provides a way to compare the iterator with itself and with the end iterator.
84 // Note: all other comparison results are undefined, just like for C++ input
85 // iterators.
operator ==(const Iterable::Iterator & other)86 bool Iterable::Iterator::operator==(const Iterable::Iterator& other) {
87   // Two different active iterators should never be compared.
88   RTC_DCHECK(this == &other || AtEnd() || other.AtEnd());
89   return AtEnd() == other.AtEnd();
90 }
91 
operator *()92 ScopedJavaLocalRef<jobject>& Iterable::Iterator::operator*() {
93   RTC_CHECK(!AtEnd());
94   return value_;
95 }
96 
AtEnd() const97 bool Iterable::Iterator::AtEnd() const {
98   RTC_DCHECK_RUN_ON(&thread_checker_);
99   return jni_ == nullptr || IsNull(jni_, iterator_);
100 }
101 
IsNull(JNIEnv * jni,const JavaRef<jobject> & obj)102 bool IsNull(JNIEnv* jni, const JavaRef<jobject>& obj) {
103   return jni->IsSameObject(obj.obj(), nullptr);
104 }
105 
GetJavaEnumName(JNIEnv * jni,const JavaRef<jobject> & j_enum)106 std::string GetJavaEnumName(JNIEnv* jni, const JavaRef<jobject>& j_enum) {
107   return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum));
108 }
109 
GetJavaMapEntrySet(JNIEnv * jni,const JavaRef<jobject> & j_map)110 Iterable GetJavaMapEntrySet(JNIEnv* jni, const JavaRef<jobject>& j_map) {
111   return Iterable(jni, JNI_Map::Java_Map_entrySet(jni, j_map));
112 }
113 
GetJavaMapEntryKey(JNIEnv * jni,const JavaRef<jobject> & j_entry)114 ScopedJavaLocalRef<jobject> GetJavaMapEntryKey(
115     JNIEnv* jni,
116     const JavaRef<jobject>& j_entry) {
117   return jni::Java_JniHelper_getKey(jni, j_entry);
118 }
119 
GetJavaMapEntryValue(JNIEnv * jni,const JavaRef<jobject> & j_entry)120 ScopedJavaLocalRef<jobject> GetJavaMapEntryValue(
121     JNIEnv* jni,
122     const JavaRef<jobject>& j_entry) {
123   return jni::Java_JniHelper_getValue(jni, j_entry);
124 }
125 
JavaToNativeLong(JNIEnv * env,const JavaRef<jobject> & j_long)126 int64_t JavaToNativeLong(JNIEnv* env, const JavaRef<jobject>& j_long) {
127   return JNI_Long::Java_Long_longValue(env, j_long);
128 }
129 
JavaToNativeOptionalBool(JNIEnv * jni,const JavaRef<jobject> & boolean)130 absl::optional<bool> JavaToNativeOptionalBool(JNIEnv* jni,
131                                               const JavaRef<jobject>& boolean) {
132   if (IsNull(jni, boolean))
133     return absl::nullopt;
134   return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean);
135 }
136 
JavaToNativeOptionalDouble(JNIEnv * jni,const JavaRef<jobject> & j_double)137 absl::optional<double> JavaToNativeOptionalDouble(
138     JNIEnv* jni,
139     const JavaRef<jobject>& j_double) {
140   if (IsNull(jni, j_double))
141     return absl::nullopt;
142   return JNI_Double::Java_Double_doubleValue(jni, j_double);
143 }
144 
JavaToNativeOptionalInt(JNIEnv * jni,const JavaRef<jobject> & integer)145 absl::optional<int32_t> JavaToNativeOptionalInt(
146     JNIEnv* jni,
147     const JavaRef<jobject>& integer) {
148   if (IsNull(jni, integer))
149     return absl::nullopt;
150   return JNI_Integer::Java_Integer_intValue(jni, integer);
151 }
152 
153 // Given a jstring, reinterprets it to a new native string.
JavaToNativeString(JNIEnv * jni,const JavaRef<jstring> & j_string)154 std::string JavaToNativeString(JNIEnv* jni, const JavaRef<jstring>& j_string) {
155   const ScopedJavaLocalRef<jbyteArray> j_byte_array =
156       jni::Java_JniHelper_getStringBytes(jni, j_string);
157 
158   const size_t len = jni->GetArrayLength(j_byte_array.obj());
159   CHECK_EXCEPTION(jni) << "error during GetArrayLength";
160   std::string str(len, '\0');
161   jni->GetByteArrayRegion(j_byte_array.obj(), 0, len,
162                           reinterpret_cast<jbyte*>(&str[0]));
163   CHECK_EXCEPTION(jni) << "error during GetByteArrayRegion";
164   return str;
165 }
166 
JavaToNativeStringMap(JNIEnv * jni,const JavaRef<jobject> & j_map)167 std::map<std::string, std::string> JavaToNativeStringMap(
168     JNIEnv* jni,
169     const JavaRef<jobject>& j_map) {
170   return JavaToNativeMap<std::string, std::string>(
171       jni, j_map,
172       [](JNIEnv* env, JavaRef<jobject> const& key,
173          JavaRef<jobject> const& value) {
174         return std::make_pair(
175             JavaToNativeString(env, static_java_ref_cast<jstring>(env, key)),
176             JavaToNativeString(env, static_java_ref_cast<jstring>(env, value)));
177       });
178 }
179 
NativeToJavaBoolean(JNIEnv * env,bool b)180 ScopedJavaLocalRef<jobject> NativeToJavaBoolean(JNIEnv* env, bool b) {
181   return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b);
182 }
183 
NativeToJavaDouble(JNIEnv * env,double d)184 ScopedJavaLocalRef<jobject> NativeToJavaDouble(JNIEnv* env, double d) {
185   return JNI_Double::Java_Double_ConstructorJLD_D(env, d);
186 }
187 
NativeToJavaInteger(JNIEnv * jni,int32_t i)188 ScopedJavaLocalRef<jobject> NativeToJavaInteger(JNIEnv* jni, int32_t i) {
189   return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i);
190 }
191 
NativeToJavaLong(JNIEnv * env,int64_t u)192 ScopedJavaLocalRef<jobject> NativeToJavaLong(JNIEnv* env, int64_t u) {
193   return JNI_Long::Java_Long_ConstructorJLLO_J(env, u);
194 }
195 
NativeToJavaString(JNIEnv * env,const char * str)196 ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* env, const char* str) {
197   jstring j_str = env->NewStringUTF(str);
198   CHECK_EXCEPTION(env) << "error during NewStringUTF";
199   return ScopedJavaLocalRef<jstring>(env, j_str);
200 }
201 
NativeToJavaString(JNIEnv * jni,const std::string & str)202 ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni,
203                                                const std::string& str) {
204   return NativeToJavaString(jni, str.c_str());
205 }
206 
NativeToJavaDouble(JNIEnv * jni,const absl::optional<double> & optional_double)207 ScopedJavaLocalRef<jobject> NativeToJavaDouble(
208     JNIEnv* jni,
209     const absl::optional<double>& optional_double) {
210   return optional_double ? NativeToJavaDouble(jni, *optional_double) : nullptr;
211 }
212 
NativeToJavaInteger(JNIEnv * jni,const absl::optional<int32_t> & optional_int)213 ScopedJavaLocalRef<jobject> NativeToJavaInteger(
214     JNIEnv* jni,
215     const absl::optional<int32_t>& optional_int) {
216   return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr;
217 }
218 
NativeToJavaString(JNIEnv * jni,const absl::optional<std::string> & str)219 ScopedJavaLocalRef<jstring> NativeToJavaString(
220     JNIEnv* jni,
221     const absl::optional<std::string>& str) {
222   return str ? NativeToJavaString(jni, *str) : nullptr;
223 }
224 
NativeToJavaByteArray(JNIEnv * env,rtc::ArrayView<int8_t> container)225 ScopedJavaLocalRef<jbyteArray> NativeToJavaByteArray(
226     JNIEnv* env,
227     rtc::ArrayView<int8_t> container) {
228   ScopedJavaLocalRef<jbyteArray> jarray(env,
229                                         env->NewByteArray(container.size()));
230   int8_t* array_ptr =
231       env->GetByteArrayElements(jarray.obj(), /*isCopy=*/nullptr);
232   memcpy(array_ptr, container.data(), container.size() * sizeof(int8_t));
233   env->ReleaseByteArrayElements(jarray.obj(), array_ptr, /*mode=*/0);
234   return jarray;
235 }
236 
NativeToJavaIntArray(JNIEnv * env,rtc::ArrayView<int32_t> container)237 ScopedJavaLocalRef<jintArray> NativeToJavaIntArray(
238     JNIEnv* env,
239     rtc::ArrayView<int32_t> container) {
240   ScopedJavaLocalRef<jintArray> jarray(env, env->NewIntArray(container.size()));
241   int32_t* array_ptr =
242       env->GetIntArrayElements(jarray.obj(), /*isCopy=*/nullptr);
243   memcpy(array_ptr, container.data(), container.size() * sizeof(int32_t));
244   env->ReleaseIntArrayElements(jarray.obj(), array_ptr, /*mode=*/0);
245   return jarray;
246 }
247 
JavaToNativeByteArray(JNIEnv * env,const JavaRef<jbyteArray> & jarray)248 std::vector<int8_t> JavaToNativeByteArray(JNIEnv* env,
249                                           const JavaRef<jbyteArray>& jarray) {
250   int8_t* array_ptr =
251       env->GetByteArrayElements(jarray.obj(), /*isCopy=*/nullptr);
252   size_t array_length = env->GetArrayLength(jarray.obj());
253   std::vector<int8_t> container(array_ptr, array_ptr + array_length);
254   env->ReleaseByteArrayElements(jarray.obj(), array_ptr, /*mode=*/JNI_ABORT);
255   return container;
256 }
257 
JavaToNativeIntArray(JNIEnv * env,const JavaRef<jintArray> & jarray)258 std::vector<int32_t> JavaToNativeIntArray(JNIEnv* env,
259                                           const JavaRef<jintArray>& jarray) {
260   int32_t* array_ptr =
261       env->GetIntArrayElements(jarray.obj(), /*isCopy=*/nullptr);
262   size_t array_length = env->GetArrayLength(jarray.obj());
263   std::vector<int32_t> container(array_ptr, array_ptr + array_length);
264   env->ReleaseIntArrayElements(jarray.obj(), array_ptr, /*mode=*/JNI_ABORT);
265   return container;
266 }
267 
NativeToJavaBooleanArray(JNIEnv * env,const std::vector<bool> & container)268 ScopedJavaLocalRef<jobjectArray> NativeToJavaBooleanArray(
269     JNIEnv* env,
270     const std::vector<bool>& container) {
271   return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env),
272                                  &NativeToJavaBoolean);
273 }
274 
NativeToJavaDoubleArray(JNIEnv * env,const std::vector<double> & container)275 ScopedJavaLocalRef<jobjectArray> NativeToJavaDoubleArray(
276     JNIEnv* env,
277     const std::vector<double>& container) {
278   ScopedJavaLocalRef<jobject> (*convert_function)(JNIEnv*, double) =
279       &NativeToJavaDouble;
280   return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env),
281                                  convert_function);
282 }
283 
NativeToJavaIntegerArray(JNIEnv * env,const std::vector<int32_t> & container)284 ScopedJavaLocalRef<jobjectArray> NativeToJavaIntegerArray(
285     JNIEnv* env,
286     const std::vector<int32_t>& container) {
287   ScopedJavaLocalRef<jobject> (*convert_function)(JNIEnv*, int32_t) =
288       &NativeToJavaInteger;
289   return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env),
290                                  convert_function);
291 }
292 
NativeToJavaLongArray(JNIEnv * env,const std::vector<int64_t> & container)293 ScopedJavaLocalRef<jobjectArray> NativeToJavaLongArray(
294     JNIEnv* env,
295     const std::vector<int64_t>& container) {
296   return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env),
297                                  &NativeToJavaLong);
298 }
299 
NativeToJavaStringArray(JNIEnv * env,const std::vector<std::string> & container)300 ScopedJavaLocalRef<jobjectArray> NativeToJavaStringArray(
301     JNIEnv* env,
302     const std::vector<std::string>& container) {
303   ScopedJavaLocalRef<jstring> (*convert_function)(JNIEnv*, const std::string&) =
304       &NativeToJavaString;
305   return NativeToJavaObjectArray(
306       env, container,
307       static_cast<jclass>(jni::Java_JniHelper_getStringClass(env).obj()),
308       convert_function);
309 }
310 
JavaListBuilder(JNIEnv * env)311 JavaListBuilder::JavaListBuilder(JNIEnv* env)
312     : env_(env), j_list_(JNI_ArrayList::Java_ArrayList_ConstructorJUALI(env)) {}
313 
314 JavaListBuilder::~JavaListBuilder() = default;
315 
add(const JavaRef<jobject> & element)316 void JavaListBuilder::add(const JavaRef<jobject>& element) {
317   JNI_ArrayList::Java_ArrayList_addZ_JUE(env_, j_list_, element);
318 }
319 
JavaMapBuilder(JNIEnv * env)320 JavaMapBuilder::JavaMapBuilder(JNIEnv* env)
321     : env_(env),
322       j_map_(JNI_LinkedHashMap::Java_LinkedHashMap_ConstructorJULIHM(env)) {}
323 
324 JavaMapBuilder::~JavaMapBuilder() = default;
325 
put(const JavaRef<jobject> & key,const JavaRef<jobject> & value)326 void JavaMapBuilder::put(const JavaRef<jobject>& key,
327                          const JavaRef<jobject>& value) {
328   JNI_Map::Java_Map_put(env_, j_map_, key, value);
329 }
330 
NativeToJavaPointer(void * ptr)331 jlong NativeToJavaPointer(void* ptr) {
332   static_assert(sizeof(intptr_t) <= sizeof(jlong),
333                 "Time to rethink the use of jlongs");
334   // Going through intptr_t to be obvious about the definedness of the
335   // conversion from pointer to integral type.  intptr_t to jlong is a standard
336   // widening by the static_assert above.
337   jlong ret = reinterpret_cast<intptr_t>(ptr);
338   RTC_DCHECK(reinterpret_cast<void*>(ret) == ptr);
339   return ret;
340 }
341 
342 // Given a list of jstrings, reinterprets it to a new vector of native strings.
JavaToStdVectorStrings(JNIEnv * jni,const JavaRef<jobject> & list)343 std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni,
344                                                 const JavaRef<jobject>& list) {
345   std::vector<std::string> converted_list;
346   if (!list.is_null()) {
347     for (const JavaRef<jobject>& str : Iterable(jni, list)) {
348       converted_list.push_back(JavaToStdString(
349           jni, JavaParamRef<jstring>(static_cast<jstring>(str.obj()))));
350     }
351   }
352   return converted_list;
353 }
354 
355 }  // namespace webrtc
356