48 lines
2.4 KiB
Python
48 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""RemoteDesktop consent broker for the local EIS input worker."""
|
|
import json
|
|
import sys
|
|
import os
|
|
import subprocess
|
|
try:
|
|
import gi
|
|
gi.require_version('Gio', '2.0')
|
|
from gi.repository import Gio, GLib
|
|
except Exception as exc:
|
|
print(json.dumps({'type': 'error', 'reason': f'PyGObject unavailable: {exc}'}), flush=True)
|
|
raise SystemExit(1)
|
|
|
|
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
|
|
proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None, 'org.freedesktop.portal.Desktop', '/org/freedesktop/portal/desktop', 'org.freedesktop.portal.RemoteDesktop', None)
|
|
def request(method, signature, values):
|
|
request_path = proxy.call_sync(method, GLib.Variant(signature, values), Gio.DBusCallFlags.NONE, -1, None).unpack()[0]
|
|
loop = GLib.MainLoop(); result = {'code': 1, 'results': {}}
|
|
def response(_conn, _sender, _path, _interface, _member, params):
|
|
result['code'], result['results'] = params.unpack(); loop.quit()
|
|
sub = bus.signal_subscribe(None, 'org.freedesktop.portal.Request', 'Response', request_path, None, Gio.DBusSignalFlags.NONE, response)
|
|
loop.run(); bus.signal_unsubscribe(sub)
|
|
if result['code'] != 0: raise RuntimeError(f'{method} portal response {result["code"]}')
|
|
return result['results']
|
|
try:
|
|
token = f'jarvis{GLib.get_real_time()}'
|
|
session = request('CreateSession', '(a{sv})', ({'session_handle_token': GLib.Variant('s', token)},))['session_handle']
|
|
request('SelectDevices', '(oa{sv})', (session, {'types': GLib.Variant('u', 3), 'persist_mode': GLib.Variant('u', 2)}))
|
|
request('Start', '(osa{sv})', (session, '', {}))
|
|
if not os.environ.get('JARVIS_LIBEI_BRIDGE'):
|
|
raise RuntimeError('portal consent succeeded but no local libei injector is configured; refusing to claim input readiness')
|
|
injector = subprocess.Popen(os.environ['JARVIS_LIBEI_BRIDGE'], shell=True, stdin=subprocess.PIPE, text=True)
|
|
print(json.dumps({'type': 'ready', 'session': session, 'restore_token_present': True}), flush=True)
|
|
except Exception as exc:
|
|
print(json.dumps({'type': 'error', 'reason': str(exc)}), flush=True)
|
|
for line in sys.stdin:
|
|
try:
|
|
action = json.loads(line)
|
|
if action.get('type') == 'close':
|
|
break
|
|
if 'injector' in globals() and injector.stdin:
|
|
injector.stdin.write(json.dumps(action) + '\n'); injector.stdin.flush()
|
|
except Exception:
|
|
continue
|
|
if 'injector' in globals():
|
|
injector.terminate()
|