mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Tool] (P11 B1): trace flavour gate tooling - package the retrace CLI as libMobileGLRetrace.so (packageRetraceExe) and run an external client as a child of the app kept in front (mobilegl_exec_argv)
This commit is contained in:
@@ -189,6 +189,15 @@ android {
|
||||
// Debuggable dev APK: adb (tcp_device_server.py, the CI TCP lane) starts the
|
||||
// server components directly by explicit component name.
|
||||
manifestPlaceholders["serverComponentsExported"] = "true"
|
||||
// P11 B1 (gate tooling): -Pmobilegl.packageRetraceExe=ON packages the adb-shell retrace CLI
|
||||
// (tools/trace_replay) as nativeLibraryDir/libMobileGLRetrace.so, so an app - the external
|
||||
// client of the B1 device gate - can exec it (targetSdk 34 forbids exec anywhere else).
|
||||
val packageRetraceExe = (findProperty("mobilegl.packageRetraceExe") ?: "OFF").toString()
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments += "-DMOBILEGL_PACKAGE_RETRACE_EXE=$packageRetraceExe"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -255,3 +255,50 @@ target_link_libraries(trace_replay_runner
|
||||
android
|
||||
log
|
||||
dl)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# P11 B1 (gate tooling, opt-in): the adb-shell retrace CLI (tools/trace_replay's
|
||||
# mobilegl_trace_replay) packaged into the trace APK as a PIE executable named like
|
||||
# a library, so an app - the external client of the B1 device gate, launched through
|
||||
# the app_process helper - can exec it from nativeLibraryDir (targetSdk 34 forbids
|
||||
# exec anywhere else). The shape of MobileGLServer's delivery (root CMakeLists):
|
||||
# lib-prefixed .so name, $ORIGIN rpath, runtime output in the AGP jniLibs dir. It
|
||||
# dlopens libMobileGL.so at run time (--mobilegl-library) and links none of it.
|
||||
# Off unless -DMOBILEGL_PACKAGE_RETRACE_EXE=ON (-Pmobilegl.packageRetraceExe=ON).
|
||||
# ---------------------------------------------------------------------------
|
||||
if(MOBILEGL_PACKAGE_RETRACE_EXE)
|
||||
set(MOBILEGL_TRACE_TOOLS "${CMAKE_CURRENT_LIST_DIR}/../../../../../tools/trace_replay")
|
||||
add_executable(MobileGLRetrace
|
||||
trace_replay_core.cpp
|
||||
"${MOBILEGL_TRACE_TOOLS}/trace_replay_cli.cpp"
|
||||
"${MOBILEGL_TRACE_TOOLS}/apitrace_fbo_dump.cpp")
|
||||
target_compile_features(MobileGLRetrace PRIVATE cxx_std_17)
|
||||
target_compile_definitions(MobileGLRetrace PRIVATE
|
||||
MOBILEGL_APITRACE_RETRACE_MAIN=mobilegl_apitrace_main)
|
||||
target_include_directories(MobileGLRetrace PRIVATE
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
"${APITRACE_ROOT}/lib/image"
|
||||
"${MOBILEGL_TRACE_TOOLS}")
|
||||
target_link_libraries(MobileGLRetrace
|
||||
"-Wl,--start-group"
|
||||
glretrace_common
|
||||
retrace_common
|
||||
image
|
||||
common
|
||||
glhelpers
|
||||
glproc
|
||||
"-Wl,--end-group"
|
||||
android
|
||||
log
|
||||
dl)
|
||||
set_target_properties(MobileGLRetrace PROPERTIES
|
||||
PREFIX "lib" SUFFIX ".so" OUTPUT_NAME "MobileGLRetrace"
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH "$ORIGIN" INSTALL_RPATH "$ORIGIN" BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
target_compile_options(MobileGLRetrace PRIVATE -fPIE)
|
||||
target_link_options(MobileGLRetrace PRIVATE -pie)
|
||||
if(CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
set_target_properties(MobileGLRetrace PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -66,6 +66,16 @@ public final class TraceReplayActivity extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
// P11 B1 (gate tooling): run an argv as a CHILD OF THIS APP - this uid, this untrusted_app
|
||||
// domain - and stay in front while it runs. The B1 device gate's route (b): a GL client in
|
||||
// another app than the server, launched through the app_process helper, with its app in the
|
||||
// foreground and the server app behind it on its foreground service.
|
||||
String[] execArgv = intent.getStringArrayExtra(EXTRA_EXEC_ARGV);
|
||||
if (execArgv != null) {
|
||||
runExternalClient(execArgv, intent.getStringExtra(EXTRA_EXEC_ENV), intent.getStringExtra(EXTRA_EXEC_LOG));
|
||||
return;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
TraceReplaySession<TraceReplayResult> retained =
|
||||
(TraceReplaySession<TraceReplayResult>) getLastNonConfigurationInstance();
|
||||
@@ -256,6 +266,58 @@ public final class TraceReplayActivity extends Activity {
|
||||
|
||||
private static native String nativeRunSpawnSpike(String serverPath, String markerPath);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// P11 B1 (gate tooling): an external GL client started from THIS app's process.
|
||||
//
|
||||
// --esa mobilegl_exec_argv <argv...> the child's argv (typically /system/bin/app_process /
|
||||
// top.mobilegl.plugin.ExternalClientHelper -- <program> ...)
|
||||
// --es mobilegl_exec_env "K=V;K" added to (K=V) / removed from (bare K) its environment -
|
||||
// CLASSPATH and MOBILEGL_IPC_TOKEN travel here, not in argv
|
||||
// --es mobilegl_exec_log <file> its stdout+stderr, then one "exit=<code>" line
|
||||
//
|
||||
// Runtime.exec forks the child in this app's uid and SELinux domain (no transition), which is
|
||||
// what the route stands for. Unlike the P11 hspike launch this Activity STAYS IN FRONT until the
|
||||
// child exits: a backgrounded app is confined to the little cores and frozen by HyperOS, which is
|
||||
// not the topology a user runs a GL program in.
|
||||
// ---------------------------------------------------------------------------
|
||||
private static final String EXTRA_EXEC_ARGV = "mobilegl_exec_argv";
|
||||
private static final String EXTRA_EXEC_ENV = "mobilegl_exec_env";
|
||||
private static final String EXTRA_EXEC_LOG = "mobilegl_exec_log";
|
||||
|
||||
private void runExternalClient(String[] argv, String envOverrides, String logPath) {
|
||||
statusView.setText("External client running\n" + String.join(" ", argv));
|
||||
new Thread(() -> {
|
||||
String outcome;
|
||||
try {
|
||||
ProcessBuilder builder = new ProcessBuilder(argv);
|
||||
builder.redirectErrorStream(true);
|
||||
if (logPath != null) {
|
||||
File log = new File(logPath);
|
||||
File parent = log.getParentFile();
|
||||
if (parent != null) parent.mkdirs();
|
||||
builder.redirectOutput(ProcessBuilder.Redirect.appendTo(log));
|
||||
}
|
||||
top.mobilegl.plugin.ServerEnvironment.apply(builder.environment(), envOverrides);
|
||||
Log.i(TAG, "external client: exec " + java.util.Arrays.toString(argv));
|
||||
Process child = builder.start();
|
||||
int code = child.waitFor();
|
||||
outcome = "exit=" + code;
|
||||
} catch (Exception error) {
|
||||
outcome = "exit=launch-failed " + error;
|
||||
Log.e(TAG, "external client launch failed", error);
|
||||
}
|
||||
Log.i(TAG, "external client: " + outcome);
|
||||
if (logPath != null) {
|
||||
try (java.io.FileOutputStream out = new java.io.FileOutputStream(logPath, true)) {
|
||||
out.write((outcome + "\n").getBytes(java.nio.charset.StandardCharsets.UTF_8));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
final String shown = outcome;
|
||||
runOnUiThread(() -> statusView.setText("External client finished: " + shown));
|
||||
}, "MobileGLExternalClient").start();
|
||||
}
|
||||
|
||||
private static final class TraceReplayRequest {
|
||||
final String tracePath;
|
||||
final String goldenPath;
|
||||
|
||||
Reference in New Issue
Block a user