random click and gesture for android 7.0+!!!

This commit is contained in:
hyb1996
2017-05-16 21:40:23 +08:00
parent ec98d75d3b
commit c4ec951a10
42 changed files with 757 additions and 564 deletions

View File

@@ -13,17 +13,60 @@ module.exports = function(__runtime__, scope){
}
automator.click = function(){
if(arguments.length >= 2 && typeof(arguments[0]) == 'number' && typeof(arguments[1]) == 'number'){
return __runtime__.automator.click(arguments[0], arguments[1]);
}
return performAction(function(target){
return __runtime__.automator.click(target);
}, arguments);
}
automator.longClick = function(a, b, c, d){
if(arguments.length == 2 && typeof(arguments[0]) == 'number' && typeof(arguments[1]) == 'number'){
return __runtime__.automator.longClick(arguments[0], arguments[1]);
}
return performAction(function(target){
return __runtime__.automator.longClick(target);
}, arguments);
}
automator.press = __runtime__.automator.press.bind(__runtime__.automator);
automator.gesture = __runtime__.automator.gesture.bind(__runtime__.automator, 0);
automator.gestureAsync = __runtime__.automator.gestureAsync.bind(__runtime__.automator, 0);
automator.swipe = __runtime__.automator.swipe.bind(__runtime__.automator);
automator.gestures = function(){
return __runtime__.automator.gestures(toStrokes(arguments));
}
automator.gesturesAsync = function(){
__runtime__.automator.gesturesAsync(toStrokes(arguments));
}
function toStrokes(args){
var screenMetrics = __runtime__.getScreenMetrics();
var len = args.length;
var strokes = [];
for(var i = 0; i < len; i++){
var gesture = args[i];
var pointsIndex = 1;
if(typeof(gesture[1]) == 'number'){
var start = gesture[0];
var delay = gesture[1];
pointsIndex = 2;
}else{
var start = 0;
var delay = gesture[0];
}
var gestureLen = gesture.length;
var path = new android.graphics.Path();
path.moveTo(screenMetrics.scaleX(gesture[pointsIndex][0]), screenMetrics.scaleY(gesture[pointsIndex][1]));
for(var j = pointsIndex + 1; j < gestureLen; j++){
path.lineTo(screenMetrics.scaleX(gesture[j][0]), screenMetrics.scaleY(gesture[j][1]));
}
strokes.push(new android.accessibilityservice.GestureDescription.StrokeDescription(path, start, delay));
}
return strokes;
}
automator.scrollDown = function(a, b, c, d){
if(arguments.length == 0)
@@ -54,7 +97,7 @@ module.exports = function(__runtime__, scope){
}
scope.__asGlobal__(__runtime__.automator, ['back', 'home', 'powerDialog', 'notifications', 'quickSettings', 'recents', 'splitScreen']);
scope.__asGlobal__(automator, ['click', 'longClick', 'scrollDown', 'scrollUp', 'input']);
scope.__asGlobal__(automator, ['click', 'longClick', 'press', 'swipe', 'gesture', 'gestures', 'gestureAsync', 'gesturesAsync', 'scrollDown', 'scrollUp', 'input']);
return automator;
}

View File

@@ -42,4 +42,6 @@ module.exports = function(__runtime__, scope){
sleep(delay);
}
}
scope.setScreenMetrics = __runtime__.setScreenMetrics.bind(__runtime__);
}

View File

@@ -1,5 +1,5 @@
module.exports = function(__runtime__, scope){
var ui = Object(__runtime__.ui);
var ui = Object.create(__runtime__.ui);
ui.__id_cache__ = {};
ui.layout = function(xml){
@@ -39,7 +39,13 @@ module.exports = function(__runtime__, scope){
if(typeof(color) == 'string'){
color = android.graphics.Color.parseColor(color);
}
activity.getWindow().setStatusBarColor(color);
if(Build.VERSION.SDK_INT >= 21){
activity.getWindow().setStatusBarColor(color);
}
}
ui.finish = function(){
activity.finish();
}
function decorate(view){

View File

@@ -23,6 +23,11 @@ import com.stardust.util.UiHandler;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.PrintWriter;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -57,7 +62,7 @@ public class ScriptEngineService {
e.printStackTrace();
onFinish(execution);
if (!causedByInterrupted(e)) {
execution.getRuntime().console.error(e.getMessage());
execution.getRuntime().console.error(getScriptTrace(e));
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_EXCEPTION, e.getMessage()));
}
}
@@ -249,4 +254,25 @@ public class ScriptEngineService {
return mMessage;
}
}
private static String getScriptTrace(Exception e) {
try {
PipedReader reader = new PipedReader(8192);
PrintWriter writer = new PrintWriter(new PipedWriter(reader));
e.printStackTrace(writer);
writer.close();
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
StringBuilder scriptTrace = new StringBuilder(e.getMessage());
while ((line = bufferedReader.readLine()) != null) {
if (line.trim().startsWith("at script"))
scriptTrace.append("\n").append(line);
}
return scriptTrace.toString();
} catch (IOException e1) {
e1.printStackTrace();
return e.getMessage();
}
}
}

View File

@@ -12,6 +12,8 @@ import com.stardust.pio.UncheckedIOException;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.ErrorReporter;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
@@ -61,7 +63,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
Reader reader = source.getNonNullScriptReader();
try {
reader = preprocess(reader);
return mContext.evaluateReader(mScriptable, reader, "<script>", 1, null);
return mContext.evaluateReader(mScriptable, reader, "<" + source.getName() + ">", 1, null);
} catch (IOException e) {
throw new UncheckedIOException(e);
}

View File

@@ -9,6 +9,7 @@ import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.runtime.api.UiSelector;
import com.stardust.autojs.runtime.api.ui.UI;
import com.stardust.autojs.runtime.simple_action.SimpleActionAutomator;
import com.stardust.util.ScreenMetrics;
import com.stardust.view.accessibility.AccessibilityInfoProvider;
/**
@@ -73,6 +74,12 @@ public abstract class AbstractScriptRuntime {
@ScriptInterface
public abstract void stop();
@ScriptInterface
public abstract void setScreenMetrics(int width, int height);
@ScriptInterface
public abstract ScreenMetrics getScreenMetrics();
public abstract void ensureAccessibilityServiceEnabled();
public abstract void onStop();

View File

@@ -1,21 +1,22 @@
package com.stardust.autojs.runtime;
import android.content.Intent;
import android.os.Build;
import android.os.Looper;
import com.stardust.autojs.R;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.engine.preprocess.Preprocessor;
import com.stardust.autojs.rhino_android.AndroidClassLoader;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.AppUtils;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.runtime.api.UiSelector;
import com.stardust.autojs.runtime.api.internal.VolatileBox;
import com.stardust.concurrent.VolatileBox;
import com.stardust.autojs.runtime.api.ui.UI;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ClipboardUtil;
import com.stardust.autojs.runtime.api.ProcessShell;
import com.stardust.util.ScreenMetrics;
import com.stardust.util.SdkVersionUtil;
import com.stardust.util.Supplier;
import com.stardust.util.UiHandler;
@@ -88,6 +89,7 @@ public class ScriptRuntime extends AbstractScriptRuntime {
private AbstractShell mRootShell;
private Supplier<AbstractShell> mShellSupplier;
private ScreenMetrics mScreenMetrics = new ScreenMetrics();
protected ScriptRuntime(Builder builder) {
@@ -98,6 +100,7 @@ public class ScriptRuntime extends AbstractScriptRuntime {
if (ui == null) {
ui = new UI(mUiHandler.getContext());
}
automator.setScreenMetrics(mScreenMetrics);
}
public UiHandler getUiHandler() {
@@ -155,6 +158,7 @@ public class ScriptRuntime extends AbstractScriptRuntime {
throw new ScriptInterruptedException();
}
mRootShell = mShellSupplier.get();
mRootShell.SetScreenMetrics(mScreenMetrics);
mShellSupplier = null;
}
}
@@ -186,7 +190,19 @@ public class ScriptRuntime extends AbstractScriptRuntime {
}
public void stop() {
Thread.interrupted();
Thread.currentThread().interrupt();
throw new ScriptInterruptedException();
}
@Override
public void setScreenMetrics(int width, int height) {
mScreenMetrics.setScreenMetrics(width, height);
}
@Override
public ScreenMetrics getScreenMetrics() {
return mScreenMetrics;
}
public void ensureAccessibilityServiceEnabled() {

View File

@@ -4,8 +4,6 @@ import android.text.TextUtils;
import com.stardust.util.ScreenMetrics;
import java.util.Arrays;
/**
* Created by Stardust on 2017/4/24.
*/
@@ -35,7 +33,7 @@ public abstract class AbstractShell {
private int mTouchDevice;
private int mScreenHeight, mScreenWidth;
private ScreenMetrics mScreenMetrics;
private boolean mRoot;
@@ -71,10 +69,14 @@ public abstract class AbstractShell {
}
public void SetScreenMetrics(int width, int height) {
mScreenWidth = width;
mScreenHeight = height;
mScreenMetrics.setScreenMetrics(width, height);
}
public void SetScreenMetrics(ScreenMetrics screenMetrics) {
mScreenMetrics = screenMetrics;
}
public void Touch(int x, int y) {
TouchX(x);
TouchY(y);
@@ -85,13 +87,7 @@ public abstract class AbstractShell {
}
private int scaleX(int x) {
if (mScreenWidth == 0)
return x;
int screenWidth = ScreenMetrics.getScreenWidth();
if (screenWidth == mScreenWidth) {
return x;
}
return x * screenWidth / mScreenWidth;
return mScreenMetrics.scaleX(x);
}
public void TouchY(int y) {
@@ -99,13 +95,8 @@ public abstract class AbstractShell {
}
private int scaleY(int y) {
if (mScreenHeight == 0)
return y;
int screenHeight = ScreenMetrics.getScreenHeight();
if (screenHeight == mScreenHeight) {
return y;
}
return y * screenHeight / mScreenHeight;
return mScreenMetrics.scaleY(y);
}
public void Tap(int x, int y) {

View File

@@ -1,47 +0,0 @@
package com.stardust.autojs.runtime.api.internal;
import com.stardust.autojs.runtime.ScriptInterruptedException;
/**
* Created by Stardust on 2017/5/8.
*/
public class VolatileBox<T> {
private volatile T mValue;
public VolatileBox() {
}
public VolatileBox(T value) {
set(value);
}
public T get() {
return mValue;
}
public void set(T value) {
mValue = value;
}
public void setAndNotify(T value) {
mValue = value;
synchronized (this) {
notify();
}
}
public T blockedGet() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
throw new ScriptInterruptedException();
}
}
return mValue;
}
}

View File

@@ -10,7 +10,7 @@ import android.widget.Button;
* Created by Stardust on 2017/5/15.
*/
public class JsButton extends Button {
public class JsButton extends android.support.v7.widget.AppCompatButton {
public JsButton(Context context) {
super(context);
}
@@ -23,12 +23,11 @@ public class JsButton extends Button {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public JsButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public String text() {
return getText().toString();
}
public void text(CharSequence text) {
setText(text);
}
}

View File

@@ -24,4 +24,9 @@ public class JsEditText extends android.support.v7.widget.AppCompatEditText {
public String text() {
return getText().toString();
}
public void text(CharSequence text) {
setText(text);
}
}

View File

@@ -35,4 +35,8 @@ public class JsLinearLayout extends LinearLayout {
super(context, attrs, defStyleAttr, defStyleRes);
}
public View id(String id) {
return JsViewHelper.findViewByStringId(this, id);
}
}

View File

@@ -11,7 +11,7 @@ import android.widget.TextView;
* Created by Stardust on 2017/5/15.
*/
public class JsTextView extends TextView {
public class JsTextView extends android.support.v7.widget.AppCompatTextView {
public JsTextView(Context context) {
super(context);
}
@@ -24,12 +24,11 @@ public class JsTextView extends TextView {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public JsTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public String text() {
return getText().toString();
}
public void text(CharSequence text) {
setText(text);
}
}

View File

@@ -1,10 +1,15 @@
package com.stardust.autojs.runtime.simple_action;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -13,11 +18,13 @@ import com.stardust.autojs.runtime.AccessibilityBridge;
import com.stardust.autojs.runtime.ScriptInterface;
import com.stardust.autojs.runtime.api.AutomatorConfig;
import com.stardust.automator.AccessibilityEventCommandHost;
import com.stardust.automator.GlobalActionAutomator;
import com.stardust.automator.UiObject;
import com.stardust.automator.simple_action.SimpleAction;
import com.stardust.automator.simple_action.ActionFactory;
import com.stardust.automator.simple_action.ActionTarget;
import com.stardust.util.DeveloperUtils;
import com.stardust.util.ScreenMetrics;
/**
* Created by Stardust on 2017/4/2.
@@ -27,25 +34,9 @@ public class SimpleActionAutomator {
private static final String TAG = "SimpleActionAutomator";
@Deprecated
private static class PerformGlobalActionCommand extends AccessibilityEventCommandHost.AbstractCommand {
boolean result;
private int mGlobalAction;
PerformGlobalActionCommand(int globalAction) {
mGlobalAction = globalAction;
}
@Override
public void execute(AccessibilityService service, AccessibilityEvent event) {
result = service.performGlobalAction(mGlobalAction);
}
}
private AccessibilityBridge mAccessibilityBridge;
private AbstractScriptRuntime mScriptRuntime;
private GlobalActionAutomator mGlobalActionAutomator = new GlobalActionAutomator();
public SimpleActionAutomator(AccessibilityBridge accessibilityBridge, AbstractScriptRuntime scriptRuntime) {
mAccessibilityBridge = accessibilityBridge;
@@ -168,6 +159,65 @@ public class SimpleActionAutomator {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean gesture(long start, long duration, int[]... points) {
prepareForGesture();
return mGlobalActionAutomator.gesture(start, duration, points);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public void gestureAsync(long start, long duration, int[]... points) {
prepareForGesture();
mGlobalActionAutomator.gestureAsync(start, duration, points);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean gestures(GestureDescription.StrokeDescription... strokes) {
prepareForGesture();
return mGlobalActionAutomator.gestures(strokes);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public void gesturesAsync(GestureDescription.StrokeDescription... strokes) {
prepareForGesture();
mGlobalActionAutomator.gesturesAsync(strokes);
}
private void prepareForGesture() {
ensureAccessibilityServiceEnabled();
mGlobalActionAutomator.setService(mAccessibilityBridge.getService());
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean click(int x, int y) {
prepareForGesture();
return mGlobalActionAutomator.click(x, y);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean press(int x, int y, int delay) {
prepareForGesture();
return mGlobalActionAutomator.press(x, y, delay);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean longClick(int x, int y) {
prepareForGesture();
return mGlobalActionAutomator.longClick(x, y);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean swipe(int x1, int y1, int x2, int y2, int delay) {
prepareForGesture();
return mGlobalActionAutomator.swipe(x1, y1, x2, y2, delay);
}
private boolean performGlobalAction(final int action) {
ensureAccessibilityServiceEnabled();
AccessibilityService service = mAccessibilityBridge.getService();
@@ -205,4 +255,9 @@ public class SimpleActionAutomator {
private boolean isRunningPackageSelf() {
return DeveloperUtils.isSelfPackage(mAccessibilityBridge.getInfoProvider().getLatestPackage());
}
public void setScreenMetrics(ScreenMetrics metrics) {
mGlobalActionAutomator.setScreenMetrics(metrics);
}
}