From d6be2f7d5497fb83afaf2537b7a1fc39c2f3ccc0 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 18 Mar 2023 12:28:48 +0000 Subject: [PATCH] Bind tildefriends HTTP to an arbitrary port, write it to a file, and have the Android activity notice that file write and load the correct URL. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4233 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- Makefile | 5 ++ core/httpd.js | 12 ++- .../unprompted/tildefriends/MainActivity.java | 81 ++++++++++++++++--- src/socket.js.c | 16 +++- 4 files changed, 102 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index cfa4c850..2805e6f2 100644 --- a/Makefile +++ b/Makefile @@ -462,6 +462,11 @@ out/%.apk: out/%.unsigned.apk apk: out/TildeFriends-debug.apk .PHONY: apk +apkgo: out/TildeFriends-debug.apk + @adb install $< + @adb shell am start com.unprompted.tildefriends/.MainActivity +.PHONY: apkgo + clean: rm -rf $(BUILD_DIR) .PHONY: clean diff --git a/core/httpd.js b/core/httpd.js index de9b136c..84529b66 100644 --- a/core/httpd.js +++ b/core/httpd.js @@ -555,7 +555,17 @@ let kBacklog = 8; let kHost = "0.0.0.0" let socket = new Socket(); -socket.bind(kHost, tildefriends.http_port).then(function() { +socket.bind(kHost, tildefriends.http_port).then(function(port) { + print("bound to", port); + print("checking", tildefriends.args.out_http_port_file); + if (tildefriends.args.out_http_port_file) { + print("going to write the file"); + File.writeFile(tildefriends.args.out_http_port_file, port.toString() + '\n').then(function(r) { + print("wrote port file", tildefriends.args.out_http_port_file, r); + }).catch(function() { + print("failed to write port file"); + }); + } let listenResult = socket.listen(kBacklog, async function() { try { let client = await socket.accept(); diff --git a/src/android/com/unprompted/tildefriends/MainActivity.java b/src/android/com/unprompted/tildefriends/MainActivity.java index c5dccbce..00ce6c9f 100644 --- a/src/android/com/unprompted/tildefriends/MainActivity.java +++ b/src/android/com/unprompted/tildefriends/MainActivity.java @@ -18,18 +18,26 @@ import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; -import java.lang.Process; -import java.lang.Thread; - +import java.io.BufferedInputStream; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.BufferedInputStream; +import java.lang.Process; +import java.lang.Thread; +import java.nio.file.FileSystems; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class MainActivity extends Activity { WebView web_view; + String base_url; @Override protected void onCreate(Bundle savedInstanceState) { @@ -70,8 +78,45 @@ public class MainActivity extends Activity { Log.w("tildefriends", e.toString()); } + String port_file_path = getFilesDir().toString() + "/port.txt"; + base_url = "http://127.0.0.1:12345/"; + + new Thread(new Runnable() { + @Override + public void run() { + try { + Log.w("tildefriends", "Watching for changes in: " + getFilesDir().toString()); + WatchService watcher = FileSystems.getDefault().newWatchService(); + Paths.get(getFilesDir().toString()).register( + watcher, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_MODIFY); + while (true) { + WatchKey key = watcher.take(); + for (WatchEvent event : key.pollEvents()) { + if (event.context().toString().equals("port.txt")) { + Log.w("tildefriends", "Observed file write: " + event.context().toString()); + base_url = "http://127.0.0.1:" + String.valueOf(read_port(port_file_path)) + "/"; + web_view.loadUrl(base_url); + watcher.close(); + break; + } + } + if (!key.reset()) { + Log.w("tildefriends", "watcher is no longer valid"); + break; + } + } + } catch (java.io.IOException e) { + Log.w("tildefriends", "IOException: " + e.toString()); + } catch (InterruptedException e) { + Log.w("tildefriends", "InterruptedException: " + e.toString()); + } + } + }).start(); + String exe = getFilesDir().toString() + "/tildefriends"; - ProcessBuilder builder = new ProcessBuilder(exe, "run", "-z", getPackageResourcePath().toString()); + ProcessBuilder builder = new ProcessBuilder(exe, "run", "-z", getPackageResourcePath().toString(), "-a", "out_http_port_file=" + port_file_path); Log.w("tildefriends", "files = " + getFilesDir().toString()); Log.w("tildefriends", "exe = " + exe); builder.directory(getFilesDir()); @@ -120,7 +165,7 @@ public class MainActivity extends Activity { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - if (request.getUrl() != null && request.getUrl().toString().startsWith("http://127.0.0.1:12345/")) { + if (request.getUrl() != null && request.getUrl().toString().startsWith(base_url)) { return false; } else { view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, request.getUrl())); @@ -129,8 +174,6 @@ public class MainActivity extends Activity { } }); - web_view.loadUrl("http://127.0.0.1:12345/"); - Button refresh = (Button)findViewById(R.id.refresh); refresh.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { @@ -147,12 +190,30 @@ public class MainActivity extends Activity { } else if (keyCode == KeyEvent.KEYCODE_FORWARD && web_view.canGoForward()) { web_view.goForward(); return true; -/* } else if (keyCode == KeyEvent.KEYCODE_REFRESH) { web_view.reload(); return true; -*/ } return super.onKeyDown(keyCode, event); } + + private int read_port(String path) { + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(path)); + return Integer.parseInt(reader.readLine()); + } catch (java.io.FileNotFoundException e) { + e.printStackTrace(); + } catch (java.io.IOException e) { + e.printStackTrace(); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (java.io.IOException e) { + } + } + return -1; + } } diff --git a/src/socket.js.c b/src/socket.js.c index 73ca1529..f28c4d01 100644 --- a/src/socket.js.c +++ b/src/socket.js.c @@ -456,7 +456,21 @@ void _socket_onResolvedForBind(uv_getaddrinfo_t* resolver, int status, struct ad } else { - tf_task_resolve_promise(data->socket->_task, data->promise, JS_UNDEFINED); + struct sockaddr_storage addr = { 0 }; + int port = 0; + int size = (int)sizeof(addr); + if (uv_tcp_getsockname(&data->socket->_socket, (struct sockaddr*)&addr, &size) == 0) + { + if (addr.ss_family == AF_INET) + { + port = ntohs(((struct sockaddr_in*)&addr)->sin_port); + } + else if (addr.ss_family == AF_INET6) + { + port = ntohs(((struct sockaddr_in6*)&addr)->sin6_port); + } + } + tf_task_resolve_promise(data->socket->_task, data->promise, JS_NewInt32(tf_task_get_context(data->socket->_task), port)); } } tf_free(data);