Skip to content

Commit aeeff5e

Browse files
Merge branch 'dev' into visual_rework
2 parents 4c4f59f + 1dabb35 commit aeeff5e

16 files changed

Lines changed: 1711 additions & 110 deletions

package-lock.json

Lines changed: 93 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@yume-chan/adb": "^2.5.1",
4444
"@yume-chan/adb-scrcpy": "^2.3.2",
4545
"@yume-chan/adb-server-node-tcp": "^2.5.2",
46+
"@yume-chan/android-bin": "^2.1.0",
4647
"@yume-chan/scrcpy-decoder-webcodecs": "^2.5.0",
4748
"@yume-chan/stream-extra": "2.1.0",
4849
"autoprefixer": "^10.4.20",
@@ -56,6 +57,7 @@
5657
"express": "^4.21.2",
5758
"geoip-lite": "^1.4.10",
5859
"i18next": "^23.15.1",
60+
"node-hid": "^3.3.0",
5961
"postcss": "^8.4.40",
6062
"react": "^18.3.1",
6163
"react-dom": "^18.3.1",

src/api/android/adb/AdbManager.ts

Lines changed: 21 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { ENV_EXTRA_VERBOSE, ENV_VERBOSE } from "../../index.ts";
1616
import { ScrcpyServer } from "../scrcpy/ScrcpyServer.ts";
1717
import { getLogger } from "@logtape/logtape";
1818
import DeviceFinder from "./DeviceFinder.ts";
19-
import {ON_DEVICE_ADB_GLOBAL_SETTINGS} from "../../core/Constants.ts";
19+
import { HeadsetSetup } from "./HeadsetSetup.ts";
2020

2121
// Override the log function
2222
const logger = getLogger(["android", "AdbManager"]);
@@ -25,6 +25,7 @@ export class AdbManager {
2525
controller: Controller;
2626
adbServer!: AdbServerClient;
2727
videoStreamServer: ScrcpyServer;
28+
headsetSetup!: HeadsetSetup;
2829
// Keep list of serial of devices with a stream already starting
2930
clientCurrentlyStreaming: Device[] = [];
3031
observer!: AdbServerClient.DeviceObserver;//!: AdbServerClient;
@@ -41,6 +42,7 @@ export class AdbManager {
4142
logger.info("Connect to device's ADB server");
4243

4344
this.videoStreamServer = new ScrcpyServer(this);
45+
this.headsetSetup = new HeadsetSetup(this.adbServer);
4446
}
4547

4648
async init() {
@@ -56,8 +58,8 @@ export class AdbManager {
5658
// Sanitize stale ADB entries on startup (side-effect: disconnects offline ones)
5759
if (this.isDeviceReady(device)) {
5860
// Apply M2L2 headset settings only if the device is ready
59-
this.checkAdbParameters(device).catch(e =>
60-
logger.error(`[${device.serial}] Unexpected error in checkAdbParameters: {e}`, { e })
61+
this.headsetSetup.setupHeadset(device).catch(e =>
62+
logger.error(`[${device.serial}] Unexpected error in setupHeadset: {e}`, { e })
6163
);
6264
}
6365

@@ -76,8 +78,8 @@ export class AdbManager {
7678
this.startNewStream(device).catch(e =>
7779
logger.error(`[${device.serial}] Unexpected error in startNewStream: {e}`, { e })
7880
);
79-
this.checkAdbParameters(device).catch(e =>
80-
logger.error(`[${device.serial}] Unexpected error in checkAdbParameters: {e}`, { e })
81+
this.headsetSetup.setupHeadset(device).catch(e =>
82+
logger.error(`[${device.serial}] Unexpected error in setupHeadset: {e}`, { e })
8183
);
8284
}
8385
});
@@ -203,6 +205,20 @@ export class AdbManager {
203205
return isReady;
204206
}
205207

208+
/** Send reboot -p to every currently streaming ADB-connected headset */
209+
async shutdownAllHeadsets(): Promise<void> {
210+
for (const device of this.clientCurrentlyStreaming) {
211+
try {
212+
const transport = await this.adbServer.createTransport(device);
213+
const adb = new Adb(transport);
214+
await adb.subprocess.noneProtocol.spawn('reboot -p');
215+
logger.info(`[${device.serial}] Power-off command sent`);
216+
} catch (e) {
217+
logger.warn(`[${device.serial}] Failed to send power-off command: {e}`, { e });
218+
}
219+
}
220+
}
221+
206222
async disconnectDevice(serial: string): Promise<void> {
207223
const index = this.clientCurrentlyStreaming.findIndex(d => d.serial === serial);
208224
if (index > -1) this.clientCurrentlyStreaming.splice(index, 1);
@@ -237,69 +253,4 @@ export class AdbManager {
237253
return success
238254
}
239255

240-
async checkAdbParameters(device: Device) {
241-
if (!this.isDeviceReady(device)) return;
242-
243-
// Only modify headsets, don't jam phone's parameters
244-
if (!device.model?.startsWith("Quest_")) return;
245-
246-
logger.debug(`[${device.serial}] Checking on-device global ADB settings...`);
247-
248-
let adb: Adb;
249-
try {
250-
adb = new Adb(await this.adbServer.createTransport(device));
251-
} catch (e) {
252-
logger.warn(`[${device.serial}] Could not open ADB transport to check parameters — device may not be authorized yet: {e}`, { e });
253-
return;
254-
}
255-
256-
for (const [globalSetting, globalSettingValue] of Object.entries(ON_DEVICE_ADB_GLOBAL_SETTINGS) as [
257-
keyof typeof ON_DEVICE_ADB_GLOBAL_SETTINGS,
258-
typeof ON_DEVICE_ADB_GLOBAL_SETTINGS[keyof typeof ON_DEVICE_ADB_GLOBAL_SETTINGS]
259-
][])
260-
{
261-
if ( ! await this.checkAdbParameter(adb, globalSetting, globalSettingValue)){
262-
logger.debug(`[${device.serial}] ADB parameters for '${globalSetting}' isn't correct, fixing it...`);
263-
await this.setAdbParameter(adb, globalSetting, globalSettingValue);
264-
if (! await this.checkAdbParameter(adb, globalSetting, globalSettingValue)) {
265-
logger.warn(`[${device.serial}] Couldn't properly set setting ${globalSetting}, skipping it...`);
266-
}
267-
}
268-
}
269-
logger.debug(`[${device.serial}] All on-device global ADB settings are good`);
270-
}
271-
272-
async checkAdbParameter(adb: Adb, globalParam: string, expectedValue: any): Promise<boolean> {
273-
let result: any;
274-
275-
const process = await adb.subprocess.noneProtocol.spawn("settings get global " + globalParam);
276-
// @ts-expect-error
277-
for await (const chunk of process.output.pipeThrough(new TextDecoderStream())) {
278-
result = chunk;
279-
}
280-
// Cleaning trailing '\n' from chunk reading
281-
result = result.trim();
282-
283-
logger.trace(`[${adb.serial}] Checking ADB parameters '${globalParam}' = ${result} and should be ${expectedValue} (${result == expectedValue})`);
284-
285-
return result == expectedValue;
286-
}
287-
288-
async setAdbParameter(adb: Adb, globalParam: string, expectedValue: any) {
289-
let result: any;
290-
291-
const process = await adb.subprocess.noneProtocol.spawn(["settings put global ", globalParam, expectedValue]);
292-
// @ts-expect-error
293-
for await (const chunk of process.output.pipeThrough(new TextDecoderStream())) {
294-
result = chunk;
295-
}
296-
297-
logger.trace(`[${adb.serial}] Setting ADB parameters '${globalParam}' = ${expectedValue} and it ${result == undefined ? "worked" : "failed"}`);
298-
299-
if (result != undefined) {
300-
logger.error(`[${adb.serial}] Something happened while setting the ADB setting '${globalParam}'`);
301-
logger.error(result.toString());
302-
}
303-
}
304-
305256
}

0 commit comments

Comments
 (0)