From 956f064737e0b7d939af57bc60fc9531aa228f7c Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Tue, 9 May 2017 15:47:31 +0800 Subject: [PATCH] modularize init script --- app/build.gradle | 4 +- .../java/com/stardust/NodeTest.java | 344 ------------------ .../main/assets/sample/对话框/简单计算器.js | 4 +- app/src/main/assets/sample/应用/卸载应用.js | 10 + .../sample/应用/发送意图-QQ文本消息分享.js | 10 + .../assets/sample/文件读写/文件编码转换.js | 6 +- .../main/assets/sample/自动操作/微信扫一扫.js | 1 + .../assets/sample/自动操作/支付宝扫一扫.js | 1 + .../java/com/stardust/scriptdroid/Pref.java | 5 +- .../OverlayPermissionChecker.java | 52 +++ .../stardust/scriptdroid/ExampleUnitTest.java | 2 - .../src/main/assets/javascript_engine_init.js | 301 +-------------- .../assets/modules/{app.js => __app__.js} | 8 +- .../src/main/assets/modules/__automator__.js | 62 ++++ autojs/src/main/assets/modules/__console__.js | 22 ++ autojs/src/main/assets/modules/__general__.js | 38 ++ autojs/src/main/assets/modules/__io__.js | 15 + .../src/main/assets/modules/__selector__.js | 36 ++ autojs/src/main/assets/modules/__shell__.js | 87 +++++ .../src/main/assets/modules/__unit_test__.js | 9 + autojs/src/main/assets/modules/__web__.js | 13 + autojs/src/main/assets/nodejs_engine_init.js | 4 +- .../engine/RhinoJavaScriptEngineManager.java | 2 +- .../autojs/runtime/AbstractScriptRuntime.java | 5 +- .../autojs/runtime/ScriptRuntime.java | 12 +- .../autojs/runtime/api/AbstractShell.java | 39 +- .../stardust/automator/UiGlobalSelector.java | 8 +- .../automator/UiObjectCollection.java | 18 + 28 files changed, 451 insertions(+), 667 deletions(-) delete mode 100644 app/src/androidTest/java/com/stardust/NodeTest.java create mode 100644 app/src/main/assets/sample/应用/卸载应用.js create mode 100644 app/src/main/assets/sample/应用/发送意图-QQ文本消息分享.js create mode 100644 app/src/main/java/com/stardust/scriptdroid/external/floating_window/OverlayPermissionChecker.java rename autojs/src/main/assets/modules/{app.js => __app__.js} (76%) create mode 100644 autojs/src/main/assets/modules/__automator__.js create mode 100644 autojs/src/main/assets/modules/__console__.js create mode 100644 autojs/src/main/assets/modules/__general__.js create mode 100644 autojs/src/main/assets/modules/__io__.js create mode 100644 autojs/src/main/assets/modules/__selector__.js create mode 100644 autojs/src/main/assets/modules/__shell__.js create mode 100644 autojs/src/main/assets/modules/__unit_test__.js create mode 100644 autojs/src/main/assets/modules/__web__.js diff --git a/app/build.gradle b/app/build.gradle index 4d4e1fd4..8e0173f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 122 - versionName "2.0.9c Alpha" + versionCode 123 + versionName "2.0.9d Alpha" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { diff --git a/app/src/androidTest/java/com/stardust/NodeTest.java b/app/src/androidTest/java/com/stardust/NodeTest.java deleted file mode 100644 index 291ba1f2..00000000 --- a/app/src/androidTest/java/com/stardust/NodeTest.java +++ /dev/null @@ -1,344 +0,0 @@ -package com.stardust; - -/** - * Created by Stardust on 2017/5/8. - */ - -// Copyright (c) 2014 Tom Zhou - - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import android.support.test.filters.SmallTest; -import android.util.Log; - -import com.iwebpp.node.EventEmitter.Listener; -import com.iwebpp.node.NodeContext; -import com.iwebpp.node.NodeContext.TimeoutListener; -import com.iwebpp.node.http.ClientRequest; -import com.iwebpp.node.http.ClientRequest.upgradeListener; -import com.iwebpp.node.http.HttpServer; -import com.iwebpp.node.http.HttpServer.clientErrorListener; -import com.iwebpp.node.http.http; -import com.iwebpp.node.http.IncomingMessage; -import com.iwebpp.node.http.ReqOptions; -import com.iwebpp.node.http.ServerResponse; -import com.iwebpp.node.net.AbstractSocket; -import com.iwebpp.node.stream.Writable.WriteCB; - -import org.junit.*; - -import static org.junit.Assert.fail; - -@SmallTest -public final class NodeTest { - private static final String TAG = "HttpTest"; - private NodeContext ctx; - - @Test - public void testListening() throws Exception { - HttpServer srv; - final int port = 6188; - srv = new HttpServer(ctx); - - srv.listen(port, "127.0.0.1", 4000, new HttpServer.ListeningCallback() { - - @Override - public void onListening() throws Exception { - Log.d(TAG, "http server listening on " + port); - } - }); - Thread.sleep(8000); - } - - @org.junit.Test - public void testConnection() throws Exception { - final int port = 6288; - final HttpServer srv = new HttpServer(ctx, new HttpServer.requestListener() { - - @Override - public void onRequest(IncomingMessage req, ServerResponse res) - throws Exception { - Log.d(TAG, "got reqeust, headers: " + req.headers()); - - Map> headers = new Hashtable>(); - headers.put("content-type", new ArrayList()); - headers.get("content-type").add("text/plain"); - ///headers.put("te", new LinkedList()); - ///headers.get("te").add("chunk"); - - res.writeHead(200, headers); - ///for (int i = 0; i < 10; i ++) - res.write("Hello Tom", "utf-8", new WriteCB() { - - @Override - public void writeDone(String error) throws Exception { - Log.d(TAG, "http res.write done"); - fail("http res.write done"); - } - - }); - - res.end(null, null, null); - ; - - } - - }); - - srv.onClientError(new clientErrorListener() { - - @Override - public void onClientError(String exception, AbstractSocket socket) throws Exception { - Log.e(TAG, "client error: " + exception + "@" + socket); - fail("client error: " + exception + "@" + socket); - } - - }); - - srv.listen(port, "0.0.0.0", 10, new HttpServer.ListeningCallback() { - - @Override - public void onListening() throws Exception { - Log.d(TAG, "http server listening on " + port); - } - }); - } - - @org.junit.Test - public void testUpgrade() throws Exception { - final String host = "192.188.1.100"; - final int port = 6668; - - // client - ReqOptions ropt = new ReqOptions(); - ropt.hostname = host; - ropt.port = port; - ropt.method = "GET"; - ropt.path = "/"; - - ropt.headers.put("Connection", new ArrayList()); - ropt.headers.get("Connection").add("Upgrade"); - - ropt.headers.put("Upgrade", new ArrayList()); - ropt.headers.get("Upgrade").add("websocket"); - - ropt.headers.put("Host", new ArrayList()); - ropt.headers.get("Host").add("192.188.1.100:6668"); - - ropt.headers.put("Origin", new ArrayList()); - ropt.headers.get("Origin").add("http://192.188.1.100:6668"); - - ropt.headers.put("Sec-WebSocket-Version", new ArrayList()); - ropt.headers.get("Sec-WebSocket-Version").add("13"); - - ropt.headers.put("Sec-WebSocket-Key", new ArrayList()); - ropt.headers.get("Sec-WebSocket-Key").add("MTMtVHVlIE9jdCAwNyAxMzozNzoyMiBHTVQrMDg6MDAgMjAxNA=="); - - ClientRequest req = http.request(ctx, ropt, new ClientRequest.responseListener() { - - @Override - public void onResponse(IncomingMessage res) throws Exception { - Log.d(TAG, "STATUS: " + res.statusCode()); - Log.d(TAG, "HEADERS: " + res.getHeaders()); - - res.setEncoding("utf-8"); - res.on("data", new Listener() { - - @Override - public void onEvent(Object chunk) throws Exception { - Log.d(TAG, "BODY: " + chunk); - - } - - }); - } - - }); - - req.onceUpgrade(new upgradeListener() { - - @Override - public void onUpgrade(IncomingMessage res, - AbstractSocket socket, ByteBuffer head) - throws Exception { - Log.d(TAG, "got upgrade: " + res.toString()); - } - - }); - - req.on("error", new Listener() { - - @Override - public void onEvent(Object e) throws Exception { - Log.d(TAG, "problem with request: " + e); - fail("problem with request: " + e); - } - - }); - - req.end(null, null, null); - - } - - @org.junit.Test - public void testConnect() throws Exception { - final String host = "192.188.1.100"; - final int port = 51680; - - // client - ReqOptions ropt = new ReqOptions(); - ropt.hostname = host; - ropt.port = port; - ropt.method = "PUT"; - ropt.path = "/"; - ///ropt.keepAlive = true; - ///ropt.keepAliveMsecs = 10000; - - ClientRequest req = http.request(ctx, ropt, new ClientRequest.responseListener() { - - @Override - public void onResponse(IncomingMessage res) throws Exception { - Log.d(TAG, "STATUS: " + res.statusCode()); - Log.d(TAG, "HEADERS: " + res.getHeaders()); - - res.setEncoding("utf-8"); - res.on("data", new Listener() { - - @Override - public void onEvent(Object chunk) throws Exception { - Log.d(TAG, "BODY: " + chunk); - - } - - }); - } - - }); - - req.on("error", new Listener() { - - @Override - public void onEvent(Object e) throws Exception { - Log.d(TAG, "problem with request: " + e); - fail("problem with request: " + e); - } - - }); - - // write data to request body - for (int i = 0; i < 8; i++) - req.write("data" + i + "\n", "utf-8", null); - - req.end(null, null, null); - - } - - @org.junit.Test - public void testConnectPair() throws Exception { - final int port = 6688; - - final HttpServer srv = http.createServer(ctx, new HttpServer.requestListener() { - - @Override - public void onRequest(IncomingMessage req, ServerResponse res) - throws Exception { - Log.d(TAG, "got reqeust, headers: " + req.headers()); - - Map> headers = new Hashtable>(); - headers.put("content-type", new ArrayList()); - headers.get("content-type").add("text/plain"); - ///headers.put("te", new ArrayList()); - ///headers.get("te").add("chunk"); - - res.writeHead(200, headers); - res.write("Hello Tom", "utf-8", new WriteCB() { - - @Override - public void writeDone(String error) throws Exception { - Log.d(TAG, "http res.write done"); - fail("http res.write done"); - } - - }); - - res.end(null, null, null); - - } - - }); - - srv.listen(port, "0.0.0.0", 1, new HttpServer.ListeningCallback() { - - @Override - public void onListening() throws Exception { - Log.d(TAG, "http server listening on " + port); - } - - }); - - // client - final ReqOptions ropt = new ReqOptions(); - ropt.hostname = "localhost"; // IP address instead localhost - ropt.port = port; - ropt.method = "GET"; - ropt.path = "/"; - - // defer 2s to connect - ctx.setTimeout(new TimeoutListener() { - - @Override - public void onTimeout() throws Exception { - - ClientRequest req = http.request(ctx, ropt, new ClientRequest.responseListener() { - - @Override - public void onResponse(IncomingMessage res) throws Exception { - Log.d(TAG, "STATUS: " + res.statusCode()); - Log.d(TAG, "HEADERS: " + res.getHeaders()); - - res.setEncoding("utf-8"); - - res.on("data", new Listener() { - - @Override - public void onEvent(Object chunk) throws Exception { - Log.d(TAG, "BODY: " + chunk); - - } - - }); - } - - }); - - req.on("error", new Listener() { - - @Override - public void onEvent(Object e) throws Exception { - Log.d(TAG, "problem with request: " + e); - fail("problem with request: " + e); - } - - }); - - // write data to request body - ///req.write("data\n", "utf-8", null); - ///req.write("data\n", "utf-8", null); - req.end(null, null, null); - } - - }, 2000); - - } - - - @Before - public void setUp() throws Exception { - this.ctx = new NodeContext(); - } -} \ No newline at end of file diff --git a/app/src/main/assets/sample/对话框/简单计算器.js b/app/src/main/assets/sample/对话框/简单计算器.js index 9d822efc..505322df 100644 --- a/app/src/main/assets/sample/对话框/简单计算器.js +++ b/app/src/main/assets/sample/对话框/简单计算器.js @@ -1,6 +1,6 @@ -var num1 = input("请输入第一个数字"); +var num1 = dialogs.input("请输入第一个数字"); var op = dialogs.singleChoice("请选择运算", 0, "加", "减", "乘", "除", "幂"); -var num2 = input("请输入第二个数字"); +var num2 = dialogs.input("请输入第二个数字"); var result = 0; switch(op){ case 0: diff --git a/app/src/main/assets/sample/应用/卸载应用.js b/app/src/main/assets/sample/应用/卸载应用.js new file mode 100644 index 00000000..7675b600 --- /dev/null +++ b/app/src/main/assets/sample/应用/卸载应用.js @@ -0,0 +1,10 @@ +//输入应用名称 +var appName = rawInput('请输入要卸载的应用名称'); +//获取应用包名 +var packageName = getPackageName(appName); +if(!packageName){ + toast("应用不存在!"); +}else{ + //卸载应用 + app.uninstall(packageName); +} \ No newline at end of file diff --git a/app/src/main/assets/sample/应用/发送意图-QQ文本消息分享.js b/app/src/main/assets/sample/应用/发送意图-QQ文本消息分享.js new file mode 100644 index 00000000..912100c6 --- /dev/null +++ b/app/src/main/assets/sample/应用/发送意图-QQ文本消息分享.js @@ -0,0 +1,10 @@ +var content = rawInput('请输入要分享的文本'); +app.startActivity({ + action: "android.intent.action.SEND", + type: "text/*", + extras: { + "android.intent.extra.TEXT": content + }, + packageName: "com.tencent.mobileqq", + className: "com.tencent.mobileqq.activity.JumpActivity" +}); \ No newline at end of file diff --git a/app/src/main/assets/sample/文件读写/文件编码转换.js b/app/src/main/assets/sample/文件读写/文件编码转换.js index e49a7de2..b1374277 100644 --- a/app/src/main/assets/sample/文件读写/文件编码转换.js +++ b/app/src/main/assets/sample/文件读写/文件编码转换.js @@ -1,9 +1,9 @@ //以UTF-8编码打开SD卡上的1.txt文件 -var in = open("/sdcard/1.txt", "r", "utf-8"); +var f = open("/sdcard/1.txt", "r", "utf-8"); //读取文件所有内容 -var text = in.read(); +var text = f.read(); //关闭文件 -in.close(); +f.close(); //以gbk编码打开SD卡上的2.txt文件 var out = open("/sdcard/2.txt", "w", "gbk"); //写入内容 diff --git a/app/src/main/assets/sample/自动操作/微信扫一扫.js b/app/src/main/assets/sample/自动操作/微信扫一扫.js index c9591ac5..f8f37872 100644 --- a/app/src/main/assets/sample/自动操作/微信扫一扫.js +++ b/app/src/main/assets/sample/自动操作/微信扫一扫.js @@ -1,4 +1,5 @@ "auto"; launch("com.tencent.mm"); +sleep(500); while(!click("发现")); while(!click("扫一扫")); \ No newline at end of file diff --git a/app/src/main/assets/sample/自动操作/支付宝扫一扫.js b/app/src/main/assets/sample/自动操作/支付宝扫一扫.js index bb393cce..8a6e0ccd 100644 --- a/app/src/main/assets/sample/自动操作/支付宝扫一扫.js +++ b/app/src/main/assets/sample/自动操作/支付宝扫一扫.js @@ -1,3 +1,4 @@ "auto"; launchApp("支付宝"); +sleep(800); while(!click("扫一扫")); \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/Pref.java b/app/src/main/java/com/stardust/scriptdroid/Pref.java index b02a5f04..20bd6bd7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/Pref.java +++ b/app/src/main/java/com/stardust/scriptdroid/Pref.java @@ -8,6 +8,9 @@ import com.stardust.autojs.runtime.api.AutomatorConfig; import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.scriptdroid.autojs.AutoJs; +import org.mozilla.javascript.tools.debugger.Dim; +import org.mozilla.javascript.tools.debugger.GuiCallback; + /** * Created by Stardust on 2017/1/31. */ @@ -78,7 +81,7 @@ public class Pref { return def().getString(getString(R.string.key_stop_record_trigger), null); } - public static boolean hasRecordTrigger(){ + public static boolean hasRecordTrigger() { String startTrigger = getStartRecordTrigger(); String stopTrigger = getStartRecordTrigger(); return startTrigger != null && !startTrigger.equals("NONE") diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/OverlayPermissionChecker.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/OverlayPermissionChecker.java new file mode 100644 index 00000000..41949a7e --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/OverlayPermissionChecker.java @@ -0,0 +1,52 @@ +package com.stardust.scriptdroid.external.floating_window; + +import android.view.WindowManager; + +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.enhancedfloaty.FloatyWindow; + +/** + * Created by Stardust on 2017/5/9. + */ + +public class OverlayPermissionChecker { + + + public static void addFloaty() { + FloatyService.addWindow(new FloatyWindow() { + @Override + public void onCreate(FloatyService floatyService, WindowManager windowManager) { + + } + + @Override + public void onServiceDestroy(FloatyService floatyService) { + + } + + @Override + public void close() { + + } + }); + } + + private static class OnePixelWindow implements FloatyWindow { + + @Override + public void onCreate(FloatyService floatyService, WindowManager windowManager) { + + } + + @Override + public void onServiceDestroy(FloatyService floatyService) { + + } + + @Override + public void close() { + + } + } + +} diff --git a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java index a505a8fb..565d43d1 100644 --- a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java +++ b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java @@ -27,12 +27,10 @@ public class ExampleUnitTest { // TODO: 2017/3/24 编辑界面文档和自动补全 // TODO: 2017/3/24 驻留模式 //// TODO: 2017/3/26 NODEJS - // TODO: 2017/3/26 加密 // TODO: 2017/3/31 自定义快捷方式图标 // FIXME: 2017/3/23 死机重启问题 - // FIXME: 2017/3/23 卡顿问题 @Test diff --git a/autojs/src/main/assets/javascript_engine_init.js b/autojs/src/main/assets/javascript_engine_init.js index 48bddfee..494d4171 100644 --- a/autojs/src/main/assets/javascript_engine_init.js +++ b/autojs/src/main/assets/javascript_engine_init.js @@ -13,296 +13,25 @@ if(__engine_name__ == "rhino"){ } } -var toast = function(text){ - __runtime__.toast(text); -} -var app = require("app")(__runtime__); - -var launchPackage = function(package){ - app.launchPackage(package); -} - -var launch = app.launch.bind(app); - -var launchApp = function(appName){ - app.launchApp(appName); -} - -var getPackageName = function(appName){ - return app.getPackageName(appName); -} - -var openAppSetting = function(packageName){ - return app.openAppSetting(packageName); -} - - - -var sleep = function(millis){ - __runtime__.sleep(millis); -} - -var isStopped = function(){ - return __runtime__.isStopped(); -} - -var notStopped = function(){ - return !isStopped(); -} - -var stop = function(){ - __runtime__.stop(); -} - -var console = __runtime__.console; - -var log = function(str){ - console.log(str); -} - -var print = log; - -var err = function(e){ - console.e(e); -} - -var openConsole = function(){ - console.show(); -} - -var clearConsole = function(){ - console.clear(); -} - -var shell = function(cmd, root){ - root = root ? 1 : 0; - return __runtime__.shell(cmd, root); -} - -var currentPackage = function(){ - return __runtime__.info.getLatestPackage(); -} - -var currentActivity = function(){ - return __runtime__.info.getLatestActivity(); -} - - - -var __this__ = this; - -var back = function(){ - return __runtime__.automator.back(); -} - -var home = function(){ - return __runtime__.automator.home(); -} - -var powerDialog = function(){ - return __runtime__.automator.powerDialog(); -} - -var notifications = function(){ - return __runtime__.automator.notifications(); -} - -var quickSettings = function(){ - return __runtime__.automator.quickSettings(); -} - -var recents = function(){ - return __runtime__.automator.recents(); -} - -var splitScreen = function(){ - return __runtime__.automator.splitScreen(); -} - -function performAction(action, args){ - if(args.length == 4){ - return action(__runtime__.automator.bounds(args[0], args[1], args[2], args[3])); - }else if(args.length == 2){ - return action(__runtime__.automator.text(args[0], args[1])); - }else { - return action(__runtime__.automator.text(args[0], -1)); +var __asGlobal__ = function(obj, functions){ + __runtime__.console.log(functions); + var len = functions.length; + for(var i = 0; i < len; i++) { + var funcName = functions[i]; + __runtime__.console.log(funcName); + this[funcName] = obj[funcName].bind(obj); } } -var click = function(){ - return performAction(function(target){ - return __runtime__.automator.click(target); - }, arguments); -} - -var longClick = function(a, b, c, d){ - return performAction(function(target){ - return __runtime__.automator.longClick(target); - }, arguments); -} +require("__general__")(__runtime__, this); -var scrollDown = function(a, b, c, d){ - if(arguments.length == 0) - return __runtime__.automator.scrollMaxForward(); - if(arguments.length == 1 && typeof a === 'number') - return __runtime__.automator.scrollForward(a); - return performAction(function(target){ - return __runtime__.automator.scrollForward(target); - }, arguments); -} - -var scrollUp = function(a, b, c, d){ - if(arguments.length == 0) - return __runtime__.automator.scrollMaxBackward(); - if(arguments.length == 1 && typeof a === 'number') - return __runtime__.automator.scrollBackward(a); - return performAction(function(target){ - return __runtime__.automator.scrollBackward(target); - }, arguments); -} - -var input = function(a, b){ - if(arguments.length == 1){ - return __runtime__.automator.setText(__runtime__.automator.editable(-1), a); - }else{ - return __runtime__.automator.setText(__runtime__.automator.editable(a), b); +(function(scope){ + var modules = ['app', 'automator', 'console', 'io', 'selector', 'shell', 'web']; + var len = modules.length; + for(var i = 0; i < len; i++) { + var m = modules[i]; + scope[m] = require('__' + m + '__')(scope.__runtime__, scope); } -} - - -var setClip = function(text){ - __runtime__.setClip(text); -} - - -var SetScreenMetrics = function(w, h){ - __runtime__.SetScreenMetrics(w, h); -} - - -var Tap = function(x, y){ - __runtime__.shellExecAsync("input tap " + x + " " + y); -} - -var Swipe = function(x1, y1, x2, y2, duration){ - if(arguments.length == 5){ - __runtime__.shellExecAsync("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration); - }else{ - __runtime__.shellExecAsync("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2); - } -} - -var Screencap = function(path){ - __runtime__.shellExecAsync("screencap -p " + path); -} - -var KeyCode = function(keyCode){ - __runtime__.shellExecAsync("input keyevent " + keyCode); -} - -var Home = function(){ - return KeyCode(3); -} - -var Back = function(){ - return KeyCode(4); -} - -var Power = function(){ - return KeyCode(26); -} - -var Up = function(){ - return KeyCode(19); -} - -var Down = function(){ - return KeyCode(20); -} - -var Left = function(){ - return KeyCode(21); -} - -var Right = function(){ - return KeyCode(22); -} - -var OK = function(){ - return KeyCode(23); -} - -var VolumeUp = function(){ - return KeyCode(24); -} - -var VolumeDown = function(){ - return KeyCode(25); -} - -var Menu = function(){ - return KeyCode(1); -} - -var Camera = function(){ - return KeyCode(27); -} - -var Text = function(text){ - __runtime__.shellExecAsync("input text " + text); -} - -var selector = function(){ - return __runtime__.selector(__engine__); -} - -var __selector__ = selector(); -var __obj__ = new java.lang.Object(); - -for(var x in __selector__){ - if(!__obj__[x] && !this[x]){ - this[x] = (function(method) { - return function(){ - var s = selector(); - //这里不知道怎么写。尴尬。只能写成这样。 - if(arguments.length == 0){ - return s[method](); - }else if(arguments.length == 1){ - return s[method](arguments[0]); - }else if(arguments.length == 2){ - return s[method](arguments[0], arguments[1]); - }else if(arguments.length == 3){ - return s[method](arguments[0], arguments[1], arguments[2]); - }else if(arguments.length == 4){ - return s[method](arguments[0], arguments[1], arguments[2], arguments[3]); - }else{ - return s[method].call(s, Array.prototype.slice.call(arguments)); - } - }; - })(x); - } - -} - -var open = function(path, mode, encoding, bufferSize){ - if(arguments.length == 1){ - return com.stardust.pio.PFile.open(path); - }else if(arguments.length == 2){ - return com.stardust.pio.PFile.open(path, mode); - }else if(arguments.length == 3){ - return com.stardust.pio.PFile.open(path, mode, encoding); - }else if(arguments.length == 4){ - return com.stardust.pio.PFile.open(path, mode, encoding, bufferSize); - } -} - - -var newInjectableWebClient = function(){ - return new com.stardust.autojs.runtime.api.InjectableWebClient(org.mozilla.javascript.Context.getCurrentContext(), __this__); -} - -var newInjectableWebView = function(activity){ - return new com.stardust.autojs.runtime.api.InjectableWebView(activity, org.mozilla.javascript.Context.getCurrentContext(), __this__); -} +})(this); diff --git a/autojs/src/main/assets/modules/app.js b/autojs/src/main/assets/modules/__app__.js similarity index 76% rename from autojs/src/main/assets/modules/app.js rename to autojs/src/main/assets/modules/__app__.js index 47bc026d..30886c6a 100644 --- a/autojs/src/main/assets/modules/app.js +++ b/autojs/src/main/assets/modules/__app__.js @@ -1,6 +1,7 @@ -module.exports = function(__runtime__){ +module.exports = function(__runtime__, scope){ var app = new Object(__runtime__.app); + var context = scope.context; app.intent = function(i) { var intent = new android.content.Intent(); @@ -30,7 +31,7 @@ module.exports = function(__runtime__){ } app.startActivity = function(i){ - context.startActivity(app.intent(i)); + context.startActivity(app.intent(i).addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)); } app.sendBroadcast = function(i){ @@ -39,5 +40,8 @@ module.exports = function(__runtime__){ app.launch = app.launchPackage; + scope.__asGlobal__(app, ['launchPackage', 'launch', 'launchApp', 'getPackageName', 'openAppSetting']); + return app; } + diff --git a/autojs/src/main/assets/modules/__automator__.js b/autojs/src/main/assets/modules/__automator__.js new file mode 100644 index 00000000..aaf92b6c --- /dev/null +++ b/autojs/src/main/assets/modules/__automator__.js @@ -0,0 +1,62 @@ + +module.exports = function(__runtime__, scope){ + var automator = {}; + + function performAction(action, args){ + if(args.length == 4){ + return action(__runtime__.automator.bounds(args[0], args[1], args[2], args[3])); + }else if(args.length == 2){ + return action(__runtime__.automator.text(args[0], args[1])); + }else { + return action(__runtime__.automator.text(args[0], -1)); + } + } + + automator.click = function(){ + return performAction(function(target){ + return __runtime__.automator.click(target); + }, arguments); + } + + automator.longClick = function(a, b, c, d){ + return performAction(function(target){ + return __runtime__.automator.longClick(target); + }, arguments); + } + + + automator.scrollDown = function(a, b, c, d){ + if(arguments.length == 0) + return __runtime__.automator.scrollMaxForward(); + if(arguments.length == 1 && typeof a === 'number') + return __runtime__.automator.scrollForward(a); + return performAction(function(target){ + return __runtime__.automator.scrollForward(target); + }, arguments); + } + + automator.scrollUp = function(a, b, c, d){ + if(arguments.length == 0) + return __runtime__.automator.scrollMaxBackward(); + if(arguments.length == 1 && typeof a === 'number') + return __runtime__.automator.scrollBackward(a); + return performAction(function(target){ + return __runtime__.automator.scrollBackward(target); + }, arguments); + } + + automator.input = function(a, b){ + if(arguments.length == 1){ + return __runtime__.automator.setText(__runtime__.automator.editable(-1), a); + }else{ + return __runtime__.automator.setText(__runtime__.automator.editable(a), b); + } + } + + scope.__asGlobal__(__runtime__.automator, ['back', 'home', 'powerDialog', 'notifications', 'quickSettings', 'recents', 'splitScreen']); + scope.__asGlobal__(automator, ['click', 'longClick', 'scrollDown', 'scrollUp', 'input']); + + return automator; +} + + diff --git a/autojs/src/main/assets/modules/__console__.js b/autojs/src/main/assets/modules/__console__.js new file mode 100644 index 00000000..af79c9d6 --- /dev/null +++ b/autojs/src/main/assets/modules/__console__.js @@ -0,0 +1,22 @@ + +module.exports = function(__runtime__, scope){ + var console = new Object(__runtime__.console); + + console.assert = function(value, message){ + message = message || ""; + console.assertTrue(value, message); + } + + scope.print = console.log.bind(console); + + scope.log = scope.print; + + scope.err = console.error.bind(console); + + scope.openConsole = console.show.bind(console); + + scope.clearConsole = console.clear.bind(console); + + + return console; +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/__general__.js b/autojs/src/main/assets/modules/__general__.js new file mode 100644 index 00000000..20cde5a9 --- /dev/null +++ b/autojs/src/main/assets/modules/__general__.js @@ -0,0 +1,38 @@ + +module.exports = function(__runtime__, scope){ + scope.toast = function(text){ + __runtime__.toast(text); + } + + scope.sleep = function(millis){ + __runtime__.sleep(millis); + } + + scope.isStopped = function(){ + return __runtime__.isStopped(); + } + + scope.notStopped = function(){ + return !isStopped(); + } + + scope.stop = function(){ + __runtime__.stop(); + } + + scope.setClip = function(text){ + __runtime__.setClip(text); + } + + scope.getClip = function(text){ + return __runtime__.getClip(); + } + + scope.currentPackage = function(){ + return __runtime__.info.getLatestPackage(); + } + + scope.currentActivity = function(){ + return __runtime__.info.getLatestActivity(); + } +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/__io__.js b/autojs/src/main/assets/modules/__io__.js new file mode 100644 index 00000000..2c6e4017 --- /dev/null +++ b/autojs/src/main/assets/modules/__io__.js @@ -0,0 +1,15 @@ + +module.exports = function(__runtime__, scope){ + scope.open = function(path, mode, encoding, bufferSize){ + if(arguments.length == 1){ + return com.stardust.pio.PFile.open(path); + }else if(arguments.length == 2){ + return com.stardust.pio.PFile.open(path, mode); + }else if(arguments.length == 3){ + return com.stardust.pio.PFile.open(path, mode, encoding); + }else if(arguments.length == 4){ + return com.stardust.pio.PFile.open(path, mode, encoding, bufferSize); + } + }; + +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/__selector__.js b/autojs/src/main/assets/modules/__selector__.js new file mode 100644 index 00000000..e66bc685 --- /dev/null +++ b/autojs/src/main/assets/modules/__selector__.js @@ -0,0 +1,36 @@ + +module.exports = function(__runtime__, scope){ + + var __selector__ = __runtime__.selector(scope.__engine__); + var __obj__ = new java.lang.Object(); + + for(var method in __selector__){ + if(!__obj__[method] && !scope[method]){ + scope[method] = (function(method) { + return function(){ + var s = selector(); + //这里不知道怎么写。尴尬。只能写成这样。 + if(arguments.length == 0){ + return s[method](); + }else if(arguments.length == 1){ + return s[method](arguments[0]); + }else if(arguments.length == 2){ + return s[method](arguments[0], arguments[1]); + }else if(arguments.length == 3){ + return s[method](arguments[0], arguments[1], arguments[2]); + }else if(arguments.length == 4){ + return s[method](arguments[0], arguments[1], arguments[2], arguments[3]); + }else{ + return s[method].call(s, Array.prototype.slice.call(arguments)); + } + }; + })(method); + } + } + + return function(){ + return __runtime__.selector(scope.__engine__); + }; +} + + diff --git a/autojs/src/main/assets/modules/__shell__.js b/autojs/src/main/assets/modules/__shell__.js new file mode 100644 index 00000000..d70d5f08 --- /dev/null +++ b/autojs/src/main/assets/modules/__shell__.js @@ -0,0 +1,87 @@ + + +module.exports = function(__runtime__, scope){ + + scope.SetScreenMetrics = function(w, h){ + __runtime__.getRootShell().SetScreenMetrics(x, y); + } + + scope.Tap = function(x, y){ + __runtime__.getRootShell().Tap(x, y); + } + + scope.Swipe = function(x1, y1, x2, y2, duration){ + if(arguments.length == 5){ + __runtime__.getRootShell().Swipe(x1, y1, x2, y2, duration); + }else{ + __runtime__.getRootShell().Swipe(x1, y1, x2, y2); + } + } + + scope.Screencap = function(path){ + __runtime__.getRootShell().Screencap(path); + } + + scope.KeyCode = function(keyCode){ + __runtime__.getRootShell().KeyCode(keyCode); + } + + scope.Home = function(){ + return KeyCode(3); + } + + scope.Back = function(){ + return KeyCode(4); + } + + scope.Power = function(){ + return KeyCode(26); + } + + scope.Up = function(){ + return KeyCode(19); + } + + scope.Down = function(){ + return KeyCode(20); + } + + scope.Left = function(){ + return KeyCode(21); + } + + scope.Right = function(){ + return KeyCode(22); + } + + scope.OK = function(){ + return KeyCode(23); + } + + scope.VolumeUp = function(){ + return KeyCode(24); + } + + scope.VolumeDown = function(){ + return KeyCode(25); + } + + scope.Menu = function(){ + return KeyCode(1); + } + + scope.Camera = function(){ + return KeyCode(27); + } + + scope.Text = function(text){ + __runtime__.getRootShell().Text(text); + } + + scope.Input = scope.Text; + + return function(cmd, root){ + root = root ? 1 : 0; + return __runtime__.shell(cmd, root); + }; +} diff --git a/autojs/src/main/assets/modules/__unit_test__.js b/autojs/src/main/assets/modules/__unit_test__.js new file mode 100644 index 00000000..dc5ec835 --- /dev/null +++ b/autojs/src/main/assets/modules/__unit_test__.js @@ -0,0 +1,9 @@ + +assert = console.assert.bind(console); + +function testApp(){ + print('正在测试模块:app'); + assert("com.tencent.mm" == app.getPackageName("微信")); + assert("com.tencent.mobileqq" == app.getPackageName("QQ")); + +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/__web__.js b/autojs/src/main/assets/modules/__web__.js new file mode 100644 index 00000000..0bbd42cc --- /dev/null +++ b/autojs/src/main/assets/modules/__web__.js @@ -0,0 +1,13 @@ + + +module.exports = function(__runtime__, scope){ + scope.newInjectableWebClient = function(){ + return new com.stardust.autojs.runtime.api.InjectableWebClient(org.mozilla.javascript.Context.getCurrentContext(), scope); + } + + scope.newInjectableWebView = function(activity){ + return new com.stardust.autojs.runtime.api.InjectableWebView(scope.activity, org.mozilla.javascript.Context.getCurrentContext(), scope); + } +} + + diff --git a/autojs/src/main/assets/nodejs_engine_init.js b/autojs/src/main/assets/nodejs_engine_init.js index 4ae1baec..99d462b9 100644 --- a/autojs/src/main/assets/nodejs_engine_init.js +++ b/autojs/src/main/assets/nodejs_engine_init.js @@ -1,4 +1,4 @@ -var __requireOld__ = require; +var __require__ = require; var __nodejs_modules__ = { 'websocket' : com.iwebpp.wspp.WebSocket, 'websocketserver': com.iwebpp.wspp.WebSocketServer, @@ -42,5 +42,5 @@ var require = function(module){ }; } - return __requireOld__(module); + return __require__(module); }; diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java index 345dd4df..9a2441be 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java @@ -86,7 +86,7 @@ public class RhinoJavaScriptEngineManager extends AbstractScriptEngineManager { AssetAndUrlModuleSourceProvider provider = new AssetAndUrlModuleSourceProvider(getContext(), list); new RequireBuilder() .setModuleScriptProvider(new SoftCachingModuleScriptProvider(provider)) - .setSandboxed(true) + .setSandboxed(false) .createRequire(context, scope) .install(scope); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java index 19674fe6..90568c15 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java @@ -46,7 +46,7 @@ public abstract class AbstractScriptRuntime { public abstract void setClip(final String text); @ScriptInterface - public abstract void shellExecAsync(String cmd); + public abstract AbstractShell getRootShell(); @ScriptInterface public abstract AbstractShell.Result shell(String cmd, int root); @@ -66,9 +66,6 @@ public abstract class AbstractScriptRuntime { @ScriptInterface public abstract void stop(); - @ScriptInterface - public abstract void SetScreenMetrics(int width, int height); - public abstract void ensureAccessibilityServiceEnabled(); public abstract void onStop(); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java index f5e21cc3..1a12de09 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -117,9 +117,10 @@ public class ScriptRuntime extends AbstractScriptRuntime { }); } - public void shellExecAsync(String cmd) { + @Override + public AbstractShell getRootShell() { ensureRootShell(); - mRootShell.exec(cmd); + return mRootShell; } private void ensureRootShell() { @@ -137,7 +138,6 @@ public class ScriptRuntime extends AbstractScriptRuntime { } public UiSelector selector(ScriptEngine engine) { - Intent intent; return new UiSelector(mAccessibilityBridge); } @@ -163,12 +163,6 @@ public class ScriptRuntime extends AbstractScriptRuntime { Thread.interrupted(); } - @Override - public void SetScreenMetrics(int width, int height) { - ensureRootShell(); - mRootShell.SetScreenMetrics(width, height); - } - public void ensureAccessibilityServiceEnabled() { mAccessibilityBridge.ensureServiceEnabled(); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java index 856691fc..104042b9 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java @@ -45,7 +45,7 @@ public abstract class AbstractShell { public AbstractShell(boolean root) { mRoot = root; - init(root ? COMMAND_SU: COMMAND_SH); + init(root ? COMMAND_SU : COMMAND_SH); } public boolean isRoot() { @@ -62,20 +62,20 @@ public abstract class AbstractShell { mTouchDevice = touchDevice; } - public void SendEvent(int type, int code, int value){ + public void SendEvent(int type, int code, int value) { SendEvent(mTouchDevice, type, code, value); } - public void SendEvent(int device, int type, int code, int value){ + public void SendEvent(int device, int type, int code, int value) { exec(TextUtils.join("", new Object[]{"sendevent /dev/input/event", device, " ", type, " ", code, " ", value})); } - public void SetScreenMetrics(int width, int height){ + public void SetScreenMetrics(int width, int height) { mScreenWidth = width; mScreenHeight = height; } - public void Touch(int x, int y){ + public void Touch(int x, int y) { TouchX(x); TouchY(y); } @@ -85,8 +85,10 @@ public abstract class AbstractShell { } private int scaleX(int x) { + if (mScreenWidth == 0) + return x; int screenWidth = ScreenMetrics.getScreenWidth(); - if(screenWidth == mScreenWidth){ + if (screenWidth == mScreenWidth) { return x; } return x * screenWidth / mScreenWidth; @@ -97,13 +99,26 @@ public abstract class AbstractShell { } private int scaleY(int y) { + if (mScreenHeight == 0) + return y; int screenHeight = ScreenMetrics.getScreenHeight(); - if(screenHeight == mScreenHeight){ + if (screenHeight == mScreenHeight) { return y; } return y * screenHeight / mScreenHeight; } + public void Tap(int x, int y) { + exec("input tap " + scaleX(x) + " " + scaleY(y)); + } + + public void Swipe(int x1, int y1, int x2, int y2) { + exec(com.stardust.util.TextUtils.join(" ", "input", "tap", scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2))); + } + + public void Swipe(int x1, int y1, int x2, int y2, int time) { + exec(com.stardust.util.TextUtils.join(" ", "input", "tap", scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2), time)); + } public void KeyCode(int keyCode) { exec("input keyevent " + keyCode); @@ -161,9 +176,17 @@ public abstract class AbstractShell { KeyCode(27); } - public void Text(String text) { + public void Input(String text) { exec("input text " + text); } + public void Screencap(String path) { + exec("screencap -p " + path); + } + + public void Text(String text) { + Input(text); + } + public abstract void exitAndWaitFor(); } diff --git a/automator/src/main/java/com/stardust/automator/UiGlobalSelector.java b/automator/src/main/java/com/stardust/automator/UiGlobalSelector.java index 55500238..d1ddaeb2 100644 --- a/automator/src/main/java/com/stardust/automator/UiGlobalSelector.java +++ b/automator/src/main/java/com/stardust/automator/UiGlobalSelector.java @@ -2,6 +2,7 @@ package com.stardust.automator; import android.graphics.Rect; import android.os.Build; +import android.support.annotation.Nullable; import com.stardust.automator.filter.BooleanFilter; import com.stardust.automator.filter.BoundsFilter; @@ -359,9 +360,14 @@ public class UiGlobalSelector { return UiObjectCollection.of(list); } + @Nullable public UiObject findOneOf(UiObject node) { // TODO: 2017/3/9 优化 - return findOf(node).get(0); + UiObjectCollection collection = findOf(node); + if (collection.size() == 0) { + return null; + } + return collection.get(0); } public UiGlobalSelector addFilter(ListFilter filter) { diff --git a/automator/src/main/java/com/stardust/automator/UiObjectCollection.java b/automator/src/main/java/com/stardust/automator/UiObjectCollection.java index b256ba88..4596ab69 100644 --- a/automator/src/main/java/com/stardust/automator/UiObjectCollection.java +++ b/automator/src/main/java/com/stardust/automator/UiObjectCollection.java @@ -2,6 +2,7 @@ package com.stardust.automator; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; import android.view.accessibility.AccessibilityNodeInfo; @@ -199,4 +200,21 @@ public class UiObjectCollection { return this; } + public UiObjectCollection find(UiGlobalSelector selector) { + List list = new ArrayList<>(); + for (UiObject object : mNodes) { + list.addAll(selector.findOf(object).mNodes); + } + return of(list); + } + + @Nullable + public UiObject findOne(UiGlobalSelector selector) { + for (UiObject object : mNodes) { + UiObject result = selector.findOneOf(object); + if (result != null) + return result; + } + return null; + } }