33import android .content .Context ;
44import android .os .Handler ;
55import android .util .Log ;
6+ import android .util .Pair ;
7+ import android .webkit .MimeTypeMap ;
68
79import org .json .JSONArray ;
810import org .json .JSONException ;
911import org .json .JSONObject ;
1012
13+ import java .io .File ;
1114import java .io .IOException ;
12- import java .util .concurrent .ConcurrentLinkedQueue ;
15+ import java .lang .reflect .Array ;
16+ import java .util .ArrayList ;
17+ import java .util .LinkedList ;
18+ import java .util .List ;
19+ import java .util .Queue ;
1320import java .util .concurrent .LinkedBlockingQueue ;
14- import java .util .concurrent .atomic .AtomicBoolean ;
1521
1622import fi .iki .elonen .NanoHTTPD ;
1723import fi .iki .elonen .NanoWSD ;
1824
19- public class AndroidJsV8Inspector {
25+ class AndroidJsV8Inspector {
2026 private static boolean DEBUG_LOG_ENABLED = false ;
2127
2228 private JsV8InspectorServer server ;
23- private Logger logger ;
2429 private Context context ;
30+ private static String applicationDir ;
2531
2632 protected native final void init ();
2733
2834 protected native final void connect (Object connection );
2935
30- protected static native final void disconnect ();
36+ protected static native void disconnect ();
3137
3238 protected native final void dispatchMessage (String message );
3339
34- protected Handler mainHandler ;
40+ private Handler mainHandler ;
3541 private LinkedBlockingQueue <String > inspectorMessages = new LinkedBlockingQueue <String >();
3642
37- public AndroidJsV8Inspector (Context context , Logger logger ) {
43+ AndroidJsV8Inspector (Context context , Logger logger ) {
3844 this .context = context ;
39- this . logger = logger ;
45+ applicationDir = context . getFilesDir (). getAbsolutePath () ;
4046 }
4147
4248 public void start () throws IOException {
@@ -45,7 +51,7 @@ public void start() throws IOException {
4551
4652 mainHandler = currentRuntime .getHandler ();
4753
48- this .server = new JsV8InspectorServer (context .getPackageName () + "-inspectorServer" );
54+ this .server = new JsV8InspectorServer (this . context .getPackageName () + "-inspectorServer" );
4955 this .server .start (-1 );
5056
5157 if (DEBUG_LOG_ENABLED ) {
@@ -93,6 +99,75 @@ private static String getInspectorMessage(Object connection) {
9399 return ((JsV8InspectorWebSocket ) connection ).getInspectorMessage ();
94100 }
95101
102+ @ RuntimeCallable
103+ public static Pair <String , String >[] getPageResources () {
104+ // necessary to align the data dir returned by context (emulator) and that used by the v8 inspector
105+ if (applicationDir .startsWith ("/data/user/0/" )) {
106+ applicationDir = applicationDir .replaceFirst ("/data/user/0/" , "/data/data/" );
107+ }
108+
109+ String dataDir = applicationDir ;
110+ File rootFilesDir = new File (dataDir , "app" );
111+
112+
113+ List <Pair <String , String >> resources = traverseResources (rootFilesDir );
114+
115+ return resources .toArray ((Pair <String , String >[]) Array .newInstance (resources .get (0 ).getClass (), resources .size ()));
116+ }
117+
118+ private static List <Pair <String , String >> traverseResources (File dir ) {
119+ List <Pair <String , String >> resources = new ArrayList <>();
120+
121+ Queue <File > directories = new LinkedList <>();
122+ directories .add (dir );
123+
124+ while (!directories .isEmpty ()) {
125+ File currentDir = directories .poll ();
126+
127+ File [] files = currentDir .listFiles ();
128+ for (File file : files ) {
129+ if (file .isDirectory ()) {
130+ directories .add (file );
131+ } else {
132+ resources .add (new Pair <>("file://" + file .getAbsolutePath (), getMimeType (file .getAbsolutePath ())));
133+ }
134+ }
135+ }
136+
137+ return resources ;
138+ }
139+
140+ private static String getMimeType (String url ) {
141+ String type = null ;
142+ String extension = MimeTypeMap .getFileExtensionFromUrl (url );
143+ if (!extension .isEmpty ()) {
144+ type = MimeTypeMap .getSingleton ().getMimeTypeFromExtension (extension );
145+
146+ // getMimeType may sometime return incorrect results in the context of NativeScript
147+ // e.g. `.ts` returns video/MP2TS
148+ switch (extension ) {
149+ case "js" :
150+ type = "text/javascript" ;
151+ break ;
152+ case "json" :
153+ type = "application/json" ;
154+ break ;
155+ case "css" :
156+ type = "text/css" ;
157+ break ;
158+ case "ts" :
159+ type = "text/typescript" ;
160+ break ;
161+ // handle shared libraries so they are marked properly and don't appear in the sources tab
162+ case "so" :
163+ type = "application/binary" ;
164+ break ;
165+ }
166+ }
167+
168+ return type ;
169+ }
170+
96171 class JsV8InspectorServer extends NanoWSD {
97172 public JsV8InspectorServer (String name ) {
98173 super (name );
0 commit comments