add events module, including EventEmiiter, KeyEvent, TouchEvent
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
### sleep(n)
|
### sleep(\[n\])
|
||||||
* n \<Number\> 毫秒数
|
* n \<Number\> 毫秒数
|
||||||
|
|
||||||
暂停运行n**毫秒**的时间。1秒等于1000毫秒。
|
暂停运行n**毫秒**的时间。1秒等于1000毫秒。
|
||||||
|
如果不加参数n,则会一直暂停,通常用于有事件监听的脚本中使用。
|
||||||
|
|
||||||
### launchPackage(packageName)
|
### launchPackage(packageName)
|
||||||
* packageName \<String\> 应用包名。参见《Shell命令:应用包名》章节。
|
* packageName \<String\> 应用包名。参见《Shell命令:应用包名》章节。
|
||||||
|
|||||||
20
app/src/main/assets/help/documentation/事件与按键监听.md
Normal file
20
app/src/main/assets/help/documentation/事件与按键监听.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# events
|
||||||
|
|
||||||
|
events也是一个\[EventEmitter\],这里只介绍其自身的函数。
|
||||||
|
|
||||||
|
### events.emitter()
|
||||||
|
|
||||||
|
返回一个新的EventEmitter。
|
||||||
|
|
||||||
|
### events.observeKey()
|
||||||
|
|
||||||
|
启用按键监听,例如音量键、Home键。
|
||||||
|
|
||||||
|
在安卓4.3以上才能使用。
|
||||||
|
|
||||||
|
### events.onKeyDown(keyName, listener)
|
||||||
|
|
||||||
|
* keyName \<String\> 要监听的按键名称
|
||||||
|
* listener \<Function\> 参数为一个\[KeyEvent\]
|
||||||
|
|
||||||
|
注册一个按键监听函数,。按键名称包括
|
||||||
@@ -62,7 +62,7 @@ function isImage(item){
|
|||||||
function notLiked(likeIcon){
|
function notLiked(likeIcon){
|
||||||
var x = likeIcon.bounds().centerX();
|
var x = likeIcon.bounds().centerX();
|
||||||
var y = likeIcon.bounds().centerY();
|
var y = likeIcon.bounds().centerY();
|
||||||
return images.detectsColor(capture, x, y, 0x767886);
|
return images.detectsColor(capture, 0x767886, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
toast("请打开QQ空间并慢慢下滑");
|
toast("请打开QQ空间并慢慢下滑");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.app.Application;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.multidex.MultiDexApplication;
|
import android.support.multidex.MultiDexApplication;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import com.squareup.leakcanary.LeakCanary;
|
import com.squareup.leakcanary.LeakCanary;
|
||||||
import com.stardust.app.SimpleActivityLifecycleCallbacks;
|
import com.stardust.app.SimpleActivityLifecycleCallbacks;
|
||||||
@@ -19,6 +20,8 @@ import com.stardust.theme.ThemeColor;
|
|||||||
import com.stardust.theme.ThemeColorManager;
|
import com.stardust.theme.ThemeColorManager;
|
||||||
import com.stardust.util.ScreenMetrics;
|
import com.stardust.util.ScreenMetrics;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
|
import com.stardust.view.accessibility.OnKeyListener;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
@@ -71,7 +74,7 @@ public class App extends MultiDexApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initVolumeChangeObserver() {
|
private void initVolumeChangeObserver() {
|
||||||
registerReceiver(mVolumeChangeObserver, new IntentFilter(VolumeChangeObserver.ACTION_VOLUME_CHANGE));
|
//registerReceiver(mVolumeChangeObserver, new IntentFilter(VolumeChangeObserver.ACTION_VOLUME_CHANGE));
|
||||||
mVolumeChangeObserver.addOnVolumeChangeListener(new VolumeChangeObserver.OnVolumeChangeListener() {
|
mVolumeChangeObserver.addOnVolumeChangeListener(new VolumeChangeObserver.OnVolumeChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onVolumeChange() {
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ import com.stardust.util.ScreenMetrics;
|
|||||||
import com.stardust.util.Supplier;
|
import com.stardust.util.Supplier;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.LayoutInspector;
|
import com.stardust.autojs.runtime.record.accessibility.AccessibilityActionRecorder;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.record.accessibility.AccessibilityActionRecorder;
|
|
||||||
import com.stardust.view.accessibility.AccessibilityService;
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
||||||
import com.stardust.scriptdroid.ui.console.JraskaConsole;
|
import com.stardust.scriptdroid.ui.console.JraskaConsole;
|
||||||
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
||||||
|
import com.stardust.view.accessibility.LayoutInspector;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +177,7 @@ public class AutoJs implements AccessibilityBridge {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public android.accessibilityservice.AccessibilityService getService() {
|
public AccessibilityService getService() {
|
||||||
return AccessibilityService.getInstance();
|
return AccessibilityService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import com.stardust.hover.SimpleHoverMenuTransitionListener;
|
|||||||
import com.stardust.hover.WindowHoverMenu;
|
import com.stardust.hover.WindowHoverMenu;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
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.FloatingLayoutBoundsView;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.view.FloatingLayoutHierarchyView;
|
import com.stardust.scriptdroid.external.floatingwindow.menu.view.FloatingLayoutHierarchyView;
|
||||||
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import com.stardust.scriptdroid.App;
|
|||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService;
|
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.tool.AccessibilityServiceTool;
|
||||||
import com.stardust.scriptdroid.ui.main.MainActivity_;
|
import com.stardust.scriptdroid.ui.main.MainActivity_;
|
||||||
import com.stardust.util.ClipboardUtil;
|
import com.stardust.util.ClipboardUtil;
|
||||||
import com.stardust.util.MessageEvent;
|
import com.stardust.util.MessageEvent;
|
||||||
import com.stardust.view.accessibility.AccessibilityService;
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
|
import com.stardust.view.accessibility.LayoutInspector;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
|
||||||
|
|||||||
@@ -10,16 +10,16 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.stardust.app.VolumeChangeObserver;
|
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.App;
|
||||||
import com.stardust.scriptdroid.Pref;
|
import com.stardust.scriptdroid.Pref;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.accessibility.AccessibilityEventHelper;
|
import com.stardust.scriptdroid.accessibility.AccessibilityEventHelper;
|
||||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService;
|
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.scriptdroid.ui.main.MainActivity;
|
||||||
import com.stardust.util.MessageEvent;
|
import com.stardust.util.MessageEvent;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import android.util.AttributeSet;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
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 com.stardust.util.ViewUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import android.widget.ListView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.stardust.scriptdroid.R;
|
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.util.ViewUtil;
|
||||||
import com.stardust.widget.LevelBeamView;
|
import com.stardust.widget.LevelBeamView;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.stardust.scriptdroid.R;
|
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.stardust.util.ClipboardUtil;
|
||||||
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||||
|
|
||||||
@@ -22,7 +22,6 @@ import java.util.Arrays;
|
|||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.OnLongClick;
|
|
||||||
import butterknife.Optional;
|
import butterknife.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view;
|
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.
|
* Created by Stardust on 2017/3/10.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
|||||||
import com.afollestad.materialdialogs.Theme;
|
import com.afollestad.materialdialogs.Theme;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService;
|
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.LayoutBoundsView;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView;
|
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.OnNodeInfoSelectListener;
|
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.OnNodeInfoSelectListener;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
|||||||
import com.afollestad.materialdialogs.Theme;
|
import com.afollestad.materialdialogs.Theme;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService;
|
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.LayoutHierarchyView;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView;
|
import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView;
|
||||||
import com.stardust.util.MessageIntent;
|
import com.stardust.util.MessageIntent;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.stardust.scriptdroid.ui.main.task;
|
package com.stardust.scriptdroid.ui.main.task;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.support.v7.widget.ThemeColorRecyclerView;
|
import android.support.v7.widget.ThemeColorRecyclerView;
|
||||||
@@ -11,6 +12,8 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.workground.WrapContentLinearLayoutManager;
|
import android.workground.WrapContentLinearLayoutManager;
|
||||||
|
|
||||||
|
import com.afollestad.materialdialogs.DialogAction;
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.stardust.autojs.ScriptEngineService;
|
import com.stardust.autojs.ScriptEngineService;
|
||||||
import com.stardust.autojs.execution.ScriptExecution;
|
import com.stardust.autojs.execution.ScriptExecution;
|
||||||
import com.stardust.autojs.execution.ScriptExecutionListener;
|
import com.stardust.autojs.execution.ScriptExecutionListener;
|
||||||
@@ -43,9 +46,19 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Abst
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
int position = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
int position = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
||||||
if(position >= 0){
|
if (position >= 0) {
|
||||||
mScriptEngines.get(position).forceStop();
|
final ScriptEngine engine = mScriptEngines.get(position);
|
||||||
}else {
|
engine.forceStop();
|
||||||
|
|
||||||
|
postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!engine.isDestroyed()) {
|
||||||
|
onScriptANR(engine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
updateEngineList();
|
updateEngineList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,6 +141,10 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Abst
|
|||||||
AutoJs.getInstance().getScriptEngineService().unregisterGlobalScriptExecutionListener(mScriptExecutionListener);
|
AutoJs.getInstance().getScriptEngineService().unregisterGlobalScriptExecutionListener(mScriptExecutionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onScriptANR(final ScriptEngine engine) {
|
||||||
|
// TODO: 2017/7/19 强制停止
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEngineCreate(final ScriptEngine engine) {
|
public void onEngineCreate(final ScriptEngine engine) {
|
||||||
synchronized (mScriptEngines) {
|
synchronized (mScriptEngines) {
|
||||||
|
|||||||
@@ -208,6 +208,8 @@
|
|||||||
<string name="text_accessibility_settings">打开无障碍服务</string>
|
<string name="text_accessibility_settings">打开无障碍服务</string>
|
||||||
<string name="text_discard_record">放弃录制</string>
|
<string name="text_discard_record">放弃录制</string>
|
||||||
<string name="text_inspect_failed">布局抓取失败,请关闭悬浮窗后动一下页面重试</string>
|
<string name="text_inspect_failed">布局抓取失败,请关闭悬浮窗后动一下页面重试</string>
|
||||||
|
<string name="script_anr">没有相应,要强制停止吗</string>
|
||||||
|
|
||||||
|
|
||||||
<string-array name="record_control_keys">
|
<string-array name="record_control_keys">
|
||||||
<item>无</item>
|
<item>无</item>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ require("__general__")(__runtime__, this);
|
|||||||
|
|
||||||
|
|
||||||
(function(scope){
|
(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;
|
var len = modules.length;
|
||||||
for(var i = 0; i < len; i++) {
|
for(var i = 0; i < len; i++) {
|
||||||
var m = modules[i];
|
var m = modules[i];
|
||||||
|
|||||||
24
autojs/src/main/assets/modules/__events__.js
Normal file
24
autojs/src/main/assets/modules/__events__.js
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -9,9 +9,7 @@ module.exports = function(__runtime__, scope){
|
|||||||
scope.log(text);
|
scope.log(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.sleep = function(millis){
|
scope.sleep = __runtime__.sleep.bind(__runtime__);
|
||||||
__runtime__.sleep(millis);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.isStopped = function(){
|
scope.isStopped = function(){
|
||||||
return __runtime__.isStopped();
|
return __runtime__.isStopped();
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.stardust.autojs.engine;
|
package com.stardust.autojs.engine;
|
||||||
|
|
||||||
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.stardust.autojs.rhino.AndroidContextFactory;
|
import com.stardust.autojs.rhino.AndroidContextFactory;
|
||||||
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
||||||
import com.stardust.autojs.runtime.ScriptInterruptedException;
|
import com.stardust.autojs.runtime.ScriptInterruptedException;
|
||||||
|
import com.stardust.autojs.runtime.api.Events;
|
||||||
import com.stardust.autojs.script.ScriptSource;
|
import com.stardust.autojs.script.ScriptSource;
|
||||||
import com.stardust.pio.UncheckedIOException;
|
import com.stardust.pio.UncheckedIOException;
|
||||||
|
|
||||||
@@ -41,6 +43,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
|
|||||||
private Thread mThread;
|
private Thread mThread;
|
||||||
private RhinoJavaScriptEngineManager mEngineManager;
|
private RhinoJavaScriptEngineManager mEngineManager;
|
||||||
private Map<String, Object> mTags = new ConcurrentHashMap<>();
|
private Map<String, Object> mTags = new ConcurrentHashMap<>();
|
||||||
|
private volatile boolean mDestroyed = false;
|
||||||
|
|
||||||
public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) {
|
public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) {
|
||||||
mEngineManager = engineManager;
|
mEngineManager = engineManager;
|
||||||
@@ -73,6 +76,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
|
|||||||
public void forceStop() {
|
public void forceStop() {
|
||||||
Log.d(LOG_TAG, "forceStop: interrupt Thread: " + mThread);
|
Log.d(LOG_TAG, "forceStop: interrupt Thread: " + mThread);
|
||||||
mThread.interrupt();
|
mThread.interrupt();
|
||||||
|
Events.quitLooperIfNeeded(mThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RhinoJavaScriptEngineManager getEngineManager() {
|
public RhinoJavaScriptEngineManager getEngineManager() {
|
||||||
@@ -86,6 +90,13 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
|
|||||||
contextCount--;
|
contextCount--;
|
||||||
Log.d(LOG_TAG, "contextCount = " + contextCount);
|
Log.d(LOG_TAG, "contextCount = " + contextCount);
|
||||||
mEngineManager.removeEngine(this);
|
mEngineManager.removeEngine(this);
|
||||||
|
Events.removeThreadRecord(mThread);
|
||||||
|
mDestroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
return mDestroyed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public interface ScriptEngine {
|
|||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
boolean isDestroyed();
|
||||||
|
|
||||||
void setTag(String key, Object value);
|
void setTag(String key, Object value);
|
||||||
|
|
||||||
Object getTag(String key);
|
Object getTag(String key);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.stardust.autojs.engine.ScriptEngine;
|
|||||||
import com.stardust.autojs.runtime.api.AbstractShell;
|
import com.stardust.autojs.runtime.api.AbstractShell;
|
||||||
import com.stardust.autojs.runtime.api.AppUtils;
|
import com.stardust.autojs.runtime.api.AppUtils;
|
||||||
import com.stardust.autojs.runtime.api.Console;
|
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.UiSelector;
|
||||||
import com.stardust.autojs.runtime.api.image.Images;
|
import com.stardust.autojs.runtime.api.image.Images;
|
||||||
import com.stardust.autojs.runtime.api.image.ScreenCaptureRequester;
|
import com.stardust.autojs.runtime.api.image.ScreenCaptureRequester;
|
||||||
@@ -41,10 +42,12 @@ public abstract class AbstractScriptRuntime {
|
|||||||
@ScriptVariable
|
@ScriptVariable
|
||||||
public UI ui;
|
public UI ui;
|
||||||
|
|
||||||
|
|
||||||
@ScriptVariable
|
@ScriptVariable
|
||||||
public Dialogs dialogs;
|
public Dialogs dialogs;
|
||||||
|
|
||||||
|
@ScriptVariable
|
||||||
|
public Events events;
|
||||||
|
|
||||||
private Images images;
|
private Images images;
|
||||||
|
|
||||||
private static WeakReference<Context> applicationContext;
|
private static WeakReference<Context> applicationContext;
|
||||||
@@ -54,11 +57,13 @@ public abstract class AbstractScriptRuntime {
|
|||||||
this.console = console;
|
this.console = console;
|
||||||
this.automator = new SimpleActionAutomator(bridge, this);
|
this.automator = new SimpleActionAutomator(bridge, this);
|
||||||
this.info = bridge.getInfoProvider();
|
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) {
|
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);
|
dialogs = new Dialogs(app, uiHandler);
|
||||||
|
events = new Events(context, bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setApplicationContext(Context context) {
|
public static void setApplicationContext(Context context) {
|
||||||
@@ -115,6 +120,7 @@ public abstract class AbstractScriptRuntime {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
images.releaseScreenCapturer();
|
images.releaseScreenCapturer();
|
||||||
}
|
}
|
||||||
|
events.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getImages() {
|
public Object getImages() {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.stardust.autojs.runtime;
|
package com.stardust.autojs.runtime;
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityService;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import com.stardust.automator.AccessibilityEventCommandHost;
|
import com.stardust.automator.AccessibilityEventCommandHost;
|
||||||
import com.stardust.automator.simple_action.SimpleActionPerformHost;
|
import com.stardust.automator.simple_action.SimpleActionPerformHost;
|
||||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/4/2.
|
* Created by Stardust on 2017/4/2.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.stardust.autojs.runtime;
|
package com.stardust.autojs.runtime;
|
||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import com.stardust.autojs.R;
|
import com.stardust.autojs.R;
|
||||||
@@ -85,7 +86,6 @@ public class ScriptRuntime extends AbstractScriptRuntime {
|
|||||||
|
|
||||||
private UiHandler mUiHandler;
|
private UiHandler mUiHandler;
|
||||||
private AccessibilityBridge mAccessibilityBridge;
|
private AccessibilityBridge mAccessibilityBridge;
|
||||||
|
|
||||||
private AbstractShell mRootShell;
|
private AbstractShell mRootShell;
|
||||||
private Supplier<AbstractShell> mShellSupplier;
|
private Supplier<AbstractShell> mShellSupplier;
|
||||||
private ScreenMetrics mScreenMetrics = new ScreenMetrics();
|
private ScreenMetrics mScreenMetrics = new ScreenMetrics();
|
||||||
|
|||||||
@@ -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<ListenerWrapper> 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<ListenerWrapper> 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<ListenerWrapper> listenerIterator = mListenerWrappers.iterator();
|
||||||
|
ArrayList<Object> 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<ListenerWrapper> listenerIterator = mListenerWrappers.iterator();
|
||||||
|
while (listenerIterator.hasNext()) {
|
||||||
|
ListenerWrapper l = listenerIterator.next();
|
||||||
|
if (l.listener == listener) {
|
||||||
|
listenerIterator.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Listeners> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
174
autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java
Normal file
174
autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java
Normal file
@@ -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<Thread, Looper> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -117,8 +117,7 @@ public class UiSelector extends UiGlobalSelector {
|
|||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
@NonNull
|
@NonNull
|
||||||
public UiObjectCollection untilFind() {
|
public UiObjectCollection untilFind() {
|
||||||
UiObjectCollection uiObjectCollection;
|
UiObjectCollection uiObjectCollection = find();
|
||||||
uiObjectCollection = find();
|
|
||||||
while (uiObjectCollection.empty()) {
|
while (uiObjectCollection.empty()) {
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
throw new ScriptInterruptedException();
|
throw new ScriptInterruptedException();
|
||||||
|
|||||||
@@ -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<R> extends Func {
|
||||||
|
R call();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Func1<T1, R> extends Func {
|
||||||
|
R call(T1 t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Func2<T1, T2, R> extends Func {
|
||||||
|
R call(T1 t1, T2 t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Func3<T1, T2, T3, R> extends Func {
|
||||||
|
R call(T1 t1, T2 t2, T3 t3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Func4<T1, T2, T3, T4, R> extends Func {
|
||||||
|
R call(T1 t1, T2 t2, T3 t3, T4 t4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.stardust.scriptdroid.external.floatingwindow.menu.record;
|
package com.stardust.autojs.runtime.record;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -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.accessibilityservice.AccessibilityService;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -8,9 +8,9 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
|||||||
|
|
||||||
import com.stardust.automator.UiObject;
|
import com.stardust.automator.UiObject;
|
||||||
import com.stardust.automator.simple_action.FilterAction;
|
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.util.SparseArrayEntries;
|
||||||
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
|
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
|
||||||
|
import com.stardust.view.accessibility.NodeInfo;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
@@ -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.accessibilityservice.AccessibilityService;
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
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 com.stardust.view.accessibility.AccessibilityDelegate;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -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.
|
* Created by Stardust on 2017/3/7.
|
||||||
@@ -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.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
import com.stardust.autojs.runtime.record.Recorder;
|
||||||
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 java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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;
|
protected boolean mConverting = false;
|
||||||
private int mState = Recorder.STATE_NOT_START;
|
private int mState = Recorder.STATE_NOT_START;
|
||||||
|
|
||||||
@@ -117,14 +116,21 @@ public abstract class InputEventConverter {
|
|||||||
} catch (EventFormatException e) {
|
} catch (EventFormatException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
if (mFirstEventFormatError) {
|
if (mFirstEventFormatError) {
|
||||||
Toast.makeText(App.getApp(), R.string.text_record_format_error, Toast.LENGTH_SHORT).show();
|
|
||||||
mFirstEventFormatError = false;
|
mFirstEventFormatError = false;
|
||||||
FlurryAgent.logEvent("EventFormatException", new MapEntries<String, String>()
|
|
||||||
.entry("message", e.getMessage())
|
|
||||||
.map());
|
|
||||||
}
|
}
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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 android.content.Context;
|
||||||
|
|
||||||
import com.stardust.autojs.runtime.api.Shell;
|
import com.stardust.autojs.runtime.api.Shell;
|
||||||
import com.stardust.scriptdroid.App;
|
import com.stardust.autojs.runtime.record.Recorder;
|
||||||
import com.stardust.scriptdroid.external.floatingwindow.menu.record.Recorder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/3/6.
|
* Created by Stardust on 2017/3/6.
|
||||||
@@ -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;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
@@ -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;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
@@ -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 android.support.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@@ -15,7 +14,6 @@ import static com.stardust.util.ScreenMetrics.getDeviceScreenWidth;
|
|||||||
|
|
||||||
public class InputEventToSendEventJsConverter extends InputEventConverter {
|
public class InputEventToSendEventJsConverter extends InputEventConverter {
|
||||||
|
|
||||||
private final static Pattern LAST_INT_PATTERN = Pattern.compile("[^0-9]+([0-9]+)$");
|
|
||||||
private double mLastEventTime;
|
private double mLastEventTime;
|
||||||
private StringBuilder mCode = new StringBuilder();
|
private StringBuilder mCode = new StringBuilder();
|
||||||
private int mTouchDevice = -1;
|
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) {
|
private void onTouchX(int device, int value) {
|
||||||
if (mTouchDevice == -1) {
|
if (mTouchDevice == -1) {
|
||||||
setTouchDevice(device);
|
setTouchDevice(device);
|
||||||
@@ -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.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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.content.Context;
|
||||||
|
|
||||||
@@ -2,9 +2,10 @@
|
|||||||
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:accessibilityEventTypes="typeAllMask"
|
android:accessibilityEventTypes="typeAllMask"
|
||||||
android:accessibilityFeedbackType="feedbackGeneric"
|
android:accessibilityFeedbackType="feedbackGeneric"
|
||||||
android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestEnhancedWebAccessibility"
|
android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestEnhancedWebAccessibility|flagRequestFilterKeyEvents"
|
||||||
android:canPerformGestures="true"
|
android:canPerformGestures="true"
|
||||||
android:canRequestEnhancedWebAccessibility="true"
|
android:canRequestEnhancedWebAccessibility="true"
|
||||||
|
android:canRequestFilterKeyEvents="true"
|
||||||
android:canRetrieveWindowContent="true"
|
android:canRetrieveWindowContent="true"
|
||||||
android:description="@string/text_accessibility_service_description"
|
android:description="@string/text_accessibility_service_description"
|
||||||
android:notificationTimeout="100"/>
|
android:notificationTimeout="100"/>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.stardust.automator.simple_action;
|
package com.stardust.automator.simple_action;
|
||||||
|
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
|
||||||
import com.stardust.automator.UiObject;
|
import com.stardust.automator.UiObject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
package com.stardust.view.accessibility;
|
package com.stardust.view.accessibility;
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.InputDevice;
|
import android.view.KeyEvent;
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
import com.stardust.util.ScreenMetrics;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -22,6 +15,9 @@ import java.util.SortedMap;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.TreeMap;
|
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.TimeUnit;
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
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 ReentrantLock LOCK = new ReentrantLock();
|
||||||
private static final Condition ENABLED = LOCK.newCondition();
|
private static final Condition ENABLED = LOCK.newCondition();
|
||||||
private static AccessibilityService instance;
|
private static AccessibilityService instance;
|
||||||
|
private static final OnKeyListener.Observer stickOnKeyObserver = new OnKeyListener.Observer();
|
||||||
private static boolean containsAllEventTypes = false;
|
private static boolean containsAllEventTypes = false;
|
||||||
private static final Set<Integer> eventTypes = new HashSet<>();
|
private static final Set<Integer> eventTypes = new HashSet<>();
|
||||||
|
private OnKeyListener.Observer mOnKeyObserver = new OnKeyListener.Observer();
|
||||||
private volatile AccessibilityNodeInfo mRootInActiveWindow;
|
private volatile AccessibilityNodeInfo mRootInActiveWindow;
|
||||||
private Timer mTimer;
|
private Timer mTimer;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
|
private ExecutorService mKeyEventExecutor;
|
||||||
|
|
||||||
public static void addDelegate(int uniquePriority, AccessibilityDelegate delegate) {
|
public static void addDelegate(int uniquePriority, AccessibilityDelegate delegate) {
|
||||||
mDelegates.put(uniquePriority, 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
|
@Override
|
||||||
public AccessibilityNodeInfo getRootInActiveWindow() {
|
public AccessibilityNodeInfo getRootInActiveWindow() {
|
||||||
return mRootInActiveWindow;
|
return mRootInActiveWindow;
|
||||||
@@ -93,7 +111,10 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
instance = null;
|
instance = null;
|
||||||
mTimer.cancel();
|
if (mTimer != null)
|
||||||
|
mTimer.cancel();
|
||||||
|
if (mKeyEventExecutor != null)
|
||||||
|
mKeyEventExecutor.shutdownNow();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,5 +176,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OnKeyListener.Observer getStickOnKeyObserver() {
|
||||||
|
return stickOnKeyObserver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector;
|
package com.stardust.view.accessibility;
|
||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector;
|
package com.stardust.view.accessibility;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.annotation.Keep;
|
import android.support.annotation.Keep;
|
||||||
@@ -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<OnKeyListener> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -151,7 +151,7 @@ public class AutoJs implements AccessibilityBridge {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public android.accessibilityservice.AccessibilityService getService() {
|
public AccessibilityService getService() {
|
||||||
return AccessibilityService.getInstance();
|
return AccessibilityService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user