Skip to content

Commit 21e1db2

Browse files
committed
add directory traversal helper methods in android inspector (Java)
1 parent 3c2a81b commit 21e1db2

1 file changed

Lines changed: 85 additions & 8 deletions

File tree

runtime/src/main/java/com/tns/AndroidJsV8Inspector.java

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,48 @@
33
import android.content.Context;
44
import android.os.Handler;
55
import android.util.Log;
6+
import android.util.Pair;
7+
import android.webkit.MimeTypeMap;
68

79
import org.json.JSONArray;
810
import org.json.JSONException;
911
import org.json.JSONObject;
1012

13+
import java.io.File;
1114
import 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;
1220
import java.util.concurrent.ConcurrentLinkedQueue;
1321
import java.util.concurrent.LinkedBlockingQueue;
1422
import java.util.concurrent.atomic.AtomicBoolean;
1523

1624
import fi.iki.elonen.NanoHTTPD;
1725
import 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

Comments
 (0)