From 528171b77d53a406cc0d48a7e376e50d478d3474 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Tue, 27 Feb 2018 17:03:09 +0800 Subject: [PATCH] api(events): events.setKeyInterceptionEnabled() --- .../stardust/autojs/engine/ScriptEngine.java | 1 - .../stardust/autojs/runtime/api/Events.java | 35 ++++++++++++++-- .../accessibility/AccessibilityService.java | 12 +++--- .../view/accessibility/KeyInterceptor.java | 41 +++++++++++++++++++ 4 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 automator/src/main/java/com/stardust/view/accessibility/KeyInterceptor.java 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 94498fc8..f40688d7 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java @@ -17,7 +17,6 @@ import java.util.concurrent.ConcurrentHashMap; * When the execution finish successfully, the engine should be destroy in the thread that created it. *

* If you want to stop the engine in other threads, you should call {@link ScriptEngine#forceStop()}. - * It will throw a {@link ScriptException}. */ public interface ScriptEngine { 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 index d864d0ef..cc931e30 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Events.java @@ -9,6 +9,8 @@ import android.os.Handler; import android.provider.Settings; import android.support.annotation.RequiresApi; import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; import com.stardust.autojs.R; import com.stardust.autojs.core.accessibility.AccessibilityBridge; @@ -24,6 +26,7 @@ import com.stardust.autojs.core.inputevent.InputEventObserver; import com.stardust.autojs.core.inputevent.TouchObserver; import com.stardust.view.accessibility.AccessibilityNotificationObserver; import com.stardust.view.accessibility.AccessibilityService; +import com.stardust.view.accessibility.KeyInterceptor; import com.stardust.view.accessibility.NotificationListener; import com.stardust.view.accessibility.OnKeyListener; @@ -47,6 +50,8 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver private boolean mListeningNotification = false; private boolean mListeningToast = false; private ScriptRuntime mScriptRuntime; + private volatile boolean mInterceptsKey = false; + private KeyInterceptor mKeyInterceptor; public Events(Context context, AccessibilityBridge accessibilityBridge, ScriptRuntime runtime) { super(runtime.bridges); @@ -72,10 +77,7 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver public void observeKey() { if (mListeningKey) return; - mScriptRuntime.ensureAccessibilityServiceEnabled(); - AccessibilityService service = mAccessibilityBridge.getService(); - if (service == null) - throw new ScriptException("AccessibilityService = null"); + AccessibilityService service = getAccessibilityService(); if ((service.getServiceInfo().flags & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) == 0) { throw new ScriptException(mContext.getString(R.string.text_should_enable_key_observing)); } @@ -102,6 +104,23 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver mTouchObserver.observe(); } + public void setKeyInterceptionEnabled(boolean enabled) { + mInterceptsKey = enabled; + if (mInterceptsKey && mKeyInterceptor == null) { + mKeyInterceptor = event -> mInterceptsKey; + getAccessibilityService().getKeyInterrupterObserver().addKeyInterrupter(mKeyInterceptor); + } + } + + private AccessibilityService getAccessibilityService() { + mScriptRuntime.ensureAccessibilityServiceEnabled(); + AccessibilityService service = mAccessibilityBridge.getService(); + if (service == null) + throw new ScriptException("AccessibilityService = null"); + return service; + } + + public Events onKeyDown(String keyName, Object listener) { on(PREFIX_KEY_DOWN + keyName, listener); return this; @@ -207,6 +226,13 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver NotificationListenerService.getInstance().removeListener(this); } } + if (mKeyInterceptor != null) { + AccessibilityService service = mAccessibilityBridge.getService(); + if (service != null) { + service.getKeyInterrupterObserver().removeKeyInterrupter(mKeyInterceptor); + } + mKeyInterceptor = null; + } } @Override @@ -243,4 +269,5 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver public void onToast(final AccessibilityNotificationObserver.Toast toast) { mHandler.post(() -> emit("toast", toast)); } + } 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 9f8ad283..f08ea18b 100644 --- a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java +++ b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java @@ -1,8 +1,6 @@ package com.stardust.view.accessibility; -import android.content.Context; import android.os.Build; -import android.os.Handler; import android.support.annotation.Nullable; import android.util.Log; import android.view.KeyEvent; @@ -13,10 +11,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; 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; @@ -40,6 +35,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi private static boolean containsAllEventTypes = false; private static final Set eventTypes = new HashSet<>(); private OnKeyListener.Observer mOnKeyObserver = new OnKeyListener.Observer(); + private KeyInterceptor.Observer mKeyInterrupterObserver = new KeyInterceptor.Observer(); private ExecutorService mKeyEventExecutor; private AccessibilityNodeInfo mFastRootInActiveWindow; @@ -97,7 +93,11 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi stickOnKeyObserver.onKeyEvent(event.getKeyCode(), event); mOnKeyObserver.onKeyEvent(event.getKeyCode(), event); }); - return false; + return mKeyInterrupterObserver.onInterceptKeyEvent(event); + } + + public KeyInterceptor.Observer getKeyInterrupterObserver() { + return mKeyInterrupterObserver; } public OnKeyListener.Observer getOnKeyObserver() { diff --git a/automator/src/main/java/com/stardust/view/accessibility/KeyInterceptor.java b/automator/src/main/java/com/stardust/view/accessibility/KeyInterceptor.java new file mode 100644 index 00000000..4bee0852 --- /dev/null +++ b/automator/src/main/java/com/stardust/view/accessibility/KeyInterceptor.java @@ -0,0 +1,41 @@ +package com.stardust.view.accessibility; + +import android.view.KeyEvent; + +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Created by Stardust on 2018/2/27. + */ + +public interface KeyInterceptor { + + boolean onInterceptKeyEvent(KeyEvent event); + + class Observer implements KeyInterceptor { + private CopyOnWriteArrayList mKeyInterceptors = new CopyOnWriteArrayList<>(); + + public void addKeyInterrupter(KeyInterceptor interrupter){ + mKeyInterceptors.add(interrupter); + } + + public boolean removeKeyInterrupter(KeyInterceptor interrupter){ + return mKeyInterceptors.remove(interrupter); + } + + + @Override + public boolean onInterceptKeyEvent(KeyEvent event) { + for(KeyInterceptor interrupter : mKeyInterceptors){ + try { + if(interrupter.onInterceptKeyEvent(event)){ + return true; + } + }catch (Exception e){ + e.printStackTrace(); + } + } + return false; + } + } +}