From 9c5f876a8f2e260ab0cafda1635834dcc41aa56f Mon Sep 17 00:00:00 2001
From: hyb1996 <946994919@qq.com>
Date: Sun, 13 Aug 2017 11:12:14 +0800
Subject: [PATCH] add: root record generates js file fix: delay of tap, swipe
by adding RootAutomator
---
app/src/main/AndroidManifest.xml | 7 +-
.../java/com/stardust/scriptdroid/Pref.java | 5 +
.../autojs/record/GlobalRecorder.java | 86 +++++------
.../menu/content/RecordNavigatorContent.java | 34 ++++-
.../external/open/ImportIntentActivity.java | 7 +-
.../ui/common/ScriptOperations.java | 17 ++-
app/src/main/res/values/strings.xml | 15 +-
app/src/main/res/xml/preferences.xml | 8 +
.../stardust/autojs/core/record/Recorder.java | 6 +
.../InputEventToAutoFileRecorder.java | 5 +
.../InputEventToRootAutomatorRecorder.java | 8 +-
.../core/record/inputevent/TouchRecorder.java | 18 ++-
.../autojs/engine/RootAutomatorEngine.java | 31 ++--
.../autojs/runtime/api/RootAutomator.java | 143 +++++++++++++-----
14 files changed, 267 insertions(+), 123 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5b66c288..48bcd78d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -186,7 +186,6 @@
-
@@ -210,9 +209,9 @@
+ android:label="@string/text_import_script"
+ android:theme="@style/AppTheme.Transparent">
@@ -228,8 +227,6 @@
-
-
diff --git a/app/src/main/java/com/stardust/scriptdroid/Pref.java b/app/src/main/java/com/stardust/scriptdroid/Pref.java
index 8b861f59..f6f08258 100644
--- a/app/src/main/java/com/stardust/scriptdroid/Pref.java
+++ b/app/src/main/java/com/stardust/scriptdroid/Pref.java
@@ -128,4 +128,9 @@ public class Pref {
public static boolean isRecordToastEnabled() {
return def().getBoolean(getString(R.string.key_record_toast), true);
}
+
+ public static boolean rootRecordGeneratesBinary() {
+ return def().getString(getString(R.string.key_root_record_out_file_type), "binary")
+ .equals("binary");
+ }
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/record/GlobalRecorder.java b/app/src/main/java/com/stardust/scriptdroid/autojs/record/GlobalRecorder.java
index 78f4cef6..f80175ff 100644
--- a/app/src/main/java/com/stardust/scriptdroid/autojs/record/GlobalRecorder.java
+++ b/app/src/main/java/com/stardust/scriptdroid/autojs/record/GlobalRecorder.java
@@ -15,6 +15,9 @@ import com.stardust.autojs.core.inputevent.InputEventCodes;
import com.stardust.autojs.core.inputevent.ShellKeyObserver;
import com.stardust.autojs.core.record.Recorder;
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
+import com.stardust.autojs.core.record.inputevent.InputEventRecorder;
+import com.stardust.autojs.core.record.inputevent.InputEventToAutoFileRecorder;
+import com.stardust.autojs.core.record.inputevent.InputEventToRootAutomatorRecorder;
import com.stardust.autojs.core.record.inputevent.TouchRecorder;
import com.stardust.autojs.runtime.api.Shell;
import com.stardust.scriptdroid.App;
@@ -45,8 +48,6 @@ public class GlobalRecorder implements Recorder.OnStateChangedListener {
private TouchRecorder mTouchRecorder;
private Context mContext;
private boolean mDiscard = false;
- private long mLastVolumeDownEventTime;
- private ShellKeyObserver mShellKeyObserver;
public static GlobalRecorder getSingleton(Context context) {
if (sSingleton == null) {
@@ -55,61 +56,25 @@ public class GlobalRecorder implements Recorder.OnStateChangedListener {
return sSingleton;
}
-
public static void initSingleton(Context context) {
getSingleton(context);
}
public GlobalRecorder(Context context) {
mContext = new ContextThemeWrapper(context.getApplicationContext(), R.style.AppTheme);
- mTouchRecorder = new TouchRecorder(context);
- addKeyListeners();
+ mTouchRecorder = new TouchRecorder(context) {
+ @Override
+ protected InputEventRecorder createInputEventRecorder() {
+ if (Pref.rootRecordGeneratesBinary())
+ return new InputEventToAutoFileRecorder(mContext);
+ else
+ return new InputEventToRootAutomatorRecorder();
+ }
+ };
EventBus.getDefault().register(this);
}
- private void addKeyListeners() {
- AccessibilityService.getStickOnKeyObserver().addListener(new OnKeyListener() {
- @Override
- public void onKeyEvent(int keyCode, KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN &&
- (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
- onVolumeDown();
- }
- }
- });
- mShellKeyObserver = new ShellKeyObserver();
- mShellKeyObserver.setKeyListener(new ShellKeyObserver.KeyListener() {
- @Override
- public void onKeyDown(String keyName) {
- if ("KEY_VOLUMEDOWN".equals(keyName)) {
- onVolumeDown();
- }
- }
-
- @Override
- public void onKeyUp(String keyName) {
-
- }
- });
- }
-
-
- private void onVolumeDown() {
- if (!Pref.isRecordVolumeControlEnable()) {
- return;
- }
- if (System.currentTimeMillis() - mLastVolumeDownEventTime < 300) {
- return;
- }
- mLastVolumeDownEventTime = System.currentTimeMillis();
- int state = getState();
- if (state == Recorder.STATE_RECORDING || state == Recorder.STATE_PAUSED) {
- stop();
- } else {
- start();
- }
- }
public void start() {
if (Pref.isRecordWithRootEnabled()) {
@@ -139,6 +104,10 @@ public class GlobalRecorder implements Recorder.OnStateChangedListener {
return mRecorder.getCode();
}
+ public String getPath() {
+ return mRecorder.getPath();
+ }
+
public int getState() {
if (mRecorder == null)
return Recorder.STATE_NOT_START;
@@ -166,7 +135,11 @@ public class GlobalRecorder implements Recorder.OnStateChangedListener {
@Override
public void onStop() {
if (!mDiscard) {
- handleRecordedScript(getCode());
+ String code = getCode();
+ if (code != null)
+ handleRecordedScript(code);
+ else
+ handleRecordedFile(getPath());
}
for (Recorder.OnStateChangedListener listener : mOnStateChangedListeners) {
listener.onStop();
@@ -212,6 +185,23 @@ public class GlobalRecorder implements Recorder.OnStateChangedListener {
}
}
+ private void handleRecordedFile(final String path) {
+ if (Looper.myLooper() != Looper.getMainLooper()) {
+ App.getApp().getUiHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ handleRecordedFile(path);
+ }
+ });
+ return;
+ }
+ new ScriptOperations(mContext, null)
+ .importFile(path)
+ .subscribe();
+
+ }
+
+
private void showRecordHandleDialog(final String script) {
DialogUtils.showDialog(new ThemeColorMaterialDialogBuilder(mContext)
.title(R.string.text_recorded)
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java
index 13bf0d5a..33c9a868 100644
--- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java
@@ -48,7 +48,7 @@ import io.mattcarroll.hover.NavigatorContent;
* Created by Stardust on 2017/3/12.
*/
-public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStateChangedListener {
+public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStateChangedListener, OnKeyListener {
private View mView;
@BindView(R.id.sw_recorded_by_root)
@@ -68,18 +68,36 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
private GlobalRecorder mRecorder;
private Context mContext;
-
+ private long mLastVolumeDownEventTime;
public RecordNavigatorContent(Context context) {
mContext = new ContextThemeWrapper(context, R.style.AppTheme);
- mView = View.inflate(context, R.layout.floating_window_record, null);
+ mView = View.inflate(mContext, R.layout.floating_window_record, null);
ButterKnife.bind(this, mView);
HoverMenuService.getEventBus().register(this);
mRecorder = GlobalRecorder.getSingleton(context);
mRecorder.addOnStateChangedListener(this);
setState(mRecorder.getState());
+ AccessibilityService.getStickOnKeyObserver().addListener(this);
}
+ private void onVolumeDown() {
+ if (!Pref.isRecordVolumeControlEnable()) {
+ return;
+ }
+ if (System.currentTimeMillis() - mLastVolumeDownEventTime < 300) {
+ return;
+ }
+ mLastVolumeDownEventTime = System.currentTimeMillis();
+ int state = mRecorder.getState();
+ if (state == Recorder.STATE_RECORDING || state == Recorder.STATE_PAUSED) {
+ mRecorder.stop();
+ } else {
+ mRecorder.start();
+ }
+ }
+
+
@NonNull
@Override
public View getView() {
@@ -161,6 +179,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
public void onMenuExit() {
HoverMenuService.getEventBus().unregister(this);
mRecorder.removeOnStateChangedListener(this);
+ AccessibilityService.getStickOnKeyObserver().removeListener(this);
}
@Override
@@ -182,4 +201,13 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
public void onResume() {
setState(Recorder.STATE_RECORDING);
}
+
+ @Override
+ public void onKeyEvent(int keyCode, KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN &&
+ (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
+ onVolumeDown();
+ }
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java
index 9dabd8a6..96934410 100644
--- a/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java
@@ -8,6 +8,7 @@ import android.text.TextUtils;
import android.webkit.MimeTypeMap;
import android.widget.Toast;
+import com.stardust.pio.PFile;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.main.MainActivity;
@@ -45,9 +46,13 @@ public class ImportIntentActivity extends BaseActivity {
private void handleIntent(Intent intent) throws FileNotFoundException {
Uri uri = intent.getData();
if (uri != null && "content".equals(uri.getScheme())) {
+ String ext = PFile.getExtension(uri.getScheme());
+ if(TextUtils.isEmpty(ext)){
+ ext = "js";
+ }
InputStream stream = getContentResolver().openInputStream(uri);
new ScriptOperations(this, null)
- .importFile("", stream)
+ .importFile("", stream, ext)
.subscribe(new Consumer() {
@Override
public void accept(@NonNull String s) throws Exception {
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java
index bc2c11a1..a47c5246 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java
@@ -96,7 +96,13 @@ public class ScriptOperations {
}
public void newScriptFile() {
- newScriptFileForScript(null);
+ showFileNameInputDialog("", "js")
+ .subscribe(new Consumer() {
+ @Override
+ public void accept(@io.reactivex.annotations.NonNull String input) throws Exception {
+ createScriptFile(getCurrentDirectoryPath() + input + ".js", null, true);
+ }
+ });
}
public Observable importFile(final String pathFrom) {
@@ -117,13 +123,13 @@ public class ScriptOperations {
});
}
- public Observable importFile(String prefix, final InputStream inputStream) {
- return showFileNameInputDialog(PFile.getNameWithoutExtension(prefix), "js")
+ public Observable importFile(String prefix, final InputStream inputStream, final String ext) {
+ return showFileNameInputDialog(PFile.getNameWithoutExtension(prefix), ext)
.observeOn(Schedulers.io())
.map(new Function() {
@Override
public String apply(@io.reactivex.annotations.NonNull String s) throws Exception {
- final String pathTo = getCurrentDirectoryPath() + s + ".js";
+ final String pathTo = getCurrentDirectoryPath() + s + "." + ext;
if (PFile.copyStream(inputStream, pathTo)) {
showMessage(R.string.text_import_succeed);
} else {
@@ -198,14 +204,13 @@ public class ScriptOperations {
}
-
private CharSequence getString(int resId) {
return mContext.getString(resId);
}
public Observable importSample(Sample sample) {
try {
- return importFile(sample.name, mContext.getAssets().open(sample.path));
+ return importFile(sample.name, mContext.getAssets().open(sample.path), PFile.getExtension(sample.path));
} catch (IOException e) {
e.printStackTrace();
showMessage(R.string.text_import_fail);
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0f2ffa3b..334c2299 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -82,7 +82,7 @@
加入QQ互赞&交流群
已复制到剪贴板
使用音量下键控制
- 开启后每次音量下键会开始或停止脚本录制
+ 开启悬浮窗后每次音量下键会开始或停止脚本录制
key_use_volume_control_record
未安装手机QQ
编辑
@@ -218,6 +218,9 @@
导入脚本文件
key_record_with_root
key_record_toast
+ key_root_record_out_file_type
+ Root录制生成文件类型
+ binary
@@ -246,4 +249,14 @@
- Off
+
+
+ - 可编辑的js文件
+ - 不可编辑的二进制文件
+
+
+
+ - js
+ - binary
+
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index b6df81ee..9abf3076 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -18,6 +18,14 @@
android:defaultValue="true"
android:key="@string/key_record_toast"
android:title="@string/text_record_msg"/>
+
+
diff --git a/autojs/src/main/java/com/stardust/autojs/core/record/Recorder.java b/autojs/src/main/java/com/stardust/autojs/core/record/Recorder.java
index 4f7af50b..b78a9a3c 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/record/Recorder.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/record/Recorder.java
@@ -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;
+ }
}
}
diff --git a/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToAutoFileRecorder.java b/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToAutoFileRecorder.java
index f72efa42..8245cdc4 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToAutoFileRecorder.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToAutoFileRecorder.java
@@ -119,6 +119,11 @@ public class InputEventToAutoFileRecorder extends InputEventRecorder {
}
public String getCode() {
+ return null;
+ }
+
+ @Override
+ public String getPath() {
return mTmpFile.getAbsolutePath();
}
diff --git a/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToRootAutomatorRecorder.java b/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToRootAutomatorRecorder.java
index dca187cb..0a03d650 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToRootAutomatorRecorder.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/InputEventToRootAutomatorRecorder.java
@@ -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();");
}
diff --git a/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/TouchRecorder.java b/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/TouchRecorder.java
index 15735336..9b610679 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/TouchRecorder.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/record/inputevent/TouchRecorder.java
@@ -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);
}
diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java
index 1c0b8e2b..8b5daaf2 100644
--- a/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java
+++ b/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java
@@ -33,18 +33,8 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine= 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= 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();
diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java
index e5fb0611..ce871564 100644
--- a/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java
+++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java
@@ -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();
+ }
+
}