|
|
WebSocket´ø½ØÍ¼/µã»÷/»¬ÆÁ/°´¼ü/Åܽű¾/״̬²éѯ
https://www.yuque.com/aiwork/nba2pr/bqfv1ssogplvivae
- // =====================================================================
- // AIWROK WebSocket ¿Í»§¶Ë£¨ÊµÓÃ°æ ¡ª ´ø½ØÍ¼/µã»÷/»¬ÆÁ/°´¼ü/Åܽű¾/״̬²éѯ£©
- //
- // ·þÎñ¶Ë¿ÉÏ·¢µÄÖ¸Átype£©£º
- // CMD_SCREENSHOT ½ØÍ¼£¨base64 ·µ»Ø£¬¿Éµ÷ quality 0.3~0.95£©
- // CMD_CLICK µã»÷ {x, y}
- // CMD_SWIPE »¬ÆÁ {x1,y1,x2,y2,duration}
- // CMD_KEY °´¼ü {key: "BACK"|"HOME"|"RECENT"|"POWER"|"NOTIFICATION"|Êý×ÖkeyCode}
- // CMD_RUN_SCRIPT Ô¶³ÌÆô¶¯½Å±¾ {path: "/sdcard/AIWROK/xxx.js", timeoutSec, args:{...}}
- // CMD_STATUS ²éÉ豸״̬£¨°üÃû/ÄÚ´æ/ÔËÐÐʱ³¤/·Ö±æÂÊ£©
- // CMD_TOAST µ¯Ìáʾ {msg}
- // CMD_CLEAR_CACHE Çå³ý±¾µØ»º´æ
- // MANAGE_TASK_NEW Ï·¢ÈÎÎñ£¨¼æÈÝÔ¸ñʽ£¬×Ô¶¯×ª³É CMD_RUN_SCRIPT »ò»ØÖ´£©
- // MANAGE_CMD_STOP_ALL Í£Ö¹Ò»ÇУ¨Ð´±êÖ¾ + Éè stopAll + »Ø CLIENT_STOPPING + ¹Ø WS£©
- // SERVER_PING ÐÄÌø»Ø°ü
- //
- // ¿Í»§¶ËÉϱ¨£º
- // CLIENT_REGISTER / CLIENT_HEARTBEAT / CLIENT_TASK_ACK
- // CMD_RESP £¨Ã¿Ìõ CMD_* Ö¸ÁîÖ´ÐÐÍê¶¼»Ø£¬¸ñʽͳһ£¬º¬ ok/msg/data/ts/cmdId£©
- // CLIENT_STOPPING £¨Í£Ö¹Ç°×îºóÒ»Ìõ¹ã²¥¸ø·þÎñ¶Ë£©
- //
- // Ó÷¨£ºCFG.serverUrl ¸Ä³É ws://ip:port/ws£¬Ö±½ÓÅÜ
- // =====================================================================
- // ---------- È«¾Ö±äÁ¿£¨±ØÐë·ÅÔÚÎļþ¶¥²¿£¬±ÜÃâ Rhino ES5 ReferenceError£©----------
- var G = {
- ws: null,
- clientId: null,
- isAllowReConnect: true,
- isInfiniteReConnect: true,
- reConnectMaxTimes: 10,
- reConnectTimes: 0,
- connectDelayMs: 3000,
- multiplier: 2,
- maxConnectDelayMs: 30000,
- heartbeatIntervalMs: 50000,
- heartbeatTimer: null,
- lastTs: 0,
- dispatcher: {},
- running: true,
- stopAll: false, // STOP_ALL È«¾Ö±êÖ¾£¨ÒµÎñ½Å±¾¶¼¿ÉÒÔ¶ÁÕâ¸öÍ˳ö£©
- startTime: nowSec(), // Æô¶¯Ê±¼ä´Á
- activeThreads: {}, // CMD_RUN_SCRIPT Æô¶¯µÄÏß³Ì id -> thread ¶ÔÏó
- STOP_FLAG: "/sdcard/AIWROK/STOP_ALL"
- };
- var CFG = {
- serverUrl: "ws://192.168.10.103:32101/ws", // Ö÷Ⱥ¿Ø·þÎñ¶Ë
- platform: "AIWROK",
- appName: "AIWROK_WebSocket¿Í»§¶Ë",
- debug: true,
- // ½ØÍ¼Ä¬ÈϲÎÊý£¨¿ÉÒÔ±» CMD_SCREENSHOT.data ¸²¸Ç£©
- defaultQuality: 0.55,
- maxWidth: 1080, // ³¬¹ý¾ÍµÈ±ÈËõ·Å£¬¼õÉÙ´ø¿í
- stopReceiverIntervalMs: 1500
- };
- // ---------- ¹¤¾ßº¯Êý ----------
- function nowSec() {
- return Math.floor((new Date()).getTime() / 1000);
- }
- function nowMs() {
- return (new Date()).getTime();
- }
- function jitter(ms) {
- return Math.floor(ms * (0.85 + Math.random() * 0.3));
- }
- function readTextFile(path) {
- try {
- var br = new java.io.BufferedReader(
- new java.io.InputStreamReader(new java.io.FileInputStream(path), "utf-8"));
- var sb = new java.lang.StringBuilder();
- var line;
- while ((line = br.readLine()) != null) sb.append(line).append("\n");
- br.close();
- return "" + sb.toString();
- } catch (e) { return null; }
- }
- function deleteFileOrDir(p) {
- try {
- var f = new java.io.File(p);
- if (!f.exists()) return true;
- if (f.isDirectory()) {
- var list = f.listFiles();
- for (var i = 0; i < list.length; i++) deleteFileOrDir(list[i].getAbsolutePath());
- }
- return f["delete"]();
- } catch (e) { return false; }
- }
- function humanSize(bytes) {
- if (bytes < 1024) return bytes + "B";
- if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + "KB";
- return (bytes / 1024 / 1024).toFixed(2) + "MB";
- }
- // ---------- ±¾µØ»º´æ·â×° ----------
- var Cache = {
- BASE: "/sdcard/AIWROK/wscache",
- ensure: function () {
- try {
- var f = new java.io.File(this.BASE);
- if (!f.exists()) f.mkdirs();
- } catch (e) {}
- },
- read: function (key) {
- this.ensure();
- try {
- var p = this.BASE + "/" + encodeURIComponent(key) + ".json";
- return JSON.parse(readTextFile(p));
- } catch (e) { return null; }
- },
- write: function (key, val) {
- this.ensure();
- try {
- var p = this.BASE + "/" + encodeURIComponent(key) + ".json";
- var fw = new java.io.FileWriter(p);
- fw.write(JSON.stringify(val));
- fw.close();
- return true;
- } catch (e) { return false; }
- },
- clear: function (key) {
- try {
- var p = this.BASE + "/" + encodeURIComponent(key) + ".json";
- var f = new java.io.File(p);
- if (f.exists()) f["delete"]();
- } catch (e) {}
- },
- clearAll: function () {
- return deleteFileOrDir(this.BASE);
- }
- };
- // ³¢ÊÔ»Ö¸´ client_id
- G.clientId = (Cache.read("wsc_client_id") || {}).id || null;
- // ---------- ͳһ CMD_RESP ----------
- function cmdResp(cmdName, cmdId, ok, msg, data) {
- var obj = {
- type: "CMD_RESP",
- cmd: cmdName,
- cmdId: cmdId || ("cid_" + nowMs() + "_" + Math.floor(Math.random() * 1000)),
- ok: !!ok,
- msg: msg || (ok ? "ok" : "failed"),
- ts: nowSec()
- };
- if (typeof data !== "undefined") obj.data = data;
- if (G.clientId) obj.client_id = G.clientId;
- WSC.send(obj);
- return obj;
- }
- // ---------- ÏûÏ¢ÅÉ·¢Æ÷ ----------
- var WSC = {
- on: function (type, fn) {
- if (!G.dispatcher[type]) G.dispatcher[type] = [];
- G.dispatcher[type].push(fn);
- },
- off: function (type, fn) {
- var arr = G.dispatcher[type] || [];
- for (var i = arr.length - 1; i >= 0; i--) if (arr[i] === fn) arr.splice(i, 1);
- },
- fire: function (type, msgObj) {
- var arr = G.dispatcher[type] || [];
- for (var i = 0; i < arr.length; i++) {
- try {
- arr[i](msgObj);
- } catch (e) {
- printl("ÅÉ·¢[" + type + "]Òì³£: " + (e.message || e));
- }
- }
- },
- send: function (obj) {
- if (!G.ws) return false;
- if (G.clientId && obj.clientId == null) obj.client_id = G.clientId;
- if (obj.timestamp == null) obj.timestamp = nowSec();
- if (obj.platform == null) obj.platform = CFG.platform;
- var txt = JSON.stringify(obj);
- try {
- G.ws.send(txt);
- if (CFG.debug) {
- var head = (obj.type || "?") + " ";
- // ½ØÍ¼»Ø°ü base64 Ì«³¤£¬Ö»´òÕªÒª
- if (obj.type === "CMD_RESP" && obj.data && obj.data.base64) {
- printl("SEND -> " + head + "[" + obj.cmd + "] base64_len=" + obj.data.base64.length + " (" + obj.data.w + "x" + obj.data.h + " q=" + obj.data.quality + ")");
- } else {
- printl("SEND -> " + head + txt.slice(0, 160));
- }
- }
- return true;
- } catch (e) {
- printl("·¢ËÍʧ°Ü: " + (e.message || e));
- return false;
- }
- },
- stop: function () {
- G.running = false;
- G.isAllowReConnect = false;
- if (G.heartbeatTimer) {
- try { clearTimeout(G.heartbeatTimer); } catch (e) {}
- G.heartbeatTimer = null;
- }
- try { if (G.ws) G.ws.close(); } catch (e) {}
- }
- };
- // ---------- ÐÄÌø£¨°²È«°æ£ºÁ´Ê½ setTimeout È«°ü try-catch£¬±ÜÃâ AIWROK δ²¶»ñÒ쳣ɱ½Å±¾£©----------
- function startHeartbeat() {
- if (G.heartbeatTimer) {
- try { clearTimeout(G.heartbeatTimer); } catch (e) {}
- }
- (function tick() {
- try {
- if (!G.running) return;
- var imei = "";
- try { if (typeof device !== "undefined") imei = device.getIMEI() || ""; } catch (e) {}
- WSC.send({
- type: "CLIENT_HEARTBEAT",
- imei: imei,
- platform: CFG.platform,
- app: CFG.appName,
- runtimeSec: nowSec() - G.startTime,
- stopAll: !!G.stopAll
- });
- } catch (eOuter) {
- try { printl("ÐÄÌøÒì³£(ÒѶµ×¡): " + (eOuter.message || eOuter)); } catch (eL) {}
- }
- try {
- G.heartbeatTimer = setTimeout(tick, G.heartbeatIntervalMs);
- } catch (eTimer) {
- try { printl("ÐÄÌøÏÂÒ»´Îµ÷¶Èʧ°Ü: " + (eTimer.message || eTimer)); } catch (eL) {}
- }
- })();
- }
- // ---------- É豸ÐÅÏ¢²É¼¯£¨Á¬½ÓʱÓã¬Ò²±» CMD_STATUS ¸´Óã©----------
- function collectDeviceInfo() {
- var info = {
- platform: CFG.platform,
- app: CFG.appName,
- imei: "",
- android: "",
- model: "",
- brand: "",
- w: 1080,
- h: 2400,
- dpi: 0,
- frontPkg: "",
- internalMB: 0,
- sdMB: 0,
- clientId: G.clientId,
- runtimeSec: nowSec() - G.startTime,
- stopAll: !!G.stopAll,
- activeScriptCount: 0
- };
- try { if (typeof device !== "undefined") info.imei = device.getIMEI() || ""; } catch (e) {}
- try { info.android = java.lang.System.getProperty("os.version") + ""; } catch (e) {}
- try { info.model = android.os.Build.MODEL + ""; } catch (e) {}
- try { info.brand = android.os.Build.BRAND + ""; } catch (e) {}
- try {
- if (typeof screen !== "undefined") {
- info.w = screen.getScreenWidth();
- info.h = screen.getScreenHeight();
- try { info.dpi = screen.getDensityDpi(); } catch (e2) {}
- }
- } catch (e) {}
- try {
- var am = context.getSystemService(android.content.Context.ACTIVITY_SERVICE);
- info.frontPkg = am.getRunningTasks(1).get(0).topActivity.getPackageName() + "";
- } catch (e) {}
- try {
- var stat = new android.os.StatFs(android.os.Environment.getDataDirectory().getAbsolutePath());
- info.internalMB = Math.floor((stat.getAvailableBytes() * 1.0) / 1024 / 1024);
- } catch (e) {}
- try {
- var sd = android.os.Environment.getExternalStorageDirectory();
- var s2 = new android.os.StatFs(sd.getAbsolutePath());
- info.sdMB = Math.floor((s2.getAvailableBytes() * 1.0) / 1024 / 1024);
- } catch (e) {}
- var cnt = 0;
- try { for (var k in G.activeThreads) if (G.activeThreads.hasOwnProperty(k)) cnt++; } catch (e) {}
- info.activeScriptCount = cnt;
- return info;
- }
- // ---------- ʼþ»Øµ÷£ºonConnected ----------
- function wsOnConnected() {
- G.reConnectTimes = 0;
- G.connectDelayMs = 3000;
- printl("✓ Á¬½Ó³É¹¦ ¡ª ÎÕÊÖÍê³É");
- var info = collectDeviceInfo();
- WSC.send({
- type: "CLIENT_REGISTER",
- platform: info.platform,
- imei: info.imei,
- app: info.app,
- lastClientId: G.clientId,
- screen: info.w + "x" + info.h,
- dpi: info.dpi,
- android: info.android,
- model: info.model,
- brand: info.brand,
- internalMB: info.internalMB,
- sdMB: info.sdMB
- });
- startHeartbeat();
- WSC.fire("_connected", info);
- }
- // ---------- ʼþ»Øµ÷£ºonTextMessage ----------
- function wsOnTextMessage(msg) {
- var s = "" + msg;
- if (CFG.debug) printl("RECV <- " + s.slice(0, 200));
- var obj = null;
- try { obj = JSON.parse(s); } catch (e) {
- printl("·ÇJSONÏûÏ¢£¬ºöÂÔ: " + s.slice(0, 120));
- WSC.fire("_text", { raw: s });
- return;
- }
- if (obj && obj.type === "SERVER_INIT") {
- if (obj.client_id) {
- G.clientId = obj.client_id;
- Cache.write("wsc_client_id", { id: G.clientId });
- printl("·þÎñ¶Ë·ÖÅä client_id: " + G.clientId + "£¨Òѱ¾µØ±£´æ£©");
- }
- if (obj.msg) printl("·þÎñ¶ËÏûÏ¢: " + obj.msg);
- }
- if (obj && obj.type) {
- WSC.fire(obj.type, obj);
- WSC.fire("_any", obj);
- }
- }
- // ---------- ʼþ»Øµ÷£ºonConnectError ----------
- function wsOnConnectError() {
- printl("✗ Á¬½Óʧ°Ü£¨Í¨³£·þÎñ¶Ë먦Æô»ò¶Ë¿Ú²»Í¨£©");
- scheduleReconnect();
- }
- // ---------- ʼþ»Øµ÷£ºonDisconnected ----------
- function wsOnDisconnected() {
- printl("✗ Á¬½ÓÒѶϿª");
- if (G.heartbeatTimer) {
- try { clearTimeout(G.heartbeatTimer); } catch (e) {}
- G.heartbeatTimer = null;
- }
- scheduleReconnect();
- }
- // ---------- Á¬½Ó + ʼþÖØ¹Ò ----------
- function connectWebSocket() {
- if (G.ws) {
- try { G.ws.close(); } catch (e) {}
- G.ws = null;
- }
- printl("¿ªÊ¼Á¬½Ó: " + CFG.serverUrl + " (ÖØÊÔ¼ÆÊý " + G.reConnectTimes + "/" + G.reConnectMaxTimes + ")");
- var ws = null;
- try { ws = new websocket(); }
- catch (e) {
- printl("new websocket() ʧ°Ü: " + (e.message || e));
- scheduleReconnect();
- return;
- }
- G.ws = ws;
- // ¹Òʼþ£ºAIWROK аæ ws.event() ÓÅÏÈ£¬Ê§°Ü¶µµ×ÊôÐÔ¸³Öµ
- var eventOk = false;
- try {
- ws.event(wsOnConnected, wsOnTextMessage, wsOnConnectError, wsOnDisconnected);
- eventOk = true;
- if (CFG.debug) printl("ws.event() ¹Òʼþ³É¹¦");
- } catch (e1) {
- if (CFG.debug) printl("ws.event() ʧ°Ü: " + (e1.message || e1) + " ¡ª ³¢ÊÔÊôÐÔ¸³Öµ");
- }
- if (!eventOk) {
- try {
- ws.onConnected = wsOnConnected;
- ws.onTextMessage = wsOnTextMessage;
- ws.onConnectError = wsOnConnectError;
- ws.onDisconnected = wsOnDisconnected;
- if (CFG.debug) printl("ÊôÐÔ¸³Öµ¹Òʼþ³É¹¦");
- } catch (e2) {
- printl("Á½ÖÖʼþ¹Ò·¨¶¼Ê§°Ü: " + (e2.message || e2));
- }
- }
- // ·¢ÆðÁ¬½Ó£ºAIWROK connet(Ë«n) ÓÅÏÈ£¬Ê§°Ü»ØÍË connect
- try {
- var ret = null;
- try { ret = ws.connet(CFG.serverUrl); }
- catch (eA) {
- printl("connet() Òì³£: " + (eA.message || eA) + " ¡ª »ØÍË connect()");
- ret = ws.connect(CFG.serverUrl);
- }
- if (CFG.debug) printl("Á¬½Ó·¢Æð·µ»Ø: " + (ret == null ? "null(±íʾÒÑ·¢Æð)" : ret));
- } catch (eB) {
- printl("Á½ÖÖÁ¬½Ó·½Ê½¶¼Ê§°Ü: " + (eB.message || eB));
- scheduleReconnect();
- }
- }
- // ---------- Ö¸ÊýÍ豆 + ¶¶¶¯ÖØÁ¬£¨°²È«°æ£ºsetTimeout ×îÍâ²ã°ü try-catch£©----------
- function scheduleReconnect() {
- try {
- if (!G.running) return;
- if (!G.isAllowReConnect) return;
- G.reConnectTimes += 1;
- if (!G.isInfiniteReConnect && G.reConnectTimes > G.reConnectMaxTimes) {
- printl("⚠️ ³¬¹ý×î´óÖØÊÔ´ÎÊý(" + G.reConnectMaxTimes + ")£¬Í£Ö¹ÖØÁ¬");
- return;
- }
- G.connectDelayMs = Math.min(G.connectDelayMs * G.multiplier, G.maxConnectDelayMs);
- var waitMs = jitter(G.connectDelayMs);
- printl("Ï´ÎÖØÁ¬µÈ´ý " + (waitMs / 1000).toFixed(2) + "s (·â¶¥" + (G.maxConnectDelayMs / 1000) + "s)");
- setTimeout(function () {
- try { connectWebSocket(); } catch (e) {
- printl("ÖØÁ¬»Øµ÷Òì³£(ÒѶµ×¡): " + (e.message || e));
- scheduleReconnect();
- }
- }, waitMs);
- } catch (eOuter) {
- printl("scheduleReconnect Íâ²ãÒì³£: " + (eOuter.message || eOuter));
- }
- }
- // =====================================================================
- // ÒµÎñÖ¸ÁîʵÏÖ£¨ÕæÕýÄÜÓõŦÄÜ£¬²»Êǿտǣ©
- // =====================================================================
- // -------- CMD_SCREENSHOT£º½ØÍ¼£¬base64 ·µ»Ø -------
- // Ö§³Ö: o.data = { quality:0.3~0.95, maxWidth:1080, full:true/false }
- WSC.on("CMD_SCREENSHOT", function (o) {
- var t0 = nowMs();
- var cmdId = o.cmdId;
- try {
- var quality = CFG.defaultQuality;
- if (o && o.data && o.data.quality && o.data.quality > 0 && o.data.quality <= 1) {
- quality = o.data.quality;
- }
- var maxW = CFG.maxWidth;
- if (o && o.data && o.data.maxWidth && o.data.maxWidth > 0) maxW = o.data.maxWidth;
- // 1) fastCapture ½ØÍ¼
- var bmp = null;
- try {
- if (typeof image !== "undefined") {
- bmp = image.fastCapture();
- } else {
- cmdResp("CMD_SCREENSHOT", cmdId, false, "image ¶ÔÏ󲻿ÉÓÃ");
- return;
- }
- } catch (e) {
- cmdResp("CMD_SCREENSHOT", cmdId, false, "fastCapture Òì³£: " + (e.message || e));
- return;
- }
- if (!bmp) { cmdResp("CMD_SCREENSHOT", cmdId, false, "½ØÍ¼·µ»Ø¿Õ"); return; }
- var w = bmp.getWidth();
- var h = bmp.getHeight();
- // 2) ³¬¿í¾ÍµÈ±ÈËõ·Å
- if (w > maxW) {
- var ratio = maxW * 1.0 / w;
- var newH = Math.floor(h * ratio);
- try {
- var scaled = android.graphics.Bitmap.createScaledBitmap(bmp, maxW, newH, true);
- try { bmp.recycle(); } catch (e) {}
- bmp = scaled;
- w = maxW;
- h = newH;
- } catch (e2) {}
- }
- // 3) JPEG ѹËõת base64
- var baos = new java.io.ByteArrayOutputStream();
- bmp.compress(android.graphics.Bitmap.CompressFormat.JPEG, Math.floor(quality * 100), baos);
- try { bmp.recycle(); } catch (e) {}
- var bytes = baos.toByteArray();
- var b64 = android.util.Base64.encodeToString(bytes, android.util.Base64.NO_WRAP);
- try { baos.close(); } catch (e) {}
- cmdResp("CMD_SCREENSHOT", cmdId, true, "ok", {
- base64: "" + b64,
- w: w,
- h: h,
- quality: quality,
- sizeKb: Math.floor(bytes.length / 1024),
- costMs: nowMs() - t0
- });
- } catch (eBig) {
- cmdResp("CMD_SCREENSHOT", cmdId, false, "½ØÍ¼×ÜÒì³£: " + (eBig.message || eBig));
- }
- });
- // -------- CMD_CLICK£ºµã»÷ {x, y} -------
- WSC.on("CMD_CLICK", function (o) {
- var cmdId = o.cmdId;
- var x = (o && o.data && o.data.x != null) ? parseInt(o.data.x, 10) : NaN;
- var y = (o && o.data && o.data.y != null) ? parseInt(o.data.y, 10) : NaN;
- if (isNaN(x) || isNaN(y) || x < 0 || y < 0) {
- cmdResp("CMD_CLICK", cmdId, false, "ȱÉÙÓÐЧ x/y ×ø±ê");
- return;
- }
- try {
- if (typeof action !== "undefined") {
- action.click(x, y);
- cmdResp("CMD_CLICK", cmdId, true, "ok", { x: x, y: y });
- } else {
- cmdResp("CMD_CLICK", cmdId, false, "action ¶ÔÏ󲻿ÉÓÃ");
- }
- } catch (e) {
- cmdResp("CMD_CLICK", cmdId, false, "µã»÷Òì³£: " + (e.message || e));
- }
- });
- // -------- CMD_SWIPE£º»¬ÆÁ {x1,y1,x2,y2,duration} -------
- WSC.on("CMD_SWIPE", function (o) {
- var cmdId = o.cmdId;
- var d = o && o.data ? o.data : {};
- var x1 = parseInt(d.x1, 10), y1 = parseInt(d.y1, 10);
- var x2 = parseInt(d.x2, 10), y2 = parseInt(d.y2, 10);
- var dur = d.duration ? parseInt(d.duration, 10) : 300;
- if ([x1, y1, x2, y2].some(function (n) { return isNaN(n) || n < 0; })) {
- cmdResp("CMD_SWIPE", cmdId, false, "×ø±êȱʧ");
- return;
- }
- try {
- if (typeof action !== "undefined") {
- action.swipe(x1, y1, x2, y2, dur);
- cmdResp("CMD_SWIPE", cmdId, true, "ok", { x1: x1, y1: y1, x2: x2, y2: y2, duration: dur });
- } else {
- cmdResp("CMD_SWIPE", cmdId, false, "action ¶ÔÏ󲻿ÉÓÃ");
- }
- } catch (e) {
- cmdResp("CMD_SWIPE", cmdId, false, "»¬ÆÁÒì³£: " + (e.message || e));
- }
- });
- // -------- CMD_KEY£º°´¼ü -------
- // data.key Ö§³Ö: "BACK" / "HOME" / "RECENT" / "POWER" / "NOTIFICATION" / Êý×Ö keyCode
- WSC.on("CMD_KEY", function (o) {
- var cmdId = o.cmdId;
- var key = (o && o.data && o.data.key != null) ? ("" + o.data.key) : "";
- if (!key) { cmdResp("CMD_KEY", cmdId, false, "ȱÉÙ key"); return; }
- try {
- // ·½Ê½1£ºaction ¿ì½Ý·½·¨
- if (typeof action !== "undefined") {
- var k = key.toUpperCase();
- if (k === "BACK") { action.back(); cmdResp("CMD_KEY", cmdId, true, "BACK"); return; }
- if (k === "HOME") { action.home(); cmdResp("CMD_KEY", cmdId, true, "HOME"); return; }
- if (k === "RECENT" || k === "RECENTS" || k === "APP_SWITCH") {
- action.recents(); cmdResp("CMD_KEY", cmdId, true, "RECENT"); return;
- }
- }
- // ·½Ê½2£ºsystempress Êý×Ö keyCode
- var code = parseInt(key, 10);
- if (!isNaN(code) && code > 0) {
- if (typeof systempress !== "undefined") {
- systempress(code);
- cmdResp("CMD_KEY", cmdId, true, "keyCode " + code);
- return;
- }
- }
- // ·½Ê½3£ºshell input keyevent£¨¶µµ×£©
- var shellKey = null;
- var k2 = key.toUpperCase();
- if (k2 === "BACK") shellKey = "4";
- else if (k2 === "HOME") shellKey = "3";
- else if (k2 === "RECENT" || k2 === "RECENTS") shellKey = "187";
- else if (k2 === "POWER") shellKey = "26";
- else if (k2 === "NOTIFICATION") shellKey = "83";
- else if (!isNaN(code) && code > 0) shellKey = "" + code;
- if (shellKey) {
- try {
- java.lang.Runtime.getRuntime().exec(["su", "-c", "input keyevent " + shellKey]).waitFor();
- cmdResp("CMD_KEY", cmdId, true, "shell key " + key);
- return;
- } catch (eS) {}
- try {
- java.lang.Runtime.getRuntime().exec(["input", "keyevent", shellKey]).waitFor();
- cmdResp("CMD_KEY", cmdId, true, "shell key(no su) " + key);
- return;
- } catch (eS2) {}
- }
- cmdResp("CMD_KEY", cmdId, false, "²»Ö§³ÖµÄ key: " + key);
- } catch (e) {
- cmdResp("CMD_KEY", cmdId, false, "°´¼üÒì³£: " + (e.message || e));
- }
- });
- // -------- CMD_RUN_SCRIPT£ºÔ¶³ÌÅܽű¾ -------
- // data = { path, timeoutSec, args }
- // ·µ»Ø { threadId, pid, ok }£¬ºóÐø¿É²éÏß³Ì״̬
- WSC.on("CMD_RUN_SCRIPT", function (o) {
- var cmdId = o.cmdId;
- var d = o && o.data ? o.data : {};
- var path = (d.path || "").trim();
- var timeoutSec = d.timeoutSec ? parseInt(d.timeoutSec, 10) : 600;
- if (!path) { cmdResp("CMD_RUN_SCRIPT", cmdId, false, "ȱÉٽű¾ path"); return; }
- // ·¾¶Ö§³ÖÁ½ÖÖ£º¾ø¶Ô·¾¶£¬»òÏà¶ÔÓÚ /sdcard/AIWROK/
- var fullPath = path;
- if (!new java.io.File(path).isAbsolute()) {
- fullPath = "/sdcard/AIWROK/" + path;
- }
- if (!new java.io.File(fullPath).exists()) {
- cmdResp("CMD_RUN_SCRIPT", cmdId, false, "½Å±¾²»´æÔÚ: " + fullPath);
- return;
- }
- try {
- // AIWROK Ô¼Êø£ºÓà thread.runJsFile() ¼ÓÔØÍⲿ½Å±¾
- if (typeof thread === "undefined") {
- cmdResp("CMD_RUN_SCRIPT", cmdId, false, "thread ¶ÔÏ󲻿ÉÓÃ");
- return;
- }
- var tid = "T" + nowMs() + "_" + Math.floor(Math.random() * 10000);
- // ¹¹Ôì³ÉÔ±£º°Ñ client_id¡¢CMD_RUN_SCRIPT µÄ args¡¢STOP_ALL ±ê־·¾¶·Å½ø½Å±¾¹²Ïí±äÁ¿
- try { scriptShared = { CMD_ARGS: d.args || {}, STOP_FLAG: G.STOP_FLAG, CLIENT_ID: G.clientId, CMD_ID: cmdId }; } catch (eSh) {}
- var th = thread.runJsFile(fullPath);
- G.activeThreads[tid] = { thread: th, path: fullPath, startAt: nowSec(), timeoutSec: timeoutSec, cmdId: cmdId };
- // ÊØ»¤Ð³Ì£º·Ç×èÈûÁ´Ê½ setTimeout ÂÖѯ£¨²»Õ¼ÓÃÅÉ·¢Ị̈߳¬±ÜÃâ AIWROK ɱ½Å±¾£©
- (function watcherStep() {
- try {
- var rec = G.activeThreads[tid];
- if (!rec) return; // ÒѾ±» STOP_ALL ÇåÀíµôÁË
- var stillAlive = true;
- try {
- // isAlive ÔÚ²¿·Ö AIWROK °æ±¾ÀïÊÇ×ֶβ»ÊÇ·½·¨£¬Á½ÖÖ¶¼¶µ×¡
- if (th && typeof th.isAlive === "function") stillAlive = th.isAlive();
- else if (th && typeof th.isAlive === "boolean") stillAlive = th.isAlive;
- else stillAlive = true;
- } catch (eChk) { stillAlive = false; }
- var runSec = nowSec() - rec.startAt;
- var timeIsUp = runSec >= (rec.timeoutSec + 1);
- var shouldStop = !stillAlive || timeIsUp || G.stopAll;
- if (!shouldStop) {
- setTimeout(watcherStep, 1000);
- return;
- }
- // ³¬Ê±»ò STOP_ALL -> Í£Ïß³Ì
- if (stillAlive && timeIsUp) {
- try { if (th && th.stop) th.stop(); } catch (eStop) {}
- }
- var cost = nowSec() - rec.startAt;
- try { delete G.activeThreads[tid]; } catch (eDel) {}
- WSC.send({
- type: "CLIENT_SCRIPT_RESULT",
- cmdId: cmdId,
- threadId: tid,
- path: fullPath,
- timeout: timeIsUp && stillAlive,
- runtimeSec: cost,
- stopAll: !!G.stopAll,
- ts: nowSec()
- });
- } catch (eOuter) {
- printl("CMD_RUN_SCRIPT ÊØ»¤Ð³ÌÒì³£(ÒѶµ×¡): " + (eOuter.message || eOuter));
- }
- })();
- cmdResp("CMD_RUN_SCRIPT", cmdId, true, "ÒÑÆô¶¯", { threadId: tid, path: fullPath, timeoutSec: timeoutSec });
- } catch (e) {
- cmdResp("CMD_RUN_SCRIPT", cmdId, false, "Æô¶¯Òì³£: " + (e.message || e));
- }
- });
- // -------- CMD_STATUS£º²é״̬ -------
- WSC.on("CMD_STATUS", function (o) {
- try {
- var info = collectDeviceInfo();
- // ÁлîÔ¾Ïß³Ì
- var threads = [];
- try {
- for (var k in G.activeThreads) if (G.activeThreads.hasOwnProperty(k)) {
- var t = G.activeThreads[k];
- threads.push({
- id: k,
- path: t.path,
- runSec: nowSec() - t.startAt,
- timeoutSec: t.timeoutSec
- });
- }
- } catch (e) {}
- info.threads = threads;
- cmdResp("CMD_STATUS", o && o.cmdId, true, "ok", info);
- } catch (e) {
- cmdResp("CMD_STATUS", o && o.cmdId, false, "״̬Òì³£: " + (e.message || e));
- }
- });
- // -------- CMD_TOAST£ºµ¯¸öÏûÏ¢ -------
- WSC.on("CMD_TOAST", function (o) {
- var cmdId = o && o.cmdId;
- var msg = (o && o.data && o.data.msg != null) ? ("" + o.data.msg) : "";
- if (!msg) { cmdResp("CMD_TOAST", cmdId, false, "ȱÉÙ msg"); return; }
- try {
- if (typeof toast !== "undefined") { toast(msg); }
- cmdResp("CMD_TOAST", cmdId, true, "ok", { msg: msg });
- } catch (e) {
- cmdResp("CMD_TOAST", cmdId, false, "toast Òì³£: " + (e.message || e));
- }
- });
- // -------- CMD_CLEAR_CACHE£ºÇå³ý±¾µØ»º´æ -------
- WSC.on("CMD_CLEAR_CACHE", function (o) {
- var cmdId = o && o.cmdId;
- try {
- Cache.clearAll();
- // ˳±ãɾ STOP_ALL ±êÖ¾
- try {
- var f2 = new java.io.File(G.STOP_FLAG);
- if (f2.exists()) f2["delete"]();
- } catch (e2) {}
- G.stopAll = false;
- cmdResp("CMD_CLEAR_CACHE", cmdId, true, "ok");
- } catch (e) {
- cmdResp("CMD_CLEAR_CACHE", cmdId, false, "Çå³ýÒì³£: " + (e.message || e));
- }
- });
- // -------- MANAGE_TASK_NEW£º¼æÈÝÔÈÎÎñÏ·¢¸ñʽ -------
- // Èç¹û data.action === "run_script" ¾Í×Ô¶¯×ß CMD_RUN_SCRIPT Âß¼£»·ñÔò´òÓ¡²¢»Ø ACK
- WSC.on("MANAGE_TASK_NEW", function (o) {
- printl("[ÈÎÎñ] ÊÕµ½: " + JSON.stringify(o.data || o).slice(0, 160));
- try {
- var d = o.data || o;
- if (d && d.action === "run_script" && d.path) {
- WSC.fire("CMD_RUN_SCRIPT", { type: "CMD_RUN_SCRIPT", cmdId: (o.taskId || ("task_" + nowMs())), data: d });
- WSC.send({ type: "CLIENT_TASK_ACK", taskId: o.taskId || (d.taskId || ""), accepted: true, mode: "auto_run_script", data: d });
- } else {
- WSC.send({ type: "CLIENT_TASK_ACK", taskId: o.taskId || (d && d.taskId || ""), accepted: true });
- }
- } catch (e) {
- WSC.send({ type: "CLIENT_TASK_ACK", taskId: o.taskId || "", accepted: false, error: (e.message || e) });
- }
- });
- // -------- MANAGE_CMD_STOP_ALL£ºÕæÍ£Ö¹Âß¼£¨²»ÊÇֻд¸öÎļþ¾ÍÍêÊ£©-------
- // ¶¯×÷£º1) Éè±êÖ¾ + дÎļþ 2) Í£Ö¹ËùÓлîÔ¾Ïß³Ì 3) ÐÄÌøÍ£ 4) Éϱ¨ CLIENT_STOPPING 5) 2 Ãëºó WSC.stop()
- WSC.on("MANAGE_CMD_STOP_ALL", function (o) {
- printl("[Ö¸Áî] STOP_ALL ¹ã²¥£¬¿ªÊ¼ÍêÕûÇåÀí");
- try { G.stopAll = true; } catch (e) {}
- try { G.isAllowReConnect = false; } catch (e) {}
- // 1) д±êÖ¾Îļþ£¨¹©ÆäËû½Å±¾¶Á£©
- try {
- var f = new java.io.File(G.STOP_FLAG);
- if (!f.exists()) f.createNewFile();
- } catch (e) {}
- // 2) Í£Ö¹ËùÓÐ CMD_RUN_SCRIPT Æô¶¯µÄ»îÔ¾Ïß³Ì
- var stoppedCnt = 0;
- try {
- for (var k in G.activeThreads) if (G.activeThreads.hasOwnProperty(k)) {
- try {
- var tObj = G.activeThreads[k];
- if (tObj && tObj.thread && tObj.thread.stop) tObj.thread.stop();
- stoppedCnt++;
- } catch (eSt) {}
- }
- } catch (e) {}
- try { G.activeThreads = {}; } catch (e) {}
- // 3) Á¢¼´·¢ CLIENT_STOPPING
- try {
- WSC.send({
- type: "CLIENT_STOPPING",
- reason: "MANAGE_CMD_STOP_ALL",
- stoppedThreads: stoppedCnt,
- runtimeSec: nowSec() - G.startTime,
- ts: nowSec()
- });
- } catch (eS) {}
- // 4) 2 Ãëºó³¹µ×¹Ø WS Óë±£»î£¨Á´Ê½ setTimeout È«²¿¶µ try-catch£¬±ÜÃâ AIWROK ÅÐ"Ò쳣δ²¶»ñ"Ö±½Óɱ£©
- try {
- setTimeout(function () {
- try {
- if (G.heartbeatTimer) { clearTimeout(G.heartbeatTimer); G.heartbeatTimer = null; }
- } catch (e1) {}
- try { WSC.stop(); } catch (e2) {}
- try { printl("[Ö¸Áî] STOP_ALL ÇåÀíÍê³É£¬ÒѶϿª WS"); } catch (e3) {}
- }, 2000);
- } catch (eOuter) {}
- });
- // -------- SERVER_PING£ºÐÄÌø»Ø°ü -------
- WSC.on("SERVER_PING", function (o) {
- WSC.send({
- type: "CLIENT_PONG",
- echo: o,
- runtimeSec: nowSec() - G.startTime,
- ts: nowSec()
- });
- });
- // =====================================================================
- // Ô¶³ÌÍ£Ö¹½ÓÊÕרÓÃỊ̈߳¨Ó²Ô¼ÊøÒªÇó£©
- // µ¥¶ÀÂÖѯ STOP_ALL ±êÖ¾Îļþ£»Ò»µ©´æÔھʹ¥·¢ÍêÕûÍ£Ö¹Âß¼
- // =====================================================================
- function startStopReceiver() {
- (function loop() {
- try {
- if (!G.running) return;
- var f = new java.io.File(G.STOP_FLAG);
- if (f.exists() && !G.stopAll) {
- printl("[½ÓÊÕÆ÷] ¼ì²âµ½ STOP_ALL ±êÖ¾Îļþ£¬´¥·¢Í£Ö¹");
- try { f["delete"](); } catch (eDel) {}
- // Ä£ÄâÊÕµ½Ò»Ìõ MANAGE_CMD_STOP_ALL ÏûÏ¢£¬×ßͬһÌ×ÇåÀíÂß¼
- WSC.fire("MANAGE_CMD_STOP_ALL", { type: "MANAGE_CMD_STOP_ALL", from: "local_flag" });
- }
- } catch (eOuter) {
- try { printl("[½ÓÊÕÆ÷] ÂÖѯÒì³£(ÒѶµ×¡): " + (eOuter.message || eOuter)); } catch (eL) {}
- }
- try { setTimeout(loop, CFG.stopReceiverIntervalMs); }
- catch (eTimer) {
- // runTime.setTimeout ¶µµ×£¨½öµ± setTimeout ²»´æÔÚʱÓã©
- try { runTime.setTimeout(loop, CFG.stopReceiverIntervalMs); } catch (eRT) {}
- }
- })();
- }
- // ---------- Æô¶¯Èë¿Ú£¨È«¾Ö try-catch + setTimeout ²»×èÈû£¬¶Å¾ø AIWROK Ëæ±ã¡ºÕýÔÚÍ£Ö¹¡»£©----------
- function main() {
- try {
- // Æô¶¯ÏÈÇåÒ»´Î STOP_ALL ±êÖ¾£¬±ÜÃâÉÏÒ»´ÎµÄ²ÐÓà
- try {
- var _f = new java.io.File(G.STOP_FLAG);
- if (_f.exists()) _f["delete"]();
- } catch (e) {}
- G.stopAll = false;
- printl("==========================================");
- printl(" AIWROK WebSocket ¿Í»§¶Ë Æô¶¯");
- printl(" ƽ̨: " + CFG.platform + " App: " + CFG.appName);
- printl(" ·þÎñ¶Ë: " + CFG.serverUrl);
- printl(" »Ö¸´ client_id: " + (G.clientId || "ÐÂ×¢²á"));
- printl(" ¿ÉÓÃÖ¸Áî: CMD_SCREENSHOT / CMD_CLICK / CMD_SWIPE / CMD_KEY");
- printl(" CMD_RUN_SCRIPT / CMD_STATUS / CMD_TOAST / CMD_CLEAR_CACHE");
- printl("==========================================");
- connectWebSocket();
- startStopReceiver();
- // Ö÷Ï̱߳£»î£¨Á´Ê½ setTimeout£¬·Ç×èÈû£¬È«°ü try-catch£©
- var keepAliveTick = 0;
- (function keepAlive() {
- try {
- if (!G.running) { printl("±£»îÏß³ÌÍ˳ö"); return; }
- keepAliveTick++;
- if (keepAliveTick % 20 === 0) {
- printl("[±£»î] client_id=" + (G.clientId || "N/A") + " ÖØÊÔ=" + G.reConnectTimes + " ÔËÐÐ=" + (nowSec() - G.startTime) + "s stopAll=" + G.stopAll);
- }
- } catch (eInner) {
- try { printl("[±£»î] Ò»´ÎÑ»·Òì³£(ÒѶµ×¡): " + (eInner.message || eInner)); } catch (eL) {}
- }
- try { setTimeout(keepAlive, 1000); }
- catch (eTimer) {
- try { runTime.setTimeout(keepAlive, 1000); } catch (eRT) {}
- }
- })();
- } catch (eTop) {
- // ÈκΠmain Àïδ²¶»ñÒì³£¶¼¶µ×¡£¬²»Èà AIWROK Ö±½Ó¸ø¡ºÕýÔÚÍ£Ö¹¡»
- try { printl("⚠️ main() ¶¥²ãÒì³£(ÒѶµ×¡): " + (eTop.message || eTop)); } catch (eL) {}
- // ³¢ÊÔ¼ÌÐøÖØÁ¬
- try { setTimeout(function () { try { connectWebSocket(); } catch (e) {} }, 5000); } catch (e) {}
- }
- }
- main();
¸´ÖÆ´úÂë
|
|