The "Trace APK must not expose a launcher activity" check predates the render-server
screen: 1f72597dd gave the trace APK a launcher on purpose and 884f6aac9 moved the entry
icon back to PostActivity with a bottom navigation bar between the two screens, so the
apk.yml build job has been red ever since - taking the whole retrace matrix down with it
(skipped, not failed), which hid the distinction.
What is left of the old isolation contract is the count: exactly one
android.intent.action.MAIN in the merged manifest (a second one means a screen grew a
launcher entry by accident), and it belongs to PostActivity. The fclPlugin metadata ban is
unchanged.
6bccf98d7 put TakeSendStats/TakeReadStats on the concrete StreamLink class, so
ClientSession.cpp and ServerLoop.cpp had to include <MG_Remote/Transport/StreamLink.h> -
which the P6.5 seam gate (scripts/ci/link_seam_purity.py, "concrete link included above
Transport") rejects, and the MGPipe generators and hygiene gates job has been red since.
The counters stay in StreamLink.cpp beside the recv/sendmsg loops that feed them; only the
struct and the two Take functions move, to LinkMetrics.h as LinkIoStats +
LinkMetricsTakeReadStats/TakeSendStats. The readers drop the concrete include; the hot
loops are untouched.
The trace flavor manifest removed PostActivity and made ServerControlActivity
the launcher, so the APK opened straight into the render server screen. Keep
both screens: PostActivity is the launcher again, and a bottom navigation bar
(NavBar, plugin flavor unaffected) switches between them via
FLAG_ACTIVITY_REORDER_TO_FRONT with transitions suppressed, so each screen
keeps its state. ServerControlActivity is singleTop now and handles extras in
onNewIntent so adb-driven starts still work. The POST screen also shows an
indeterminate progress bar while the self-test runs.
run_matrix.sh drives interleaved monolith/inproc/spawn+shm/spawn+tcp
benchmark rounds on an adb device with per-run arm-marker verification;
profile_matrix.sh layers simpleperf, ftrace wakeup capture and a /proc
sampler on top; make_report.py aggregates runs into REPORT.md. The wifi
kit carries the cross-host control-plane hang repro and phone-side
strace/fd-reconcile helpers. .trace-work/ (run output) is now ignored.
listen/token/env/onscreen prefill the form, --ez start true starts the
server, --ez stop true stops it - adb drives the screen without the IME,
which is how the on-screen unix path (@name + shm, ServerOwned window)
was verified end to end from the UI.
mobilegl_server_serve_inprocess refused anything but tcp:// because its
only supervisor was the TCP one's thread hand-off. A unix endpoint
(@abstract name or filesystem path) now runs a supervisor of the same
shape minus the TCP exposure machinery: AcceptPair pairs a client's
control and SCM_RIGHTS connections by arrival order, there is no
DataBind to route and no pre-auth gate, sessions run on threads one at
a time with Busy for a second client, the latch resets between sessions
and g_inProcessStop ends it. That gives the on-screen server the
on-device fast path: ServerOwned windows over a unix socket with shm
data, no TCP copies.
The control screen's tcp-only guard for the on-screen mode goes with
the refusal it mirrored.
MOBILEGL_BUILD_TRACE_REPLAY now also produces mobilegl_trace_replay on
ANDROID: the same CLI as desktop, linked against the APK runner's
glws/glproc glue. On the device it dials a render server with no
Activity at all - MOBILEGL_IPC_CONTROL=unix:@name with shm data to the
offscreen supervisor (a cross-uid abstract connect needs root or an
SELinux waiver; loopback TCP works from plain adb shell), or
tcp:// with MOBILEGL_IPC_SURFACE=server to the on-screen display server.
glws_android grows the desktop glws_egl's server-owned null-window
createWindowSurface, gated on MOBILEGL_TRACE_SURFACE=window so the APK's
pbuffer mode keeps its old answer, and the config carries EGL_WINDOW_BIT
for it. The control screen refuses unix endpoints in on-screen mode:
the in-process display server serves tcp:// only.
Verified on-device with an OpenRA retrace, ssim=1.0 both ways:
offscreen service on @mgl-cli with the CLI as root, and the display
Activity on tcp://127.0.0.1:40613 with the replay's frames on the
phone's screen.
transport_wait_ns measures wall time in Ring::Wait's flush/spin/sleep, so
the client's parked time is read directly instead of inferred by
subtracting CPU clocks that run concurrently with the server.
frame_stats.py matches client and server present serials into per-frame
avg/p50/p99 splits; the README documents the MOBILEGL_PIPE_STATS=1
workflow.
An On-screen window checkbox switches Start from the offscreen service
to MobileGLDisplayActivity (process :mglwin), which serves in its own
process and renders a client's window surface onto its SurfaceView.
Stop ends either shape: stopService for the supervisor, killProcess for
:mglwin, and the running check covers both. Verified end to end with an
OpenRA retrace: the client dialed tcp://127.0.0.1:40613 with
MOBILEGL_IPC_SURFACE=server from a freeform window while the display
Activity held the screen, frames landed on the SurfaceView and the run
passed with ssim=1.0.
The endpoint field accepts @abstract names and filesystem paths beside
tcp://, matching what mobilegl_server_main's Listen already binds - on
Android the abstract namespace is the on-device rendezvous that always
works, and a relative path lands in the app's files dir, the service's
working directory. Unix endpoints skip the token rule (same-device
reach by construction) and are probed with LocalSocket instead of a
TCP connect. The screen is now titled MobileGL Render Server.
ServerControlActivity (trace flavor) collects the listen endpoint, auth
token and extra env, then drives MobileGLServerService with the same
extras adb used. Non-loopback listens are held to the 16-byte token the
server enforces, and a connect probe confirms the supervisor bound its
socket. The screen is the APK's launcher icon, which the trace flavor
lacked since PostActivity is removed there.