VulpesOS/tundra/tools/run-beatles-gecko-probe.py
2026-10-22 20:42:26 +02:00

75 lines
4.3 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: MPL-2.0
"""Run the offline Gecko probe in a previously staged private Nokia runtime."""
import argparse
import json
from pathlib import Path
import subprocess
import time
from kaios_debug import KaiOSDebugger
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / 'out/beatles/gecko-armhf'
REMOTE = '/data/local/tmp/vulpes-gecko-armhf'
def main():
global OUT, REMOTE
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('mode', choices=('version', 'render'))
parser.add_argument('--engine', choices=('153.5.0esr', '156.0.1'), default='153.5.0esr')
args = parser.parse_args()
if args.engine == '156.0.1':
OUT = ROOT / 'out/beatles/gecko-156.0.1'
REMOTE = '/data/local/vulpes-beatles'
rows = subprocess.check_output(['adb', 'devices', '-l'], text=True).splitlines()
devices = [r.split()[0] for r in rows if len(r.split()) > 2
and r.split()[1] == 'device' and 'model:Nokia_2720_Flip' in r.split()]
if len(devices) != 1:
raise RuntimeError('Exactly one connected Nokia is required')
adb = ['adb', '-s', devices[0]]
if subprocess.check_output(adb + ['shell', 'getprop ro.product.codename'], text=True).strip() != 'beatles':
raise RuntimeError('Unexpected device')
command = ['clang', '--target=armv7-linux-gnueabihf', '-march=armv7-a',
'-marm', '-mfloat-abi=soft', '-fuse-ld=lld', '-Os', '-ffreestanding',
'-fno-builtin', '-fno-stack-protector', '-fno-pie', '-fno-unwind-tables',
'-fno-asynchronous-unwind-tables', '-Wall', '-Wextra', '-Werror',
'-nostdlib', '-static', '-Wl,--build-id=none', '-Wl,-e,_start',
str(ROOT / 'probes/armv7-gecko-launch.c'), '-o', str(OUT / 'gecko-probe-launcher')]
if args.engine == '156.0.1':
command += ['-DROOT="' + REMOTE + '/rootfs"', '-DGECKO="/opt/firefox/firefox"']
subprocess.run(command, check=True)
subprocess.run(adb + ['shell', 'mkdir -p ' + REMOTE + '/rootfs/work'], check=True, capture_output=True)
for local, relative in ((OUT / 'gecko-probe-launcher', 'gecko-probe-launcher'),
(ROOT / 'devices/beatles/run-gecko-test.sh', 'probe-run.sh'),
(ROOT / 'devices/beatles/gecko-test.html', 'rootfs/work/test.html')):
subprocess.run(adb + ['push', str(local), REMOTE + '/' + relative], check=True, capture_output=True)
subprocess.run(adb + ['shell', 'chmod 755 ' + REMOTE + '/gecko-probe-launcher; rm -f '
+ REMOTE + '/' + args.mode + '.exit'], check=True, capture_output=True)
with KaiOSDebugger(devices[0]) as client:
console = client.request('root', 'getProcess', id=0)['form']['consoleActor']
script_args = [REMOTE + '/probe-run.sh', args.mode, args.engine]
script = '''(function(){var Cc=Components.classes,Ci=Components.interfaces;
var f=Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);f.initWithPath("/system/bin/sh");
var p=Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);p.init(f);
var args=%s;p.runAsync(args,args.length,null,false);return "started";})()''' % json.dumps(script_args)
print(client.evaluate(console, script), flush=True)
for _ in range(75):
result = subprocess.check_output(adb + ['shell', 'cat ' + REMOTE + '/' + args.mode + '.exit'], text=True).strip()
if result.isdigit():
log = subprocess.check_output(adb + ['shell', 'cat ' + REMOTE + '/' + args.mode + '.log'], text=True)
(OUT / (args.mode + '.log')).write_text(log)
(OUT / (args.mode + '-result.json')).write_text(json.dumps({'exitCode': int(result),
'mode': args.mode, 'device': 'beatles', 'engine': args.engine, 'offline': True}, indent=2) + '\n')
print(log, flush=True)
print('Exit:', result, flush=True)
if result == '0' and args.mode == 'render':
subprocess.run(adb + ['pull', REMOTE + '/rootfs/work/gecko.png', str(OUT / 'gecko.png')],
check=True, capture_output=True)
raise SystemExit(int(result))
time.sleep(1)
raise RuntimeError('No completion marker; inspect owned diagnostic process before retrying')
if __name__ == '__main__':
main()