mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
Merge branch 'main' into feat/hamburger-rail
This commit is contained in:
commit
60a3ff8372
4 files changed
+53
-3
No files matched your search
@@ -135,6 +135,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private var frameGenEngine by mutableStateOf(FrameGen.ENGINE_OFF)
|
||||
private var frameGenMultiplier by mutableStateOf(2)
|
||||
private var fexPreset by mutableStateOf("")
|
||||
private var suspendPolicy by mutableStateOf(SessionPrefs.SUSPEND_MANUAL)
|
||||
private var oscMode by mutableStateOf(SessionPrefs.OSC_AUTO)
|
||||
private var shapeMode by mutableStateOf(SessionPrefs.SHAPE_AUTO)
|
||||
private var secondScreenMode by mutableStateOf(SecondScreenMode.NONE)
|
||||
@@ -260,7 +261,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
fillScreen = if (SessionState.mode == SessionService.MODE_STEAM) fillScreen else null,
|
||||
frameGenEngine = frameGenEngine, frameGenMultiplier = frameGenMultiplier,
|
||||
lsfgReady = LsfgNative.isInstalled(this@SessionActivity),
|
||||
oscMode = oscMode, touchMode = touchMode,
|
||||
oscMode = oscMode, suspendPolicy = suspendPolicy, touchMode = touchMode,
|
||||
touchAuto = if (usingTouchpad()) "touchpad" else "direct",
|
||||
shapeMode = shapeMode, fexPreset = fexPreset,
|
||||
secondScreenMode = secondScreenMode,
|
||||
@@ -283,6 +284,11 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
backActionsInverted = inverted
|
||||
},
|
||||
onOsc = { v -> SessionPrefs.setOscMode(this@SessionActivity, v); readPrefs(); updateOnScreenControls() },
|
||||
onSuspendPolicy = { policy ->
|
||||
SessionPrefs.setSuspendPolicy(this@SessionActivity, SessionState.mode, policy)
|
||||
suspendPolicy = policy
|
||||
SessionService.suspendPolicyChanged(this@SessionActivity)
|
||||
},
|
||||
onTouch = { v -> SessionPrefs.setTouchMode(this@SessionActivity, v); readPrefs() },
|
||||
onShape = { v -> SessionPrefs.setShapeMode(this@SessionActivity, v); readPrefs() },
|
||||
onFexPreset = { v -> SessionPrefs.setFexPreset(this@SessionActivity, v); readPrefs() },
|
||||
@@ -391,6 +397,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
frameGenEngine = FrameGen.engine(this)
|
||||
frameGenMultiplier = FrameGen.multiplier(this)
|
||||
fexPreset = SessionPrefs.fexPreset(this)
|
||||
suspendPolicy = SessionPrefs.suspendPolicy(this, SessionState.mode)
|
||||
oscMode = SessionPrefs.oscMode(this)
|
||||
shapeMode = SessionPrefs.shapeMode(this)
|
||||
backActionsInverted = SessionPrefs.backActionsInverted(this)
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.os.Process;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.StructStat;
|
||||
import android.system.StructUtsname;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
@@ -32,6 +33,7 @@ public final class LinuxRuntime {
|
||||
/** Shortcut extra naming which of the modes above a Linux entry launches. */
|
||||
public static final String EXTRA_LINUX_MODE = "linux_mode";
|
||||
private static final String KGSL_DEVICE = "/dev/kgsl-3d0";
|
||||
private static final String GUEST_HOSTNAME = "DroidDeck";
|
||||
/** Where every Linux session's debug log lands: public, so a user can just hand the folder over. */
|
||||
public static final String DEBUG_LOG_DIR = "DroidDeck";
|
||||
|
||||
@@ -116,6 +118,8 @@ public final class LinuxRuntime {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add(prootBinary(context).getPath());
|
||||
cmd.add("--kill-on-exit");
|
||||
// Preserve the host kernel identity while giving the guest the app's branded host name.
|
||||
cmd.add("--kernel-release=" + guestUtsname());
|
||||
// Android's app seccomp policy traps the whole set*id family. Xwayland's Popen() calls
|
||||
// setgid()/setuid() before it execs xkbcomp and _exit(127)s when they fail, so without
|
||||
// this the keymap never compiles and Xwayland dies. -i makes proot answer those calls
|
||||
@@ -245,6 +249,13 @@ public final class LinuxRuntime {
|
||||
cmd.add(spec);
|
||||
}
|
||||
|
||||
/** PRoot's complex -k format: sysname, nodename, release, version, machine, domain, HWCAP. */
|
||||
private static String guestUtsname() {
|
||||
StructUtsname host = Os.uname();
|
||||
return "\\" + host.sysname + "\\" + GUEST_HOSTNAME + "\\" + host.release
|
||||
+ "\\" + host.version + "\\" + host.machine + "\\localdomain\\-1\\";
|
||||
}
|
||||
|
||||
/** X access control and Steam look the session user up by uid: the app uid is root inside. */
|
||||
public static void writeAccounts(Context context) throws IOException {
|
||||
File root = rootDir(context);
|
||||
|
||||
@@ -144,6 +144,13 @@ class SessionService : Service() {
|
||||
updateSuspendPolicy()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
ACTION_SUSPEND_POLICY_CHANGED -> {
|
||||
if (!SessionState.running) return START_NOT_STICKY
|
||||
suspendPolicy = SessionPrefs.suspendPolicy(this, SessionState.mode)
|
||||
suspendAttemptFailed = false
|
||||
updateSuspendPolicy()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
ACTION_RESUME -> {
|
||||
activityVisible = true
|
||||
screenOn = (getSystemService(Context.POWER_SERVICE) as? PowerManager)?.isInteractive ?: screenOn
|
||||
@@ -594,7 +601,9 @@ class SessionService : Service() {
|
||||
components.add(networkLink)
|
||||
components.forEach { it.start() }
|
||||
|
||||
val line = command.joinToString(" ") { it.replace(" ", "\\ ") }
|
||||
val line = command.joinToString(" ") {
|
||||
it.replace("\\", "\\\\").replace(" ", "\\ ")
|
||||
}
|
||||
watchLaunchRequests(sessionRoot)
|
||||
// One session replacing another (the desktop's Steam launchers): the old proot is killed
|
||||
// by the teardown a second after the new one has started, and its exit used to arrive
|
||||
@@ -1016,6 +1025,7 @@ class SessionService : Service() {
|
||||
const val ACTION_RESUME = "com.droiddeck.launcher.RESUME_SESSION"
|
||||
const val ACTION_HOME_GUIDE = "com.droiddeck.launcher.HOME_GUIDE"
|
||||
const val ACTION_AGENT_START = "com.droiddeck.launcher.AGENT_START"
|
||||
private const val ACTION_SUSPEND_POLICY_CHANGED = "com.droiddeck.launcher.SUSPEND_POLICY_CHANGED"
|
||||
private const val ACTION_ACTIVITY_VISIBLE = "com.droiddeck.launcher.ACTIVITY_VISIBLE"
|
||||
private const val ACTION_ACTIVITY_HIDDEN = "com.droiddeck.launcher.ACTIVITY_HIDDEN"
|
||||
private const val ACTION_TRACK_AUXILIARY = "com.droiddeck.launcher.TRACK_AUXILIARY"
|
||||
@@ -1070,6 +1080,11 @@ class SessionService : Service() {
|
||||
context.startService(Intent(context, SessionService::class.java).setAction(ACTION_RESUME))
|
||||
}
|
||||
|
||||
fun suspendPolicyChanged(context: Context) {
|
||||
if (!SessionState.running) return
|
||||
context.startService(Intent(context, SessionService::class.java).setAction(ACTION_SUSPEND_POLICY_CHANGED))
|
||||
}
|
||||
|
||||
/** Let the session service clean up the PTY's proot tree if the control screen closes. */
|
||||
fun stopTerminalProcess(context: Context, pid: Int) {
|
||||
if (pid > 1) context.startService(
|
||||
|
||||
@@ -87,7 +87,7 @@ import com.droiddeck.launcher.input.SecondScreenMode
|
||||
import kotlinx.coroutines.flow.collect
|
||||
|
||||
private val drawerPageTitles = listOf("Now", "Controls", "Session")
|
||||
private val drawerPageEntries = listOf("hud", "touch", "shape")
|
||||
private val drawerPageEntries = listOf("hud", "touch", "suspend")
|
||||
|
||||
private class DrawerFocus {
|
||||
private val requesters = HashMap<String, FocusRequester>()
|
||||
@@ -194,6 +194,7 @@ class DrawerActions(
|
||||
val frameGenMultiplier: Int,
|
||||
val lsfgReady: Boolean,
|
||||
val oscMode: String,
|
||||
val suspendPolicy: String,
|
||||
val backActionsInverted: Boolean,
|
||||
val touchMode: String,
|
||||
val touchAuto: String,
|
||||
@@ -213,6 +214,7 @@ class DrawerActions(
|
||||
val onSteamMenu: (() -> Unit)?,
|
||||
val onQam: (() -> Unit)?,
|
||||
val onOsc: (String) -> Unit,
|
||||
val onSuspendPolicy: (String) -> Unit,
|
||||
val onBackActionsInverted: (Boolean) -> Unit,
|
||||
val onTouch: (String) -> Unit,
|
||||
val onShape: (String) -> Unit,
|
||||
@@ -475,6 +477,21 @@ fun SessionDrawer(open: Boolean, page: Int, controllerActive: Boolean, onPageCha
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingsGroup("Session behavior") {
|
||||
ChoiceRow(
|
||||
host, "suspend", "Background behavior",
|
||||
"Applies now and to future sessions in this mode.",
|
||||
listOf(
|
||||
SessionPrefs.SUSPEND_AUTO to "Auto",
|
||||
SessionPrefs.SUSPEND_MANUAL to "Manual",
|
||||
SessionPrefs.SUSPEND_NEVER to "Never",
|
||||
),
|
||||
a.suspendPolicy,
|
||||
note = "Auto pauses in the background and resumes when visible. Manual pauses there and waits for Resume. Never keeps the session running.",
|
||||
chipModifier = focus.track(page, "suspend"),
|
||||
onPick = a.onSuspendPolicy,
|
||||
)
|
||||
}
|
||||
SettingsGroup("Next session") {
|
||||
ChoiceRow(host, "shape", "Screen ratio", null,
|
||||
SessionPrefs.shapeChoices, a.shapeMode,
|
||||
|
||||
Reference in new issue
Block a user