mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Feat] (Android): the render server screen and binary ship in the plugin APK too, not just trace
This commit is contained in:
@@ -35,7 +35,10 @@ fun Project.mobileGlCmakeCompilerLauncher(): String =
|
||||
|
||||
// Match the native module's two switches, including INPROC implying the parent
|
||||
// option. A D/P plugin must ask its launcher to select the transport at runtime;
|
||||
// compiling MG_Remote alone leaves ConfigLoader's default on monolith.
|
||||
// compiling MG_Remote alone leaves ConfigLoader's default on monolith. The native module
|
||||
// builds the split shape by default in a standalone build (it carries the render server),
|
||||
// so this is only the opt-in for the launcher-selected in-process TRANSPORT: unset, the
|
||||
// plugin still runs monolith.
|
||||
fun Project.mobileGlDisaggregatedEnabled(): Boolean {
|
||||
fun enabled(value: Any?): Boolean = value?.toString()?.trim()?.uppercase().orEmpty() in setOf("1", "ON", "YES", "TRUE", "Y")
|
||||
return enabled(findProperty("mobilegl.buildDisaggregated") ?: System.getenv("MOBILEGL_BUILD_DISAGGREGATED")) ||
|
||||
@@ -172,11 +175,17 @@ android {
|
||||
productFlavors {
|
||||
create("plugin") {
|
||||
dimension = "profile"
|
||||
// The shipped renderer plugin keeps its render-server components private; the
|
||||
// screen and NavBar start them from inside the app.
|
||||
manifestPlaceholders["serverComponentsExported"] = "false"
|
||||
}
|
||||
create("trace") {
|
||||
dimension = "profile"
|
||||
applicationIdSuffix = ".trace"
|
||||
versionNameSuffix = "-trace"
|
||||
// Debuggable dev APK: adb (tcp_device_server.py, the CI TCP lane) starts the
|
||||
// server components directly by explicit component name.
|
||||
manifestPlaceholders["serverComponentsExported"] = "true"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- The render server (ServerControlActivity / MobileGLServerService /
|
||||
MobileGLDisplayActivity): a TCP listener kept alive by a wake lock in a data-sync
|
||||
foreground service. -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
<application
|
||||
android:hasCode="true"
|
||||
android:label="${appLabel}"
|
||||
@@ -22,6 +30,41 @@
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.MobileGLPlugin.NoDisplay" />
|
||||
|
||||
<!-- Render server control screen: start/stop the offscreen TCP supervisor
|
||||
(MobileGLServerService) or the on-screen display server. Not a launcher: the
|
||||
bottom navigation bar (NavBar) switches between it and PostActivity. Both flavors
|
||||
ship the server (libMobileGLServer.so + the display server's JNI in libMobileGL.so).
|
||||
serverComponentsExported: the trace flavor is a debuggable dev APK that adb drives by
|
||||
explicit component (listen/token/env/onscreen/start/stop extras), so it exports
|
||||
them. The plugin flavor ships to users, and an exported component would let any app
|
||||
on the device start a server with an env of its own choosing. singleTop delivers the
|
||||
adb extras to a running screen through onNewIntent. -->
|
||||
<activity
|
||||
android:name=".ServerControlActivity"
|
||||
android:exported="${serverComponentsExported}"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/Theme.MobileGLPlugin" />
|
||||
<service
|
||||
android:name=".MobileGLServerService"
|
||||
android:exported="${serverComponentsExported}"
|
||||
android:foregroundServiceType="dataSync"
|
||||
android:process=":mglsrv" />
|
||||
<!-- P12 (on-screen server window): the ON-SCREEN display server. Its own process (:mglwin)
|
||||
runs the TCP server on a thread and renders a headless client's window surface
|
||||
(MOBILEGL_IPC_SURFACE=server) onto its SurfaceView. One server at a time: starting it
|
||||
stops MobileGLServerService, starting the service kills :mglwin. Software window
|
||||
rendering keeps HWUI off EGL here (Espryt's teardown terminates the default display);
|
||||
configChanges keeps the Surface through rotation and overlay changes. -->
|
||||
<activity
|
||||
android:name=".MobileGLDisplayActivity"
|
||||
android:configChanges="@integer/trace_replay_config_changes"
|
||||
android:exported="${serverComponentsExported}"
|
||||
android:hardwareAccelerated="false"
|
||||
android:launchMode="singleTop"
|
||||
android:process=":mglwin"
|
||||
android:taskAffinity="${applicationId}.mglwin"
|
||||
android:theme="@style/Theme.MobileGLPlugin" />
|
||||
|
||||
<!-- One benchmark run per process: the backend is latched at MobileGL
|
||||
init and Espryt teardown kills the process-default EGL display, so
|
||||
the bench must never share a process with the POST UI. The service
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** Trace-only entry point for a TCP supervisor; EGL belongs to its session children. */
|
||||
/** Entry point for the offscreen TCP supervisor; EGL belongs to its session children. */
|
||||
public final class MobileGLServerService extends Service {
|
||||
private static final String TAG = "MobileGLServer";
|
||||
private static final String CHANNEL = "mobilegl-server";
|
||||
@@ -10,11 +10,9 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Bottom navigation bar switching between the dev screens (POST and the render
|
||||
* server control). The bar only appears in flavors that ship both screens: the
|
||||
* plugin flavor has no ServerControlActivity, so wrap() returns the content
|
||||
* unchanged there. Tabs switch by reordering the other activity to the front,
|
||||
* so each screen keeps its state while the other is open.
|
||||
* Bottom navigation bar switching between the POST screen and the render server
|
||||
* control screen. Tabs switch by reordering the other activity to the front, so each
|
||||
* screen keeps its state while the other is open.
|
||||
*/
|
||||
public final class NavBar {
|
||||
public static final int TAB_POST = 0;
|
||||
@@ -25,19 +23,10 @@ public final class NavBar {
|
||||
private static final int COLOR_TAB_INACTIVE = 0xFF9E9E9E;
|
||||
private static final int BAR_HEIGHT_DP = 56;
|
||||
|
||||
private static final String SERVER_ACTIVITY = "top.mobilegl.plugin.ServerControlActivity";
|
||||
|
||||
private NavBar() {}
|
||||
|
||||
/** Returns content wrapped with the bottom bar, or content unchanged in plugin builds. */
|
||||
/** Returns content wrapped with the bottom bar. */
|
||||
public static View wrap(Activity activity, View content, int currentTab) {
|
||||
final Class<?> serverClass;
|
||||
try {
|
||||
serverClass = Class.forName(SERVER_ACTIVITY);
|
||||
} catch (ClassNotFoundException notInThisFlavor) {
|
||||
return content;
|
||||
}
|
||||
|
||||
LinearLayout root = new LinearLayout(activity);
|
||||
root.setOrientation(LinearLayout.VERTICAL);
|
||||
root.addView(content, new LinearLayout.LayoutParams(
|
||||
@@ -47,7 +36,7 @@ public final class NavBar {
|
||||
bar.setOrientation(LinearLayout.HORIZONTAL);
|
||||
bar.setBackgroundColor(COLOR_BAR);
|
||||
addTab(activity, bar, "POST", PostActivity.class, currentTab == TAB_POST);
|
||||
addTab(activity, bar, "Render Server", serverClass, currentTab == TAB_SERVER);
|
||||
addTab(activity, bar, "Render Server", ServerControlActivity.class, currentTab == TAB_SERVER);
|
||||
root.addView(bar, new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, dp(activity, BAR_HEIGHT_DP)));
|
||||
return root;
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The server role's environment, shared by the two servers the trace APK can run.
|
||||
* The server role's environment, shared by the two servers the APK can run.
|
||||
*
|
||||
* <p>{@link MobileGLServerService} exec's the offscreen supervisor with it (a ProcessBuilder
|
||||
* environment); {@link MobileGLDisplayActivity} applies it to its OWN process with Os.setenv /
|
||||
@@ -2,42 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
<application>
|
||||
<!-- Render server control screen: start/stop the offscreen TCP supervisor
|
||||
(MobileGLServerService) or the on-screen display server. Not the launcher:
|
||||
PostActivity is the entry icon and the bottom navigation bar switches between
|
||||
the two screens; exported so adb can drive it by explicit component with
|
||||
listen/token/env/onscreen/start/stop extras. -->
|
||||
<activity
|
||||
android:name=".ServerControlActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/Theme.MobileGLPlugin" />
|
||||
<service
|
||||
android:name=".MobileGLServerService"
|
||||
android:exported="true"
|
||||
android:foregroundServiceType="dataSync"
|
||||
android:process=":mglsrv" />
|
||||
<!-- P12 (on-screen server window): the ON-SCREEN display server. Its own process (:mglwin)
|
||||
runs the TCP server on a thread and renders a headless client's window surface
|
||||
(MOBILEGL_IPC_SURFACE=server) onto its SurfaceView. One server at a time: starting it
|
||||
stops MobileGLServerService, starting the service kills :mglwin. Software window
|
||||
rendering keeps HWUI off EGL here (Espryt's teardown terminates the default display);
|
||||
configChanges keeps the Surface through rotation and overlay changes. -->
|
||||
<activity
|
||||
android:name=".MobileGLDisplayActivity"
|
||||
android:configChanges="@integer/trace_replay_config_changes"
|
||||
android:exported="true"
|
||||
android:hardwareAccelerated="false"
|
||||
android:launchMode="singleTop"
|
||||
android:process=":mglwin"
|
||||
android:taskAffinity="${applicationId}.mglwin"
|
||||
android:theme="@style/Theme.MobileGLPlugin" />
|
||||
<activity
|
||||
android:name=".PluginActivity"
|
||||
tools:node="remove" />
|
||||
|
||||
@@ -30,9 +30,13 @@ subprojects {
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
// P5 trace A/B: :MobileGL owns libMobileGL.so, not :app's replay runner.
|
||||
// Both flavors ship the render server, so the split shape is on by default
|
||||
// (-Pmobilegl.buildDisaggregated=OFF opts out); INPROC follows it, as in
|
||||
// MobileGL/build.gradle.
|
||||
val disaggregated = project.findProperty("mobilegl.buildDisaggregated") ?: "ON"
|
||||
arguments += listOf(
|
||||
"-DMOBILEGL_BUILD_DISAGGREGATED=${project.findProperty("mobilegl.buildDisaggregated") ?: "OFF"}",
|
||||
"-DMOBILEGL_BUILD_DISAGGREGATED_INPROC=${project.findProperty("mobilegl.buildDisaggregatedInproc") ?: "OFF"}",
|
||||
"-DMOBILEGL_BUILD_DISAGGREGATED=$disaggregated",
|
||||
"-DMOBILEGL_BUILD_DISAGGREGATED_INPROC=${project.findProperty("mobilegl.buildDisaggregatedInproc") ?: disaggregated}",
|
||||
)
|
||||
mobileGlCmakeCompilerLauncher().takeIf(String::isNotEmpty)?.let { compilerLauncher ->
|
||||
arguments += listOf(
|
||||
|
||||
Reference in New Issue
Block a user