Ocean
Loading...
Searching...
No Matches
platform/android/Utilities.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_PLATFORM_ANDROID_UTILITIES_H
9#define META_OCEAN_PLATFORM_ANDROID_UTILITIES_H
10
13
14namespace Ocean
15{
16
17namespace Platform
18{
19
20namespace Android
21{
22
23/**
24 * This class implements helper functions for android platforms.
25 * @ingroup platformandroid
26 */
27class OCEAN_PLATFORM_ANDROID_EXPORT Utilities
28{
29 public:
30
31 /**
32 * Checks whether a Java exception is pending on the calling thread, and clears it.
33 * A pending exception makes almost every following JNI call undefined, and it terminates the process in case the thread detaches while the exception is still pending.
34 * An exception must therefore be cleared before the calling thread makes any further JNI call, returns to Java, or ends.
35 * The description of the exception is written to the error log, as Ocean cannot handle a Java exception in any other way.
36 * This function is safe to call at any time, also when no exception is pending.
37 * @param jniEnvironment The JNI environment of the calling thread
38 * @return True, if an exception was pending and has been cleared; False, if no exception was pending
39 */
40 static bool clearPotentialException(JNIEnv& jniEnvironment);
41
42 /**
43 * Returns the class with a given name, and handles a potential exception.
44 * Beware: A thread which has been attached by Ocean has no Java frames on the stack, so that the class is resolved with the bootstrap class loader and an application class cannot be found.
45 * Resolve application classes on a thread which has been called from Java, and keep them as a global reference.
46 * @param jniEnvironment The JNI environment of the calling thread
47 * @param className The name of the class to be returned, e.g., "android/content/Intent", must be valid
48 * @return The requested class, invalid if the class could not be found
49 */
50 static ScopedJClass findClass(JNIEnv& jniEnvironment, const std::string& className);
51
52 /**
53 * Returns the id of a non-static method of a class, and handles a potential exception.
54 * @param jniEnvironment The JNI environment of the calling thread
55 * @param javaClass The class providing the method, must be valid
56 * @param name The name of the method, must be valid
57 * @param signature The signature of the method, e.g., "(Ljava/lang/String;)I", must be valid
58 * @return The id of the method, nullptr if the method does not exist
59 */
60 static jmethodID getMethodId(JNIEnv& jniEnvironment, jclass javaClass, const std::string& name, const std::string& signature);
61
62 /**
63 * Returns the id of a static method of a class, and handles a potential exception.
64 * @param jniEnvironment The JNI environment of the calling thread
65 * @param javaClass The class providing the method, must be valid
66 * @param name The name of the method, must be valid
67 * @param signature The signature of the method, e.g., "(Ljava/lang/String;)I", must be valid
68 * @return The id of the method, nullptr if the method does not exist
69 */
70 static jmethodID getStaticMethodId(JNIEnv& jniEnvironment, jclass javaClass, const std::string& name, const std::string& signature);
71
72 /**
73 * Returns the id of a non-static field of a class, and handles a potential exception.
74 * @param jniEnvironment The JNI environment of the calling thread
75 * @param javaClass The class providing the field, must be valid
76 * @param name The name of the field, must be valid
77 * @param signature The signature of the field, e.g., "Ljava/lang/String;", must be valid
78 * @return The id of the field, nullptr if the field does not exist
79 */
80 static jfieldID getFieldId(JNIEnv& jniEnvironment, jclass javaClass, const std::string& name, const std::string& signature);
81
82 /**
83 * Returns the id of a static field of a class, and handles a potential exception.
84 * @param jniEnvironment The JNI environment of the calling thread
85 * @param javaClass The class providing the field, must be valid
86 * @param name The name of the field, must be valid
87 * @param signature The signature of the field, e.g., "Ljava/lang/String;", must be valid
88 * @return The id of the field, nullptr if the field does not exist
89 */
90 static jfieldID getStaticFieldId(JNIEnv& jniEnvironment, jclass javaClass, const std::string& name, const std::string& signature);
91
92 /**
93 * Calls a non-static Java method returning an object, and handles a potential exception.
94 * @param jniEnvironment The JNI environment of the calling thread
95 * @param object The object on which the method will be called, must be valid
96 * @param methodId The id of the method to be called, must be valid
97 * @param args The arguments of the method, must match the signature of the method
98 * @return The resulting object, invalid if the method has thrown an exception or has returned null
99 * @tparam T The data type of the returned reference, e.g., jobject or jstring
100 * @tparam TArgs The data types of the arguments of the method
101 */
102 template <typename T = jobject, typename... TArgs>
103 static ScopedJNILocalObject<T> callObjectMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, TArgs&&... args);
104
105 /**
106 * Calls a static Java method returning an object, and handles a potential exception.
107 * @param jniEnvironment The JNI environment of the calling thread
108 * @param javaClass The class providing the method, must be valid
109 * @param methodId The id of the method to be called, must be valid
110 * @param args The arguments of the method, must match the signature of the method
111 * @return The resulting object, invalid if the method has thrown an exception or has returned null
112 * @tparam T The data type of the returned reference, e.g., jobject or jstring
113 * @tparam TArgs The data types of the arguments of the method
114 */
115 template <typename T = jobject, typename... TArgs>
116 static ScopedJNILocalObject<T> callStaticObjectMethod(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, TArgs&&... args);
117
118 /**
119 * Creates a new instance of a class, and handles a potential exception.
120 * @param jniEnvironment The JNI environment of the calling thread
121 * @param javaClass The class to be instantiated, must be valid
122 * @param methodId The id of the constructor to be called, must be valid
123 * @param args The arguments of the constructor, must match the signature of the constructor
124 * @return The resulting object, invalid if the constructor has thrown an exception
125 * @tparam T The data type of the returned reference, e.g., jobject or jstring
126 * @tparam TArgs The data types of the arguments of the constructor
127 */
128 template <typename T = jobject, typename... TArgs>
129 static ScopedJNILocalObject<T> newObject(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, TArgs&&... args);
130
131 /**
132 * Calls a non-static Java method without return value, and handles a potential exception.
133 * @param jniEnvironment The JNI environment of the calling thread
134 * @param object The object on which the method will be called, must be valid
135 * @param methodId The id of the method to be called, must be valid
136 * @param args The arguments of the method, must match the signature of the method
137 * @return True, if the method did not throw an exception
138 * @tparam TArgs The data types of the arguments of the method
139 */
140 template <typename... TArgs>
141 static bool callVoidMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, TArgs&&... args);
142
143 /**
144 * Calls a non-static Java method returning a boolean, and handles a potential exception.
145 * The return value is provided as a parameter, as a thrown exception and a returned 'false' cannot be distinguished otherwise.
146 * @param jniEnvironment The JNI environment of the calling thread
147 * @param object The object on which the method will be called, must be valid
148 * @param methodId The id of the method to be called, must be valid
149 * @param returnValue The resulting return value of the method, only valid if this function succeeds
150 * @param args The arguments of the method, must match the signature of the method
151 * @return True, if the method did not throw an exception
152 * @tparam TArgs The data types of the arguments of the method
153 */
154 template <typename... TArgs>
155 static bool callBooleanMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, bool& returnValue, TArgs&&... args);
156
157 /**
158 * Calls a static Java method returning a boolean, and handles a potential exception.
159 * The return value is provided as a parameter, as a thrown exception and a returned 'false' cannot be distinguished otherwise.
160 * @param jniEnvironment The JNI environment of the calling thread
161 * @param javaClass The class providing the method, must be valid
162 * @param methodId The id of the method to be called, must be valid
163 * @param returnValue The resulting return value of the method, only valid if this function succeeds
164 * @param args The arguments of the method, must match the signature of the method
165 * @return True, if the method did not throw an exception
166 * @tparam TArgs The data types of the arguments of the method
167 */
168 template <typename... TArgs>
169 static bool callStaticBooleanMethod(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, bool& returnValue, TArgs&&... args);
170
171 /**
172 * Calls a non-static Java method returning an integer, and handles a potential exception.
173 * The return value is provided as a parameter, as a thrown exception and a returned '0' cannot be distinguished otherwise.
174 * @param jniEnvironment The JNI environment of the calling thread
175 * @param object The object on which the method will be called, must be valid
176 * @param methodId The id of the method to be called, must be valid
177 * @param returnValue The resulting return value of the method, only valid if this function succeeds
178 * @param args The arguments of the method, must match the signature of the method
179 * @return True, if the method did not throw an exception
180 * @tparam TArgs The data types of the arguments of the method
181 */
182 template <typename... TArgs>
183 static bool callIntMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, int32_t& returnValue, TArgs&&... args);
184
185 /**
186 * Calls a static Java method returning an integer, and handles a potential exception.
187 * The return value is provided as a parameter, as a thrown exception and a returned '0' cannot be distinguished otherwise.
188 * @param jniEnvironment The JNI environment of the calling thread
189 * @param javaClass The class providing the method, must be valid
190 * @param methodId The id of the method to be called, must be valid
191 * @param returnValue The resulting return value of the method, only valid if this function succeeds
192 * @param args The arguments of the method, must match the signature of the method
193 * @return True, if the method did not throw an exception
194 * @tparam TArgs The data types of the arguments of the method
195 */
196 template <typename... TArgs>
197 static bool callStaticIntMethod(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, int32_t& returnValue, TArgs&&... args);
198
199 /**
200 * Calls a non-static Java method returning a float, and handles a potential exception.
201 * The return value is provided as a parameter, as a thrown exception and a returned '0' cannot be distinguished otherwise.
202 * @param jniEnvironment The JNI environment of the calling thread
203 * @param object The object on which the method will be called, must be valid
204 * @param methodId The id of the method to be called, must be valid
205 * @param returnValue The resulting return value of the method, only valid if this function succeeds
206 * @param args The arguments of the method, must match the signature of the method
207 * @return True, if the method did not throw an exception
208 * @tparam TArgs The data types of the arguments of the method
209 */
210 template <typename... TArgs>
211 static bool callFloatMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, float& returnValue, TArgs&&... args);
212
213 /**
214 * Converts a Java native string to a std string.
215 * @param env The Java environment, must be valid
216 * @param javaString Java string to be converted, may be nullptr
217 * @return Resulting std string
218 */
219 static std::string toAString(JNIEnv* env, jstring javaString);
220
221 /**
222 * Converts a std string to a Java native string.
223 * @param env The Java environment, must be valid
224 * @param stdString Std string to be converted
225 * @return Resulting Java native string
226 */
227 static jstring toJavaString(JNIEnv* env, const std::string& stdString);
228
229 /**
230 * Converts a vector of std strings to a Java array with native strings.
231 * @param env The Java environment, must be valid
232 * @param strings Std strings to be converted, can be empty
233 * @return Resulting Java native string
234 */
235 static jobjectArray toJavaStringArray(JNIEnv* env, const Strings& strings);
236
237 /**
238 * Converts a Java native list with string to a vector of strings.
239 * @param env The Java environment, must be valid
240 * @param javaStringList Java list with strings to be converted, must be valid
241 * @param strings The resulting vector of strings
242 * @return True, if succeeded
243 */
244 static bool toVector(JNIEnv* env, jobject javaStringList, Strings& strings);
245
246 /**
247 * Converts a Java native list with integer to a vector of integers.
248 * @param env The Java environment, must be valid
249 * @param javaIntegerList Java list with integers to be converted, must be valid
250 * @param values The resulting vector of integers
251 * @return True, if succeeded
252 */
253 static bool toVector(JNIEnv* env, jobject javaIntegerList, std::vector<int>& values);
254
255 /**
256 * Returns the class name of an object.
257 * @param env The Java environment, must be valid
258 * @param object The object for which the class name will be returned, must be valid
259 * @param name The resulting class name
260 * @return True, if succeeded
261 */
262 static bool className(JNIEnv* env, jobject object, std::string& name);
263
264 /**
265 * Returns the version code stored in the application manifest.
266 * @param javaVM The Java virtual machine, must be valid
267 * @param activity The Android main activity, must be valid
268 * @param versionCode The resulting version code of the application
269 * @param versionName The resulting version name of the application
270 * @return True, if succeeded
271 */
272 static bool manifestVersion(JavaVM* javaVM, jobject activity, int& versionCode, std::string& versionName);
273
274 /**
275 * Deprecated.
276 *
277 * Returns the version code stored in the application manifest.
278 * @param javaVM The Java virtual machine, must be valid
279 * @param activity The Android main activity, must be valid
280 * @param versionCode The version code of the application
281 * @return True, if succeeded
282 */
283 static bool manifestVersionCode(JavaVM* javaVM, jobject activity, int& versionCode);
284
285 /**
286 * Returns the minimum and target SDK versions stored in the application manifest.
287 * @param env The Java environment, must be valid
288 * @param activity The Android main activity, must be valid
289 * @param minSdkVersion The resulting minimum SDK version of the application as defined in its manifest
290 * @param targetSdkVersion The resulting target SDK version of the application as defined in its manifest
291 * @return True, if succeeded
292 */
293 static bool manifestSdkVersions(JNIEnv* env, jobject activity, unsigned int& minSdkVersion, unsigned int& targetSdkVersion);
294
295 /**
296 * Return the Android release version of the system (android.os.Build.VERSION.RELEASE).
297 * @param env The Java environment, must be valid
298 * @param version The resulting Android release version, only valid if this function returns 'true'
299 * @return True, if succeeded, otherwise false
300 */
301 static bool androidReleaseVersion(JNIEnv* env, std::string& version);
302
303 /**
304 * Return the Android SDK version of the system (android.os.Build.VERSION.SDK).
305 * @param env The Java environment, must be valid
306 * @param version The resulting Android SDK version, only valid if this function returns 'true'
307 * @return True, if succeeded, otherwise false
308 */
309 static bool androidSdkVersion(JNIEnv* env, unsigned int& version);
310
311 /**
312 * Returns the value of a specific system property.
313 * @param name The name of the system property, must be valid
314 * @param value The resulting value
315 * @return True, if succeeded
316 */
317 static bool systemPropertyValue(const std::string& name, std::string& value);
318
319 /**
320 * Returns the brand string of the device.
321 * @param env The Java environment, must be valid
322 * @param brand The resulting model string
323 * @return True, if succeeded
324 */
325 static bool deviceBrand(JNIEnv* env, std::string& brand);
326
327 /**
328 * Returns the model string of the device.
329 * @param env The Java environment, must be valid
330 * @param model The resulting model string
331 * @return True, if succeeded
332 */
333 static bool deviceModel(JNIEnv* env, std::string& model);
334
335 /**
336 * Returns the serial number of the device.
337 * On Android 8.0 (API 26) and above, access to the serial number is restricted to system apps.
338 * @param serialNumber The resulting device's serial number
339 * @return True, if succeeded
340 */
341 static bool deviceSerialNumber(std::string& serialNumber);
342
343 /**
344 * Returns the name of the package.
345 * @param packageName The resulting package name
346 * @return True, if succeeded
347 */
348 static bool determinePackageName(std::string& packageName);
349
350 /**
351 * Sends an explicit intent to another component or application.
352 * @param env The Java environment, must be valid
353 * @param activity The Android main activity, must be valid
354 * @param packageName The name of the package to which the intent will be sent, must be valid
355 * @param className The name of the class or activity to which the intent will be sent, must be valid
356 * @param extraText The data that will be sent with the intent, must be valid
357 * @return True, if the intent was sent successfully, otherwise false
358 */
359 static bool sendIntentToComponent(JNIEnv* env, jobject activity, const std::string& packageName, const std::string& className, const std::string& extraText);
360
361 /**
362 * Starts an new activity from a root activity.
363 * @param env The Java environment, must be valid
364 * @param rootActivity The root activity from which the new activity will be started, must be valid
365 * @param activityClassName The name of the class of the activity to start, must be valid
366 * @return True, if succeeded
367 */
368 static bool startActivity(JNIEnv* env, jobject rootActivity, const std::string& activityClassName);
369
370 /**
371 * Joins a Wi-Fi network (WPA2-PSK).
372 * This only works with Android SDK version 28 or below.
373 * @param env The Java environment, must be valid
374 * @param activity The root activity from which the new activity will be started, must be valid
375 * @param ssid The Wi-Fi network name (SSID), the network must be using WPA2, must be valid
376 * @param password The Wi-Fi network password, must be valid
377 * @return True, if joined successfully, otherwise false
378 **/
379 static bool connectToWifi(JNIEnv* env, jobject activity, const std::string& ssid, const std::string& password);
380
381 /**
382 * Sends an intent to the OS to request it to join a Wi-Fi network (WPA2-PSK).
383 * The intent is send to the system settings app to save and connect to a new Wi-Fi network. This will display a notification to user to accept or reject the new Wi-Fi network.
384 * Additional notes:
385 * * The Wi-Fi network must use the security protocol WPA2-PSK.
386 * * This function requires Android SDK version 29 or higher.
387 * * This function requires the permissions `android.permission.CHANGE_NETWORK_STATE` and `android.permission.WRITE_SETTINGS` to be set in the app manifest to work.
388 * * Rejecting a new network does NOT revoke the permission `android.permission.CHANGE_NETWORK_STATE` again. Re-tries are possible.
389 * * The newly added networks do NOT have to reachable at the time of adding them (they will be stored for when they become available).
390 * * The system app receiving the intent sent here must implement a handler for the action type `Settings.ACTION_WIFI_ADD_NETWORKS`. Otherwise this function will have no effect (and still return `true`).
391 * @param env The Java environment, must be valid
392 * @param activity The root activity from which the new activity will be started, must be valid
393 * @param ssid The Wi-Fi network name (SSID), the network must be using WPA2, must be valid
394 * @param password The Wi-Fi network password, must be valid
395 * @return True, if the intent was sent successfully, otherwise false
396 **/
397 static bool sendIntentToConnectToWifi(JNIEnv* env, jobject activity, const std::string& ssid, const std::string& password);
398
399 /**
400 * Returns current Wi-Fi network name (SSID).
401 * @param env The Java environment, must be valid
402 * @param activity The root activity from which the new activity will be started, must be valid
403 * @param ssid The resulting Wi-Fi network name (SSID), will be empty if there is no Wi-Fi connection
404 * @return True, if succeeded
405 */
406 static bool currentWifiSsid(JNIEnv* env, jobject activity, std::string& ssid);
407
408 /**
409 * Triggers a vibration.
410 * This function needs permission 'android.permission.VIBRATE'.
411 * @param env The Java environment, must be valid
412 * @param activity The root activity from which the new activity will be started, must be valid
413 * @param intensity The intensity of the vibration, the higher the stronger, with range [0, 2]
414 * @param duration The duration of the vibration in milliseconds, with range [1, infinity)
415 * @return True, if succeeded
416 */
417 static bool triggerVibration(JNIEnv* env, jobject activity, unsigned int intensity = 1u, const unsigned int duration = 50u);
418
419 /**
420 * Returns the refresh rate of the display in Hz.
421 * On Android 30 (API 30) and above, uses Activity.getDisplay().
422 * On older versions, uses WindowManager.getDefaultDisplay().
423 * @param env The Java environment, must be valid
424 * @param activity The Android main activity, must be valid
425 * @param refreshRateHz The resulting refresh rate in Hz, will be 0 if the display could not be determined
426 * @return True, if succeeded
427 */
428 static bool displayRefreshRate(JNIEnv* env, jobject activity, float& refreshRateHz);
429
430 protected:
431
432 /**
433 * Returns whether all given data types can be handed to a JNI function call with variable arguments.
434 * A JNI argument is either a reference like jobject or jstring, or a primitive like jint or jboolean, as any other type would be pushed onto the variable argument list of the runtime.
435 * Beware: This does not verify that the arguments match the signature of the Java method, e.g., an jint handed to a method expecting a jlong is still wrong.
436 * @return True, if so
437 * @tparam TArgs The data types to be checked, can be empty
438 */
439 template <typename... TArgs>
440 static constexpr bool isValidArgumentTypes();
441};
442
443template <typename... TArgs>
445{
446 return ((std::is_pointer<typename std::decay<TArgs>::type>::value || std::is_arithmetic<typename std::decay<TArgs>::type>::value) && ...);
447}
448
449template <typename T, typename... TArgs>
450ScopedJNILocalObject<T> Utilities::callObjectMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, TArgs&&... args)
451{
452 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
453
454 ocean_assert(object != nullptr);
455 ocean_assert(methodId != nullptr);
456
457 ScopedJNILocalObject<T> result(jniEnvironment, T(jniEnvironment.CallObjectMethod(object, methodId, std::forward<TArgs>(args)...)));
458
459 if (clearPotentialException(jniEnvironment))
460 {
461 // the return value is undefined in case the method has thrown an exception
462
464 }
465
466 return result;
467}
468
469template <typename T, typename... TArgs>
470ScopedJNILocalObject<T> Utilities::callStaticObjectMethod(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, TArgs&&... args)
471{
472 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
473
474 ocean_assert(javaClass != nullptr);
475 ocean_assert(methodId != nullptr);
476
477 ScopedJNILocalObject<T> result(jniEnvironment, T(jniEnvironment.CallStaticObjectMethod(javaClass, methodId, std::forward<TArgs>(args)...)));
478
479 if (clearPotentialException(jniEnvironment))
480 {
482 }
483
484 return result;
485}
486
487template <typename T, typename... TArgs>
488ScopedJNILocalObject<T> Utilities::newObject(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, TArgs&&... args)
489{
490 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
491
492 ocean_assert(javaClass != nullptr);
493 ocean_assert(methodId != nullptr);
494
495 ScopedJNILocalObject<T> result(jniEnvironment, T(jniEnvironment.NewObject(javaClass, methodId, std::forward<TArgs>(args)...)));
496
497 if (clearPotentialException(jniEnvironment))
498 {
500 }
501
502 return result;
503}
504
505template <typename... TArgs>
506bool Utilities::callVoidMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, TArgs&&... args)
507{
508 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
509
510 ocean_assert(object != nullptr);
511 ocean_assert(methodId != nullptr);
512
513 jniEnvironment.CallVoidMethod(object, methodId, std::forward<TArgs>(args)...);
514
515 return !clearPotentialException(jniEnvironment);
516}
517
518template <typename... TArgs>
519bool Utilities::callBooleanMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, bool& returnValue, TArgs&&... args)
520{
521 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
522
523 ocean_assert(object != nullptr);
524 ocean_assert(methodId != nullptr);
525
526 const jboolean result = jniEnvironment.CallBooleanMethod(object, methodId, std::forward<TArgs>(args)...);
527
528 if (clearPotentialException(jniEnvironment))
529 {
530 return false;
531 }
532
533 returnValue = result == JNI_TRUE;
534
535 return true;
536}
537
538template <typename... TArgs>
539bool Utilities::callStaticBooleanMethod(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, bool& returnValue, TArgs&&... args)
540{
541 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
542
543 ocean_assert(javaClass != nullptr);
544 ocean_assert(methodId != nullptr);
545
546 const jboolean result = jniEnvironment.CallStaticBooleanMethod(javaClass, methodId, std::forward<TArgs>(args)...);
547
548 if (clearPotentialException(jniEnvironment))
549 {
550 return false;
551 }
552
553 returnValue = result == JNI_TRUE;
554
555 return true;
556}
557
558template <typename... TArgs>
559bool Utilities::callIntMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, int32_t& returnValue, TArgs&&... args)
560{
561 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
562
563 ocean_assert(object != nullptr);
564 ocean_assert(methodId != nullptr);
565
566 const jint result = jniEnvironment.CallIntMethod(object, methodId, std::forward<TArgs>(args)...);
567
568 if (clearPotentialException(jniEnvironment))
569 {
570 return false;
571 }
572
573 returnValue = int32_t(result);
574
575 return true;
576}
577
578template <typename... TArgs>
579bool Utilities::callStaticIntMethod(JNIEnv& jniEnvironment, jclass javaClass, jmethodID methodId, int32_t& returnValue, TArgs&&... args)
580{
581 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
582
583 ocean_assert(javaClass != nullptr);
584 ocean_assert(methodId != nullptr);
585
586 const jint result = jniEnvironment.CallStaticIntMethod(javaClass, methodId, std::forward<TArgs>(args)...);
587
588 if (clearPotentialException(jniEnvironment))
589 {
590 return false;
591 }
592
593 returnValue = int32_t(result);
594
595 return true;
596}
597
598template <typename... TArgs>
599bool Utilities::callFloatMethod(JNIEnv& jniEnvironment, jobject object, jmethodID methodId, float& returnValue, TArgs&&... args)
600{
601 static_assert(isValidArgumentTypes<TArgs...>(), "A JNI argument must be a JNI reference or a JNI primitive!");
602
603 ocean_assert(object != nullptr);
604 ocean_assert(methodId != nullptr);
605
606 const jfloat result = jniEnvironment.CallFloatMethod(object, methodId, std::forward<TArgs>(args)...);
607
608 if (clearPotentialException(jniEnvironment))
609 {
610 return false;
611 }
612
613 returnValue = float(result);
614
615 return true;
616}
617
618}
619
620}
621
622}
623
624#endif // META_OCEAN_PLATFORM_ANDROID_UTILITIES_H
This class implements a scoped local reference to a JNI object.
Definition ScopedJNILocalObject.h:107
This class implements helper functions for android platforms.
Definition platform/android/Utilities.h:28
static jfieldID getFieldId(JNIEnv &jniEnvironment, jclass javaClass, const std::string &name, const std::string &signature)
Returns the id of a non-static field of a class, and handles a potential exception.
static bool callStaticIntMethod(JNIEnv &jniEnvironment, jclass javaClass, jmethodID methodId, int32_t &returnValue, TArgs &&... args)
Calls a static Java method returning an integer, and handles a potential exception.
Definition platform/android/Utilities.h:579
static bool deviceModel(JNIEnv *env, std::string &model)
Returns the model string of the device.
static bool manifestSdkVersions(JNIEnv *env, jobject activity, unsigned int &minSdkVersion, unsigned int &targetSdkVersion)
Returns the minimum and target SDK versions stored in the application manifest.
static bool displayRefreshRate(JNIEnv *env, jobject activity, float &refreshRateHz)
Returns the refresh rate of the display in Hz.
static bool deviceSerialNumber(std::string &serialNumber)
Returns the serial number of the device.
static bool sendIntentToConnectToWifi(JNIEnv *env, jobject activity, const std::string &ssid, const std::string &password)
Sends an intent to the OS to request it to join a Wi-Fi network (WPA2-PSK).
static bool manifestVersionCode(JavaVM *javaVM, jobject activity, int &versionCode)
Deprecated.
static bool determinePackageName(std::string &packageName)
Returns the name of the package.
static bool deviceBrand(JNIEnv *env, std::string &brand)
Returns the brand string of the device.
static constexpr bool isValidArgumentTypes()
Returns whether all given data types can be handed to a JNI function call with variable arguments.
Definition platform/android/Utilities.h:444
static bool androidReleaseVersion(JNIEnv *env, std::string &version)
Return the Android release version of the system (android.os.Build.VERSION.RELEASE).
static bool callIntMethod(JNIEnv &jniEnvironment, jobject object, jmethodID methodId, int32_t &returnValue, TArgs &&... args)
Calls a non-static Java method returning an integer, and handles a potential exception.
Definition platform/android/Utilities.h:559
static bool callBooleanMethod(JNIEnv &jniEnvironment, jobject object, jmethodID methodId, bool &returnValue, TArgs &&... args)
Calls a non-static Java method returning a boolean, and handles a potential exception.
Definition platform/android/Utilities.h:519
static ScopedJNILocalObject< T > callObjectMethod(JNIEnv &jniEnvironment, jobject object, jmethodID methodId, TArgs &&... args)
Calls a non-static Java method returning an object, and handles a potential exception.
Definition platform/android/Utilities.h:450
static bool sendIntentToComponent(JNIEnv *env, jobject activity, const std::string &packageName, const std::string &className, const std::string &extraText)
Sends an explicit intent to another component or application.
static bool manifestVersion(JavaVM *javaVM, jobject activity, int &versionCode, std::string &versionName)
Returns the version code stored in the application manifest.
static bool androidSdkVersion(JNIEnv *env, unsigned int &version)
Return the Android SDK version of the system (android.os.Build.VERSION.SDK).
static jmethodID getMethodId(JNIEnv &jniEnvironment, jclass javaClass, const std::string &name, const std::string &signature)
Returns the id of a non-static method of a class, and handles a potential exception.
static ScopedJNILocalObject< T > callStaticObjectMethod(JNIEnv &jniEnvironment, jclass javaClass, jmethodID methodId, TArgs &&... args)
Calls a static Java method returning an object, and handles a potential exception.
Definition platform/android/Utilities.h:470
static ScopedJClass findClass(JNIEnv &jniEnvironment, const std::string &className)
Returns the class with a given name, and handles a potential exception.
static bool clearPotentialException(JNIEnv &jniEnvironment)
Checks whether a Java exception is pending on the calling thread, and clears it.
static bool startActivity(JNIEnv *env, jobject rootActivity, const std::string &activityClassName)
Starts an new activity from a root activity.
static bool toVector(JNIEnv *env, jobject javaIntegerList, std::vector< int > &values)
Converts a Java native list with integer to a vector of integers.
static bool connectToWifi(JNIEnv *env, jobject activity, const std::string &ssid, const std::string &password)
Joins a Wi-Fi network (WPA2-PSK).
static bool callFloatMethod(JNIEnv &jniEnvironment, jobject object, jmethodID methodId, float &returnValue, TArgs &&... args)
Calls a non-static Java method returning a float, and handles a potential exception.
Definition platform/android/Utilities.h:599
static bool callStaticBooleanMethod(JNIEnv &jniEnvironment, jclass javaClass, jmethodID methodId, bool &returnValue, TArgs &&... args)
Calls a static Java method returning a boolean, and handles a potential exception.
Definition platform/android/Utilities.h:539
static jmethodID getStaticMethodId(JNIEnv &jniEnvironment, jclass javaClass, const std::string &name, const std::string &signature)
Returns the id of a static method of a class, and handles a potential exception.
static ScopedJNILocalObject< T > newObject(JNIEnv &jniEnvironment, jclass javaClass, jmethodID methodId, TArgs &&... args)
Creates a new instance of a class, and handles a potential exception.
Definition platform/android/Utilities.h:488
static bool callVoidMethod(JNIEnv &jniEnvironment, jobject object, jmethodID methodId, TArgs &&... args)
Calls a non-static Java method without return value, and handles a potential exception.
Definition platform/android/Utilities.h:506
static bool toVector(JNIEnv *env, jobject javaStringList, Strings &strings)
Converts a Java native list with string to a vector of strings.
static bool currentWifiSsid(JNIEnv *env, jobject activity, std::string &ssid)
Returns current Wi-Fi network name (SSID).
static jstring toJavaString(JNIEnv *env, const std::string &stdString)
Converts a std string to a Java native string.
static bool triggerVibration(JNIEnv *env, jobject activity, unsigned int intensity=1u, const unsigned int duration=50u)
Triggers a vibration.
static bool className(JNIEnv *env, jobject object, std::string &name)
Returns the class name of an object.
static jfieldID getStaticFieldId(JNIEnv &jniEnvironment, jclass javaClass, const std::string &name, const std::string &signature)
Returns the id of a static field of a class, and handles a potential exception.
static bool systemPropertyValue(const std::string &name, std::string &value)
Returns the value of a specific system property.
static jobjectArray toJavaStringArray(JNIEnv *env, const Strings &strings)
Converts a vector of std strings to a Java array with native strings.
static std::string toAString(JNIEnv *env, jstring javaString)
Converts a Java native string to a std string.
std::vector< std::string > Strings
Definition of a vector holding strings.
Definition Base.h:162
The namespace covering the entire Ocean framework.
Definition Accessor.h:15