Get android running its sandbox in a seprate, isolated service process. So that we support not extracting the native code from the APK, so that we support distributing as an .aab file, so that we may one day release on the app store.

This commit is contained in:
2024-07-04 13:02:39 -04:00
parent 71268636df
commit ed6bef6d24
8 changed files with 300 additions and 55 deletions

View File

@ -154,41 +154,74 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a
}
else
{
uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream);
memset(pipe, 0, sizeof(*pipe));
if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0)
tf_android_start_service_t* start_service = tf_task_get_android_start_service();
if (start_service)
{
tf_printf("uv_pipe_init failed\n");
}
uv_os_sock_t fds[2];
int socketpair_result = uv_socketpair(SOCK_STREAM, 0, fds, 0, 0);
if (socketpair_result)
{
tf_printf("uv_socketpair: %s\n", uv_strerror(socketpair_result));
}
uv_stdio_container_t io[3];
io[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE;
io[0].data.stream = (uv_stream_t*)pipe;
io[1].flags = UV_INHERIT_FD;
io[1].data.fd = STDOUT_FILENO;
io[2].flags = UV_INHERIT_FD;
io[2].data.fd = STDERR_FILENO;
uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream);
*pipe = (uv_pipe_t) { 0 };
if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0)
{
tf_printf("uv_pipe_init failed\n");
}
uv_process_options_t options = { 0 };
options.args = command_argv;
options.exit_cb = _taskstub_on_process_exit;
options.stdio = io;
options.stdio_count = sizeof(io) / sizeof(*io);
options.file = command_argv[0];
options.env = (char*[]) { "ASAN_OPTIONS=detect_leaks=0", NULL };
int pipe_result = uv_pipe_open(pipe, fds[0]);
if (pipe_result)
{
tf_printf("uv_pipe_open: %s\n", uv_strerror(pipe_result));
}
stub->_process.data = stub;
int spawn_result = uv_spawn(tf_task_get_loop(parent), &stub->_process, &options);
if (spawn_result == 0)
{
start_service(fds[1]);
stub->_process.data = stub;
tf_packetstream_set_on_receive(stub->_stream, tf_task_on_receive_packet, stub);
tf_packetstream_start(stub->_stream);
result = taskObject;
}
else
{
tf_printf("uv_spawn failed: %s\n", uv_strerror(spawn_result));
JS_FreeValue(context, taskObject);
uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream);
memset(pipe, 0, sizeof(*pipe));
if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0)
{
tf_printf("uv_pipe_init failed\n");
}
uv_stdio_container_t io[3];
io[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE;
io[0].data.stream = (uv_stream_t*)pipe;
io[1].flags = UV_INHERIT_FD;
io[1].data.fd = STDOUT_FILENO;
io[2].flags = UV_INHERIT_FD;
io[2].data.fd = STDERR_FILENO;
uv_process_options_t options = { 0 };
options.args = command_argv;
options.exit_cb = _taskstub_on_process_exit;
options.stdio = io;
options.stdio_count = sizeof(io) / sizeof(*io);
options.file = command_argv[0];
options.env = (char*[]) { "ASAN_OPTIONS=detect_leaks=0", NULL };
stub->_process.data = stub;
int spawn_result = uv_spawn(tf_task_get_loop(parent), &stub->_process, &options);
if (spawn_result == 0)
{
tf_packetstream_set_on_receive(stub->_stream, tf_task_on_receive_packet, stub);
tf_packetstream_start(stub->_stream);
result = taskObject;
}
else
{
tf_printf("uv_spawn failed: %s\n", uv_strerror(spawn_result));
JS_FreeValue(context, taskObject);
}
}
}
return JS_DupValue(context, result);
@ -443,7 +476,15 @@ JSValue tf_taskstub_kill(tf_taskstub_t* stub)
JSValue result = JS_UNDEFINED;
if (!tf_task_get_one_proc(stub->_owner))
{
uv_process_kill(&stub->_process, SIGKILL);
tf_android_stop_service_t* stop_service = tf_task_get_android_stop_service();
if (stop_service)
{
stop_service();
}
else
{
uv_process_kill(&stub->_process, SIGKILL);
}
}
else
{