新增 手势监听功能(效果不佳不启用)

This commit is contained in:
hyb1996
2018-12-01 17:46:57 +08:00
parent 708cde848c
commit 4bf237a499
23 changed files with 168 additions and 115 deletions

View File

@@ -277,7 +277,7 @@
</activity>
<service
android:name=".accessibility.AccessibilityService"
android:name="com.stardust.autojs.core.accessibility.AccessibilityService"
android:label="@string/_app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>

View File

@@ -1,27 +0,0 @@
package org.autojs.autojs.accessibility;
import android.accessibilityservice.AccessibilityServiceInfo;
import org.autojs.autojs.Pref;
/**
* Created by Stardust on 2017/8/14.
*/
public class AccessibilityService extends com.stardust.view.accessibility.AccessibilityService {
@Override
protected void onServiceConnected() {
AccessibilityServiceInfo serviceInfo = getServiceInfo();
if (Pref.isStableModeEnabled()) {
serviceInfo.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
} else {
serviceInfo.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
}
setServiceInfo(serviceInfo);
super.onServiceConnected();
}
}

View File

@@ -162,7 +162,7 @@ public class AutoJs extends com.stardust.autojs.AutoJs {
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting();
if (!org.autojs.autojs.accessibility.AccessibilityService.Companion.waitForEnabled(-1)) {
if (!AccessibilityService.Companion.waitForEnabled(-1)) {
throw new ScriptInterruptedException();
}
}

View File

@@ -57,7 +57,6 @@ public class ApkBuilder {
String packageName;
ArrayList<File> ignoredDirs = new ArrayList<>();
Callable<Bitmap> icon;
ProjectConfig projectConfig;
public static AppConfig fromProjectConfig(String projectDir, ProjectConfig projectConfig) {
String icon = projectConfig.getIcon();
@@ -68,7 +67,6 @@ public class ApkBuilder {
.setVersionCode(projectConfig.getVersionCode())
.setVersionName(projectConfig.getVersionName())
.setSourcePath(projectDir);
appConfig.projectConfig = projectConfig;
if (icon != null) {
appConfig.setIcon(new File(projectDir, icon).getPath());
}
@@ -243,16 +241,25 @@ public class ApkBuilder {
return new File(mWorkspacePath, "AndroidManifest.xml");
}
private void updateProjectConfig(AppConfig config) {
if (!PFiles.isDir(config.sourcePath)) {
return;
private void updateProjectConfig(AppConfig appConfig) {
ProjectConfig config;
if (!PFiles.isDir(appConfig.sourcePath)) {
config = new ProjectConfig()
.setMainScriptFile("main.js")
.setName(appConfig.appName)
.setPackageName(appConfig.packageName)
.setVersionName(appConfig.versionName)
.setVersionCode(appConfig.versionCode);
config.setBuildInfo(BuildInfo.generate(appConfig.versionCode));
PFiles.write(new File(mWorkspacePath, "assets/project/project.json").getPath(), config.toJson());
} else {
config = ProjectConfig.fromProjectDir(appConfig.sourcePath);
long buildNumber = config.getBuildInfo().getBuildNumber();
config.setBuildInfo(BuildInfo.generate(buildNumber + 1));
PFiles.write(ProjectConfig.configFileOfDir(appConfig.sourcePath), config.toJson());
}
ProjectConfig projectConfig = ProjectConfig.fromProjectDir(config.sourcePath);
long buildNumber = projectConfig.getBuildInfo().getBuildNumber();
projectConfig.setBuildInfo(BuildInfo.generate(buildNumber + 1));
mKey = MD5.md5(mAppConfig.projectConfig.getPackageName() + mAppConfig.projectConfig.getVersionName() + mAppConfig.projectConfig.getMainScriptFile());
mInitVector = MD5.md5(mAppConfig.projectConfig.getBuildInfo().getBuildId() + mAppConfig.projectConfig.getName()).substring(0, 16);
PFiles.write(ProjectConfig.configFileOfDir(config.sourcePath), projectConfig.toJson());
mKey = MD5.md5(config.getPackageName() + config.getVersionName() + config.getMainScriptFile());
mInitVector = MD5.md5(config.getBuildInfo().getBuildId() + config.getName()).substring(0, 16);
}
public ApkBuilder build() throws IOException {

View File

@@ -9,11 +9,11 @@ import android.util.Log;
import android.widget.Toast;
import com.stardust.app.GlobalAppContext;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.LayoutInspector;
import com.stardust.view.accessibility.NodeInfo;
import org.autojs.autojs.R;
import org.autojs.autojs.accessibility.AccessibilityService;
import org.autojs.autojs.autojs.AutoJs;
import org.autojs.autojs.tool.AccessibilityServiceTool;
import org.autojs.autojs.ui.floating.FloatyWindowManger;

View File

@@ -8,8 +8,9 @@ import com.stardust.app.GlobalAppContext;
import org.autojs.autojs.Pref;
import org.autojs.autojs.App;
import org.autojs.autojs.R;
import com.stardust.autojs.core.accessibility.AccessibilityService;
import com.stardust.autojs.core.util.ProcessShell;
import org.autojs.autojs.accessibility.AccessibilityService;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import java.util.Locale;

View File

@@ -17,7 +17,6 @@ import com.stardust.enhancedfloaty.FloatyWindow;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
import org.autojs.autojs.accessibility.AccessibilityService;
import org.autojs.autojs.autojs.AutoJs;
import org.autojs.autojs.autojs.record.GlobalActionRecorder;
import org.autojs.autojs.model.explorer.ExplorerDirPage;
@@ -34,6 +33,7 @@ import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.ClipboardUtil;
import com.stardust.util.Func1;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.LayoutInspector;
import com.stardust.view.accessibility.NodeInfo;

View File

@@ -431,6 +431,8 @@
<string name="text_run_on_startup">Auto.js启动时</string>
<string name="text_usage_stats_permission">查看使用统计权限</string>
<string name="description_usage_stats_permission">通过\"查看使用统计\"权限可以获取本设备过去使用应用的情况,从而使获取当前应用(currentPackage)时更准确。</string>
<string name="text_gesture_observing">手势监听</string>
<string name="summary_gesture_observing">开启后将支持events手势事件但Auto.js崩溃时可能会导致屏幕失灵</string>
<plurals name="air_error_short_description" key="air_error_short_description">
<item quantity="one">描述至少要 %d 个字.</item>
<item quantity="other">描述至少要 %d 个字.</item>

View File

@@ -58,15 +58,6 @@ module = (typeof module === 'undefined') ? {} : module;
Module._load = function _load(file, parent, core, main) {
return NativeRequire.require(file);
var module = new Module(file, parent, core);
var body = readFile(module.filename, module.core);
var dir = new File(module.filename).getParent();
var func = new Function('exports', 'module', 'require', '__filename', '__dirname', body);
func.apply(module,
[module.exports, module, module.require, module.filename, dir]);
module.loaded = true;
module.main = main;
return module.exports;
};
Module.runMain = function runMain(main) {

View File

@@ -0,0 +1,28 @@
package com.stardust.autojs.core.accessibility
import android.accessibilityservice.AccessibilityServiceInfo
import android.os.Build
import com.stardust.autojs.core.pref.Pref
import com.stardust.view.accessibility.AccessibilityService
class AccessibilityService : AccessibilityService() {
override fun onServiceConnected() {
val serviceInfo = serviceInfo
if (Pref.isStableModeEnabled) {
serviceInfo.flags = serviceInfo.flags and AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS.inv()
} else {
serviceInfo.flags = serviceInfo.flags or AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (Pref.isGestureObservingEnabled) {
serviceInfo.flags = serviceInfo.flags or AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
} else {
serviceInfo.flags = serviceInfo.flags and AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE.inv()
}
}
setServiceInfo(serviceInfo)
super.onServiceConnected()
}
}

View File

@@ -0,0 +1,18 @@
package com.stardust.autojs.core.pref
import android.preference.PreferenceManager
import com.stardust.app.GlobalAppContext
object Pref {
private val preferences = PreferenceManager.getDefaultSharedPreferences(GlobalAppContext.get())
val isStableModeEnabled: Boolean
get() {
return preferences.getBoolean("key_stable_mode", false)
}
val isGestureObservingEnabled: Boolean
get() {
return preferences.getBoolean("key_gesture_observing", false)
}
}

View File

@@ -126,7 +126,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
Collections.singletonList(new File("/").toURI()));
new RequireBuilder()
.setModuleScriptProvider(new SoftCachingModuleScriptProvider(provider))
.setSandboxed(false)
.setSandboxed(true)
.createRequire(context, scope)
.install(scope);

View File

@@ -7,7 +7,9 @@ import android.graphics.Point;
import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
import androidx.annotation.RequiresApi;
import android.view.KeyEvent;
import com.stardust.autojs.R;
@@ -23,6 +25,7 @@ import com.stardust.notification.NotificationListenerService;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.autojs.core.inputevent.InputEventObserver;
import com.stardust.autojs.core.inputevent.TouchObserver;
import com.stardust.util.MapBuilder;
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.KeyInterceptor;
@@ -30,16 +33,35 @@ import com.stardust.view.accessibility.NotificationListener;
import com.stardust.view.accessibility.OnKeyListener;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by Stardust on 2017/7/18.
*/
public class Events extends EventEmitter implements OnKeyListener, TouchObserver.OnTouchEventListener, NotificationListener, AccessibilityNotificationObserver.ToastListener {
public class Events extends EventEmitter implements OnKeyListener, TouchObserver.OnTouchEventListener, NotificationListener, AccessibilityNotificationObserver.ToastListener, AccessibilityService.GestureListener {
private static final String PREFIX_KEY_DOWN = "__key_down__#";
private static final String PREFIX_KEY_UP = "__key_up__#";
private static final Map<Integer, String> GESTURES = new MapBuilder<Integer, String>()
.put(AccessibilityService.GESTURE_SWIPE_UP, "up")
.put(AccessibilityService.GESTURE_SWIPE_DOWN, "down")
.put(AccessibilityService.GESTURE_SWIPE_LEFT, "left")
.put(AccessibilityService.GESTURE_SWIPE_RIGHT, "right")
.put(AccessibilityService.GESTURE_SWIPE_LEFT_AND_RIGHT, "left_right")
.put(AccessibilityService.GESTURE_SWIPE_RIGHT_AND_LEFT, "right_left")
.put(AccessibilityService.GESTURE_SWIPE_UP_AND_DOWN, "up_down")
.put(AccessibilityService.GESTURE_SWIPE_DOWN_AND_UP, "down_up")
.put(AccessibilityService.GESTURE_SWIPE_LEFT_AND_UP, "left_up")
.put(AccessibilityService.GESTURE_SWIPE_LEFT_AND_DOWN, "left_down")
.put(AccessibilityService.GESTURE_SWIPE_RIGHT_AND_UP, "right_up")
.put(AccessibilityService.GESTURE_SWIPE_RIGHT_AND_DOWN, "right_down")
.put(AccessibilityService.GESTURE_SWIPE_UP_AND_LEFT, "up_left")
.put(AccessibilityService.GESTURE_SWIPE_UP_AND_RIGHT, "up_right")
.put(AccessibilityService.GESTURE_SWIPE_DOWN_AND_LEFT, "down_left")
.put(AccessibilityService.GESTURE_SWIPE_DOWN_AND_RIGHT, "down_right")
.build();
private AccessibilityBridge mAccessibilityBridge;
private Context mContext;
@@ -50,6 +72,7 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
private Loopers mLoopers;
private Handler mHandler;
private boolean mListeningNotification = false;
private boolean mListeningGesture = false;
private boolean mListeningToast = false;
private ScriptRuntime mScriptRuntime;
private volatile boolean mInterceptsAllKey = false;
@@ -222,6 +245,21 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
mAccessibilityBridge.getNotificationObserver().addToastListener(this);
}
public void observeGesture() {
ScriptRuntime.requiresApi(Build.VERSION_CODES.O);
if (mListeningGesture) {
return;
}
AccessibilityService service = getAccessibilityService();
if ((service.getServiceInfo().flags & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) == 0) {
throw new ScriptException(mContext.getString(R.string.text_should_enable_gesture_observing));
}
service.getGestureEventDispatcher().addListener(this);
ensureHandler();
mLoopers.waitWhenIdle(true);
mListeningGesture = true;
}
public Events onNotification(Object listener) {
on("notification", listener);
return this;
@@ -260,6 +298,12 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
}
mKeyInterceptor = null;
}
if (mListeningGesture) {
AccessibilityService service = mAccessibilityBridge.getService();
if (service != null) {
service.getGestureEventDispatcher().removeListener(this);
}
}
}
@Override
@@ -297,4 +341,13 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
mHandler.post(() -> emit("toast", toast));
}
@Override
public void onGesture(int gestureId) {
mHandler.post(() -> {
String gesture = GESTURES.get(gestureId);
if (gesture != null) {
emit("gesture", gesture);
}
});
}
}

View File

@@ -15,6 +15,7 @@
<string name="text_accessibility_service_description">使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。</string>
<string name="_app_name">AutoJs</string>
<string name="text_should_enable_key_observing">按键监听未启用,请在软件设置中开启</string>
<string name="text_should_enable_gesture_observing">手势监听未启用,请在软件设置中开启</string>
<string name="no_write_settings_permissin">沒有修改系統设置权限</string>
<string name="exception_notification_service_disabled">通知服务未运行,请重新启用通知权限</string>
<string name="text_requires_app_version_to_run_the_script" formatted="true">本脚本需要Auto.js版本号%d以上才能运行</string>

View File

@@ -6,6 +6,7 @@
android:canPerformGestures="true"
android:canRequestEnhancedWebAccessibility="true"
android:canRequestFilterKeyEvents="true"
android:canRequestTouchExplorationMode="true"
android:canRetrieveWindowContent="true"
android:description="@string/text_accessibility_service_description"
android:notificationTimeout="0"/>

View File

@@ -22,9 +22,11 @@ class BoundsFilter(private val mBounds: Rect, private val mType: Int) : DfsFilte
}
override fun toString(): String {
return String.format(Locale.getDefault(), "bounds%s(%d, %d, %d, %d)", if (mType == TYPE_EQUALS)
""
else if (mType == TYPE_INSIDE) "Inside" else "Contains",
return String.format(Locale.getDefault(), "bounds%s(%d, %d, %d, %d)", when (mType) {
TYPE_EQUALS -> ""
TYPE_INSIDE -> "Inside"
else -> "Contains"
},
mBounds.left, mBounds.top, mBounds.right, mBounds.bottom)
}

View File

@@ -10,7 +10,7 @@ object IdFilter {
private val ID_GETTER = object : KeyGetter {
override fun getKey(nodeInfo: UiObject): String {
override fun getKey(nodeInfo: UiObject): String? {
return nodeInfo.viewIdResourceName
}

View File

@@ -5,25 +5,39 @@ import android.util.Log
import android.view.KeyEvent
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import com.stardust.event.EventDispatcher
import java.util.HashSet
import java.util.SortedMap
import java.util.TreeMap
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
/**
* Created by Stardust on 2017/5/2.
*/
open class AccessibilityService : android.accessibilityservice.AccessibilityService() {
interface GestureListener {
fun onGesture(gestureId: Int)
}
val onKeyObserver = OnKeyListener.Observer()
val keyInterrupterObserver = KeyInterceptor.Observer()
private var mKeyEventExecutor: ExecutorService? = null
val gestureEventDispatcher = EventDispatcher<GestureListener>()
private var mEventExecutor: ExecutorService? = null
private var mFastRootInActiveWindow: AccessibilityNodeInfo? = null
private val eventExecutor: ExecutorService
get() {
return mEventExecutor ?: {
val executor = Executors.newSingleThreadExecutor()
mEventExecutor = executor
executor
}()
}
override fun onAccessibilityEvent(event: AccessibilityEvent) {
instance = this
@@ -55,29 +69,34 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
}
override fun onKeyEvent(event: KeyEvent): Boolean {
if (mKeyEventExecutor == null) {
mKeyEventExecutor = Executors.newSingleThreadExecutor()
}
mKeyEventExecutor!!.execute {
eventExecutor.execute {
stickOnKeyObserver.onKeyEvent(event.keyCode, event)
onKeyObserver.onKeyEvent(event.keyCode, event)
}
return keyInterrupterObserver.onInterceptKeyEvent(event)
}
override fun onGesture(gestureId: Int): Boolean {
eventExecutor.execute {
gestureEventDispatcher.dispatchEvent {
onGesture(gestureId)
}
}
return false
}
override fun getRootInActiveWindow(): AccessibilityNodeInfo? {
try {
return super.getRootInActiveWindow()
return try {
super.getRootInActiveWindow()
} catch (e: Exception) {
return null
null
}
}
override fun onDestroy() {
instance = null
if (mKeyEventExecutor != null)
mKeyEventExecutor!!.shutdownNow()
mEventExecutor?.shutdownNow()
super.onDestroy()
}

View File

@@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":441,"versionName":"4.0.4 Alpha12","enabled":true,"outputFile":"commonRelease-4.0.4 Alpha12.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.4 Alpha12.apk","properties":{}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":450,"versionName":"4.0.5 Alpha","enabled":true,"outputFile":"commonRelease-4.0.5 Alpha.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.5 Alpha.apk","properties":{}}]

View File

@@ -45,19 +45,6 @@
<activity android:name=".SettingsActivity"/>
<service
android:name=".autojs.AccessibilityService"
android:label="inrt"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config"/>
</service>
<service
android:name="com.stardust.notification.NotificationListenerService"
android:label="inrt"

View File

@@ -2,7 +2,7 @@
"assets": [],
"build": {
"build_id": "B883A485-9",
"build_number": 9,
"build_number": 1,
"build_time": 1543638246643
},
"main": "main.js",

View File

@@ -20,10 +20,6 @@ public class Pref {
return sPreferences;
}
public static boolean isStableModeEnabled() {
return getPreferences().getBoolean(getString(R.string.key_stable_mode), false);
}
private static String getString(int res) {
return GlobalAppContext.getString(res);
}

View File

@@ -1,26 +0,0 @@
package com.stardust.auojs.inrt.autojs;
import android.accessibilityservice.AccessibilityServiceInfo;
import com.stardust.auojs.inrt.Pref;
/**
* Created by Stardust on 2017/12/8.
*/
public class AccessibilityService extends com.stardust.view.accessibility.AccessibilityService {
@Override
protected void onServiceConnected() {
AccessibilityServiceInfo serviceInfo = getServiceInfo();
if (Pref.isStableModeEnabled()) {
serviceInfo.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
} else {
serviceInfo.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
}
setServiceInfo(serviceInfo);
super.onServiceConnected();
}
}