add: root record generates js file
fix: delay of tap, swipe by adding RootAutomator
This commit is contained in:
@@ -55,6 +55,8 @@ public interface Recorder {
|
||||
|
||||
String getCode();
|
||||
|
||||
String getPath();
|
||||
|
||||
int getState();
|
||||
|
||||
void setOnStateChangedListener(OnStateChangedListener onStateChangedListener);
|
||||
@@ -171,5 +173,9 @@ public interface Recorder {
|
||||
mOnStateChangedListener = onStateChangedListener == null ? NO_OPERATION_LISTENER : onStateChangedListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,11 @@ public class InputEventToAutoFileRecorder extends InputEventRecorder {
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return mTmpFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public class InputEventToRootAutomatorRecorder extends InputEventRecorder {
|
||||
private int mLastTouchY = -1;
|
||||
|
||||
public InputEventToRootAutomatorRecorder() {
|
||||
mCode.append("var ra = new RootAutomator();\n")
|
||||
mCode.append("var ra = new RootAutomator(context);\n")
|
||||
.append("ra.setScreenMetrics(").append(getDeviceScreenWidth()).append(", ")
|
||||
.append(getDeviceScreenHeight()).append(");\n");
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public class InputEventToRootAutomatorRecorder extends InputEventRecorder {
|
||||
if (mLastEventTime == 0) {
|
||||
mLastEventTime = event.time;
|
||||
} else if (event.time - mLastEventTime > 0.001) {
|
||||
mCode.append("ra.sleep(").append((long) (1000L * (event.time - mLastEventTime))).append(");\n");
|
||||
mCode.append("sleep(").append((long) (1000L * (event.time - mLastEventTime))).append(");\n");
|
||||
mLastEventTime = event.time;
|
||||
}
|
||||
int device = parseDeviceNumber(event.device);
|
||||
@@ -96,7 +96,7 @@ public class InputEventToRootAutomatorRecorder extends InputEventRecorder {
|
||||
}
|
||||
|
||||
private void setTouchDevice(int i) {
|
||||
mCode.append("ra.setInputDevice(").append(i).append(");\n");
|
||||
//mCode.append("ra.setInputDevice(").append(i).append(");\n");
|
||||
mTouchDevice = i;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class InputEventToRootAutomatorRecorder extends InputEventRecorder {
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
mCode.append("log(ra.writeToDevice(context));");
|
||||
mCode.append("ra.exit();");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.stardust.autojs.core.record.Recorder;
|
||||
|
||||
public class TouchRecorder extends Recorder.AbstractRecorder {
|
||||
|
||||
private static TouchRecorder sInstance;
|
||||
private InputEventRecorder mInputEventRecorder;
|
||||
private Context mContext;
|
||||
private InputEventObserver mInputEventObserver;
|
||||
@@ -27,19 +26,17 @@ public class TouchRecorder extends Recorder.AbstractRecorder {
|
||||
mInputEventObserver.observe();
|
||||
}
|
||||
|
||||
public static TouchRecorder getGlobal(Context context) {
|
||||
if (sInstance == null)
|
||||
sInstance = new TouchRecorder(context);
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startImpl() {
|
||||
mInputEventRecorder = new InputEventToAutoFileRecorder(mContext);
|
||||
mInputEventRecorder = createInputEventRecorder();
|
||||
mInputEventObserver.addListener(mInputEventRecorder);
|
||||
mInputEventRecorder.start();
|
||||
}
|
||||
|
||||
protected InputEventRecorder createInputEventRecorder() {
|
||||
return new InputEventToAutoFileRecorder(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void pauseImpl() {
|
||||
super.pauseImpl();
|
||||
@@ -64,6 +61,11 @@ public class TouchRecorder extends Recorder.AbstractRecorder {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return mInputEventRecorder.getPath();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
setState(STATE_NOT_START);
|
||||
}
|
||||
|
||||
@@ -33,18 +33,8 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
||||
|
||||
public RootAutomatorEngine(Context context, String deviceNameOrPath) {
|
||||
mContext = context;
|
||||
if (sTouchDevice < 0) {
|
||||
sTouchDevice = PreferenceManager.getDefaultSharedPreferences(context).getInt(KEY_TOUCH_DEVICE, -1);
|
||||
}
|
||||
if (sTouchDevice >= 0) {
|
||||
mDeviceNameOrPath = "/dev/input/event" + sTouchDevice;
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.edit()
|
||||
.putInt(KEY_TOUCH_DEVICE, sTouchDevice)
|
||||
.apply();
|
||||
} else {
|
||||
mDeviceNameOrPath = deviceNameOrPath;
|
||||
}
|
||||
mDeviceNameOrPath = getDeviceNameOrPath(context, deviceNameOrPath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +52,22 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
||||
return r;
|
||||
}
|
||||
|
||||
private static String getExecutablePath(Context context) {
|
||||
|
||||
public static String getDeviceNameOrPath(Context context, String deviceNameOrPath) {
|
||||
if (sTouchDevice < 0) {
|
||||
sTouchDevice = PreferenceManager.getDefaultSharedPreferences(context).getInt(KEY_TOUCH_DEVICE, -1);
|
||||
}
|
||||
if (sTouchDevice >= 0) {
|
||||
deviceNameOrPath = "/dev/input/event" + sTouchDevice;
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.edit()
|
||||
.putInt(KEY_TOUCH_DEVICE, sTouchDevice)
|
||||
.apply();
|
||||
}
|
||||
return deviceNameOrPath;
|
||||
}
|
||||
|
||||
public static String getExecutablePath(Context context) {
|
||||
File tmp = new File(context.getCacheDir(), "root_automator");
|
||||
PFile.copyAsset(context, ROOT_AUTOMATOR_EXECUTABLE_ASSET, tmp.getAbsolutePath());
|
||||
return tmp.getAbsolutePath();
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.stardust.autojs.runtime.api;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
|
||||
import com.stardust.autojs.core.inputevent.InputDevices;
|
||||
import com.stardust.autojs.engine.RootAutomatorEngine;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.util.ScreenMetrics;
|
||||
|
||||
@@ -19,6 +26,7 @@ import static com.stardust.autojs.core.inputevent.InputEventCodes.*;
|
||||
|
||||
public class RootAutomator {
|
||||
|
||||
private static final String LOG_TAG = "RootAutomator";
|
||||
|
||||
public static final byte DATA_TYPE_SLEEP = 0;
|
||||
public static final byte DATA_TYPE_EVENT = 1;
|
||||
@@ -26,31 +34,22 @@ public class RootAutomator {
|
||||
public static final byte DATA_TYPE_EVENT_TOUCH_X = 3;
|
||||
public static final byte DATA_TYPE_EVENT_TOUCH_Y = 4;
|
||||
|
||||
private DataOutputStream mTmpFileOutputStream;
|
||||
private File mEventTmpFile;
|
||||
@Nullable
|
||||
private ScreenMetrics mScreenMetrics;
|
||||
private String mDevicePath;
|
||||
private AbstractShell mShell;
|
||||
private int mDefaultId = -1;
|
||||
|
||||
public RootAutomator() {
|
||||
try {
|
||||
mEventTmpFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), ".auto");
|
||||
mEventTmpFile.deleteOnExit();
|
||||
mTmpFileOutputStream = new DataOutputStream(new FileOutputStream(mEventTmpFile));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
public RootAutomator(Context context) {
|
||||
mShell = new ProcessShell(true);
|
||||
String path = RootAutomatorEngine.getExecutablePath(context);
|
||||
String deviceNameOrPath = RootAutomatorEngine.getDeviceNameOrPath(context, InputDevices.getTouchDeviceName());
|
||||
mShell.exec("chmod 777 " + path);
|
||||
mShell.exec(path + " -d " + deviceNameOrPath);
|
||||
}
|
||||
|
||||
|
||||
public void sendEvent(int type, int code, int value) throws IOException {
|
||||
mTmpFileOutputStream.writeByte(DATA_TYPE_EVENT);
|
||||
mTmpFileOutputStream.writeShort(type);
|
||||
mTmpFileOutputStream.writeShort(code);
|
||||
mTmpFileOutputStream.writeInt(value);
|
||||
}
|
||||
|
||||
public void setInputDevice(int i) throws IOException {
|
||||
mDevicePath = "/dev/input/event" + i;
|
||||
mShell.exec(type + " " + code + " " + value);
|
||||
}
|
||||
|
||||
public void touch(int x, int y) throws IOException {
|
||||
@@ -70,6 +69,8 @@ public class RootAutomator {
|
||||
}
|
||||
|
||||
private int scaleX(int x) {
|
||||
if (mScreenMetrics == null)
|
||||
return x;
|
||||
return mScreenMetrics.scaleX(x);
|
||||
}
|
||||
|
||||
@@ -78,43 +79,117 @@ public class RootAutomator {
|
||||
}
|
||||
|
||||
public void sendSync() throws IOException {
|
||||
sendEvent(0, 0, 0);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
public void sendMtSync() throws IOException {
|
||||
sendEvent(EV_SYN, SYN_MT_REPORT, 0);
|
||||
}
|
||||
|
||||
private int scaleY(int y) {
|
||||
if (mScreenMetrics == null)
|
||||
return y;
|
||||
return mScreenMetrics.scaleY(y);
|
||||
|
||||
}
|
||||
|
||||
public void sleep(int n) throws IOException {
|
||||
mTmpFileOutputStream.writeByte(DATA_TYPE_SLEEP);
|
||||
mTmpFileOutputStream.writeInt(n);
|
||||
public void tap(int x, int y, int id) throws IOException {
|
||||
touchDown(x, y, id);
|
||||
touchUp(id);
|
||||
}
|
||||
|
||||
public void tap(int x, int y) throws IOException {
|
||||
//sendEvent(EV_ABS, ABS_MT_TRACKING_ID, 0x0000398c);
|
||||
sendEvent(x, y, mDefaultId);
|
||||
}
|
||||
|
||||
public void swipe(int x1, int y1, int x2, int y2, int duration, int id) throws IOException {
|
||||
long now = SystemClock.uptimeMillis();
|
||||
touchDown(x1, y1, id);
|
||||
long startTime = now;
|
||||
long endTime = startTime + duration;
|
||||
while (now < endTime) {
|
||||
long elapsedTime = now - startTime;
|
||||
float alpha = (float) elapsedTime / duration;
|
||||
touchMove((int) lerp(x1, x2, alpha), (int) lerp(y1, y2, alpha), id);
|
||||
now = SystemClock.uptimeMillis();
|
||||
}
|
||||
touchUp(id);
|
||||
}
|
||||
|
||||
public void swipe(int x1, int y1, int x2, int y2, int duration) throws IOException {
|
||||
swipe(x1, y1, x2, y2, duration, mDefaultId);
|
||||
}
|
||||
|
||||
public void swipe(int x1, int y1, int x2, int y2) throws IOException {
|
||||
swipe(x1, y1, x2, y2, 300, mDefaultId);
|
||||
}
|
||||
|
||||
public void touchDown(int x, int y, int id) throws IOException {
|
||||
sendEvent(EV_ABS, ABS_MT_TRACKING_ID, id);
|
||||
sendEvent(EV_KEY, BTN_TOUCH, 0x00000001);
|
||||
sendEvent(EV_KEY, BTN_TOOL_FINGER, 0x00000001);
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_X, x);
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_Y, y);
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_X, scaleX(x));
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_Y, scaleY(y));
|
||||
sendEvent(EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0x00000000);
|
||||
//sendEvent(EV_ABS, ABS_MT_TRACKING_ID, 0xffffffff);
|
||||
}
|
||||
|
||||
public void touchDown(int x, int y) throws IOException {
|
||||
touchDown(x, y, mDefaultId);
|
||||
}
|
||||
|
||||
public void touchUp(int id) throws IOException {
|
||||
sendEvent(EV_ABS, ABS_MT_TRACKING_ID, id);
|
||||
sendEvent(EV_KEY, BTN_TOUCH, 0x00000000);
|
||||
sendEvent(EV_KEY, BTN_TOOL_FINGER, 0x00000000);
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0x00000000);
|
||||
}
|
||||
|
||||
public void swipe(int x, int y, int duration){
|
||||
|
||||
public void touchUp() throws IOException {
|
||||
touchUp(mDefaultId);
|
||||
}
|
||||
|
||||
public AbstractShell.Result writeToDevice(Context context) {
|
||||
if (mDevicePath == null) {
|
||||
return new RootAutomatorEngine(context).execute(mEventTmpFile.getAbsolutePath());
|
||||
} else {
|
||||
return new RootAutomatorEngine(context, mDevicePath).execute(mEventTmpFile.getAbsolutePath());
|
||||
public void touchMove(int x, int y, int id) throws IOException {
|
||||
sendEvent(EV_ABS, ABS_MT_TRACKING_ID, id);
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_X, scaleX(x));
|
||||
sendEvent(EV_ABS, ABS_MT_POSITION_Y, scaleY(y));
|
||||
sendEvent(EV_SYN, SYN_REPORT, 0x00000000);
|
||||
}
|
||||
|
||||
public void touchMove(int x, int y) throws IOException {
|
||||
touchMove(x, y, mDefaultId);
|
||||
}
|
||||
|
||||
public int getDefaultId() {
|
||||
return mDefaultId;
|
||||
}
|
||||
|
||||
public void setDefaultId(int defaultId) {
|
||||
mDefaultId = defaultId;
|
||||
}
|
||||
|
||||
private void sleep(long duration) {
|
||||
try {
|
||||
Thread.sleep(duration);
|
||||
} catch (InterruptedException e) {
|
||||
throw new ScriptInterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
private static float lerp(float a, float b, float alpha) {
|
||||
return (b - a) * alpha + a;
|
||||
}
|
||||
|
||||
public void exit() throws IOException {
|
||||
sendEvent(0xffff, 0xffff, 0xefefefef);
|
||||
mShell.exec("exit");
|
||||
mShell.exec("exit");
|
||||
mShell.exec("exit");
|
||||
mShell.exec("exit");
|
||||
mShell.exec("exit");
|
||||
mShell.exec("exit");
|
||||
mShell.exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user