Skip to content

Commit 1dabb35

Browse files
RoiArthurBclaude
andcommitted
feat: Add system/secure settings, OVR prefs and proximity broadcast
- Add ON_DEVICE_ADB_SYSTEM_SETTINGS (screen_off_timeout: 24h) - Add ON_DEVICE_ADB_SECURE_SETTINGS (sleep_timeout: disabled) - Add ON_DEVICE_ADB_BROADCASTS with prox_close to force proximity sensor to "worn" state — prevents screen blackout on headset removal - Refactor checkGlobalSetting/setGlobalSetting into generic checkSetting/setSetting with namespace param (global/system/secure) - Add applySystemSettings, applySecureSettings, applyBroadcasts methods Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c39a46c commit 1dabb35

2 files changed

Lines changed: 63 additions & 19 deletions

File tree

src/api/android/adb/HeadsetSetup.ts

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { readFile, stat } from "node:fs/promises";
1818
import { resolve } from "node:path";
1919

2020
import { getLogger } from "@logtape/logtape";
21-
import { ON_DEVICE_ADB_GLOBAL_SETTINGS, ON_DEVICE_ADB_SHELL_SETTINGS, ON_DEVICE_OVR_PREFS } from "../../core/Constants.ts";
21+
import { ON_DEVICE_ADB_GLOBAL_SETTINGS, ON_DEVICE_ADB_SYSTEM_SETTINGS, ON_DEVICE_ADB_SECURE_SETTINGS, ON_DEVICE_ADB_SHELL_SETTINGS, ON_DEVICE_OVR_PREFS, ON_DEVICE_ADB_BROADCASTS } from "../../core/Constants.ts";
2222

2323
const logger = getLogger(["android", "HeadsetSetup"]);
2424

@@ -42,24 +42,23 @@ export class HeadsetSetup {
4242
}
4343

4444
await this.applyGlobalSettings(adb, device.serial);
45+
await this.applySystemSettings(adb, device.serial);
46+
await this.applySecureSettings(adb, device.serial);
4547
await this.applyShellSettings(adb, device.serial);
4648
await this.applyOvrPrefs(adb, device.serial);
49+
await this.applyBroadcasts(adb, device.serial);
4750
await this.checkRequiredApps(adb, device.serial);
4851
}
4952

5053
private async applyGlobalSettings(adb: Adb, serial: string) {
5154
logger.debug(`[${serial}] Checking on-device global ADB settings...`);
5255

53-
for (const [globalSetting, globalSettingValue] of Object.entries(ON_DEVICE_ADB_GLOBAL_SETTINGS) as [
54-
keyof typeof ON_DEVICE_ADB_GLOBAL_SETTINGS,
55-
typeof ON_DEVICE_ADB_GLOBAL_SETTINGS[keyof typeof ON_DEVICE_ADB_GLOBAL_SETTINGS]
56-
][])
57-
{
58-
if (!await this.checkGlobalSetting(adb, globalSetting, globalSettingValue)) {
59-
logger.debug(`[${serial}] ADB parameters for '${globalSetting}' isn't correct, fixing it...`);
60-
await this.setGlobalSetting(adb, globalSetting, globalSettingValue);
61-
if (!await this.checkGlobalSetting(adb, globalSetting, globalSettingValue)) {
62-
logger.warn(`[${serial}] Couldn't properly set setting ${globalSetting}, skipping it...`);
56+
for (const [key, value] of Object.entries(ON_DEVICE_ADB_GLOBAL_SETTINGS)) {
57+
if (!await this.checkSetting(adb, "global", key, value)) {
58+
logger.debug(`[${serial}] Global setting '${key}' isn't correct, fixing it...`);
59+
await this.setSetting(adb, "global", key, value);
60+
if (!await this.checkSetting(adb, "global", key, value)) {
61+
logger.warn(`[${serial}] Couldn't properly set global setting '${key}', skipping it...`);
6362
}
6463
}
6564
}
@@ -135,34 +134,64 @@ export class HeadsetSetup {
135134
logger.debug(`[${serial}] All on-device OVR preference overrides are good`);
136135
}
137136

138-
private async checkGlobalSetting(adb: Adb, globalParam: string, expectedValue: any): Promise<boolean> {
137+
private async applySystemSettings(adb: Adb, serial: string) {
138+
logger.debug(`[${serial}] Checking on-device system settings...`);
139+
for (const [key, value] of Object.entries(ON_DEVICE_ADB_SYSTEM_SETTINGS)) {
140+
if (!await this.checkSetting(adb, "system", key, value)) {
141+
logger.debug(`[${serial}] System setting '${key}' isn't correct, fixing it...`);
142+
await this.setSetting(adb, "system", key, value);
143+
}
144+
}
145+
logger.debug(`[${serial}] All on-device system settings are good`);
146+
}
147+
148+
private async applySecureSettings(adb: Adb, serial: string) {
149+
logger.debug(`[${serial}] Checking on-device secure settings...`);
150+
for (const [key, value] of Object.entries(ON_DEVICE_ADB_SECURE_SETTINGS)) {
151+
if (!await this.checkSetting(adb, "secure", key, value)) {
152+
logger.debug(`[${serial}] Secure setting '${key}' isn't correct, fixing it...`);
153+
await this.setSetting(adb, "secure", key, value);
154+
}
155+
}
156+
logger.debug(`[${serial}] All on-device secure settings are good`);
157+
}
158+
159+
private async applyBroadcasts(adb: Adb, serial: string) {
160+
logger.debug(`[${serial}] Sending on-device broadcasts...`);
161+
for (const action of ON_DEVICE_ADB_BROADCASTS) {
162+
await adb.subprocess.noneProtocol.spawn(`am broadcast -a ${action}`);
163+
}
164+
logger.debug(`[${serial}] All on-device broadcasts sent`);
165+
}
166+
167+
private async checkSetting(adb: Adb, namespace: string, param: string, expectedValue: any): Promise<boolean> {
139168
let result: any;
140169

141-
const process = await adb.subprocess.noneProtocol.spawn("settings get global " + globalParam);
170+
const process = await adb.subprocess.noneProtocol.spawn(`settings get ${namespace} ${param}`);
142171
// @ts-expect-error
143172
for await (const chunk of process.output.pipeThrough(new TextDecoderStream())) {
144173
result = chunk;
145174
}
146175
result = result.trim();
147176

148-
logger.trace(`[${adb.serial}] Checking ADB parameters '${globalParam}' = ${result} and should be ${expectedValue} (${result == expectedValue})`);
177+
logger.trace(`[${adb.serial}] Checking ${namespace} setting '${param}' = ${result}, should be ${expectedValue} (${result == expectedValue})`);
149178

150179
return result == expectedValue;
151180
}
152181

153-
private async setGlobalSetting(adb: Adb, globalParam: string, expectedValue: any) {
182+
private async setSetting(adb: Adb, namespace: string, param: string, value: any) {
154183
let result: any;
155184

156-
const process = await adb.subprocess.noneProtocol.spawn(["settings put global ", globalParam, expectedValue]);
185+
const process = await adb.subprocess.noneProtocol.spawn(`settings put ${namespace} ${param} ${value}`);
157186
// @ts-expect-error
158187
for await (const chunk of process.output.pipeThrough(new TextDecoderStream())) {
159188
result = chunk;
160189
}
161190

162-
logger.trace(`[${adb.serial}] Setting ADB parameters '${globalParam}' = ${expectedValue} and it ${result == undefined ? "worked" : "failed"}`);
191+
logger.trace(`[${adb.serial}] Set ${namespace} setting '${param}' = ${value}: ${result == undefined ? "ok" : "failed"}`);
163192

164193
if (result != undefined) {
165-
logger.error(`[${adb.serial}] Something happened while setting the ADB setting '${globalParam}'`);
194+
logger.error(`[${adb.serial}] Something happened while setting ${namespace} setting '${param}'`);
166195
logger.error(result.toString());
167196
}
168197
}

src/api/core/Constants.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,25 @@ export const ON_DEVICE_ADB_SHELL_SETTINGS: string[][] = [
202202
["cmd", "appops", "et", "com.oculus.nux.ota", "RUN_ANY_IN_BACKGROUND", "deny", "deny"],
203203
]
204204

205+
// Android system settings (settings put/get system).
206+
export const ON_DEVICE_ADB_SYSTEM_SETTINGS: Record<string, number|string> = {
207+
"screen_off_timeout": 86400000, // 24h — let OVR prefs control the actual display-off
208+
}
209+
210+
// Android secure settings (settings put/get secure).
211+
export const ON_DEVICE_ADB_SECURE_SETTINGS: Record<string, number|string> = {
212+
"sleep_timeout": -1, // Disabled at Android level — OVR prefs control sleep instead
213+
}
214+
205215
// Oculus PreferencesService overrides (persist.ovr.prefs_overrides.*).
206216
// Checked via `getprop persist.ovr.prefs_overrides.<key>` (returns seconds as string).
207217
// Set via `service call PreferencesService 1 s16 "<key>" i32 <value>`.
208218
export const ON_DEVICE_OVR_PREFS: Record<string, number> = {
209219
"idle_time_threshold": 14400, // Display Off — 4 hours
210220
"autosleep_time": 14400, // Sleep Mode — 4 hours
211-
}
221+
}
222+
223+
// Broadcasts sent unconditionally on every connection (fire-and-forget, no check needed).
224+
export const ON_DEVICE_ADB_BROADCASTS: string[] = [
225+
"com.oculus.vrpowermanager.prox_close", // Force proximity to "worn" — prevents screen blackout on headset removal
226+
]

0 commit comments

Comments
 (0)