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 ;
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 ;
1220import java .util .concurrent .ConcurrentLinkedQueue ;
1321import java .util .concurrent .LinkedBlockingQueue ;
1422import java .util .concurrent .atomic .AtomicBoolean ;
1523
1624import fi .iki .elonen .NanoHTTPD ;
1725import fi .iki .elonen .NanoWSD ;
1826
19- public class AndroidJsV8Inspector {
20- private static boolean DEBUG_LOG_ENABLED = false ;
27+ class AndroidJsV8Inspector {
28+ private static boolean DEBUG_LOG_ENABLED = true ;
2129
2230 private JsV8InspectorServer server ;
23- private Logger logger ;
2431 private Context context ;
32+ private static String applicationDir ;
2533
2634 protected native final void init ();
2735
2836 protected native final void connect (Object connection );
2937
30- protected static native final void disconnect ();
38+ protected static native void disconnect ();
3139
3240 protected native final void dispatchMessage (String message );
3341
34- protected Handler mainHandler ;
42+ private Handler mainHandler ;
3543 private LinkedBlockingQueue <String > inspectorMessages = new LinkedBlockingQueue <String >();
3644
37- public AndroidJsV8Inspector (Context context , Logger logger ) {
45+ AndroidJsV8Inspector (Context context , Logger logger ) {
3846 this .context = context ;
39- this . logger = logger ;
47+ applicationDir = context . getFilesDir (). getAbsolutePath () ;
4048 }
4149
4250 public void start () throws IOException {
@@ -45,7 +53,7 @@ public void start() throws IOException {
4553
4654 mainHandler = currentRuntime .getHandler ();
4755
48- this .server = new JsV8InspectorServer (context .getPackageName () + "-inspectorServer" );
56+ this .server = new JsV8InspectorServer (this . context .getPackageName () + "-inspectorServer" );
4957 this .server .start (-1 );
5058
5159 if (DEBUG_LOG_ENABLED ) {
@@ -93,6 +101,75 @@ private static String getInspectorMessage(Object connection) {
93101 return ((JsV8InspectorWebSocket ) connection ).getInspectorMessage ();
94102 }
95103
104+ @ RuntimeCallable
105+ public static Pair <String , String >[] getPageResources () {
106+ // necessary to align the data dir returned by context (emulator) and that used by the v8 inspector
107+ if (applicationDir .startsWith ("/data/user/0/" )) {
108+ applicationDir = applicationDir .replaceFirst ("/data/user/0/" , "/data/data/" );
109+ }
110+
111+ String dataDir = applicationDir ;
112+ File rootFilesDir = new File (dataDir , "app" );
113+
114+
115+ List <Pair <String , String >> resources = traverseResources (rootFilesDir );
116+
117+ return resources .toArray ((Pair <String , String >[]) Array .newInstance (resources .get (0 ).getClass (), resources .size ()));
118+ }
119+
120+ private static List <Pair <String , String >> traverseResources (File dir ) {
121+ List <Pair <String , String >> resources = new ArrayList <>();
122+
123+ Queue <File > directories = new LinkedList <>();
124+ directories .add (dir );
125+
126+ while (!directories .isEmpty ()) {
127+ File currentDir = directories .poll ();
128+
129+ File [] files = currentDir .listFiles ();
130+ for (File file : files ) {
131+ if (file .isDirectory ()) {
132+ directories .add (file );
133+ } else {
134+ resources .add (new Pair <>("file://" + file .getAbsolutePath (), getMimeType (file .getAbsolutePath ())));
135+ }
136+ }
137+ }
138+
139+ return resources ;
140+ }
141+
142+ private static String getMimeType (String url ) {
143+ String type = null ;
144+ String extension = MimeTypeMap .getFileExtensionFromUrl (url );
145+ if (extension != null ) {
146+ type = MimeTypeMap .getSingleton ().getMimeTypeFromExtension (extension );
147+
148+ // getMimeType may sometime return incorrect results in the context of NativeScript
149+ // e.g. `.ts` returns video/MP2TS
150+ switch (extension ) {
151+ case "js" :
152+ type = "text/javascript" ;
153+ break ;
154+ case "json" :
155+ type = "application/json" ;
156+ break ;
157+ case "css" :
158+ type = "text/css" ;
159+ break ;
160+ case "ts" :
161+ type = "text/typescript" ;
162+ break ;
163+ // handle shared libraries so they are marked properly and don't appear in the sources tab
164+ case "so" :
165+ type = "application/binary" ;
166+ break ;
167+ }
168+ }
169+
170+ return type ;
171+ }
172+
96173 class JsV8InspectorServer extends NanoWSD {
97174 public JsV8InspectorServer (String name ) {
98175 super (name );
0 commit comments