11use crate :: impls:: apk_load:: read_apk;
2+ use crate :: impls:: server:: { FileOpenContext , ServerMessage } ;
3+ use crate :: impls:: util:: new_tokio_thread;
24use crate :: ui:: { AppContainer , DirInfo , Left } ;
35use crate :: { Accessor , AccessorEnum , AccessorMut , AsmServer , LoadingState , ServerMut } ;
46use java_asm:: smali:: SmaliNode ;
@@ -7,9 +9,10 @@ use log::{error, info};
79use std:: fs:: File ;
810use std:: io:: { Read , Seek } ;
911use std:: ops:: { Deref , DerefMut } ;
10- use std:: sync:: { Arc , Mutex } ;
12+ use std:: sync:: Arc ;
1113use std:: time:: Instant ;
12- use tokio:: runtime;
14+ use tokio:: sync:: mpsc;
15+ use tokio:: sync:: mpsc:: Sender ;
1316use zip:: result:: ZipError ;
1417use zip:: ZipArchive ;
1518
@@ -28,53 +31,61 @@ impl AsmServer {
2831
2932 pub fn smart_open ( server : ServerMut , path : & str , render_target : AppContainer ) {
3033 let context = FileOpenContext { path : path. to_string ( ) , start_time : Instant :: now ( ) } ;
31- std:: thread:: spawn ( move || {
32- let tokio_runtime = runtime:: Builder :: new_multi_thread ( )
33- . enable_all ( ) . build ( ) . unwrap ( ) ;
34- tokio_runtime. block_on ( async move {
35- let new_server = AsmServer :: new ( ) ;
36- let path = & context. path ;
37- let accessor = new_server. accessor . clone ( ) ;
38- if path. ends_with ( ".apk" ) {
39- let opened_file = File :: open ( path) ;
40- match opened_file {
41- Ok ( opened_file) => {
42- let read_result = Self :: from_apk ( opened_file, accessor) ;
43- if let Err ( e) = read_result {
44- error ! ( "resolve file meets an error. {e:?}" ) ;
45- }
34+ new_tokio_thread ( |runtime| async move {
35+ let ( sender, receiver) = mpsc:: channel :: < ServerMessage > ( 5 ) ;
36+
37+ let new_server = AsmServer :: new ( ) ;
38+ * server. lock ( ) = Some ( new_server. clone ( ) ) ;
39+
40+ let server_for_receiver = server. clone ( ) ;
41+ runtime. spawn ( async move {
42+ let server = server_for_receiver;
43+ let mut receiver = receiver;
44+ while let Some ( msg) = receiver. recv ( ) . await {
45+ let mut server = server. lock ( ) ;
46+ let server_ref = server. deref_mut ( ) ;
47+ let Some ( server_ref) = server_ref else { continue } ;
48+ match msg {
49+ ServerMessage :: Progress ( progress) => {
50+ println ! ( "progress: {}" , progress. progress) ;
51+ server_ref. loading_state . loading_progress = progress. progress ;
52+ server_ref. loading_state . in_loading = progress. in_loading ;
4653 }
47- Err ( e) => {
48- let error = OpenFileError :: Io ( e) ;
49- error ! ( "read {path} meet an io error. {error:?}" ) ;
54+ }
55+ }
56+ } ) ;
57+
58+ let path = & context. path ;
59+ let accessor = new_server. accessor . clone ( ) ;
60+ if path. ends_with ( ".apk" ) {
61+ let opened_file = File :: open ( path) ;
62+ match opened_file {
63+ Ok ( opened_file) => {
64+ let read_result = Self :: from_apk ( opened_file, sender, accessor) . await ;
65+ if let Err ( e) = read_result {
66+ error ! ( "resolve file meets an error. {e:?}" ) ;
5067 }
5168 }
52- } else {
53- error ! ( "unsupported file type: {:?}" , path) ;
54- } ;
55- * server. lock ( ) = Some ( new_server. clone ( ) ) ;
56- new_server. on_file_opened ( & context, render_target) ;
57- } )
69+ Err ( e) => {
70+ let error = OpenFileError :: Io ( e) ;
71+ error ! ( "read {path} meet an io error. {error:?}" ) ;
72+ }
73+ }
74+ } else {
75+ error ! ( "unsupported file type: {:?}" , path) ;
76+ } ;
77+ new_server. on_file_opened ( & context, render_target) ;
5878 } ) ;
5979 }
6080
61- fn on_file_opened (
62- & self ,
63- context : & FileOpenContext ,
64- render_target : AppContainer ,
65- ) {
66- let FileOpenContext { path, start_time } = context;
67- info ! ( "open file {path} cost: {:?}" , start_time. elapsed( ) ) ;
68- self . render_to_app ( render_target) ;
69- }
70-
71- pub fn from_apk (
81+ pub async fn from_apk (
7282 apk_content : impl Read + Seek ,
83+ sender : Sender < ServerMessage > ,
7384 accessor : AccessorMut ,
7485 ) -> Result < ( ) , OpenFileError > {
7586 let zip = ZipArchive :: new ( apk_content)
7687 . map_err ( OpenFileError :: LoadZip ) ?;
77- let apk_accessor = read_apk ( zip) ?;
88+ let apk_accessor = read_apk ( zip, sender ) . await ?;
7889 // safe unwrap, no other places in current thread will access it.
7990 * accessor. lock ( ) = Some ( AccessorEnum :: Apk ( apk_accessor) ) ;
8091 Ok ( ( ) )
@@ -85,10 +96,6 @@ impl AsmServer {
8596 }
8697}
8798
88- struct FileOpenContext {
89- pub path : String ,
90- pub start_time : Instant ,
91- }
9299
93100/// input operation processing
94101impl AsmServer {
0 commit comments