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(); + } + }