@@ -20,18 +20,14 @@ macro_rules! logging {
2020}
2121
2222macro_rules! try_jvm {
23- ( $env: expr, |$jenv: ident| $codes: block) => { {
24- let mut $jenv = unsafe { JNIEnv :: from_raw( $env) } . unwrap( ) ;
25-
23+ ( $( $tokens: tt) * ) => { {
2624 match std:: panic:: catch_unwind( std:: panic:: AssertUnwindSafe ( || {
27- #[ allow( unused_variables) ]
28- let $jenv = & mut $jenv;
29- $codes
25+ $( $tokens) *
3026 } ) ) {
3127 Ok ( val) => val,
3228 Err ( e) => {
33- let _ = $ jenv. exception_clear( ) ;
34- $ jenv. throw( ( "java/lang/RuntimeException" , format!( "Terracotta panics: {:?}" , e) ) ) . unwrap( ) ;
29+ let _ = jenv. exception_clear( ) ;
30+ jenv. throw( ( "java/lang/RuntimeException" , format!( "Terracotta panics: {:?}" , e) ) ) . unwrap( ) ;
3531 unsafe { std:: mem:: zeroed( ) }
3632 }
3733 }
@@ -43,8 +39,11 @@ use crate::once_cell::OnceCell;
4339use chrono:: { FixedOffset , TimeZone , Utc } ;
4440use jni:: objects:: JClass ;
4541use jni:: signature:: { Primitive , ReturnType } ;
46- use jni:: sys:: { jclass, jlong, jshort, jsize, jstring, jvalue, JavaVM } ;
47- use jni:: { objects:: JString , sys:: { jboolean, jint, JNI_FALSE , JNI_TRUE } , JNIEnv } ;
42+ use jni:: {
43+ objects:: JString ,
44+ sys:: { jclass, jlong, jshort, jsize, jstring, jvalue, jboolean, jint, JNI_FALSE , JNI_TRUE } ,
45+ JNIEnv , JavaVM
46+ } ;
4847use libc:: { c_char, c_int} ;
4948use std:: fs:: File ;
5049use std:: io:: Write ;
@@ -55,6 +54,8 @@ use std::time::Duration;
5554use std:: {
5655 env, ffi:: CString , net:: { IpAddr , Ipv4Addr , Ipv6Addr } , sync:: { Arc , Mutex } , thread,
5756} ;
57+ use std:: ffi:: c_void;
58+ use jni:: sys:: JNI_VERSION_1_8 ;
5859
5960pub mod controller;
6061mod easytier;
@@ -65,8 +66,6 @@ mod mc;
6566mod ports;
6667mod once_cell;
6768
68- type JNIRawEnv = * mut jni:: sys:: JNIEnv ;
69-
7069lazy_static:: lazy_static! {
7170 static ref ADDRESSES : Vec <IpAddr > = {
7271 let mut addresses: Vec <IpAddr > = vec![ ] ;
@@ -103,17 +102,23 @@ static MACHINE_ID_FILE: OnceCell<std::path::PathBuf> = OnceCell::new();
103102static LOGGING_FD : Mutex < Option < std:: fs:: File > > = Mutex :: new ( None ) ;
104103static VPN_SERVICE_CFG : Mutex < Option < crate :: easytier:: EasyTierTunRequest > > = Mutex :: new ( None ) ;
105104
106- // FIXME: Third-party crate 'jni-sys' leaves a dynamic link to JNI_GetCreatedJavaVMs,
107- // which doesn't exist on Android, so A dummy JNI_GetCreatedJavaVMs is declared as a workaround.
105+ // FIXME: Third-party crate 'jni-sys' leaves a dynamic link to JNI_GetCreatedJavaVMs which doesn't exist on Android.
106+ // A dummy JNI_GetCreatedJavaVMs is declared as a workaround to prevent fatal errors while linking .
108107#[ unsafe( no_mangle) ]
109108#[ allow( non_snake_case) ]
110- extern "system" fn JNI_GetCreatedJavaVMs ( _: * mut * mut JavaVM , _: jsize , _: * mut jsize ) -> jint {
109+ extern "system" fn JNI_GetCreatedJavaVMs ( _: * mut c_void , _: jsize , _: * mut c_void ) -> jint {
111110 unreachable ! ( ) ;
112111}
113112
114113#[ unsafe( no_mangle) ]
115114#[ allow( non_snake_case) ]
116- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_start0 ( env : JNIRawEnv , clazz : jclass , dir : jstring , logging_fd : jint ) -> jint {
115+ extern "system" fn JNI_OnLoad ( vm : JavaVM , _: * mut c_void ) -> jint {
116+ JNI_VERSION_1_8
117+ }
118+
119+ #[ unsafe( no_mangle) ]
120+ #[ allow( non_snake_case) ]
121+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_start0 ( jenv : & JNIEnv , clazz : jclass , dir : jstring , logging_fd : jint ) -> jint {
117122 std:: panic:: set_backtrace_style ( std:: panic:: BacktraceStyle :: Full ) ;
118123 std:: panic:: update_hook ( |prev, info| {
119124 let data = Arc :: new ( Mutex :: new ( Vec :: < u8 > :: new ( ) ) ) ;
@@ -143,7 +148,6 @@ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_start0(en
143148 env!( "CARGO_CFG_TARGET_ENV" ) ,
144149 ) ;
145150
146- let jenv = unsafe { JNIEnv :: from_raw ( env) } . unwrap ( ) ;
147151 let jvm = jenv. get_java_vm ( ) . unwrap ( ) ;
148152 let clazz = jenv. new_global_ref ( unsafe { JClass :: from_raw ( clazz) } ) . unwrap ( ) ;
149153
@@ -226,34 +230,34 @@ fn logging_android(line: String) {
226230
227231#[ unsafe( no_mangle) ]
228232#[ allow( non_snake_case) ]
229- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_getState0 ( env : JNIRawEnv , _: jclass ) -> jstring {
230- try_jvm ! ( env , |jenv| {
233+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_getState0 ( jenv : & JNIEnv , _: jclass ) -> jstring {
234+ try_jvm ! {
231235 jenv. new_string( serde_json:: to_string( & controller:: get_state( ) ) . unwrap( ) ) . unwrap( ) . into_raw( )
232- } )
236+ }
233237}
234238
235239#[ unsafe( no_mangle) ]
236240#[ allow( non_snake_case) ]
237- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setWaiting0 ( env : JNIRawEnv , _: jclass ) {
238- try_jvm ! ( env , |jenv| {
241+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setWaiting0 ( jenv : & JNIEnv , _: jclass ) {
242+ try_jvm ! {
239243 controller:: set_waiting( )
240- } )
244+ }
241245}
242246
243247#[ unsafe( no_mangle) ]
244248#[ allow( non_snake_case) ]
245- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setScanning0 ( env : JNIRawEnv , _: jclass , room : jstring , player : jstring ) {
246- try_jvm ! ( env , |jenv| {
249+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setScanning0 ( jenv : & JNIEnv , _: jclass , room : jstring , player : jstring ) {
250+ try_jvm ! {
247251 let room = parse_jstring( jenv, room) ;
248252 let player = parse_jstring( jenv, player) ;
249253 controller:: set_scanning( room, player) ;
250- } )
254+ }
251255}
252256
253257#[ unsafe( no_mangle) ]
254258#[ allow( non_snake_case) ]
255- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setGuesting0 ( env : JNIRawEnv , _: jclass , room : jstring , player : jstring ) -> jboolean {
256- try_jvm ! ( env , |jenv| {
259+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setGuesting0 ( jenv : & JNIEnv , _: jclass , room : jstring , player : jstring ) -> jboolean {
260+ try_jvm ! {
257261 let room = parse_jstring( jenv, room) . expect( "'room' must not be NULL." ) ;
258262 let player = parse_jstring( jenv, player) ;
259263
@@ -262,13 +266,13 @@ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_setGuesti
262266 } else {
263267 JNI_FALSE
264268 }
265- } )
269+ }
266270}
267271
268272#[ unsafe( no_mangle) ]
269273#[ allow( non_snake_case) ]
270- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_verifyRoomCode0 ( env : JNIRawEnv , _: jclass , room : jstring ) -> jint {
271- try_jvm ! ( env , |jenv| {
274+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_verifyRoomCode0 ( jenv : & JNIEnv , _: jclass , room : jstring ) -> jint {
275+ try_jvm ! {
272276 let room = parse_jstring( jenv, room) . expect( "'room' must not be NULL." ) ;
273277
274278 match Room :: from( & room) {
@@ -279,23 +283,23 @@ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_verifyRoo
279283 } ,
280284 None => -1
281285 }
282- } )
286+ }
283287}
284288
285289#[ unsafe( no_mangle) ]
286290#[ allow( non_snake_case) ]
287- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_getMetadata0 ( env : JNIRawEnv , _: jclass ) -> jstring {
288- try_jvm ! ( env , |jenv| {
291+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_getMetadata0 ( jenv : & JNIEnv , _: jclass ) -> jstring {
292+ try_jvm ! {
289293 jenv. new_string( format!(
290294 "{}\0 {}\0 {}" , env!( "TERRACOTTA_VERSION" ) , timestamp:: compile_time!( ) as i64 , env!( "TERRACOTTA_ET_VERSION" )
291295 ) ) . unwrap( ) . into_raw( )
292- } )
296+ }
293297}
294298
295299#[ unsafe( no_mangle) ]
296300#[ allow( non_snake_case) ]
297- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_prepareExportLogs0 ( env : JNIRawEnv , _: jclass ) -> jlong {
298- try_jvm ! ( env , |jenv| {
301+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_prepareExportLogs0 ( jenv : & JNIEnv , _: jclass ) -> jlong {
302+ try_jvm ! {
299303 let mut logging = LOGGING_FD . lock( ) . unwrap( ) ;
300304
301305 if let Some ( file) = logging. as_mut( ) {
@@ -305,33 +309,33 @@ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_prepareEx
305309 } else {
306310 0
307311 }
308- } )
312+ }
309313}
310314
311315#[ unsafe( no_mangle) ]
312316#[ allow( non_snake_case) ]
313- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_finishExportLogs0 ( env : JNIRawEnv , _: jclass , ptr : jlong ) {
314- try_jvm ! ( env , |jenv| {
317+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_finishExportLogs0 ( jenv : & JNIEnv , _: jclass , ptr : jlong ) {
318+ try_jvm ! {
315319 unsafe {
316320 let _ = Box :: from_raw( ptr as * mut MutexGuard <Option <File >>) ;
317321 }
318- } )
322+ }
319323}
320324
321325#[ unsafe( no_mangle) ]
322326#[ allow( non_snake_case) ]
323- extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_panic0 ( env : JNIRawEnv , _: jclass ) {
324- try_jvm ! ( env , |jenv| {
327+ extern "system" fn Java_net_burningtnt_terracotta_TerracottaAndroidAPI_panic0 ( jenv : & JNIEnv , _: jclass ) {
328+ try_jvm ! {
325329 panic!( "User triggered panic manually." ) ;
326- } )
330+ }
327331}
328332
329333pub ( crate ) fn on_vpnservice_change ( request : crate :: easytier:: EasyTierTunRequest ) {
330334 let mut guard = VPN_SERVICE_CFG . lock ( ) . unwrap ( ) ;
331335 * guard = Some ( request) ;
332336}
333337
334- fn parse_jstring ( env : & JNIEnv < ' static > , value : jstring ) -> Option < String > {
338+ fn parse_jstring ( env : & JNIEnv , value : jstring ) -> Option < String > {
335339 if value. is_null ( ) {
336340 None
337341 } else {
0 commit comments