@@ -179,21 +179,28 @@ pub extern "system" fn Java_com_shoesproxy_ShoesNative_start<'local>(
179179 _class : JClass < ' local > ,
180180 config_yaml : JString < ' local > ,
181181 protect_callback : JObject < ' local > ,
182+ traffic_callback : JObject < ' local > ,
182183) -> jlong {
183184 info ! ( "Starting shoes service" ) ;
184185
185186 let result = unowned
186187 . with_env (
187- |env| -> jni:: errors:: Result < ( String , Global < JObject < ' static > > , jni:: JavaVM ) > {
188+ |env| -> jni:: errors:: Result < (
189+ String ,
190+ Global < JObject < ' static > > ,
191+ Global < JObject < ' static > > ,
192+ jni:: JavaVM ,
193+ ) > {
188194 let config_str: String = env. get_string ( & config_yaml) . map ( |s| s. to_string ( ) ) ?;
189- let callback_ref = env. new_global_ref ( protect_callback) ?;
195+ let protect_ref = env. new_global_ref ( protect_callback) ?;
196+ let traffic_ref = env. new_global_ref ( traffic_callback) ?;
190197 let jvm = env. get_java_vm ( ) ?;
191- Ok ( ( config_str, callback_ref , jvm) )
198+ Ok ( ( config_str, protect_ref , traffic_ref , jvm) )
192199 } ,
193200 )
194201 . into_outcome ( ) ;
195202
196- let ( config_str, callback_ref , jvm) = match result {
203+ let ( config_str, protect_ref , traffic_ref , jvm) = match result {
197204 Outcome :: Ok ( v) => v,
198205 Outcome :: Err ( e) => {
199206 error ! ( "Failed to extract JNI values for start: {}" , e) ;
@@ -204,15 +211,15 @@ pub extern "system" fn Java_com_shoesproxy_ShoesNative_start<'local>(
204211 let jvm: Arc < jni:: JavaVM > = Arc :: new ( jvm) ;
205212
206213 // Socket protector calls VpnService.protect() to exempt sockets from VPN routing
207- let callback_ref : Arc < Global < JObject < ' static > > > = Arc :: new ( callback_ref ) ;
214+ let protect_ref : Arc < Global < JObject < ' static > > > = Arc :: new ( protect_ref ) ;
208215 let jvm_clone = jvm. clone ( ) ;
209- let callback_clone = callback_ref . clone ( ) ;
216+ let protect_clone = protect_ref . clone ( ) ;
210217
211218 let protector = FnSocketProtector :: new ( move |fd : i32 | {
212219 let protect_ok = jvm_clone
213220 . attach_current_thread ( |env : & mut jni:: Env | -> jni:: errors:: Result < bool > {
214221 let v = env. call_method (
215- & * callback_clone ,
222+ & * protect_clone ,
216223 jni:: jni_str!( "protect" ) ,
217224 jni:: jni_sig!( "(I)Z" ) ,
218225 & [ JValue :: Int ( fd) ] ,
@@ -233,6 +240,23 @@ pub extern "system" fn Java_com_shoesproxy_ShoesNative_start<'local>(
233240
234241 set_global_socket_protector ( Arc :: new ( protector) ) ;
235242
243+ // Traffic callback calls TrafficListener.onTrafficUpdate(long, long)
244+ let traffic_ref: Arc < Global < JObject < ' static > > > = Arc :: new ( traffic_ref) ;
245+ let jvm_traffic = jvm. clone ( ) ;
246+ crate :: tun:: traffic:: reset_traffic_counters ( ) ;
247+ crate :: tun:: traffic:: set_traffic_callback ( Arc :: new ( move |upload : u64 , download : u64 | {
248+ let _ =
249+ jvm_traffic. attach_current_thread ( |env : & mut jni:: Env | -> jni:: errors:: Result < ( ) > {
250+ env. call_method (
251+ & * traffic_ref,
252+ jni:: jni_str!( "onTrafficUpdate" ) ,
253+ jni:: jni_sig!( "(JJ)V" ) ,
254+ & [ JValue :: Long ( upload as i64 ) , JValue :: Long ( download as i64 ) ] ,
255+ ) ?;
256+ Ok ( ( ) )
257+ } ) ;
258+ } ) ) ;
259+
236260 let runtime = match Runtime :: new ( ) {
237261 Ok ( rt) => rt,
238262 Err ( e) => {
@@ -282,6 +306,7 @@ pub extern "system" fn Java_com_shoesproxy_ShoesNative_stop(
282306 _handle : jlong ,
283307) {
284308 common:: stop_service ( ) ;
309+ crate :: tun:: traffic:: clear_traffic_callback ( ) ;
285310}
286311
287312/// Check if the TUN service is running.
0 commit comments