使代码实现和文档描述一致

This commit is contained in:
hyb1996
2018-12-21 14:25:14 +08:00
parent d3ef346f62
commit 311307c489
10 changed files with 185 additions and 93 deletions

View File

@@ -42,7 +42,7 @@ module.exports = function (runtime, global) {
} }
if (i.type) { if (i.type) {
if (i.data) { if (i.data) {
intent.setDataAndType(android.net.Uri.parse(i.data), i.type); intent.setDataAndType(app.parseUri(i.data), i.type);
} else { } else {
intent.setType(i.type); intent.setType(i.type);
} }

View File

@@ -138,11 +138,15 @@ module.exports = function(runtime, global){
} }
auto.setFlags = function(flags){ auto.setFlags = function(flags){
if(typeof(flags) !== "string"){ let flagStrings;
throw new TypeError("flags should be a string"); if(Array.isArray(flags)){
flagStrings = flags;
} else if(typeof(flags) == "string"){
flagStrings = [flags];
} else {
throw new TypeError("flags = " + flags);
} }
let flagsInt = 0; let flagsInt = 0;
let flagStrings = flags.split("|");
for(let i = 0; i < flagStrings.length; i++){ for(let i = 0; i < flagStrings.length; i++){
let flag = flagsMap[flagStrings[i]]; let flag = flagsMap[flagStrings[i]];
if(flag == undefined){ if(flag == undefined){
@@ -153,22 +157,36 @@ module.exports = function(runtime, global){
runtime.accessibilityBridge.setFlags(flagsInt); runtime.accessibilityBridge.setFlags(flagsInt);
} }
auto.getService = function(){ auto.__defineGetter__("service", function() {
return runtime.accessibilityBridge.getService(); return runtime.accessibilityBridge.getService();
} });
auto.getWindows = function(){ auto.__defineGetter__("windows", function() {
var service = auto.getService(); var service = auto.getService();
return service == null ? [] : util.java.toJsArray(service.getWindows(), true); return service == null ? [] : util.java.toJsArray(service.getWindows(), true);
} });
auto.getRoot = function(){ auto.__defineGetter__("root", function() {
var root = runtime.accessibilityBridge.getRootInCurrentWindow(); var root = runtime.accessibilityBridge.getRootInCurrentWindow();
if(root == null){ if(root == null){
return null; return null;
} }
return com.stardust.automator.UiObject.Companion.createRoot(root); return com.stardust.automator.UiObject.Companion.createRoot(root);
});
auto.__defineGetter__("rootInActiveWindow", function() {
var root = runtime.accessibilityBridge.getRootInActiveWindow();
if(root == null){
return null;
} }
return com.stardust.automator.UiObject.Companion.createRoot(root);
});
auto.__defineGetter__("windowRoots", function() {
return util.java.toJsArray(runtime.accessibilityBridge.windowRoots(), false)
.map(root => com.stardust.automator.UiObject.Companion.createRoot(root));
});
auto.setWindowFilter = function(filter){ auto.setWindowFilter = function(filter){
runtime.accessibilityBridge.setWindowFilter(new com.stardust.autojs.core.accessibility.AccessibilityBridge.WindowFilter(filter)); runtime.accessibilityBridge.setWindowFilter(new com.stardust.autojs.core.accessibility.AccessibilityBridge.WindowFilter(filter));

View File

@@ -188,29 +188,32 @@ module.exports = function (runtime, scope) {
images.inRange = function (img, lowerBound, upperBound) { images.inRange = function (img, lowerBound, upperBound) {
initIfNeeded(); initIfNeeded();
var lb, ub; var lb = new Scalar(colors.red(lowerBound), colors.green(lowerBound),
if (typeof (lowerBound) == 'string') {
if (typeof (upperBound) == 'string') {
lb = new Scalar(colors.red(lowerBound), colors.green(lowerBound),
colors.blue(lowerBound), colors.alpha(lowerBound)); colors.blue(lowerBound), colors.alpha(lowerBound));
ub = new Scalar(colors.red(upperBound), colors.green(upperBound), var ub = new Scalar(colors.red(upperBound), colors.green(upperBound),
colors.blue(upperBound), colors.alpha(lowerBound)); colors.blue(upperBound), colors.alpha(lowerBound))
} else if (typeof (upperBound) == 'number') { if (typeof (upperBound) == 'number') {
var color = lowerBound; var color = lowerBound;
var threshold = upperBound; var threshold = upperBound;
lb = new Scalar(colors.red(color) - threshold, colors.green(color) - threshold,
colors.blue(color) - threshold, colors.alpha(color));
ub = new Scalar(colors.red(color) + threshold, colors.green(color) + threshold,
colors.blue(color) + threshold, colors.alpha(color));
} else { } else {
throw new TypeError('lowerBound = ' + lowerBound, + 'upperBound = ' + upperBound); throw new TypeError('lowerBound = ' + lowerBound, + 'upperBound = ' + upperBound);
} }
}
var bi = new Mat(); var bi = new Mat();
Core.inRange(img.mat, lb, ub, bi); Core.inRange(img.mat, lb, ub, bi);
return images.matToImage(bi); return images.matToImage(bi);
} }
images.interval = function (img, color, threshold) {
initIfNeeded();
var lb = new Scalar(colors.red(color) - threshold, colors.green(color) - threshold,
colors.blue(color) - threshold, colors.alpha(color));
var ub = new Scalar(colors.red(color) + threshold, colors.green(color) + threshold,
colors.blue(color) + threshold, colors.alpha(color));
var bi = new Mat();
Core.inRange(img.mat, lb, ub, bi);
return images.matToImage(bi);
}
images.adaptiveThreshold = function (img, maxValue, adaptiveMethod, thresholdType, blockSize, C) { images.adaptiveThreshold = function (img, maxValue, adaptiveMethod, thresholdType, blockSize, C) {
initIfNeeded(); initIfNeeded();
@@ -225,7 +228,7 @@ module.exports = function (runtime, scope) {
initIfNeeded(); initIfNeeded();
var mat = new Mat(); var mat = new Mat();
size = newSize(size); size = newSize(size);
type = Imgproc["BORDER_" + (type || "CONSTANT")]; type = Imgproc["BORDER_" + (type || "DEFAULT")];
if (point == undefined) { if (point == undefined) {
Imgproc.blur(img.mat, mat, size); Imgproc.blur(img.mat, mat, size);
} else { } else {
@@ -322,12 +325,10 @@ module.exports = function (runtime, scope) {
return javaImages.rotate(img, x, y, degree); return javaImages.rotate(img, x, y, degree);
} }
images.concat = function (img1, img2, direction, rect1, rect2) { images.concat = function (img1, img2, direction) {
initIfNeeded(); initIfNeeded();
direction = direction || "right"; direction = direction || "right";
rect1 = buildRegion(rect1, img1); return javaImages.concat(img1, img2, android.view.Gravity[direction.toUpperCase()]);
rect2 = buildRegion(rect2, img1);
return javaImages.concat(img1, rect1, img2, rect2, android.view.Gravity[direction.toUpperCase()]);
} }
images.detectsColor = function (img, color, x, y, threshold, algorithm) { images.detectsColor = function (img, color, x, y, threshold, algorithm) {

View File

@@ -19,6 +19,10 @@ import com.stardust.autojs.core.activity.ActivityInfoProvider;
import com.stardust.view.accessibility.AccessibilityNotificationObserver; import com.stardust.view.accessibility.AccessibilityNotificationObserver;
import com.stardust.view.accessibility.AccessibilityService; import com.stardust.view.accessibility.AccessibilityService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/** /**
* Created by Stardust on 2017/4/2. * Created by Stardust on 2017/4/2.
@@ -62,26 +66,51 @@ public abstract class AccessibilityBridge {
@Nullable @Nullable
public abstract AccessibilityService getService(); public abstract AccessibilityService getService();
public List<AccessibilityNodeInfo> windowRoots() {
AccessibilityService service = getService();
if (service == null)
return Collections.emptyList();
ArrayList<AccessibilityNodeInfo> roots = new ArrayList<>();
if (mWindowFilter != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
for (AccessibilityWindowInfo window : service.getWindows()) {
if (mWindowFilter.filter(window)) {
AccessibilityNodeInfo root = window.getRoot();
if (root != null) {
roots.add(root);
}
}
}
return roots;
}
if ((mMode & MODE_FAST) != 0) {
return Collections.singletonList(service.fastRootInActiveWindow());
}
return Collections.singletonList(service.getRootInActiveWindow());
}
@Nullable @Nullable
public AccessibilityNodeInfo getRootInCurrentWindow() { public AccessibilityNodeInfo getRootInCurrentWindow() {
AccessibilityService service = getService(); AccessibilityService service = getService();
if (service == null) if (service == null)
return null; return null;
if (mWindowFilter != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (mWindowFilter != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AccessibilityWindowInfo activeWindow = null;
for (AccessibilityWindowInfo window : service.getWindows()) { for (AccessibilityWindowInfo window : service.getWindows()) {
if (mWindowFilter.filter(window)) { if (mWindowFilter.filter(window)) {
return window.getRoot(); return window.getRoot();
} }
if (window.isActive()) {
activeWindow = window;
} }
return null;
} }
if (activeWindow != null) { if ((mMode & MODE_FAST) != 0) {
return activeWindow.getRoot(); return service.fastRootInActiveWindow();
} }
return service.getRootInActiveWindow();
} }
public AccessibilityNodeInfo getRootInActiveWindow() {
AccessibilityService service = getService();
if (service == null)
return null;
if ((mMode & MODE_FAST) != 0) { if ((mMode & MODE_FAST) != 0) {
return service.fastRootInActiveWindow(); return service.fastRootInActiveWindow();
} }

View File

@@ -5,7 +5,9 @@ import android.accessibilityservice.GestureDescription;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import android.util.Log; import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
@@ -20,6 +22,8 @@ import com.stardust.automator.simple_action.SimpleAction;
import com.stardust.util.DeveloperUtils; import com.stardust.util.DeveloperUtils;
import com.stardust.util.ScreenMetrics; import com.stardust.util.ScreenMetrics;
import java.util.List;
/** /**
* Created by Stardust on 2017/4/2. * Created by Stardust on 2017/4/2.
*/ */
@@ -253,11 +257,15 @@ public class SimpleActionAutomator {
Log.d(TAG, "performAction: running package is self. return false"); Log.d(TAG, "performAction: running package is self. return false");
return false; return false;
} }
AccessibilityNodeInfo root = mAccessibilityBridge.getRootInCurrentWindow(); List<AccessibilityNodeInfo> roots = mAccessibilityBridge.windowRoots();
if (root == null) if (roots.isEmpty())
return false; return false;
Log.v(TAG, "performAction: " + simpleAction + " root = " + root); Log.v(TAG, "performAction: " + simpleAction + " windowRoots = " + roots);
return simpleAction.perform(UiObject.Companion.createRoot(root)); boolean succeed = true;
for (AccessibilityNodeInfo root : roots) {
succeed &= simpleAction.perform(UiObject.Companion.createRoot(root));
}
return succeed;
} }
private boolean isRunningPackageSelf() { private boolean isRunningPackageSelf() {

View File

@@ -21,6 +21,9 @@ import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE;
@@ -94,17 +97,24 @@ public class UiSelector extends UiGlobalSelector {
@NonNull @NonNull
@ScriptInterface @ScriptInterface
protected UiObjectCollection findImpl(int max) { protected UiObjectCollection findImpl(int max) {
AccessibilityNodeInfo root = mAccessibilityBridge.getRootInCurrentWindow(); List<AccessibilityNodeInfo> roots = mAccessibilityBridge.windowRoots();
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
Log.d(TAG, "find: root = " + root); Log.d(TAG, "find: roots = " + roots);
if (root == null) { if (roots.isEmpty()) {
return UiObjectCollection.Companion.getEMPTY(); return UiObjectCollection.Companion.getEMPTY();
} }
List<UiObject> result = new ArrayList<>();
for (AccessibilityNodeInfo root : roots) {
if (root.getPackageName() != null && mAccessibilityBridge.getConfig().whiteListContains(root.getPackageName().toString())) { if (root.getPackageName() != null && mAccessibilityBridge.getConfig().whiteListContains(root.getPackageName().toString())) {
Log.d(TAG, "package in white list, return null"); Log.d(TAG, "package in white list, return null");
return UiObjectCollection.Companion.getEMPTY(); return UiObjectCollection.Companion.getEMPTY();
} }
return findOf(UiObject.Companion.createRoot(root, mAllocator), max); result.addAll(findAndReturnList(UiObject.Companion.createRoot(root, mAllocator), max - result.size()));
if (result.size() >= max) {
break;
}
}
return UiObjectCollection.Companion.of(result);
} }
@Override @Override

View File

@@ -7,8 +7,10 @@ import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.SystemClock
import android.util.Log import android.util.Log
import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityWindowInfo
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import com.stardust.app.isOpPermissionGranted import com.stardust.app.isOpPermissionGranted
import com.stardust.autojs.core.util.Shell import com.stardust.autojs.core.util.Shell
@@ -76,7 +78,13 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
override fun onAccessibilityEvent(service: AccessibilityService, event: AccessibilityEvent): Boolean { override fun onAccessibilityEvent(service: AccessibilityService, event: AccessibilityEvent): Boolean {
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window = service.getWindow(event.windowId)
if (window?.isFocused != false) {
setLatestComponent(event.packageName, event.className) setLatestComponent(event.packageName, event.className)
return false
}
}
} }
return false return false
} }
@@ -146,19 +154,24 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
} }
private fun setLatestComponent(latestPackage: CharSequence?, latestClass: CharSequence?) { private fun setLatestComponent(latestPackage: CharSequence?, latestClass: CharSequence?) {
if (latestPackage == null || latestClass == null) if (latestPackage == null)
return return
val latestPackageStr = latestPackage.toString() val latestPackageStr = latestPackage.toString()
val latestClassStr = latestClass.toString() val latestClassStr = (latestClass ?: "").toString()
if (latestClassStr.startsWith("android.view.") || latestClassStr.startsWith("android.widget.")) if (isPackageExists(latestPackageStr)) {
return
try {
val componentName = ComponentName(latestPackageStr, latestClassStr)
mLatestActivity = mPackageManager.getActivityInfo(componentName, PackageManager.MATCH_DEFAULT_ONLY).name
} catch (ignored: PackageManager.NameNotFoundException) {
return
}
mLatestPackage = latestPackage.toString() mLatestPackage = latestPackage.toString()
mLatestActivity = latestClassStr
}
Log.d(LOG_TAG, "setLatestComponent: $latestPackage/$latestClassStr $mLatestPackage/$mLatestActivity")
}
private fun isPackageExists(packageName: String): Boolean {
return try {
mPackageManager.getPackageInfo(packageName, 0)
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
} }
companion object { companion object {
@@ -179,3 +192,13 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
private const val LOG_TAG = "ActivityInfoProvider" private const val LOG_TAG = "ActivityInfoProvider"
} }
} }
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun AccessibilityService.getWindow(windowId: Int): AccessibilityWindowInfo? {
windows.forEach {
if (it.id == windowId) {
return it
}
}
return null
}

View File

@@ -34,6 +34,7 @@ import com.stardust.util.ScreenMetrics;
import org.opencv.core.Point; import org.opencv.core.Point;
import org.opencv.core.Rect; import org.opencv.core.Rect;
import org.opencv.imgproc.Imgproc;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -145,7 +146,7 @@ public class Images {
return image.pixel(x, y); return image.pixel(x, y);
} }
public static ImageWrapper concat(ImageWrapper img1, Rect rect1, ImageWrapper img2, Rect rect2, int direction) { public static ImageWrapper concat(ImageWrapper img1, ImageWrapper img2, int direction) {
if (!Arrays.asList(Gravity.LEFT, Gravity.RIGHT, Gravity.TOP, Gravity.BOTTOM).contains(direction)) { if (!Arrays.asList(Gravity.LEFT, Gravity.RIGHT, Gravity.TOP, Gravity.BOTTOM).contains(direction)) {
throw new IllegalArgumentException("unknown direction " + direction); throw new IllegalArgumentException("unknown direction " + direction);
} }
@@ -157,21 +158,21 @@ public class Images {
img2 = tmp; img2 = tmp;
} }
if (direction == Gravity.LEFT || direction == Gravity.RIGHT) { if (direction == Gravity.LEFT || direction == Gravity.RIGHT) {
width = rect1.width + rect2.width; width = img1.getWidth() + img2.getWidth();
height = Math.max(rect1.height, rect2.height); height = Math.max(img1.getHeight(), img2.getHeight());
} else { } else {
width = Math.max(rect1.width, rect2.height); width = Math.max(img1.getWidth(), img2.getHeight());
height = rect1.height + rect2.height; height = img1.getHeight() + img2.getHeight();
} }
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(); Paint paint = new Paint();
if (direction == Gravity.LEFT || direction == Gravity.RIGHT) { if (direction == Gravity.LEFT || direction == Gravity.RIGHT) {
canvas.drawBitmap(img1.getBitmap(), 0, (height - rect1.height) / 2, paint); canvas.drawBitmap(img1.getBitmap(), 0, (height - img1.getHeight()) / 2, paint);
canvas.drawBitmap(img2.getBitmap(), rect1.width, (height - rect2.height) / 2, paint); canvas.drawBitmap(img2.getBitmap(), img1.getWidth(), (height - img2.getHeight()) / 2, paint);
} else { } else {
canvas.drawBitmap(img1.getBitmap(), (width - rect1.width) / 2, 0, paint); canvas.drawBitmap(img1.getBitmap(), (width - img1.getWidth()) / 2, 0, paint);
canvas.drawBitmap(img2.getBitmap(), (width - rect2.width) / 2, rect1.height, paint); canvas.drawBitmap(img2.getBitmap(), (width - img2.getWidth()) / 2, img1.getHeight(), paint);
} }
return ImageWrapper.ofBitmap(bitmap); return ImageWrapper.ofBitmap(bitmap);
} }

View File

@@ -41,7 +41,7 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
override fun onAccessibilityEvent(event: AccessibilityEvent) { override fun onAccessibilityEvent(event: AccessibilityEvent) {
instance = this instance = this
//Log.v(TAG, "onAccessibilityEvent: " + event); // Log.v(TAG, "onAccessibilityEvent: $event");
if (!containsAllEventTypes && !eventTypes.contains(event.eventType)) if (!containsAllEventTypes && !eventTypes.contains(event.eventType))
return return
val type = event.eventType val type = event.eventType

View File

@@ -14,18 +14,20 @@ object Pref {
private const val KEY_FIRST_USING = "key_first_using" private const val KEY_FIRST_USING = "key_first_using"
private var sPreferences: SharedPreferences? = null private var sPreferences: SharedPreferences? = null
val preferences: SharedPreferences? val preferences: SharedPreferences
get() { get() {
if (sPreferences == null) return sPreferences ?: {
sPreferences = PreferenceManager.getDefaultSharedPreferences(GlobalAppContext.get()) val pref = PreferenceManager.getDefaultSharedPreferences(GlobalAppContext.get())
return sPreferences sPreferences = pref
pref
}()
} }
val isFirstUsing: Boolean val isFirstUsing: Boolean
get() { get() {
val firstUsing = preferences!!.getBoolean(KEY_FIRST_USING, true) val firstUsing = preferences.getBoolean(KEY_FIRST_USING, true)
if (firstUsing) { if (firstUsing) {
preferences!!.edit().putBoolean(KEY_FIRST_USING, false).apply() preferences.edit().putBoolean(KEY_FIRST_USING, false).apply()
} }
return firstUsing return firstUsing
} }
@@ -35,14 +37,14 @@ object Pref {
} }
fun shouldEnableAccessibilityServiceByRoot(): Boolean { fun shouldEnableAccessibilityServiceByRoot(): Boolean {
return preferences!!.getBoolean(getString(R.string.key_enable_accessibility_service_by_root), false) return preferences.getBoolean(getString(R.string.key_enable_accessibility_service_by_root), false)
} }
fun shouldHideLogs(): Boolean { fun shouldHideLogs(): Boolean {
return preferences!!.getBoolean(getString(R.string.key_dont_show_main_activity), false) return preferences.getBoolean(getString(R.string.key_dont_show_main_activity), false)
} }
fun shouldStopAllScriptsWhenVolumeUp(): Boolean { fun shouldStopAllScriptsWhenVolumeUp(): Boolean {
return preferences!!.getBoolean(getString(R.string.key_use_volume_control_running), true) return preferences.getBoolean(getString(R.string.key_use_volume_control_running), true)
} }
} }