1 use std::sync::Arc;
2 
3 pub use jni::Executor;
4 
5 pub use ndk::native_activity::NativeActivity;
6 
7 pub use jni::{
8     errors::Result as JResult,
9     objects::{JList, JObject, JValue},
10     strings::JavaStr,
11     JNIEnv, JavaVM,
12 };
13 
get_activity() -> &'static NativeActivity14 pub fn get_activity() -> &'static NativeActivity {
15     ndk_glue::native_activity()
16 }
17 
with_attached<F, R>(activity: &NativeActivity, closure: F) -> JResult<R> where F: FnOnce(&JNIEnv, JObject) -> JResult<R>,18 pub fn with_attached<F, R>(activity: &NativeActivity, closure: F) -> JResult<R>
19 where
20     F: FnOnce(&JNIEnv, JObject) -> JResult<R>,
21 {
22     let vm = Arc::new(unsafe { JavaVM::from_raw(activity.vm())? });
23     let activity = activity.activity();
24     Executor::new(vm).with_attached(|env| closure(env, activity.into()))
25 }
26 
call_method_no_args_ret_int_array<'a>( env: &JNIEnv<'a>, subject: JObject, method: &str, ) -> JResult<Vec<i32>>27 pub fn call_method_no_args_ret_int_array<'a>(
28     env: &JNIEnv<'a>,
29     subject: JObject,
30     method: &str,
31 ) -> JResult<Vec<i32>> {
32     let array = env.auto_local(env.call_method(subject, method, "()[I", &[])?.l()?);
33 
34     let raw_array = array.as_obj().into_inner();
35 
36     let length = env.get_array_length(raw_array)?;
37     let mut values = Vec::with_capacity(length as usize);
38 
39     env.get_int_array_region(raw_array, 0, values.as_mut())?;
40 
41     Ok(values)
42 }
43 
call_method_no_args_ret_int<'a>( env: &JNIEnv<'a>, subject: JObject, method: &str, ) -> JResult<i32>44 pub fn call_method_no_args_ret_int<'a>(
45     env: &JNIEnv<'a>,
46     subject: JObject,
47     method: &str,
48 ) -> JResult<i32> {
49     env.call_method(subject, method, "()I", &[])?.i()
50 }
51 
call_method_no_args_ret_bool<'a>( env: &JNIEnv<'a>, subject: JObject, method: &str, ) -> JResult<bool>52 pub fn call_method_no_args_ret_bool<'a>(
53     env: &JNIEnv<'a>,
54     subject: JObject,
55     method: &str,
56 ) -> JResult<bool> {
57     env.call_method(subject, method, "()Z", &[])?.z()
58 }
59 
call_method_no_args_ret_string<'a>( env: &JNIEnv<'a>, subject: JObject, method: &str, ) -> JResult<String>60 pub fn call_method_no_args_ret_string<'a>(
61     env: &JNIEnv<'a>,
62     subject: JObject,
63     method: &str,
64 ) -> JResult<String> {
65     env.get_string(
66         env.call_method(subject, method, "()Ljava/lang/String;", &[])?
67             .l()?
68             .into(),
69     )
70     .map(String::from)
71 }
72 
call_method_no_args_ret_char_sequence<'a>( env: &JNIEnv<'a>, subject: JObject, method: &str, ) -> JResult<String>73 pub fn call_method_no_args_ret_char_sequence<'a>(
74     env: &JNIEnv<'a>,
75     subject: JObject,
76     method: &str,
77 ) -> JResult<String> {
78     env.get_string(
79         env.call_method(
80             env.call_method(subject, method, "()Ljava/lang/CharSequence;", &[])?
81                 .l()?,
82             "toString",
83             "()Ljava/lang/String;",
84             &[],
85         )?
86         .l()?
87         .into(),
88     )
89     .map(String::from)
90 }
91 
call_method_string_arg_ret_bool<'a, S: AsRef<str>>( env: &JNIEnv<'a>, subject: JObject, name: &str, arg: S, ) -> JResult<bool>92 pub fn call_method_string_arg_ret_bool<'a, S: AsRef<str>>(
93     env: &JNIEnv<'a>,
94     subject: JObject,
95     name: &str,
96     arg: S,
97 ) -> JResult<bool> {
98     env.call_method(
99         subject,
100         name,
101         "(Ljava/lang/String;)Z",
102         &[JObject::from(env.new_string(arg)?).into()],
103     )?
104     .z()
105 }
106 
call_method_string_arg_ret_string<'a: 'b, 'b, S: AsRef<str>>( env: &'b JNIEnv<'a>, subject: JObject<'a>, name: &str, arg: S, ) -> JResult<JavaStr<'a, 'b>>107 pub fn call_method_string_arg_ret_string<'a: 'b, 'b, S: AsRef<str>>(
108     env: &'b JNIEnv<'a>,
109     subject: JObject<'a>,
110     name: &str,
111     arg: S,
112 ) -> JResult<JavaStr<'a, 'b>> {
113     env.get_string(
114         env.call_method(
115             subject,
116             name,
117             "(Ljava/lang/String;)Ljava/lang/String;",
118             &[JObject::from(env.new_string(arg)?).into()],
119         )?
120         .l()?
121         .into(),
122     )
123 }
124 
call_method_string_arg_ret_object<'a>( env: &JNIEnv<'a>, subject: JObject<'a>, method: &str, arg: &str, ) -> JResult<JObject<'a>>125 pub fn call_method_string_arg_ret_object<'a>(
126     env: &JNIEnv<'a>,
127     subject: JObject<'a>,
128     method: &str,
129     arg: &str,
130 ) -> JResult<JObject<'a>> {
131     env.call_method(
132         subject,
133         method,
134         "(Ljava/lang/String;)Ljava/lang/Object;",
135         &[JObject::from(env.new_string(arg)?).into()],
136     )?
137     .l()
138 }
139 
get_package_manager<'a>(env: &JNIEnv<'a>, subject: JObject<'a>) -> JResult<JObject<'a>>140 pub fn get_package_manager<'a>(env: &JNIEnv<'a>, subject: JObject<'a>) -> JResult<JObject<'a>> {
141     env.call_method(
142         subject,
143         "getPackageManager",
144         "()Landroid/content/pm/PackageManager;",
145         &[],
146     )?
147     .l()
148 }
149 
has_system_feature<'a>(env: &JNIEnv<'a>, subject: JObject, name: &str) -> JResult<bool>150 pub fn has_system_feature<'a>(env: &JNIEnv<'a>, subject: JObject, name: &str) -> JResult<bool> {
151     call_method_string_arg_ret_bool(env, subject, "hasSystemFeature", name)
152 }
153 
get_system_service<'a>( env: &JNIEnv<'a>, subject: JObject<'a>, name: &str, ) -> JResult<JObject<'a>>154 pub fn get_system_service<'a>(
155     env: &JNIEnv<'a>,
156     subject: JObject<'a>,
157     name: &str,
158 ) -> JResult<JObject<'a>> {
159     call_method_string_arg_ret_object(env, subject, "getSystemService", name)
160 }
161 
get_property<'a: 'b, 'b>( env: &'b JNIEnv<'a>, subject: JObject<'a>, name: &str, ) -> JResult<JavaStr<'a, 'b>>162 pub fn get_property<'a: 'b, 'b>(
163     env: &'b JNIEnv<'a>,
164     subject: JObject<'a>,
165     name: &str,
166 ) -> JResult<JavaStr<'a, 'b>> {
167     call_method_string_arg_ret_string(env, subject, "getProperty", name)
168 }
169 
get_devices<'a: 'b, 'b>( env: &'b JNIEnv<'a>, subject: JObject<'a>, flags: i32, ) -> JResult<JObject<'a>>170 pub fn get_devices<'a: 'b, 'b>(
171     env: &'b JNIEnv<'a>,
172     subject: JObject<'a>,
173     flags: i32,
174 ) -> JResult<JObject<'a>> {
175     env.call_method(
176         subject,
177         "getDevices",
178         "(I)[Landroid/media/AudioDeviceInfo;",
179         &[flags.into()],
180     )?
181     .l()
182 }
183