This commit is contained in:
Andrii Dokhniak 2025-04-11 13:30:19 +02:00
parent 782d390f30
commit 650757fe19
5 changed files with 39 additions and 33 deletions

View File

@ -1,20 +1,20 @@
import { WebSocketServer } from "ws"; import { WebSocketServer } from "ws";
import child_process from "child_process"; import child_process from "child_process";
import fs from "fs"; import fs from "fs";
import { send_notification } from "./notifications.mjs" import { send_notification } from "./notifications.mjs";
async function spawnPromise(program, args) { async function spawnPromise(program, args) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let output = ""; let output = "";
const process = child_process.spawn(program, args); const process = child_process.spawn(program, args);
process.stdout.on('data', (data) => { process.stdout.on("data", (data) => {
output += data; output += data;
}); });
process.stderr.on('data', (data) => { process.stderr.on("data", (data) => {
output += data; output += data;
}); });
process.on("close", (code) => { process.on("close", (code) => {
resolve({output, code}); resolve({ output, code });
}); });
}); });
} }
@ -41,7 +41,11 @@ wss.on("connection", (ws) => {
await spawnPromise("bash", ["/conf/home.sh"]); await spawnPromise("bash", ["/conf/home.sh"]);
} else if (data === "install") { } else if (data === "install") {
const res = await spawnPromise("bash", ["/conf/install.sh"]); const res = await spawnPromise("bash", ["/conf/install.sh"]);
send_notification(res.code === 0, "Installing the application", res.output); send_notification(
res.code === 0,
"Installing the application",
res.output
);
} else if (data.includes("drag")) { } else if (data.includes("drag")) {
const dataSplit = data.split(" "); const dataSplit = data.split(" ");

View File

@ -4,12 +4,11 @@ import { WebSocketServer } from "ws";
const notification_proxy = new WebSocketServer({ port: 3001 }); const notification_proxy = new WebSocketServer({ port: 3001 });
let notification_subs = []; let notification_subs = [];
notification_proxy.on('connection', (ws) => { notification_proxy.on("connection", (ws) => {
notification_subs.push(ws); notification_subs.push(ws);
}); });
export function send_notification(is_ok, context, message) export function send_notification(is_ok, context, message) {
{
let updated_subs = []; let updated_subs = [];
if (notification_subs.length === 0) { if (notification_subs.length === 0) {
@ -17,19 +16,25 @@ export function send_notification(is_ok, context, message)
} }
for (const sub of notification_subs) { for (const sub of notification_subs) {
if (sub.readyState == WebSocket.CONNECTING) { if (sub.readyState == WebSocket.CONNECTING) {
console.log("WARNING: Unable to forward a notification to client that is still connecting"); console.log(
"WARNING: Unable to forward a notification to client that is still connecting"
);
updated_subs.push(sub); updated_subs.push(sub);
} else { } else {
try { try {
sub.send(JSON.stringify({ sub.send(
JSON.stringify({
is_ok, is_ok,
context, context,
message message,
})); })
);
updated_subs.push(sub); updated_subs.push(sub);
} catch { } catch {
sub.close(); sub.close();
console.log("WARNING: Fail to send a notification, closing the connection"); console.log(
"WARNING: Fail to send a notification, closing the connection"
);
} }
} }
} }

View File

@ -6,9 +6,9 @@ import {
waitFullBoot, waitFullBoot,
} from "./screenshot.mjs"; } from "./screenshot.mjs";
import { execSync } from 'node:child_process'; import { execSync } from "node:child_process";
import fileUpload from 'express-fileupload'; import fileUpload from "express-fileupload";
const device_size_x = 320; const device_size_x = 320;
const device_size_y = 640; const device_size_y = 640;
@ -16,7 +16,7 @@ const device_size_y = 640;
const app = express(); const app = express();
app.use(express.urlencoded({ extended: false })); app.use(express.urlencoded({ extended: false }));
app.use(express.static('/code/dist')) app.use(express.static("/code/dist"));
console.log("Waiting for full boot..."); console.log("Waiting for full boot...");
await waitFullBoot(); await waitFullBoot();
@ -62,23 +62,23 @@ app.post("/back", function (req, res) {
// default options // default options
app.use(fileUpload()); app.use(fileUpload());
app.post('/upload_apk', async function (req, res) { app.post("/upload_apk", async function (req, res) {
if (!req.files || Object.keys(req.files).length === 0) { if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.'); return res.status(400).send("No files were uploaded.");
} }
execSync("rm -rf /shared_buffer/*"); execSync("rm -rf /shared_buffer/*");
if (Array.isArray(req.files.app)) { if (Array.isArray(req.files.app)) {
for (const [idx, file] of req.files.app.entries()) { for (const [idx, file] of req.files.app.entries()) {
let uploadPath = '/shared_buffer/app' + idx + '.apk'; let uploadPath = "/shared_buffer/app" + idx + ".apk";
await file.mv(uploadPath); await file.mv(uploadPath);
} }
} else { } else {
let uploadPath = '/shared_buffer/app' + 0 + '.apk'; let uploadPath = "/shared_buffer/app" + 0 + ".apk";
await req.files.app.mv(uploadPath); await req.files.app.mv(uploadPath);
} }
android_websocket.send(`install`); android_websocket.send(`install`);
res.send('Files uploaded!'); res.send("Files uploaded!");
}) });
app.post("/home", function (req, res) { app.post("/home", function (req, res) {
android_websocket.send(`home`); android_websocket.send(`home`);
@ -110,4 +110,3 @@ app.post("/drag", function (req, res) {
}); });
app.listen(8080, () => console.log("Listening in port 8080")); app.listen(8080, () => console.log("Listening in port 8080"));

View File

@ -13,12 +13,11 @@ async function screenshot() {
while (android_websocket.readyState != WebSocket.OPEN) { while (android_websocket.readyState != WebSocket.OPEN) {
await sleep(15); await sleep(15);
retries++; retries++;
if (retries > 50) if (retries > 50) {
{
console.error("Screenshot ws timeout"); console.error("Screenshot ws timeout");
doneWrite = 0; doneWrite = 0;
screenshotPromise = null; screenshotPromise = null;
return ; return;
} }
} }
android_websocket.send("screenshot"); android_websocket.send("screenshot");

View File

@ -1,5 +1,4 @@
import { render, Component } from "preact"; import { render, Component } from "preact";
import { useState } from "preact/hooks";
function rand_num() { function rand_num() {
return Math.floor(Math.random() * Number.MAX_VALUE); return Math.floor(Math.random() * Number.MAX_VALUE);
@ -11,12 +10,12 @@ class Notifications extends Component {
this.state = { notifications: [] }; this.state = { notifications: [] };
} }
remove_notification (id) { remove_notification(id) {
const newNotifications = this.state.notifications.filter( const newNotifications = this.state.notifications.filter(
(notification) => notification.id !== id (notification) => notification.id !== id
); );
this.setState({ notifications: newNotifications }); this.setState({ notifications: newNotifications });
}; }
componentDidMount() { componentDidMount() {
// This should also be dynamic // This should also be dynamic
@ -32,8 +31,8 @@ class Notifications extends Component {
}); });
// a 10 sec timeout // a 10 sec timeout
setTimeout(() => { setTimeout(() => {
this.remove_notification(new_id) this.remove_notification(new_id);
}, 10000) }, 10000);
}; };
} }