#!/usr/bin/python3.11 # SPDX-License-Identifier: MPL-2.0 """Narrow stdio-to-socket adapter for the Android CameraService broker.""" import os import json import socket import sys SOCKET = '/work/camera-ipc/camera.sock' def read_exact(stream, size): data = bytearray() while len(data) < size: chunk = stream.recv(size - len(data)) if not chunk: raise EOFError('Camera broker closed the session') data.extend(chunk) return bytes(data) def forward(sock, target, size): header = read_exact(sock, size) target.write(header); target.flush() return header def packet(sock, output): header = read_exact(sock, 4) size = int.from_bytes(header, 'little') if size > 65536: raise ValueError('Camera broker sent an oversized response') payload = read_exact(sock, size) output.write(header + payload); output.flush() return json.loads(payload.decode('utf-8')) def main(): client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client.connect(SOCKET) output = os.fdopen(os.dup(1), 'wb', buffering=0) try: client.sendall(b'start\n') header = forward(client, output, 4) length = int.from_bytes(header, 'little') if not 0 < length <= 65536: return 2 forward(client, output, length) while True: command = sys.stdin.buffer.readline(2049) if not command or len(command) > 2048: break client.sendall(command) if command.strip() == b'frame': header = forward(client, output, 8) length = int.from_bytes(header[4:], 'little') if length > 320 * 240 * 3 // 2: return 3 if length: forward(client, output, length) elif command.strip() == b'stop': packet(client, output) break else: response = packet(client, output) jpeg = response.get('jpegLength', 0) if isinstance(jpeg, int) and 0 < jpeg <= 32 * 1024 * 1024: forward(client, output, jpeg) except (BrokenPipeError, ConnectionError, EOFError): return 0 finally: client.close(); output.close() return 0 if __name__ == '__main__': sys.exit(main())