diff --git a/app/src/main/assets/help/documentation/一般常用函数.md b/app/src/main/assets/help/documentation/一般常用函数.md index 7198c4bd..a74e205d 100644 --- a/app/src/main/assets/help/documentation/一般常用函数.md +++ b/app/src/main/assets/help/documentation/一般常用函数.md @@ -1,7 +1,8 @@ -### sleep(n) +### sleep(\[n\]) * n \ 毫秒数 暂停运行n**毫秒**的时间。1秒等于1000毫秒。 +如果不加参数n,则会一直暂停,通常用于有事件监听的脚本中使用。 ### launchPackage(packageName) * packageName \ 应用包名。参见《Shell命令:应用包名》章节。 diff --git a/app/src/main/assets/help/documentation/事件与按键监听.md b/app/src/main/assets/help/documentation/事件与按键监听.md new file mode 100644 index 00000000..fb2975f4 --- /dev/null +++ b/app/src/main/assets/help/documentation/事件与按键监听.md @@ -0,0 +1,20 @@ +# events + +events也是一个\[EventEmitter\],这里只介绍其自身的函数。 + +### events.emitter() + +返回一个新的EventEmitter。 + +### events.observeKey() + +启用按键监听,例如音量键、Home键。 + +在安卓4.3以上才能使用。 + +### events.onKeyDown(keyName, listener) + +* keyName \ 要监听的按键名称 +* listener \ 参数为一个\[KeyEvent\] + +注册一个按键监听函数,。按键名称包括 \ No newline at end of file diff --git a/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js b/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js index 3b6a4209..a3e349b4 100644 --- a/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js +++ b/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js @@ -62,7 +62,7 @@ function isImage(item){ function notLiked(likeIcon){ var x = likeIcon.bounds().centerX(); var y = likeIcon.bounds().centerY(); - return images.detectsColor(capture, x, y, 0x767886); + return images.detectsColor(capture, 0x767886, x, y); } toast("请打开QQ空间并慢慢下滑"); diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index 5e44b536..db632249 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -5,6 +5,7 @@ import android.app.Application; import android.content.IntentFilter; import android.os.Bundle; import android.support.multidex.MultiDexApplication; +import android.view.KeyEvent; import com.squareup.leakcanary.LeakCanary; import com.stardust.app.SimpleActivityLifecycleCallbacks; @@ -19,6 +20,8 @@ import com.stardust.theme.ThemeColor; import com.stardust.theme.ThemeColorManager; import com.stardust.util.ScreenMetrics; import com.stardust.util.UiHandler; +import com.stardust.view.accessibility.AccessibilityService; +import com.stardust.view.accessibility.OnKeyListener; import java.lang.ref.WeakReference; @@ -71,7 +74,7 @@ public class App extends MultiDexApplication { } private void initVolumeChangeObserver() { - registerReceiver(mVolumeChangeObserver, new IntentFilter(VolumeChangeObserver.ACTION_VOLUME_CHANGE)); + //registerReceiver(mVolumeChangeObserver, new IntentFilter(VolumeChangeObserver.ACTION_VOLUME_CHANGE)); mVolumeChangeObserver.addOnVolumeChangeListener(new VolumeChangeObserver.OnVolumeChangeListener() { @Override public void onVolumeChange() { @@ -80,6 +83,14 @@ public class App extends MultiDexApplication { } } }); + AccessibilityService.getStickOnKeyObserver().addListener(new OnKeyListener() { + @Override + public void onKeyEvent(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && Pref.isRunningVolumeControlEnabled()) { + AutoJs.getInstance().getScriptEngineService().stopAllAndToast(); + } + } + }); } 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 22e03df3..70c18ce5 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java @@ -32,12 +32,12 @@ import com.stardust.util.ScreenMetrics; import com.stardust.util.Supplier; import com.stardust.util.UiHandler; import com.stardust.view.accessibility.AccessibilityInfoProvider; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.LayoutInspector; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.accessibility.AccessibilityActionRecorder; +import com.stardust.autojs.runtime.record.accessibility.AccessibilityActionRecorder; import com.stardust.view.accessibility.AccessibilityService; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.scriptdroid.ui.console.JraskaConsole; import com.stardust.view.accessibility.AccessibilityServiceUtils; +import com.stardust.view.accessibility.LayoutInspector; /** @@ -177,7 +177,7 @@ public class AutoJs implements AccessibilityBridge { @Nullable @Override - public android.accessibilityservice.AccessibilityService getService() { + public AccessibilityService getService() { return AccessibilityService.getInstance(); } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java index 8a52e75f..962a28f3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java @@ -17,7 +17,7 @@ import com.stardust.hover.SimpleHoverMenuTransitionListener; import com.stardust.hover.WindowHoverMenu; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; import com.stardust.scriptdroid.external.floatingwindow.menu.view.FloatingLayoutBoundsView; import com.stardust.scriptdroid.external.floatingwindow.menu.view.FloatingLayoutHierarchyView; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java index dc6ed7c0..bcc261ab 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java @@ -12,12 +12,12 @@ import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.LayoutInspector; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.scriptdroid.ui.main.MainActivity_; import com.stardust.util.ClipboardUtil; import com.stardust.util.MessageEvent; import com.stardust.view.accessibility.AccessibilityService; +import com.stardust.view.accessibility.LayoutInspector; import org.greenrobot.eventbus.Subscribe; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java index 5f67a444..fd501787 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java @@ -10,16 +10,16 @@ import android.widget.TextView; import android.widget.Toast; import com.stardust.app.VolumeChangeObserver; +import com.stardust.autojs.runtime.record.Recorder; +import com.stardust.autojs.runtime.record.accessibility.AccessibilityActionRecorder; +import com.stardust.autojs.runtime.record.inputevent.KeyObserver; +import com.stardust.autojs.runtime.record.inputevent.TouchRecorder; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.accessibility.AccessibilityEventHelper; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.Recorder; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.accessibility.AccessibilityActionRecorder; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent.KeyObserver; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent.TouchRecorder; import com.stardust.scriptdroid.ui.main.MainActivity; import com.stardust.util.MessageEvent; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java index b22fef68..95750881 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java @@ -13,7 +13,7 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; import com.stardust.util.ViewUtil; import java.util.ArrayList; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java index 0da221ff..c0381c7e 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java @@ -14,7 +14,7 @@ import android.widget.ListView; import android.widget.TextView; import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; import com.stardust.util.ViewUtil; import com.stardust.widget.LevelBeamView; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java index 22762a6c..2a8c68e3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java @@ -12,7 +12,7 @@ import android.widget.TextView; import android.widget.Toast; import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; import com.stardust.util.ClipboardUtil; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; @@ -22,7 +22,6 @@ import java.util.Arrays; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; -import butterknife.OnLongClick; import butterknife.Optional; /** diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java index 04627361..5fb29295 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java @@ -1,6 +1,6 @@ package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; /** * Created by Stardust on 2017/3/10. diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java index 100c3184..f6c6ba1a 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java @@ -11,7 +11,7 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.Theme; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.LayoutBoundsView; import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView; import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.OnNodeInfoSelectListener; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java index 534154e6..1ad55694 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java @@ -11,7 +11,7 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.Theme; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; +import com.stardust.view.accessibility.NodeInfo; import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.LayoutHierarchyView; import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView; import com.stardust.util.MessageIntent; diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java index 4771dc96..0750f619 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java @@ -1,6 +1,7 @@ package com.stardust.scriptdroid.ui.main.task; import android.content.Context; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.ThemeColorRecyclerView; @@ -11,6 +12,8 @@ import android.view.ViewGroup; import android.widget.TextView; import android.workground.WrapContentLinearLayoutManager; +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; import com.stardust.autojs.ScriptEngineService; import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.execution.ScriptExecutionListener; @@ -43,9 +46,19 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Abst @Override public void onClick(View v) { int position = getChildViewHolder((View) v.getParent()).getAdapterPosition(); - if(position >= 0){ - mScriptEngines.get(position).forceStop(); - }else { + if (position >= 0) { + final ScriptEngine engine = mScriptEngines.get(position); + engine.forceStop(); + + postDelayed(new Runnable() { + @Override + public void run() { + if (!engine.isDestroyed()) { + onScriptANR(engine); + } + } + }, 3000); + } else { updateEngineList(); } } @@ -128,6 +141,10 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Abst AutoJs.getInstance().getScriptEngineService().unregisterGlobalScriptExecutionListener(mScriptExecutionListener); } + private void onScriptANR(final ScriptEngine engine) { + // TODO: 2017/7/19 强制停止 + } + @Override public void onEngineCreate(final ScriptEngine engine) { synchronized (mScriptEngines) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1c8dfea1..4be83403 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,6 +208,8 @@ 打开无障碍服务 放弃录制 布局抓取失败,请关闭悬浮窗后动一下页面重试 + 没有相应,要强制停止吗 + diff --git a/autojs/src/main/assets/javascript_engine_init.js b/autojs/src/main/assets/javascript_engine_init.js index 57803c14..bf1fd63d 100644 --- a/autojs/src/main/assets/javascript_engine_init.js +++ b/autojs/src/main/assets/javascript_engine_init.js @@ -27,7 +27,7 @@ require("__general__")(__runtime__, this); (function(scope){ - var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui', "images"]; + var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui', "images", "events"]; var len = modules.length; for(var i = 0; i < len; i++) { var m = modules[i]; diff --git a/autojs/src/main/assets/modules/__events__.js b/autojs/src/main/assets/modules/__events__.js new file mode 100644 index 00000000..b2ae7fcb --- /dev/null +++ b/autojs/src/main/assets/modules/__events__.js @@ -0,0 +1,24 @@ + +module.exports = function(__runtime__, scope){ + var events = Object.create(__runtime__.events); + + var caller = function(func, args){ + var arr = []; + var len = args.length; + for(var i = 0; i < len; i++){ + arr.push(args[i]); + } + return func.apply(null, arr); + }; + + events.setFunctionCaller(caller); + + events.emitter = function(){ + var e = new com.stardust.autojs.runtime.api.EventEmitter(); + e.setFunctionCaller(caller); + return e; + } + + return events; +} + diff --git a/autojs/src/main/assets/modules/__general__.js b/autojs/src/main/assets/modules/__general__.js index 07c3523d..043855e6 100644 --- a/autojs/src/main/assets/modules/__general__.js +++ b/autojs/src/main/assets/modules/__general__.js @@ -9,9 +9,7 @@ module.exports = function(__runtime__, scope){ scope.log(text); } - scope.sleep = function(millis){ - __runtime__.sleep(millis); - } + scope.sleep = __runtime__.sleep.bind(__runtime__); scope.isStopped = function(){ return __runtime__.isStopped(); diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java index bc252fbf..362d02a6 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java @@ -1,10 +1,12 @@ package com.stardust.autojs.engine; +import android.os.Looper; import android.util.Log; import com.stardust.autojs.rhino.AndroidContextFactory; import com.stardust.autojs.rhino.RhinoAndroidHelper; import com.stardust.autojs.runtime.ScriptInterruptedException; +import com.stardust.autojs.runtime.api.Events; import com.stardust.autojs.script.ScriptSource; import com.stardust.pio.UncheckedIOException; @@ -41,6 +43,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine { private Thread mThread; private RhinoJavaScriptEngineManager mEngineManager; private Map mTags = new ConcurrentHashMap<>(); + private volatile boolean mDestroyed = false; public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) { mEngineManager = engineManager; @@ -73,6 +76,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine { public void forceStop() { Log.d(LOG_TAG, "forceStop: interrupt Thread: " + mThread); mThread.interrupt(); + Events.quitLooperIfNeeded(mThread); } public RhinoJavaScriptEngineManager getEngineManager() { @@ -86,6 +90,13 @@ public class RhinoJavaScriptEngine implements ScriptEngine { contextCount--; Log.d(LOG_TAG, "contextCount = " + contextCount); mEngineManager.removeEngine(this); + Events.removeThreadRecord(mThread); + mDestroyed = true; + } + + @Override + public boolean isDestroyed() { + return mDestroyed; } @Override diff --git a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java index 525fe2a0..f2b88fde 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java @@ -25,6 +25,8 @@ public interface ScriptEngine { void destroy(); + boolean isDestroyed(); + void setTag(String key, Object value); Object getTag(String key); 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 0ac908a8..0ca6081f 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java @@ -8,6 +8,7 @@ import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.autojs.runtime.api.AppUtils; import com.stardust.autojs.runtime.api.Console; +import com.stardust.autojs.runtime.api.Events; import com.stardust.autojs.runtime.api.UiSelector; import com.stardust.autojs.runtime.api.image.Images; import com.stardust.autojs.runtime.api.image.ScreenCaptureRequester; @@ -41,10 +42,12 @@ public abstract class AbstractScriptRuntime { @ScriptVariable public UI ui; - @ScriptVariable public Dialogs dialogs; + @ScriptVariable + public Events events; + private Images images; private static WeakReference applicationContext; @@ -54,11 +57,13 @@ public abstract class AbstractScriptRuntime { this.console = console; this.automator = new SimpleActionAutomator(bridge, this); this.info = bridge.getInfoProvider(); - this.ui = new UI(uiHandler.getContext()); + Context context = uiHandler.getContext(); + this.ui = new UI(context); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - images = new Images(uiHandler.getContext(), this, screenCaptureRequester); + images = new Images(context, this, screenCaptureRequester); } dialogs = new Dialogs(app, uiHandler); + events = new Events(context, bridge); } public static void setApplicationContext(Context context) { @@ -115,6 +120,7 @@ public abstract class AbstractScriptRuntime { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { images.releaseScreenCapturer(); } + events.recycle(); } public Object getImages() { diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/AccessibilityBridge.java b/autojs/src/main/java/com/stardust/autojs/runtime/AccessibilityBridge.java index 9c8235e9..a35301e5 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AccessibilityBridge.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AccessibilityBridge.java @@ -1,11 +1,11 @@ package com.stardust.autojs.runtime; -import android.accessibilityservice.AccessibilityService; import android.support.annotation.Nullable; import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.automator.simple_action.SimpleActionPerformHost; import com.stardust.view.accessibility.AccessibilityInfoProvider; +import com.stardust.view.accessibility.AccessibilityService; /** * Created by Stardust on 2017/4/2. 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 68204ba2..bda7e736 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -1,6 +1,7 @@ package com.stardust.autojs.runtime; import android.os.Build; +import android.os.Handler; import android.os.Looper; import com.stardust.autojs.R; @@ -85,7 +86,6 @@ public class ScriptRuntime extends AbstractScriptRuntime { private UiHandler mUiHandler; private AccessibilityBridge mAccessibilityBridge; - private AbstractShell mRootShell; private Supplier mShellSupplier; private ScreenMetrics mScreenMetrics = new ScreenMetrics(); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/EventEmitter.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/EventEmitter.java new file mode 100644 index 00000000..e4ba5a99 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/EventEmitter.java @@ -0,0 +1,195 @@ +package com.stardust.autojs.runtime.api; + +import android.support.annotation.NonNull; + +import com.stardust.autojs.runtime.ScriptStopException; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TooManyListenersException; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Created by Stardust on 2017/7/19. + */ + +public class EventEmitter { + + public interface FunctionCaller { + Object call(Object func, Object[] arg); + } + + private static class ListenerWrapper { + Object listener; + boolean isOnce; + + public ListenerWrapper(Object listener, boolean isOnce) { + this.listener = listener; + this.isOnce = isOnce; + } + } + + + private class Listeners { + private CopyOnWriteArrayList mListenerWrappers = new CopyOnWriteArrayList<>(); + + void add(Object listener, boolean once) { + ensureListenersNotAtLimit(); + mListenerWrappers.add(new ListenerWrapper(listener, once)); + } + + private void ensureListenersNotAtLimit() { + if (mMaxListeners != 0 && mListenersMap.size() >= mMaxListeners) { + throw new ScriptStopException(new TooManyListenersException("max = " + mMaxListeners)); + } + } + + boolean empty() { + return mListenerWrappers.isEmpty(); + } + + void emit(Object[] args) { + Iterator listenerIterator = mListenerWrappers.iterator(); + while (listenerIterator.hasNext()) { + ListenerWrapper listenerWrapper = listenerIterator.next(); + onEvent(listenerWrapper, args); + if (listenerWrapper.isOnce) { + listenerIterator.remove(); + } + } + } + + private void onEvent(ListenerWrapper listenerWrapper, Object[] args) { + if (mFunctionCaller != null) { + mFunctionCaller.call(listenerWrapper.listener, args); + } + } + + int count() { + return mListenerWrappers.size(); + } + + Object[] toArray() { + Iterator listenerIterator = mListenerWrappers.iterator(); + ArrayList listeners = new ArrayList<>(mListenerWrappers.size()); + while (listenerIterator.hasNext()) { + listeners.add(listenerIterator.next().listener); + } + return listeners.toArray(new Object[listeners.size()]); + } + + void prepend(Object listener, boolean once) { + ensureListenersNotAtLimit(); + mListenerWrappers.add(0, new ListenerWrapper(listener, once)); + } + + void remove(Object listener) { + Iterator listenerIterator = mListenerWrappers.iterator(); + while (listenerIterator.hasNext()) { + ListenerWrapper l = listenerIterator.next(); + if (l.listener == listener) { + listenerIterator.remove(); + break; + } + } + } + } + + private Map mListenersMap = new HashMap<>(); + private int mMaxListeners = defaultMaxListeners(); + private FunctionCaller mFunctionCaller; + + public EventEmitter once(String eventName, Object listener) { + getListeners(eventName).add(listener, true); + return this; + } + + @NonNull + private Listeners getListeners(String eventName) { + Listeners listeners = mListenersMap.get(eventName); + if (listeners == null) { + listeners = new Listeners(); + mListenersMap.put(eventName, listeners); + } + return listeners; + } + + + public EventEmitter on(String eventName, Object listener) { + getListeners(eventName).add(listener, false); + return this; + } + + public EventEmitter addListener(String eventName, Object listener) { + return on(eventName, listener); + } + + public boolean emit(String eventName, Object... args) { + Listeners listeners = mListenersMap.get(eventName); + if (listeners == null || listeners.empty()) + return false; + listeners.emit(args); + return true; + } + + public String[] eventNames() { + return mListenersMap.keySet().toArray(new String[mListenersMap.size()]); + } + + public int listenerCount(String eventName) { + Listeners listeners = mListenersMap.get(eventName); + if (listeners == null) + return 0; + return listeners.count(); + } + + public Object[] listeners(String eventName) { + return getListeners(eventName).toArray(); + } + + public EventEmitter prependListener(String eventName, Object listener) { + getListeners(eventName).prepend(listener, false); + return this; + } + + public EventEmitter prependOnceListener(String eventName, Object listener) { + getListeners(eventName).prepend(listener, true); + return this; + } + + public EventEmitter removeAllListeners() { + mListenersMap.clear(); + return this; + } + + public EventEmitter removeAllListeners(String eventName) { + mListenersMap.remove(eventName); + return this; + } + + public EventEmitter removeListener(String eventName, Object listener) { + Listeners listeners = mListenersMap.get(eventName); + if (listeners != null) + listeners.remove(listener); + return this; + } + + public EventEmitter setMaxListeners(int n) { + mMaxListeners = n; + return this; + } + + public int getMaxListeners() { + return mMaxListeners; + } + + public static int defaultMaxListeners() { + return 0; + } + + public void setFunctionCaller(FunctionCaller functionCaller) { + mFunctionCaller = functionCaller; + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java new file mode 100644 index 00000000..00efc853 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java @@ -0,0 +1,174 @@ +package com.stardust.autojs.runtime.api; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.text.method.KeyListener; +import android.view.KeyEvent; + +import com.stardust.autojs.runtime.AccessibilityBridge; +import com.stardust.autojs.runtime.ScriptStopException; +import com.stardust.autojs.runtime.record.inputevent.InputEventRecorder; +import com.stardust.autojs.runtime.record.inputevent.TouchObserver; +import com.stardust.view.accessibility.AccessibilityService; +import com.stardust.view.accessibility.OnKeyListener; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by Stardust on 2017/7/18. + */ + +public class Events extends EventEmitter implements OnKeyListener, TouchObserver.OnTouchEventListener { + + private static final String PREFIX_KEY_DOWN = "__key_down__#"; + private static final String PREFIX_KEY_UP = "__key_up__#"; + + private static ConcurrentHashMap sLoopers = new ConcurrentHashMap<>(); + private AccessibilityBridge mAccessibilityBridge; + private boolean mListeningKey = false; + private Handler mHandler; + private Context mContext; + private TouchObserver mTouchObserver; + private long mLastTouchEventMillis; + private long mTouchEventTimeout = 10; + + public Events(Context context, AccessibilityBridge accessibilityBridge) { + mAccessibilityBridge = accessibilityBridge; + mContext = context; + } + + public void observeKey() { + ensureListeningKey(); + } + + public void observeTouch() { + if (mTouchObserver != null) + return; + mTouchObserver = new TouchObserver(mContext); + mTouchObserver.setOnTouchEventListener(this); + mTouchObserver.observe(); + } + + private void ensureListeningKey() { + if (mListeningKey) { + return; + } + mListeningKey = true; + mAccessibilityBridge.ensureServiceEnabled(); + AccessibilityService service = mAccessibilityBridge.getService(); + if (service == null) + throw new ScriptStopException(); + service.getOnKeyObserver().addListener(this); + Looper.prepare(); + sLoopers.put(Thread.currentThread(), Looper.myLooper()); + mHandler = new Handler(); + } + + public void loop() { + Looper.loop(); + } + + public Events onKeyDown(String keyName, Object listener) { + on(PREFIX_KEY_DOWN + keyName, listener); + return this; + } + + public Events onceKeyDown(String keyName, Object listener) { + once(PREFIX_KEY_DOWN + keyName, listener); + return this; + } + + public Events removeAllKeyDownListeners(String keyName) { + removeAllListeners(PREFIX_KEY_DOWN + keyName); + return this; + } + + public Events onKeyUp(String keyName, Object listener) { + on(PREFIX_KEY_UP + keyName, listener); + return this; + } + + public Events onceKeyUp(String keyName, Object listener) { + once(PREFIX_KEY_UP + keyName, listener); + return this; + } + + public Events removeAllKeyUpListeners(String keyName) { + removeAllListeners(PREFIX_KEY_UP + keyName); + return this; + } + + public Events onTouch(Object listener) { + on("touch", listener); + return this; + } + + public Events removeAllTouchListeners() { + removeAllListeners("touch"); + return this; + } + + public long getTouchEventTimeout() { + return mTouchEventTimeout; + } + + public void setTouchEventTimeout(long touchEventTimeout) { + mTouchEventTimeout = touchEventTimeout; + } + + + public void recycle() { + if (mListeningKey) { + AccessibilityService service = mAccessibilityBridge.getService(); + if (service != null) { + service.getOnKeyObserver().removeListener(this); + mListeningKey = false; + } + } + if (mTouchObserver != null) { + mTouchObserver.stop(); + } + } + + @Override + public void onKeyEvent(final int keyCode, final KeyEvent event) { + mHandler.post(new Runnable() { + @Override + public void run() { + String keyName = KeyEvent.keyCodeToString(keyCode).substring(8).toLowerCase(); + emit(keyName, event); + if (event.getAction() == KeyEvent.ACTION_DOWN) { + emit(PREFIX_KEY_DOWN + keyName, event); + emit("key_down", keyCode, event); + } else if (event.getAction() == KeyEvent.ACTION_UP) { + emit(PREFIX_KEY_UP + keyName, event); + emit("key_up", keyCode, event); + } + emit("key", keyCode, event); + } + }); + } + + @Override + public void onTouch(int x, int y) { + if (System.currentTimeMillis() - mLastTouchEventMillis < mTouchEventTimeout) { + return; + } + mLastTouchEventMillis = System.currentTimeMillis(); + emit("touch", x, y); + } + + public static void removeThreadRecord(Thread thread) { + sLoopers.remove(thread); + } + + public static void quitLooperIfNeeded(Thread thread) { + Looper looper = sLoopers.get(thread); + if (looper != null) { + looper.quit(); + } + } + + +} 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 6bf3ea40..d09a1060 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 @@ -117,8 +117,7 @@ public class UiSelector extends UiGlobalSelector { @ScriptInterface @NonNull public UiObjectCollection untilFind() { - UiObjectCollection uiObjectCollection; - uiObjectCollection = find(); + UiObjectCollection uiObjectCollection = find(); while (uiObjectCollection.empty()) { if (Thread.currentThread().isInterrupted()) { throw new ScriptInterruptedException(); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/internal/Functions.java b/autojs/src/main/java/com/stardust/autojs/runtime/internal/Functions.java new file mode 100644 index 00000000..c677cb06 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/internal/Functions.java @@ -0,0 +1,50 @@ +package com.stardust.autojs.runtime.internal; + +/** + * Created by Stardust on 2017/7/19. + */ + +public class Functions { + + @SuppressWarnings("unchecked") + public static Object call(Func func, Object[] args) { + if (func instanceof Func0) { + return ((Func0) func).call(); + } else if (func instanceof Func1) { + return ((Func1) func).call(args[0]); + } else if (func instanceof Func2) { + return ((Func2) func).call(args[0], args[1]); + } else if (func instanceof Func3) { + return ((Func3) func).call(args[0], args[1], args[2]); + } else if (func instanceof Func4) { + return ((Func4) func).call(args[0], args[1], args[2], args[3]); + } + throw new IllegalArgumentException("Unknown func: " + func); + } + + public interface Func { + + } + + public interface Func0 extends Func { + R call(); + } + + public interface Func1 extends Func { + R call(T1 t1); + } + + public interface Func2 extends Func { + R call(T1 t1, T2 t2); + } + + public interface Func3 extends Func { + R call(T1 t1, T2 t2, T3 t3); + } + + public interface Func4 extends Func { + R call(T1 t1, T2 t2, T3 t3, T4 t4); + } + + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/Recorder.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/Recorder.java similarity index 98% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/Recorder.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/Recorder.java index fb0f7f44..12780d7c 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/Recorder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/Recorder.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record; +package com.stardust.autojs.runtime.record; import java.util.Arrays; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/accessibility/AccessibilityActionConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/accessibility/AccessibilityActionConverter.java similarity index 96% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/accessibility/AccessibilityActionConverter.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/accessibility/AccessibilityActionConverter.java index 8e00e5dd..23aef3d0 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/accessibility/AccessibilityActionConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/accessibility/AccessibilityActionConverter.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.accessibility; +package com.stardust.autojs.runtime.record.accessibility; import android.accessibilityservice.AccessibilityService; import android.os.Build; @@ -8,9 +8,9 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.stardust.automator.UiObject; import com.stardust.automator.simple_action.FilterAction; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; import com.stardust.util.SparseArrayEntries; import com.stardust.view.accessibility.AccessibilityNodeInfoHelper; +import com.stardust.view.accessibility.NodeInfo; import org.greenrobot.eventbus.EventBus; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/accessibility/AccessibilityActionRecorder.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/accessibility/AccessibilityActionRecorder.java similarity index 93% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/accessibility/AccessibilityActionRecorder.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/accessibility/AccessibilityActionRecorder.java index dc2a0ac2..5d2c6b1a 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/accessibility/AccessibilityActionRecorder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/accessibility/AccessibilityActionRecorder.java @@ -1,9 +1,9 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.accessibility; +package com.stardust.autojs.runtime.record.accessibility; import android.accessibilityservice.AccessibilityService; import android.view.accessibility.AccessibilityEvent; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.Recorder; +import com.stardust.autojs.runtime.record.Recorder; import com.stardust.view.accessibility.AccessibilityDelegate; import java.util.Arrays; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/EventFormatException.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/EventFormatException.java similarity index 87% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/EventFormatException.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/EventFormatException.java index c33c6c47..f12aa1d3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/EventFormatException.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/EventFormatException.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; /** * Created by Stardust on 2017/3/7. diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventConverter.java similarity index 83% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventConverter.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventConverter.java index 76212612..0facfcb7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventConverter.java @@ -1,14 +1,10 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; import android.support.annotation.NonNull; import android.text.TextUtils; import android.widget.Toast; -import com.flurry.android.FlurryAgent; -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.Recorder; -import com.stardust.util.MapEntries; +import com.stardust.autojs.runtime.record.Recorder; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -66,6 +62,9 @@ public abstract class InputEventConverter { } + private final static Pattern LAST_INT_PATTERN = Pattern.compile("[^0-9]+([0-9]+)$"); + + protected boolean mConverting = false; private int mState = Recorder.STATE_NOT_START; @@ -117,14 +116,21 @@ public abstract class InputEventConverter { } catch (EventFormatException e) { e.printStackTrace(); if (mFirstEventFormatError) { - Toast.makeText(App.getApp(), R.string.text_record_format_error, Toast.LENGTH_SHORT).show(); mFirstEventFormatError = false; - FlurryAgent.logEvent("EventFormatException", new MapEntries() - .entry("message", e.getMessage()) - .map()); } return null; } + } + public static int parseDeviceNumber(String device) { + Matcher matcher = LAST_INT_PATTERN.matcher(device); + if (matcher.find()) { + String someNumberStr = matcher.group(1); + return Integer.parseInt(someNumberStr); + } + return -1; + } + + } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventRecorder.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventRecorder.java similarity index 90% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventRecorder.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventRecorder.java index bf8acc79..8a0c823b 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventRecorder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventRecorder.java @@ -1,10 +1,9 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; import android.content.Context; import com.stardust.autojs.runtime.api.Shell; -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.external.floatingwindow.menu.record.Recorder; +import com.stardust.autojs.runtime.record.Recorder; /** * Created by Stardust on 2017/3/6. diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToJsConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToJsConverter.java similarity index 98% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToJsConverter.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToJsConverter.java index 98349601..0d836079 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToJsConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToJsConverter.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; import android.support.annotation.NonNull; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToSendEventConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToSendEventConverter.java similarity index 94% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToSendEventConverter.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToSendEventConverter.java index e2dc2539..aa7c9261 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToSendEventConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToSendEventConverter.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; import android.support.annotation.NonNull; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToSendEventJsConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToSendEventJsConverter.java similarity index 87% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToSendEventJsConverter.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToSendEventJsConverter.java index c9be24bc..d1263f6d 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/InputEventToSendEventJsConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToSendEventJsConverter.java @@ -1,6 +1,5 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; -import android.media.Image; import android.support.annotation.NonNull; import java.util.regex.Matcher; @@ -15,7 +14,6 @@ import static com.stardust.util.ScreenMetrics.getDeviceScreenWidth; public class InputEventToSendEventJsConverter extends InputEventConverter { - private final static Pattern LAST_INT_PATTERN = Pattern.compile("[^0-9]+([0-9]+)$"); private double mLastEventTime; private StringBuilder mCode = new StringBuilder(); private int mTouchDevice = -1; @@ -73,15 +71,6 @@ public class InputEventToSendEventJsConverter extends InputEventConverter { } - private int parseDeviceNumber(String device) { - Matcher matcher = LAST_INT_PATTERN.matcher(device); - if (matcher.find()) { - String someNumberStr = matcher.group(1); - return Integer.parseInt(someNumberStr); - } - return -1; - } - private void onTouchX(int device, int value) { if (mTouchDevice == -1) { setTouchDevice(device); diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/KeyObserver.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/KeyObserver.java similarity index 94% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/KeyObserver.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/KeyObserver.java index 5c8bc501..f8f8de1f 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/KeyObserver.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/KeyObserver.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; import android.content.Context; import android.support.annotation.NonNull; diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchObserver.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchObserver.java new file mode 100644 index 00000000..d7ed8bf7 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchObserver.java @@ -0,0 +1,102 @@ +package com.stardust.autojs.runtime.record.inputevent; + +import android.content.Context; +import android.support.annotation.NonNull; + +/** + * Created by Stardust on 2017/7/20. + */ + +public class TouchObserver { + + public interface OnTouchEventListener { + void onTouch(int x, int y); + } + + private int mTouchX, mTouchY; + private InputEventRecorder mRecorder; + private OnTouchEventListener mOnTouchEventListener; + + public TouchObserver(Context context) { + mRecorder = new InputEventRecorder(context, new TouchEventObserver()); + } + + public void observe() { + mRecorder.listen(); + mRecorder.start(); + } + + public void stop() { + mRecorder.stop(); + } + + public void setOnTouchEventListener(OnTouchEventListener onTouchEventListener) { + mOnTouchEventListener = onTouchEventListener; + } + + private void onTouch(int x, int y) { + mTouchX = x; + mTouchY = y; + if(mOnTouchEventListener != null){ + mOnTouchEventListener.onTouch(x, y); + } + } + + + + private class TouchEventObserver extends InputEventConverter { + + private int mLastTouchX, mLastTouchY; + + @Override + public void convertEvent(@NonNull Event event) { + int device = parseDeviceNumber(event.device); + int type = (int) Long.parseLong(event.type, 16); + int code = (int) Long.parseLong(event.code, 16); + int value = (int) Long.parseLong(event.value, 16); + if (type != 3) { + return; + } + if (code == 53) { + onTouchX(value); + return; + } + if (code == 54) { + onTouchY(value); + return; + } + if (mLastTouchX >= 0) { + onTouch(mLastTouchX, mTouchY); + mLastTouchX = -1; + return; + } + if (mLastTouchY >= 0) { + onTouch(mTouchX, mLastTouchY); + mLastTouchY = -1; + } + } + + private void onTouchX(int value) { + mLastTouchX = value; + } + + private void onTouchY(int value) { + if (mLastTouchX > 0) { + onTouch(mLastTouchX, value); + return; + } + mLastTouchY = value; + } + + @Override + public String getGetEventCommand() { + return "getevent -t"; + } + + @Override + public String getCode() { + return null; + } + } + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/TouchRecorder.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java similarity index 80% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/TouchRecorder.java rename to autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java index 74288e42..d63d3d5b 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/record/inputevent/TouchRecorder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.record.inputevent; +package com.stardust.autojs.runtime.record.inputevent; import android.content.Context; diff --git a/autojs/src/main/res/xml/accessibility_service_config.xml b/autojs/src/main/res/xml/accessibility_service_config.xml index 62a664d6..84c6464a 100644 --- a/autojs/src/main/res/xml/accessibility_service_config.xml +++ b/autojs/src/main/res/xml/accessibility_service_config.xml @@ -2,9 +2,10 @@ \ No newline at end of file diff --git a/automator/src/main/java/com/stardust/automator/simple_action/SearchTargetAction.java b/automator/src/main/java/com/stardust/automator/simple_action/SearchTargetAction.java index e1c41c89..22f7e453 100644 --- a/automator/src/main/java/com/stardust/automator/simple_action/SearchTargetAction.java +++ b/automator/src/main/java/com/stardust/automator/simple_action/SearchTargetAction.java @@ -1,5 +1,7 @@ package com.stardust.automator.simple_action; +import android.graphics.BitmapFactory; + import com.stardust.automator.UiObject; import java.util.List; diff --git a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java index 12cd0993..6f595397 100644 --- a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java +++ b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java @@ -1,19 +1,12 @@ package com.stardust.view.accessibility; -import android.accessibilityservice.AccessibilityServiceInfo; import android.content.Context; -import android.graphics.Rect; import android.os.Build; import android.os.Handler; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.util.Log; -import android.view.InputDevice; +import android.view.KeyEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; -import android.widget.FrameLayout; - -import com.stardust.util.ScreenMetrics; import java.util.HashSet; import java.util.Map; @@ -22,6 +15,9 @@ import java.util.SortedMap; import java.util.Timer; import java.util.TimerTask; import java.util.TreeMap; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -39,11 +35,14 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi private static final ReentrantLock LOCK = new ReentrantLock(); private static final Condition ENABLED = LOCK.newCondition(); private static AccessibilityService instance; + private static final OnKeyListener.Observer stickOnKeyObserver = new OnKeyListener.Observer(); private static boolean containsAllEventTypes = false; private static final Set eventTypes = new HashSet<>(); + private OnKeyListener.Observer mOnKeyObserver = new OnKeyListener.Observer(); private volatile AccessibilityNodeInfo mRootInActiveWindow; private Timer mTimer; private Handler mHandler; + private ExecutorService mKeyEventExecutor; public static void addDelegate(int uniquePriority, AccessibilityDelegate delegate) { mDelegates.put(uniquePriority, delegate); @@ -85,6 +84,25 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi } + @Override + protected boolean onKeyEvent(final KeyEvent event) { + if (mKeyEventExecutor == null) { + mKeyEventExecutor = Executors.newSingleThreadExecutor(); + } + mKeyEventExecutor.execute(new Runnable() { + @Override + public void run() { + stickOnKeyObserver.onKeyEvent(event.getKeyCode(), event); + mOnKeyObserver.onKeyEvent(event.getKeyCode(), event); + } + }); + return false; + } + + public OnKeyListener.Observer getOnKeyObserver() { + return mOnKeyObserver; + } + @Override public AccessibilityNodeInfo getRootInActiveWindow() { return mRootInActiveWindow; @@ -93,7 +111,10 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi @Override public void onDestroy() { instance = null; - mTimer.cancel(); + if (mTimer != null) + mTimer.cancel(); + if (mKeyEventExecutor != null) + mKeyEventExecutor.shutdownNow(); super.onDestroy(); } @@ -155,5 +176,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi } } - + public static OnKeyListener.Observer getStickOnKeyObserver() { + return stickOnKeyObserver; + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java b/automator/src/main/java/com/stardust/view/accessibility/LayoutInspector.java similarity index 96% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java rename to automator/src/main/java/com/stardust/view/accessibility/LayoutInspector.java index d81f4470..9cc30e1b 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java +++ b/automator/src/main/java/com/stardust/view/accessibility/LayoutInspector.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector; +package com.stardust.view.accessibility; import android.os.Build; import android.support.annotation.RequiresApi; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java b/automator/src/main/java/com/stardust/view/accessibility/NodeInfo.java similarity index 97% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java rename to automator/src/main/java/com/stardust/view/accessibility/NodeInfo.java index 7fd1b7c5..e961a2e3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java +++ b/automator/src/main/java/com/stardust/view/accessibility/NodeInfo.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector; +package com.stardust.view.accessibility; import android.graphics.Rect; import android.support.annotation.Keep; diff --git a/automator/src/main/java/com/stardust/view/accessibility/OnKeyListener.java b/automator/src/main/java/com/stardust/view/accessibility/OnKeyListener.java new file mode 100644 index 00000000..0453a6ef --- /dev/null +++ b/automator/src/main/java/com/stardust/view/accessibility/OnKeyListener.java @@ -0,0 +1,42 @@ +package com.stardust.view.accessibility; + +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; + +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Created by Stardust on 2017/7/18. + */ + +public interface OnKeyListener { + + void onKeyEvent(int keyCode, KeyEvent event); + + class Observer implements OnKeyListener { + + private static final String TAG = "OnKeyListenerObserver"; + + private CopyOnWriteArrayList mOnKeyListeners = new CopyOnWriteArrayList<>(); + + @Override + public void onKeyEvent(int keyCode, KeyEvent event) { + for (OnKeyListener listener : mOnKeyListeners) { + try { + listener.onKeyEvent(keyCode, event); + } catch (Exception e) { + Log.e(TAG, "Error OnKeyEvent: " + event + " Listener: " + listener, e); + } + } + } + + public void addListener(OnKeyListener listener) { + mOnKeyListeners.add(listener); + } + + public boolean removeListener(OnKeyListener listener) { + return mOnKeyListeners.remove(listener); + } + } +} diff --git a/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java b/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java index bbfd74c7..e79e5ffb 100644 --- a/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java +++ b/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java @@ -151,7 +151,7 @@ public class AutoJs implements AccessibilityBridge { @Nullable @Override - public android.accessibilityservice.AccessibilityService getService() { + public AccessibilityService getService() { return AccessibilityService.getInstance(); }