diff --git a/.idea/dictionaries/Stardust.xml b/.idea/dictionaries/Stardust.xml index 792fd648..60983c2a 100644 --- a/.idea/dictionaries/Stardust.xml +++ b/.idea/dictionaries/Stardust.xml @@ -3,6 +3,7 @@ dismissable interruptible + prefill scriptable tasker diff --git a/.idea/misc.xml b/.idea/misc.xml index db1ea67d..ace2cb0d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,8 +5,8 @@ - - + + diff --git a/app/build.gradle b/app/build.gradle index 9d689554..8673b867 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 121 - versionName "2.0.9b Beta" + versionCode 122 + versionName "2.0.9c Alpha" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 568bf4c2..8cec44d0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -36,7 +36,7 @@ @org.greenrobot.eventbus.Subscribe ; } -keepclassmembers class ** { - @com.stardust.autojs.runtime.JavascriptInterface ; + @com.stardust.autojs.runtime.ScriptInterface ; } -keep class org.msgpack.** { *; } diff --git a/app/src/main/assets/js/autojs_init.js b/app/src/main/assets/js/autojs_init.js index e1978b3e..11d8aca7 100644 --- a/app/src/main/assets/js/autojs_init.js +++ b/app/src/main/assets/js/autojs_init.js @@ -1 +1,82 @@ -__importClass__(com.stardust.scriptdroid.autojs.Shell); +__importClass__(com.stardust.scriptdroid.autojs.api.Shell); + + +var dialogs = {}; + +dialogs.rawInput = function(title, prefill){ + prefill = prefill || ""; + return __runtime__.dialogs.rawInput(title, prefill); +}; + +dialogs.input = function(title, prefill){ + return eval(rawInput(title, prefill)); +} + +dialogs.prompt = dialogs.rawInput; + +dialogs.alert = function(title, prefill){ + prefill = prefill || ""; + return __runtime__.dialogs.alert(title, prefill); +} + +dialogs.confirm = function(title, prefill){ + prefill = prefill || ""; + return __runtime__.dialogs.confirm(title, prefill); +} + +dialogs.select = function(title, items){ + return __runtime__.dialogs.select(title, [].slice.call(arguments, 1)); +} + +dialogs.singleChoice = function(title, index, items){ + return __runtime__.dialogs.singleChoice(title, index, [].slice.call(arguments, 2)); +} + +dialogs.multiChoice = function(title, index, items){ + var javaArray = __runtime__.dialogs.multiChoice(title, index, [].slice.call(arguments, 2)); + var jsArray = {}; + for each(i in javaArray){ + jsArray.push(i); + } + return jsArray; +} + +var rawInput = function(title, prefill){ + return dialogs.rawInput(title, prefill); +} + +var input = function(title, prefill){ + return dialogs.input(title, prefill); +} + +var alert = function(title, prefill){ + dialogs.alert(title, prefill); +} + +var confirm = function(title, prefill){ + return dialogs.confirm(title, prefill); +} + +var prompt = function(title, prefill){ + return dialogs.prompt(title, prefill); +} +/* + +dialogs.rawInput = function(title, prefill){ + prefill = prefill || ""; + return __runtime__.dialogs.rawInput(title, prefill); +} + +dialogs.input = function(title, prefill){ + return eval(rawInput(title, prefill)); +} + +dialogs.alert = function(title, content){ + __runtime__.dialogs.alert(title, content); +} + +dialogs.select = function(title, content){ + __runtime__.dialogs.alert(title, content); +} + +*/ \ No newline at end of file diff --git a/app/src/main/assets/js/functions.json b/app/src/main/assets/js/functions.json new file mode 100644 index 00000000..71bf1ec8 --- /dev/null +++ b/app/src/main/assets/js/functions.json @@ -0,0 +1,62 @@ +[ "toast", + "app", + "launchPackage", + "launch", + "launchApp", + "getPackageName", + "openAppSetting", + "sleep", + "isStopped", + "notStopped", + "stop", + "console", + "log", + "print", + "err", + "openConsole", + "clearConsole", + "shell", + "currentPackage", + "currentActivity", + "back", + "home", + "powerDialog", + "notifications", + "quickSettings", + "recents", + "splitScreen", + "click", + "longClick", + "scrollDown", + "scrollUp", + "input", + "setClip", + "SetScreenMetrics", + "Tap", + "Swipe", + "Screencap", + "KeyCode", + "Home", + "Back", + "Power", + "Up", + "Down", + "Left", + "Right", + "OK", + "VolumeUp", + "VolumeDown", + "Menu", + "Camera", + "Text", + "selector", + "open", + "newInjectableWebClient", + "newInjectableWebView", + "dialogs", + "rawInput", + "input", + "alert", + "confirm", + "prompt" +] \ No newline at end of file diff --git a/app/src/main/assets/sample/对话框/应用工具.js b/app/src/main/assets/sample/对话框/应用工具.js new file mode 100644 index 00000000..85284052 --- /dev/null +++ b/app/src/main/assets/sample/对话框/应用工具.js @@ -0,0 +1,31 @@ +var i = dialogs.select("请选择工具", "获取应用包名", "打开应用详情页", "卸载应用"); + +if(i == -1){ + alert("没有选择任何工具!"); +} + +switch(i){ +case 0: + //获取应用包名 + appName = rawInput("请输入应用名称", "QQ"); + packageName = getPackageName(appName); + toast(packageName); + setClip(packageName); + toast("已复制到剪贴板"); + break; +case 1: + //打开应用详情页 + appName = rawInput("请输入应用名称", "微信"); + openAppSetting(getPackageName(appName)); + break; +case 2: + //卸载应用 + appName = rawInput("请输入应用名称"); + packageName = getPackageName(appName); + if(packageName == ""){ + toast("应用不存在"); + }else if(confirm("确定卸载应用" + packageName + "吗?")){ + app.uninstall(packageName); + } + break; +} \ No newline at end of file diff --git a/app/src/main/assets/sample/对话框/打开应用.js b/app/src/main/assets/sample/对话框/打开应用.js new file mode 100644 index 00000000..be8dc545 --- /dev/null +++ b/app/src/main/assets/sample/对话框/打开应用.js @@ -0,0 +1,2 @@ +var appName = rawInput("请输入应用名称"); +launchApp(appName); \ No newline at end of file diff --git a/app/src/main/assets/sample/对话框/简单计算器.js b/app/src/main/assets/sample/对话框/简单计算器.js new file mode 100644 index 00000000..9d822efc --- /dev/null +++ b/app/src/main/assets/sample/对话框/简单计算器.js @@ -0,0 +1,22 @@ +var num1 = input("请输入第一个数字"); +var op = dialogs.singleChoice("请选择运算", 0, "加", "减", "乘", "除", "幂"); +var num2 = input("请输入第二个数字"); +var result = 0; +switch(op){ +case 0: + result = num1 + num2; + break; +case 1: + result = num1 - num2; + break; +case 2: + result = num1 * num2; + break; +case 3: + result = num1 / num2; + break; +case 4: + result = Math.pow(num1, num2); + break; +} +alert("运算结果", result); \ No newline at end of file diff --git a/app/src/main/assets/sample/需要Root权限的自动操作/打开QQ谁赞过我.js b/app/src/main/assets/sample/需要Root权限的自动操作/打开QQ谁赞过我.js new file mode 100644 index 00000000..e3b3633b --- /dev/null +++ b/app/src/main/assets/sample/需要Root权限的自动操作/打开QQ谁赞过我.js @@ -0,0 +1,20 @@ +SetScreenMetrics(1080, 1920); +launchApp("QQ"); + +//点击动态图标 +Tap(891, 1851); +//点击好友动态 +Tap(192, 453); +//点击头像 +Tap(155, 638); +//点击留言 +Tap(747, 775); + +while(true){ + //点击箭头图标 + Tap(1029, 433); + //点击删除 + Tap(530, 820); + //点击确定 + Tap(331, 1122); +} diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index 7d561ac6..13dff026 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -31,7 +31,6 @@ public class App extends MultiDexApplication { private static final String TAG = "App"; private static WeakReference instance; - private static WeakReference currentActivity; public static App getApp() { return instance.get(); @@ -89,27 +88,23 @@ public class App extends MultiDexApplication { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { super.onActivityCreated(activity, savedInstanceState); + AutoJs.getInstance().getAppUtils().setCurrentActivity(activity); } @Override public void onActivityPaused(Activity activity) { - currentActivity = null; + AutoJs.getInstance().getAppUtils().setCurrentActivity(null); } @Override public void onActivityResumed(Activity activity) { ScreenMetrics.initIfNeeded(activity); - currentActivity = new WeakReference<>(activity); + AutoJs.getInstance().getAppUtils().setCurrentActivity(activity); } }); } - @Keep - public static Activity currentActivity() { - return currentActivity.get(); - } - public static String getResString(int id) { return getApp().getString(id); } diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java index d09d9b3f..5070c849 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java @@ -8,7 +8,10 @@ import com.stardust.autojs.ScriptEngineService; import com.stardust.autojs.ScriptEngineServiceBuilder; import com.stardust.autojs.engine.NodeJsJavaScriptEngineManager; import com.stardust.autojs.engine.ScriptEngineManager; -import com.stardust.autojs.runtime.*; +import com.stardust.autojs.runtime.AccessibilityBridge; +import com.stardust.autojs.runtime.ScriptStopException; +import com.stardust.autojs.runtime.api.AbstractShell; +import com.stardust.autojs.runtime.api.AppUtils; import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.automator.simple_action.SimpleActionPerformHost; import com.stardust.pio.PFile; @@ -16,9 +19,9 @@ import com.stardust.pio.UncheckedIOException; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.autojs.api.Shell; import com.stardust.scriptdroid.script.StorageScriptProvider; import com.stardust.scriptdroid.ui.console.StardustConsole; -import com.stardust.util.AssetsCache; import com.stardust.util.Supplier; import com.stardust.util.UiHandler; import com.stardust.view.accessibility.AccessibilityInfoProvider; @@ -56,10 +59,12 @@ public class AutoJs implements AccessibilityBridge { private final ScriptEngineService mScriptEngineService; private final AccessibilityInfoProvider mAccessibilityInfoProvider; private final UiHandler mUiHandler; + private final AppUtils mAppUtils; private AutoJs(final Context context) { mUiHandler = new UiHandler(context); + mAppUtils = new AppUtils(context); mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager()); ScriptEngineManager manager = createScriptEngineManager(context); mScriptEngineService = new ScriptEngineServiceBuilder() @@ -70,7 +75,17 @@ public class AutoJs implements AccessibilityBridge { @Override public ScriptRuntime get() { - return new ScriptRuntime(mUiHandler, new StardustConsole(mUiHandler), AutoJs.this); + return new ScriptRuntime.Builder() + .setAppUtils(mAppUtils) + .setConsole(new StardustConsole(mUiHandler)) + .setAccessibilityBridge(AutoJs.this) + .setUiHandler(mUiHandler) + .setShellSupplier(new Supplier() { + @Override + public AbstractShell get() { + return new Shell(true); + } + }).build(); } }) .build(); @@ -100,6 +115,10 @@ public class AutoJs implements AccessibilityBridge { return mAccessibilityActionRecorder; } + public AppUtils getAppUtils() { + return mAppUtils; + } + public UiHandler getUiHandler() { return mUiHandler; } diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptRuntime.java b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptRuntime.java new file mode 100644 index 00000000..b46d1d90 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptRuntime.java @@ -0,0 +1,71 @@ +package com.stardust.scriptdroid.autojs; + +import com.stardust.autojs.runtime.AccessibilityBridge; +import com.stardust.autojs.runtime.ScriptVariable; +import com.stardust.autojs.runtime.api.AbstractShell; +import com.stardust.autojs.runtime.api.AppUtils; +import com.stardust.autojs.runtime.api.Console; +import com.stardust.scriptdroid.autojs.api.Dialogs; +import com.stardust.util.Supplier; +import com.stardust.util.UiHandler; + +/** + * Created by Stardust on 2017/5/8. + */ + +public class ScriptRuntime extends com.stardust.autojs.runtime.ScriptRuntime { + + + public static class Builder { + private AppUtils mAppUtils; + private UiHandler mUiHandler; + private Console mConsole; + private AccessibilityBridge mAccessibilityBridge; + private Supplier mShellSupplier; + + + public Builder() { + + } + + public Builder setAppUtils(AppUtils appUtils) { + mAppUtils = appUtils; + return this; + } + + public Builder setUiHandler(UiHandler uiHandler) { + mUiHandler = uiHandler; + return this; + } + + public Builder setConsole(Console console) { + mConsole = console; + return this; + } + + public Builder setAccessibilityBridge(AccessibilityBridge accessibilityBridge) { + mAccessibilityBridge = accessibilityBridge; + return this; + } + + public Builder setShellSupplier(Supplier shellSupplier) { + mShellSupplier = shellSupplier; + return this; + } + + public ScriptRuntime build() { + return new ScriptRuntime(mAppUtils, mUiHandler, mConsole, mAccessibilityBridge, mShellSupplier); + } + + } + + @ScriptVariable + public Dialogs dialogs; + + public ScriptRuntime(AppUtils appUtils, UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge, Supplier shellSupplier) { + super(appUtils, uiHandler, console, accessibilityBridge, shellSupplier); + dialogs = new Dialogs(appUtils, uiHandler); + } + + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/api/BlockedMaterialDialog.java b/app/src/main/java/com/stardust/scriptdroid/autojs/api/BlockedMaterialDialog.java new file mode 100644 index 00000000..bc14aaf7 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/api/BlockedMaterialDialog.java @@ -0,0 +1,135 @@ +package com.stardust.scriptdroid.autojs.api; + +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.View; +import android.view.WindowManager; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.stardust.util.UiHandler; + +/** + * Created by Stardust on 2017/5/8. + */ + +public class BlockedMaterialDialog extends MaterialDialog { + + protected BlockedMaterialDialog(MaterialDialog.Builder builder) { + super(builder); + } + + @Override + public void show() { + if (!(getContext() instanceof Activity)) { + getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + } + super.show(); + } + + + public static class Builder extends MaterialDialog.Builder { + + private UiHandler mUiHandler; + + public Builder(Context context, UiHandler uiHandler) { + super(context); + mUiHandler = uiHandler; + } + + public MaterialDialog.Builder input(@Nullable CharSequence hint, @Nullable CharSequence prefill, boolean allowEmptyInput, final VolatileBox result) { + dismissListener(result); + super.input(hint, prefill, allowEmptyInput, new MaterialDialog.InputCallback() { + @Override + public void onInput(@NonNull MaterialDialog dialog, CharSequence input) { + result.set(input.toString()); + synchronized (result) { + result.notify(); + } + } + }); + return this; + } + + public Builder confirm(final VolatileBox result) { + onAny(new SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + if (which == DialogAction.POSITIVE) { + result.setAndNotify(true); + } else { + result.setAndNotify(false); + } + } + }); + return this; + } + + public MaterialDialog.Builder itemsCallback(final VolatileBox result) { + dismissListener(result); + super.itemsCallback(new ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) { + result.setAndNotify(position); + } + }); + return this; + } + + public MaterialDialog.Builder itemsCallbackMultiChoice(@Nullable Integer[] selectedIndices, final VolatileBox result) { + dismissListener(result); + super.itemsCallbackMultiChoice(selectedIndices, new ListCallbackMultiChoice() { + @Override + public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text) { + result.setAndNotify(which); + return true; + } + }); + return this; + } + + public MaterialDialog.Builder itemsCallbackSingleChoice(int selectedIndex, final VolatileBox result) { + dismissListener(result); + super.itemsCallbackSingleChoice(selectedIndex, new ListCallbackSingleChoice() { + @Override + public boolean onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { + result.setAndNotify(which); + return true; + } + }); + return this; + } + + public Builder dismissListener(final VolatileBox result) { + super.dismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + synchronized (result) { + result.notify(); + } + } + }); + return this; + } + + @Override + public MaterialDialog show() { + mUiHandler.post(new Runnable() { + @Override + public void run() { + Builder.super.show(); + } + }); + return null; + } + + @Override + public MaterialDialog build() { + return new BlockedMaterialDialog(this); + } + + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/api/Dialogs.java b/app/src/main/java/com/stardust/scriptdroid/autojs/api/Dialogs.java new file mode 100644 index 00000000..d6d0def4 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/api/Dialogs.java @@ -0,0 +1,123 @@ +package com.stardust.scriptdroid.autojs.api; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.DialogInterface; +import android.text.TextUtils; +import android.view.ContextThemeWrapper; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.stardust.autojs.runtime.ScriptInterface; +import com.stardust.autojs.runtime.ScriptInterruptedException; +import com.stardust.autojs.runtime.api.AppUtils; +import com.stardust.scriptdroid.App; +import com.stardust.scriptdroid.R; +import com.stardust.util.ArrayUtils; +import com.stardust.util.UiHandler; + +/** + * Created by Stardust on 2017/5/8. + */ + +public class Dialogs { + + private AppUtils mAppUtils; + private UiHandler mUiHandler; + private ContextWrapper mContextWrapper; + + public Dialogs(AppUtils appUtils, UiHandler uiHandler) { + mAppUtils = appUtils; + mUiHandler = uiHandler; + } + + @ScriptInterface + public String rawInput(String title, String prefill) { + VolatileBox result = new VolatileBox<>(null); + dialogBuilder() + .input(null, prefill, true, result) + .title(title) + .show(); + return result.blockedGet(); + } + + @ScriptInterface + public void alert(String title, String content) { + VolatileBox lock = new VolatileBox<>(); + MaterialDialog.Builder builder = dialogBuilder() + .dismissListener(lock) + .title(title) + .positiveText(R.string.ok); + if (!TextUtils.isEmpty(content)) { + builder.content(content); + } + builder.show(); + lock.blockedGet(); + } + + @ScriptInterface + public boolean confirm(String title, String content) { + VolatileBox result = new VolatileBox<>(false); + MaterialDialog.Builder builder = dialogBuilder() + .dismissListener(result) + .confirm(result) + .title(title) + .positiveText(R.string.ok) + .negativeText(R.string.cancel); + if (!TextUtils.isEmpty(content)) { + builder.content(content); + } + builder.show(); + return result.blockedGet(); + } + + private Context getContext() { + if (mContextWrapper == null) { + mContextWrapper = new ContextThemeWrapper(mUiHandler.getContext(), R.style.AppTheme); + } + return mContextWrapper; + } + + @ScriptInterface + public int select(String title, String... items) { + VolatileBox result = new VolatileBox<>(-1); + dialogBuilder() + .itemsCallback(result) + .title(title) + .items((CharSequence[]) items) + .show(); + return result.blockedGet(); + } + + @ScriptInterface + public int singleChoice(String title, int selectedIndex, String... items) { + VolatileBox result = new VolatileBox<>(-1); + dialogBuilder() + .itemsCallbackSingleChoice(selectedIndex, result) + .title(title) + .positiveText(R.string.ok) + .items((CharSequence[]) items) + .show(); + return result.blockedGet(); + } + + @ScriptInterface + public int[] multiChoice(String title, int[] indices, String... items) { + VolatileBox result = new VolatileBox<>(new Integer[0]); + dialogBuilder() + .itemsCallbackMultiChoice(ArrayUtils.box(indices), result) + .title(title) + .positiveText(R.string.ok) + .items((CharSequence[]) items) + .show(); + return ArrayUtils.unbox(result.blockedGet()); + } + + + private BlockedMaterialDialog.Builder dialogBuilder() { + Context context = mAppUtils.getCurrentActivity(); + if (context == null) { + context = getContext(); + } + return new BlockedMaterialDialog.Builder(context, mUiHandler); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java b/app/src/main/java/com/stardust/scriptdroid/autojs/api/Shell.java similarity index 98% rename from app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java rename to app/src/main/java/com/stardust/scriptdroid/autojs/api/Shell.java index 42d5ae65..c36f0757 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/api/Shell.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.autojs; +package com.stardust.scriptdroid.autojs.api; import android.content.Context; import android.os.Handler; @@ -10,6 +10,7 @@ import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.lang.ThreadCompat; import com.stardust.pio.UncheckedIOException; import com.stardust.scriptdroid.App; +import com.stardust.scriptdroid.autojs.AutoJs; import java.io.BufferedReader; import java.io.IOException; diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/api/VolatileBox.java b/app/src/main/java/com/stardust/scriptdroid/autojs/api/VolatileBox.java new file mode 100644 index 00000000..a0cc60eb --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/api/VolatileBox.java @@ -0,0 +1,47 @@ +package com.stardust.scriptdroid.autojs.api; + +import com.stardust.autojs.runtime.ScriptInterruptedException; + +/** + * Created by Stardust on 2017/5/8. + */ + +public class VolatileBox { + + private volatile T mValue; + + public VolatileBox() { + + } + + public VolatileBox(T value) { + set(value); + } + + public T get() { + return mValue; + } + + public void set(T value) { + mValue = value; + } + + public void setAndNotify(T value) { + mValue = value; + synchronized (this) { + notify(); + } + } + + public T blockedGet() { + synchronized (this) { + try { + this.wait(); + } catch (InterruptedException e) { + throw new ScriptInterruptedException(); + } + } + return mValue; + } + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java index 62e9c922..51fa9bad 100644 --- a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java +++ b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java @@ -1,24 +1,8 @@ package com.stardust.scriptdroid.record.inputevent; -import android.preference.PreferenceManager; -import android.util.Log; - -import com.stardust.pio.UncheckedIOException; -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.autojs.Shell; +import com.stardust.scriptdroid.autojs.api.Shell; import com.stardust.scriptdroid.record.Recorder; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; - -import jackpal.androidterm.ShellTermSession; -import jackpal.androidterm.emulatorview.TermSession; -import jackpal.androidterm.util.TermSettings; - /** * Created by Stardust on 2017/3/6. */ diff --git a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventToSendEventJsConverter.java b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventToSendEventJsConverter.java index 3aeb94a6..dbcf95ad 100644 --- a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventToSendEventJsConverter.java +++ b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventToSendEventJsConverter.java @@ -23,7 +23,7 @@ public class InputEventToSendEventJsConverter extends InputEventConverter { public InputEventToSendEventJsConverter() { mCode.append("var sh = new Shell(true);\n") - .append("sh.SetScreenScale(").append(getScreenWidth()).append(", ") + .append("sh.SetScreenMetrics(").append(getScreenWidth()).append(", ") .append(getScreenHeight()).append(");\n"); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java index b8686bbe..49c70492 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java @@ -1,12 +1,19 @@ package com.stardust.scriptdroid.ui.edit.completion; +import android.content.Context; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import com.google.gson.Gson; +import com.stardust.pio.PFile; +import com.stardust.pio.UncheckedIOException; +import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.jecelyin.editor.v2.core.widget.TextView; +import java.io.IOException; +import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -106,7 +113,7 @@ public class CodeCompletion implements TextWatcher { mFunctions = functions; } - private String[] mFunctions = {"toast", "launchPackage", "launch", "launchApp", "click", "longClick", "scrollUp", "scrollDown", "select", "focus", "paste", "input", "sleep", "isStopped", "notStopped", "printf", "err", "openConsole", "clearConsole", "shell", "getTexts", "getPackageName", "getActivityName", "setClip", "addAccessibilityDelegate"}; + private String[] mFunctions = new String[0]; private boolean searchCodeCompletion(String str) { Collection c = searchWordCompletion(str); @@ -148,8 +155,7 @@ public class CodeCompletion implements TextWatcher { return searchCodeCompletion(str, KEYWORDS); } - - private static final String[] DEFAULT_CODE_COMPLETIONS = new String[]{"=", "(", ")", ";", "{", "}", "\"", "!", "[", "]", "\\", ".", ", "}; + private static final String[] DEFAULT_CODE_COMPLETIONS = new String[]{"=", "(", ")", ";", "{", "}", "\"", "!", "[", "]", "\\", ">", "<", ".", ", "}; private static final List DEFAULT_CODE_COMPLETION_LIST = new ArrayList<>(); static { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java index 44a71884..ffe79afe 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java @@ -14,10 +14,14 @@ import android.widget.TextView; import android.widget.Toast; import android.workground.WrapContentLinearLayoutManager; +import com.google.gson.Gson; +import com.stardust.pio.UncheckedIOException; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; +import java.io.IOException; +import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -79,7 +83,7 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio private void init() { setAdapter(new CodeCompletionAdapter()); setLayoutManager(new WrapContentLinearLayoutManager(getContext(), HORIZONTAL, false)); - mCodeCompletion.setFunctions(AutoJs.getInstance().getScriptEngineService().getGlobalFunctions()); + mCodeCompletion.setFunctions(readFunctions(getContext(), "js/functions.json")); } public void setEditTextBridge(EditTextBridge editTextBridge) { @@ -124,4 +128,14 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio itemView.setOnLongClickListener(mOnCodeCompletionItemLongClickListener); } } + + private static String[] readFunctions(Context context, String path) { + Gson gson = new Gson(); + try { + return gson.fromJson(new InputStreamReader(context.getAssets().open(path)), String[].class); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } diff --git a/autojs/src/main/assets/javascript_engine_init.js b/autojs/src/main/assets/javascript_engine_init.js index 623f39f4..dfdfdb97 100644 --- a/autojs/src/main/assets/javascript_engine_init.js +++ b/autojs/src/main/assets/javascript_engine_init.js @@ -17,28 +17,30 @@ var toast = function(text){ __runtime__.toast(text); } +var app = __runtime__.app; + var launchPackage = function(package){ - __runtime__.app.launchPackage(package); + app.launchPackage(package); } var launch = function(a, b){ if(arguments.length == 2){ - __runtime__.app.launch(a, b); + app.launch(a, b); }else{ - __runtime__.app.launchPackage(a); + app.launchPackage(a); } } var launchApp = function(appName){ - __runtime__.app.launchApp(appName); + app.launchApp(appName); } var getPackageName = function(appName){ - return __runtime__.app.getPackageName(appName); + return app.getPackageName(appName); } var openAppSetting = function(packageName){ - return __runtime__.app.openAppSetting(packageName); + return app.openAppSetting(packageName); } @@ -182,6 +184,11 @@ var setClip = function(text){ } +var SetScreenMetrics = function(w, h){ + __runtime__.SetScreenMetrics(w, h); +} + + var Tap = function(x, y){ __runtime__.shellExecAsync("input tap " + x + " " + y); } diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java b/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java index 1835eb87..7fc6e342 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java +++ b/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java @@ -43,9 +43,19 @@ public class ScriptEngineService { EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_START, execution.getSource().toString())); } + @Override + public void onSuccess(ScriptExecution execution, Object result) { + onFinish(execution); + } + + private void onFinish(ScriptExecution execution) { + execution.getRuntime().onStop(); + } + @Override public void onException(ScriptExecution execution, Exception e) { e.printStackTrace(); + onFinish(execution); if (!causedByInterrupted(e)) { execution.getRuntime().console.error(e.getMessage()); EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_EXCEPTION, e.getMessage())); @@ -54,7 +64,7 @@ public class ScriptEngineService { }; - private final Supplier mRuntimeSupplier; + private final Supplier mRuntimeSupplier; private final Context mContext; private UiHandler mUiHandler; private final Console mGlobalConsole; diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java b/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java index 3d67f05a..457c8764 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java +++ b/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java @@ -13,7 +13,7 @@ import com.stardust.util.UiHandler; public class ScriptEngineServiceBuilder { - Supplier mRuntimeSupplier; + Supplier mRuntimeSupplier; ScriptEngineManager mScriptEngineManager; Console mGlobalConsole; UiHandler mUiHandler; @@ -22,7 +22,7 @@ public class ScriptEngineServiceBuilder { } - public ScriptEngineServiceBuilder runtime(Supplier runtimeSupplier) { + public ScriptEngineServiceBuilder runtime(Supplier runtimeSupplier) { mRuntimeSupplier = runtimeSupplier; return this; } 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 15bc10e3..345dd4df 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java @@ -102,6 +102,7 @@ public class RhinoJavaScriptEngineManager extends AbstractScriptEngineManager { ScriptEngine engine = createEngine(); ScriptSource source = new StringScriptSource("this", "this"); engine.setTag("script", source); + engine.init(); Scriptable scriptable = (Scriptable) engine.execute(source); Object[] ids = scriptable.getIds(); String[] functions = new String[ids.length]; diff --git a/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java index fd8fcf5f..9a8e96bb 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java @@ -25,15 +25,19 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu @Override public void run() { - mScriptEngine = mScriptEngineService.createScriptEngine(); - mScriptRuntime = mScriptEngineService.createScriptRuntime(); - execute(mScriptRuntime, mScriptEngine); + execute(); } - private void execute(ScriptRuntime runtime, ScriptEngine engine) { + public Object execute() { + mScriptEngine = mScriptEngineService.createScriptEngine(); + mScriptRuntime = mScriptEngineService.createScriptRuntime(); + return execute(mScriptRuntime, mScriptEngine); + } + + private Object execute(ScriptRuntime runtime, ScriptEngine engine) { try { prepare(runtime, engine); - doExecution(engine); + return doExecution(engine); } catch (Exception e) { e.printStackTrace(); getListener().onException(this, e); @@ -41,6 +45,7 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu Log.d(TAG, "Engine destroy"); engine.destroy(); } + return null; } private void prepare(ScriptRuntime runtime, ScriptEngine engine) { @@ -51,10 +56,12 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu engine.init(); } - private void doExecution(ScriptEngine engine) { + private Object doExecution(ScriptEngine engine) { engine.setTag("script", getSource()); getListener().onStart(this); - getListener().onSuccess(this, engine.execute(getSource())); + Object result = engine.execute(getSource()); + getListener().onSuccess(this, result); + return result; } @Override 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 24a70e43..19674fe6 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java @@ -14,17 +14,17 @@ import com.stardust.view.accessibility.AccessibilityInfoProvider; public abstract class AbstractScriptRuntime { - @JavascriptField - public AppUtils app; + @ScriptVariable + public AppUtils app; - @JavascriptField - public Console console; + @ScriptVariable + public Console console; - @JavascriptField - public SimpleActionAutomator automator; + @ScriptVariable + public SimpleActionAutomator automator; - @JavascriptField - public AccessibilityInfoProvider info; + @ScriptVariable + public AccessibilityInfoProvider info; public AbstractScriptRuntime(AppUtils app, Console console, AccessibilityBridge bridge) { this.app = app; @@ -36,35 +36,40 @@ public abstract class AbstractScriptRuntime { public AbstractScriptRuntime() { } - @JavascriptInterface + @ScriptInterface public abstract void toast(final String text); - @JavascriptInterface + @ScriptInterface public abstract void sleep(long millis); - @JavascriptInterface + @ScriptInterface public abstract void setClip(final String text); - @JavascriptInterface + @ScriptInterface public abstract void shellExecAsync(String cmd); - @JavascriptInterface + @ScriptInterface public abstract AbstractShell.Result shell(String cmd, int root); - @JavascriptInterface + @ScriptInterface public abstract UiSelector selector(ScriptEngine engine); - @JavascriptInterface + @ScriptInterface public abstract boolean isStopped(); - @JavascriptInterface + @ScriptInterface public abstract void requiresApi(int i); - @JavascriptInterface + @ScriptInterface public abstract void loadJar(String path); - @JavascriptInterface + @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/JavascriptClass.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptClass.java similarity index 89% rename from autojs/src/main/java/com/stardust/autojs/runtime/JavascriptClass.java rename to autojs/src/main/java/com/stardust/autojs/runtime/ScriptClass.java index 0962f15c..3331f5d8 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/JavascriptClass.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptClass.java @@ -10,5 +10,5 @@ import java.lang.annotation.Target; */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) -public @interface JavascriptClass { +public @interface ScriptClass { } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/JavascriptInterface.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterface.java similarity index 88% rename from autojs/src/main/java/com/stardust/autojs/runtime/JavascriptInterface.java rename to autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterface.java index 8f30c961..334ee2a3 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/JavascriptInterface.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterface.java @@ -10,5 +10,5 @@ import java.lang.annotation.Target; */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.METHOD}) -public @interface JavascriptInterface { +public @interface ScriptInterface { } 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 2d816bbb..735866d5 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -13,6 +13,7 @@ import com.stardust.pio.UncheckedIOException; import com.stardust.util.ClipboardUtil; import com.stardust.autojs.runtime.api.ProcessShell; import com.stardust.util.SdkVersionUtil; +import com.stardust.util.Supplier; import com.stardust.util.UiHandler; import org.mozilla.javascript.ContextFactory; @@ -29,15 +30,69 @@ public class ScriptRuntime extends AbstractScriptRuntime { private static final String TAG = "ScriptRuntime"; + public static class Builder { + private AppUtils mAppUtils; + private UiHandler mUiHandler; + private Console mConsole; + private AccessibilityBridge mAccessibilityBridge; + private Supplier mShellSupplier; + + + public Builder() { + + } + + public Builder setAppUtils(AppUtils appUtils) { + mAppUtils = appUtils; + return this; + } + + public Builder setUiHandler(UiHandler uiHandler) { + mUiHandler = uiHandler; + return this; + } + + public Builder setConsole(Console console) { + mConsole = console; + return this; + } + + public Builder setAccessibilityBridge(AccessibilityBridge accessibilityBridge) { + mAccessibilityBridge = accessibilityBridge; + return this; + } + + public Builder setShellSupplier(Supplier shellSupplier) { + mShellSupplier = shellSupplier; + return this; + } + + public ScriptRuntime build() { + return new ScriptRuntime(mAppUtils, mUiHandler, mConsole, mAccessibilityBridge, mShellSupplier); + } + + } + private UiHandler mUiHandler; private AccessibilityBridge mAccessibilityBridge; private AbstractShell mRootShell; + private Supplier mShellSupplier; - public ScriptRuntime(UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge) { - super(new AppUtils(uiHandler.getContext()), console, accessibilityBridge); + + protected ScriptRuntime(AppUtils appUtils, UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge, Supplier shellSupplier) { + super(appUtils, console, accessibilityBridge); mAccessibilityBridge = accessibilityBridge; mUiHandler = uiHandler; + mShellSupplier = shellSupplier; + } + + public UiHandler getUiHandler() { + return mUiHandler; + } + + public AccessibilityBridge getAccessibilityBridge() { + return mAccessibilityBridge; } public void toast(final String text) { @@ -62,12 +117,20 @@ public class ScriptRuntime extends AbstractScriptRuntime { } public void shellExecAsync(String cmd) { - if (mRootShell == null) { - mRootShell = new ProcessShell(true); - } + ensureRootShell(); mRootShell.exec(cmd); } + private void ensureRootShell() { + if (mRootShell == null) { + if (mShellSupplier == null) { + throw new ScriptInterruptedException(); + } + mRootShell = mShellSupplier.get(); + mShellSupplier = null; + } + } + public AbstractShell.Result shell(String cmd, int root) { return ProcessShell.execCommand(cmd, root != 0); } @@ -98,7 +161,22 @@ 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(); } + + @Override + public void onStop() { + if (mRootShell != null) { + mRootShell.exit(); + mRootShell = null; + } + mShellSupplier = null; + } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntimeBuilder.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntimeBuilder.java new file mode 100644 index 00000000..cd30ea3c --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntimeBuilder.java @@ -0,0 +1,11 @@ +package com.stardust.autojs.runtime; + +import com.stardust.autojs.runtime.api.AbstractShell; +import com.stardust.autojs.runtime.api.AppUtils; +import com.stardust.autojs.runtime.api.Console; +import com.stardust.util.Supplier; +import com.stardust.util.UiHandler; + +public class ScriptRuntimeBuilder { + +} \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/JavascriptField.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptVariable.java similarity index 89% rename from autojs/src/main/java/com/stardust/autojs/runtime/JavascriptField.java rename to autojs/src/main/java/com/stardust/autojs/runtime/ScriptVariable.java index 2ca7eb81..ea48ef1f 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/JavascriptField.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptVariable.java @@ -11,5 +11,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.SOURCE) @Target({ElementType.FIELD}) -public @interface JavascriptField { +public @interface ScriptVariable { } 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 5a67207d..856691fc 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 @@ -70,7 +70,7 @@ public abstract class AbstractShell { exec(TextUtils.join("", new Object[]{"sendevent /dev/input/event", device, " ", type, " ", code, " ", value})); } - public void SetScreenScale(int width, int height){ + public void SetScreenMetrics(int width, int height){ mScreenWidth = width; mScreenHeight = height; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java index fd1df5ae..0e0e60d4 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java @@ -1,10 +1,14 @@ package com.stardust.autojs.runtime.api; +import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.net.Uri; +import android.support.annotation.Nullable; -import com.stardust.autojs.runtime.JavascriptInterface; +import com.stardust.autojs.runtime.ScriptInterface; import com.stardust.util.IntentUtil; import java.util.List; @@ -16,13 +20,13 @@ import java.util.List; public class AppUtils { private Context mContext; + private Activity mCurrentActivity; public AppUtils(Context context) { mContext = context; } - - @JavascriptInterface + @ScriptInterface public boolean launchPackage(String packageName) { try { PackageManager packageManager = mContext.getPackageManager(); @@ -34,12 +38,12 @@ public class AppUtils { } - @JavascriptInterface + @ScriptInterface public boolean launchApp(String appName) { return launchPackage(getPackageName(appName)); } - @JavascriptInterface + @ScriptInterface public String getPackageName(String appName) { PackageManager packageManager = mContext.getPackageManager(); List installedApplications = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); @@ -51,10 +55,23 @@ public class AppUtils { return ""; } - @JavascriptInterface + @ScriptInterface public boolean openAppSetting(String packageName) { return IntentUtil.goToAppDetailSettings(mContext, packageName); } + @Nullable + public Activity getCurrentActivity() { + return mCurrentActivity; + } + @ScriptInterface + public void uninstall(String packageName) { + mContext.startActivity(new Intent(Intent.ACTION_DELETE, Uri.parse("package:" + packageName)) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + + public void setCurrentActivity(Activity currentActivity) { + mCurrentActivity = currentActivity; + } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java index ea044275..5578415b 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java @@ -2,7 +2,7 @@ package com.stardust.autojs.runtime.api; import android.support.annotation.Nullable; -import com.stardust.autojs.runtime.JavascriptInterface; +import com.stardust.autojs.runtime.ScriptInterface; /** * Created by Stardust on 2017/4/2. @@ -10,31 +10,31 @@ import com.stardust.autojs.runtime.JavascriptInterface; public interface Console { - @JavascriptInterface + @ScriptInterface void verbose(@Nullable Object data, Object... options); - @JavascriptInterface + @ScriptInterface void log(@Nullable Object data, Object... options); - @JavascriptInterface + @ScriptInterface void info(@Nullable Object data, Object... options); - @JavascriptInterface + @ScriptInterface void warn(@Nullable Object data, Object... options); - @JavascriptInterface + @ScriptInterface void error(@Nullable Object data, Object... options); - @JavascriptInterface + @ScriptInterface void assertTrue(boolean value, @Nullable Object data, Object... options); - @JavascriptInterface + @ScriptInterface void clear(); - @JavascriptInterface + @ScriptInterface void show(); - @JavascriptInterface + @ScriptInterface void hide(); void println(int level, CharSequence charSequence); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebView.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebView.java index 5b57cf09..c9217617 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebView.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebView.java @@ -4,15 +4,15 @@ import android.content.Context; import android.webkit.ValueCallback; import android.webkit.WebView; -import com.stardust.autojs.runtime.JavascriptClass; -import com.stardust.autojs.runtime.JavascriptInterface; +import com.stardust.autojs.runtime.ScriptClass; +import com.stardust.autojs.runtime.ScriptInterface; import org.mozilla.javascript.Scriptable; /** * Created by Stardust on 2017/4/1. */ -@JavascriptClass +@ScriptClass public class InjectableWebView extends WebView { private InjectableWebClient mInjectableWebClient; @@ -27,12 +27,12 @@ public class InjectableWebView extends WebView { setWebViewClient(mInjectableWebClient); } - @JavascriptInterface + @ScriptInterface public void inject(String script, ValueCallback callback) { mInjectableWebClient.inject(script, callback); } - @JavascriptInterface + @ScriptInterface public void inject(String script) { mInjectableWebClient.inject(script); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java index 6e6244bc..573bf826 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java @@ -7,7 +7,7 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import com.stardust.autojs.runtime.AccessibilityBridge; -import com.stardust.autojs.runtime.JavascriptInterface; +import com.stardust.autojs.runtime.ScriptInterface; import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.automator.ActionArgument; @@ -85,7 +85,7 @@ public class UiSelector extends UiGlobalSelector { mAllocator = allocator; } - @JavascriptInterface + @ScriptInterface public UiObjectCollection find() { ensureAccessibilityServiceEnabled(); if (AutomatorConfig.isUnintendedGuardEnabled() && isRunningPackageSelf()) { @@ -111,7 +111,7 @@ public class UiSelector extends UiGlobalSelector { } - @JavascriptInterface + @ScriptInterface @NonNull public UiObjectCollection untilFind() { UiObjectCollection uiObjectCollection; @@ -125,7 +125,7 @@ public class UiSelector extends UiGlobalSelector { return uiObjectCollection; } - @JavascriptInterface + @ScriptInterface public UiObject findOne() { return untilFindOne(); } @@ -136,7 +136,7 @@ public class UiSelector extends UiGlobalSelector { return new UiObject(collection.get(0).getInfo()); } - @JavascriptInterface + @ScriptInterface public UiSelector id(final String id) { if (!id.contains(":")) { addFilter(new DfsFilter() { @@ -157,131 +157,131 @@ public class UiSelector extends UiGlobalSelector { return untilFind().performAction(action, arguments); } - @JavascriptInterface + @ScriptInterface public boolean click() { return performAction(ACTION_CLICK); } - @JavascriptInterface + @ScriptInterface public boolean longClick() { return performAction(ACTION_LONG_CLICK); } - @JavascriptInterface + @ScriptInterface public boolean accessibilityFocus() { return performAction(ACTION_ACCESSIBILITY_FOCUS); } - @JavascriptInterface + @ScriptInterface public boolean clearAccessibilityFocus() { return performAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS); } - @JavascriptInterface + @ScriptInterface public boolean focus() { return performAction(ACTION_FOCUS); } - @JavascriptInterface + @ScriptInterface public boolean clearFocus() { return performAction(ACTION_CLEAR_FOCUS); } - @JavascriptInterface + @ScriptInterface public boolean copy() { return performAction(ACTION_COPY); } - @JavascriptInterface + @ScriptInterface public boolean paste() { return performAction(ACTION_PASTE); } - @JavascriptInterface + @ScriptInterface public boolean select() { return performAction(ACTION_SELECT); } - @JavascriptInterface + @ScriptInterface public boolean cut() { return performAction(ACTION_CUT); } - @JavascriptInterface + @ScriptInterface public boolean collapse() { return performAction(ACTION_COLLAPSE); } - @JavascriptInterface + @ScriptInterface public boolean expand() { return performAction(ACTION_EXPAND); } - @JavascriptInterface + @ScriptInterface public boolean dismiss() { return performAction(ACTION_DISMISS); } - @JavascriptInterface + @ScriptInterface public boolean show() { return performAction(ACTION_SHOW_ON_SCREEN.getId()); } - @JavascriptInterface + @ScriptInterface public boolean scrollForward() { return performAction(ACTION_SCROLL_FORWARD); } - @JavascriptInterface + @ScriptInterface public boolean scrollBackward() { return performAction(ACTION_SCROLL_BACKWARD); } - @JavascriptInterface + @ScriptInterface public boolean scrollUp() { return performAction(ACTION_SCROLL_UP.getId()); } - @JavascriptInterface + @ScriptInterface public boolean scrollDown() { return performAction(ACTION_SCROLL_DOWN.getId()); } - @JavascriptInterface + @ScriptInterface public boolean scrollLeft() { return performAction(ACTION_SCROLL_LEFT.getId()); } - @JavascriptInterface + @ScriptInterface public boolean scrollRight() { return performAction(ACTION_SCROLL_RIGHT.getId()); } - @JavascriptInterface + @ScriptInterface public boolean contextClick() { return performAction(ACTION_CONTEXT_CLICK.getId()); } - @JavascriptInterface + @ScriptInterface public boolean setSelection(int s, int e) { return performAction(ACTION_SET_SELECTION, new ActionArgument.IntActionArgument(ACTION_ARGUMENT_SELECTION_START_INT, s), new ActionArgument.IntActionArgument(ACTION_ARGUMENT_SELECTION_END_INT, e)); } - @JavascriptInterface + @ScriptInterface public boolean setText(String text) { return performAction(ACTION_SET_TEXT, new ActionArgument.CharSequenceActionArgument(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text)); } - @JavascriptInterface + @ScriptInterface public boolean setProgress(float value) { return performAction(ACTION_SET_PROGRESS.getId(), new ActionArgument.FloatActionArgument(ACTION_ARGUMENT_PROGRESS_VALUE, value)); } - @JavascriptInterface + @ScriptInterface public boolean scrollTo(int row, int column) { return performAction(ACTION_SCROLL_TO_POSITION.getId(), new ActionArgument.IntActionArgument(ACTION_ARGUMENT_ROW_INT, row), diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/simple_action/SimpleActionAutomator.java b/autojs/src/main/java/com/stardust/autojs/runtime/simple_action/SimpleActionAutomator.java index e8757d68..139664ca 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/simple_action/SimpleActionAutomator.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/simple_action/SimpleActionAutomator.java @@ -10,8 +10,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.stardust.autojs.runtime.AbstractScriptRuntime; import com.stardust.autojs.runtime.AccessibilityBridge; -import com.stardust.autojs.runtime.JavascriptInterface; -import com.stardust.autojs.runtime.ScriptRuntime; +import com.stardust.autojs.runtime.ScriptInterface; import com.stardust.autojs.runtime.api.AutomatorConfig; import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.automator.UiObject; @@ -53,74 +52,74 @@ public class SimpleActionAutomator { mScriptRuntime = scriptRuntime; } - @JavascriptInterface + @ScriptInterface public ActionTarget text(String text, int i) { return new ActionTarget.TextActionTarget(text, i); } - @JavascriptInterface + @ScriptInterface public ActionTarget bounds(int left, int top, int right, int bottom) { return new ActionTarget.BoundsActionTarget(new Rect(left, top, right, bottom)); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - @JavascriptInterface + @ScriptInterface public ActionTarget editable(int i) { mScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP); return new ActionTarget.EditableActionTarget(i); } - @JavascriptInterface + @ScriptInterface public ActionTarget id(String id) { return new ActionTarget.IdActionTarget(id); } - @JavascriptInterface + @ScriptInterface public boolean click(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_CLICK)); } - @JavascriptInterface + @ScriptInterface public boolean longClick(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_LONG_CLICK)); } - @JavascriptInterface + @ScriptInterface public boolean scrollUp(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)); } - @JavascriptInterface + @ScriptInterface public boolean scrollDown(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)); } - @JavascriptInterface + @ScriptInterface public boolean scrollBackward(int i) { return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i)); } - @JavascriptInterface + @ScriptInterface public boolean scrollForward(int i) { return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i)); } - @JavascriptInterface + @ScriptInterface public boolean scrollMaxBackward() { return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)); } - @JavascriptInterface + @ScriptInterface public boolean scrollMaxForward() { return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)); } - @JavascriptInterface + @ScriptInterface public boolean focus(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_FOCUS)); } - @JavascriptInterface + @ScriptInterface public boolean select(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT)); } @@ -131,39 +130,39 @@ public class SimpleActionAutomator { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text)); } - @JavascriptInterface + @ScriptInterface public boolean back() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); } - @JavascriptInterface + @ScriptInterface public boolean home() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME); } - @JavascriptInterface + @ScriptInterface @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public boolean powerDialog() { mScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP); return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG); } - @JavascriptInterface + @ScriptInterface public boolean notifications() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS); } - @JavascriptInterface + @ScriptInterface public boolean quickSettings() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS); } - @JavascriptInterface + @ScriptInterface public boolean recents() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS); } - @JavascriptInterface + @ScriptInterface @RequiresApi(api = Build.VERSION_CODES.N) public boolean splitScreen() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN); @@ -177,7 +176,7 @@ public class SimpleActionAutomator { return service.performGlobalAction(action); } - @JavascriptInterface + @ScriptInterface public boolean paste(ActionTarget target) { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE)); } diff --git a/common/src/main/java/com/stardust/util/ArrayUtils.java b/common/src/main/java/com/stardust/util/ArrayUtils.java new file mode 100644 index 00000000..2d7f7c59 --- /dev/null +++ b/common/src/main/java/com/stardust/util/ArrayUtils.java @@ -0,0 +1,26 @@ +package com.stardust.util; + +/** + * Created by Stardust on 2017/5/8. + */ + +public class ArrayUtils { + + + public static Integer[] box(int[] array) { + Integer[] box = new Integer[array.length]; + for (int i = 0; i < array.length; i++) { + box[i] = array[i]; + } + return box; + } + + + public static int[] unbox(Integer[] array) { + int[] unbox = new int[array.length]; + for (int i = 0; i < array.length; i++) { + unbox[i] = array[i]; + } + return unbox; + } +} diff --git a/get_global_functions.py b/get_global_functions.py new file mode 100644 index 00000000..c9292321 --- /dev/null +++ b/get_global_functions.py @@ -0,0 +1,25 @@ +import re + +def get_functions(path): + list = [] + with open(path) as f: + for line in f: + func = get_function_or_null(line) + if func: + list.append(func) + return to_str(list) + +def to_str(list): + return str(list).replace("'", '"') + +def get_function_or_null(line): + m = re.match(r'^var\s(\S+)\s=', line) + if m and not m.group(1).startswith('__'): + return m.group(1) + else: + return None + +if __name__ == "__main__": + print(get_functions(r'autojs\src\main\assets\javascript_engine_init.js')) + print(get_functions(r'app\src\main\assets\js\autojs_init.js')) + \ No newline at end of file