Fix and improve root rocording

This commit is contained in:
hyb1996
2017-05-05 00:35:45 +08:00
parent 7473d7c6a5
commit 163f38760e
80 changed files with 1386 additions and 1017 deletions

View File

@@ -1,11 +1,11 @@
if(__engine_name__ == "rhino"){
__importClassOld__ = importClass;
__importClass__ = importClass;
var importClass = function(pack){
if(typeof(pack) == "string"){
__importClassOld__(Packages[pack]);
__importClass__(Packages[pack]);
}else{
__importClassOld__(pack);
__importClass__(pack);
}
}
var loadJar = function(path){
@@ -183,23 +183,23 @@ var setClip = function(text){
var Tap = function(x, y){
__runtime__.shellExecNotReturnResultWithRoot("input tap " + x + " " + y);
__runtime__.shellExecAsync("input tap " + x + " " + y);
}
var Swipe = function(x1, y1, x2, y2, duration){
if(arguments.length == 5){
__runtime__.shellExecNotReturnResultWithRoot("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration);
__runtime__.shellExecAsync("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration);
}else{
__runtime__.shellExecNotReturnResultWithRoot("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
__runtime__.shellExecAsync("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
}
}
var Screencap = function(path){
__runtime__.shellExecNotReturnResultWithRoot("screencap -p " + path);
__runtime__.shellExecAsync("screencap -p " + path);
}
var KeyCode = function(keyCode){
__runtime__.shellExecNotReturnResultWithRoot("input keyevent " + keyCode);
__runtime__.shellExecAsync("input keyevent " + keyCode);
}
var Home = function(){
@@ -251,7 +251,7 @@ var Camera = function(){
}
var Text = function(text){
__runtime__.shellExecNotReturnResultWithRoot("input text " + text);
__runtime__.shellExecAsync("input text " + text);
}
var selector = function(){
@@ -299,8 +299,6 @@ var open = function(path, mode, encoding, bufferSize){
}
//__importClassOld__(com.stardust.autojs.runtime.api.SlowShell);
var newInjectableWebClient = function(){
return new com.stardust.autojs.runtime.api.InjectableWebClient(org.mozilla.javascript.Context.getCurrentContext(), __this__);
}
@@ -308,11 +306,3 @@ var newInjectableWebClient = function(){
var newInjectableWebView = function(activity){
return new com.stardust.autojs.runtime.api.InjectableWebView(activity, org.mozilla.javascript.Context.getCurrentContext(), __this__);
}
/*
importClass("com.stardust.script__runtime__.service.AccessibilityDelegate");
var addAccessibilityDelegate = function(delegate){
__runtime__.addAccessibilityDelegate(delegate);
}
*/

View File

@@ -147,10 +147,9 @@ public class ScriptEngineService {
@Subscribe
public void onScriptExecution(ScriptExecutionEvent event) {
if (event.getCode() == ScriptExecutionEvent.ON_START) {
mGlobalConsole.verbose(DateFormat.getTimeInstance().format(new Date()) + " " + mContext.getString(R.string.text_start_running) + " " + event.getMessage());
mGlobalConsole.verbose(mContext.getString(R.string.text_start_running) + "[" + event.getMessage() + "]");
} else if (event.getCode() == ScriptExecutionEvent.ON_EXCEPTION) {
mUiHandler.toast(mContext.getString(R.string.text_error) + ": " + event.getMessage());
mGlobalConsole.error(event.getMessage());
}
}

View File

@@ -0,0 +1,70 @@
package com.stardust.autojs.runtime;
import com.stardust.autojs.engine.JavaScriptEngine;
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.simple_action.SimpleActionAutomator;
import com.stardust.view.accessibility.AccessibilityInfoProvider;
/**
* Created by Stardust on 2017/5/4.
*/
public abstract class AbstractScriptRuntime {
@JavascriptField
public AppUtils app;
@JavascriptField
public Console console;
@JavascriptField
public SimpleActionAutomator automator;
@JavascriptField
public AccessibilityInfoProvider info;
public AbstractScriptRuntime(AppUtils app, Console console, AccessibilityBridge bridge) {
this.app = app;
this.console = console;
this.automator = new SimpleActionAutomator(bridge, this);
this.info = bridge.getInfoProvider();
}
public AbstractScriptRuntime() {
}
@JavascriptInterface
public abstract void toast(final String text);
@JavascriptInterface
public abstract void sleep(long millis);
@JavascriptInterface
public abstract void setClip(final String text);
@JavascriptInterface
public abstract void shellExecAsync(String cmd);
@JavascriptInterface
public abstract AbstractShell.Result shell(String cmd, int root);
@JavascriptInterface
public abstract UiSelector selector(JavaScriptEngine engine);
@JavascriptInterface
public abstract boolean isStopped();
@JavascriptInterface
public abstract void requiresApi(int i);
@JavascriptInterface
public abstract void loadJar(String path);
@JavascriptInterface
public abstract void stop();
public abstract void ensureAccessibilityServiceEnabled();
}

View File

@@ -6,17 +6,14 @@ import com.stardust.autojs.R;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.rhino_android.AndroidClassLoader;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.SlowShell;
import com.stardust.autojs.runtime.simple_action.SimpleActionAutomator;
import com.stardust.autojs.runtime.api.AppUtils;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.runtime.api.UiSelector;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ClipboardUtil;
import com.stardust.autojs.runtime.api.ProcessShell;
import com.stardust.util.SdkVersionUtil;
import com.stardust.util.Shell;
import com.stardust.util.UiHandler;
import com.stardust.view.accessibility.AccessibilityInfoProvider;
import org.mozilla.javascript.ContextFactory;
@@ -28,42 +25,25 @@ import java.io.IOException;
* Created by Stardust on 2017/1/27.
*/
public class ScriptRuntime {
public class ScriptRuntime extends AbstractScriptRuntime {
private static final String TAG = "ScriptRuntime";
private UiHandler mUiHandler;
private AccessibilityBridge mAccessibilityBridge;
@JavascriptField
public AppUtils app;
@JavascriptField
public Console console;
@JavascriptField
public SimpleActionAutomator automator;
@JavascriptField
public AccessibilityInfoProvider info;
private AbstractShell mRootShell;
public ScriptRuntime(UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge) {
super(new AppUtils(uiHandler.getContext()), console, accessibilityBridge);
mAccessibilityBridge = accessibilityBridge;
mUiHandler = uiHandler;
app = new AppUtils(uiHandler.getContext());
info = accessibilityBridge.getInfoProvider();
this.console = console;
automator = new SimpleActionAutomator(accessibilityBridge, this);
}
@JavascriptInterface
public void toast(final String text) {
mUiHandler.toast(text);
}
@JavascriptInterface
public void sleep(long millis) {
try {
Thread.sleep(millis);
@@ -72,7 +52,6 @@ public class ScriptRuntime {
}
}
@JavascriptInterface
public void setClip(final String text) {
mUiHandler.post(new Runnable() {
@Override
@@ -82,38 +61,31 @@ public class ScriptRuntime {
});
}
@JavascriptInterface
public void shellExecNotReturnResultWithRoot(String cmd) {
public void shellExecAsync(String cmd) {
if (mRootShell == null) {
mRootShell = new SlowShell(true);
mRootShell = new ProcessShell(true);
}
mRootShell.exec(cmd);
}
@JavascriptInterface
public Shell.CommandResult shell(String cmd, int root) {
return Shell.execCommand(cmd, root != 0);
public AbstractShell.Result shell(String cmd, int root) {
return ProcessShell.exec(cmd, root != 0);
}
@JavascriptInterface
public UiSelector selector(JavaScriptEngine engine) {
return new UiSelector(mAccessibilityBridge);
}
@JavascriptInterface
public boolean isStopped() {
return Thread.currentThread().isInterrupted();
}
@JavascriptInterface
public void requiresApi(int i) {
if (Build.VERSION.SDK_INT < i) {
throw new ScriptStopException(mUiHandler.getContext().getString(R.string.text_requires_sdk_version_to_run_the_script) + SdkVersionUtil.sdkIntToString(i));
}
}
@JavascriptInterface
public void loadJar(String path) {
try {
((AndroidClassLoader) ContextFactory.getGlobal().getApplicationClassLoader()).loadJar(new File(path));
@@ -122,7 +94,6 @@ public class ScriptRuntime {
}
}
@JavascriptInterface
public void stop() {
Thread.interrupted();
}

View File

@@ -1,8 +1,9 @@
package com.stardust.autojs.runtime;
package com.stardust.autojs.runtime.api;
import android.support.annotation.Nullable;
import android.util.Log;
import com.stardust.autojs.runtime.ScriptStopException;
import com.stardust.autojs.runtime.api.Console;
/**

View File

@@ -1,23 +1,110 @@
package com.stardust.autojs.runtime.api;
import android.text.TextUtils;
import com.stardust.util.ScreenMetrics;
import java.util.Arrays;
/**
* Created by Stardust on 2017/4/24.
*/
public abstract class AbstractShell {
public static class Result {
public int code = -1;
public String error;
public String result;
@Override
public String toString() {
return "ShellResult{" +
"code=" + code +
", error='" + error + '\'' +
", result='" + result + '\'' +
'}';
}
}
private static final String COMMAND_SU = "su";
private static final String COMMAND_SH = "sh";
static final String COMMAND_EXIT = "exit\n";
static final String COMMAND_LINE_END = "\n";
private int mTouchDevice;
private int mScreenHeight, mScreenWidth;
private boolean mRoot;
public AbstractShell() {
this(false);
}
public AbstractShell(boolean root) {
init(root ? "su" : "sh");
mRoot = root;
init(root ? COMMAND_SU: COMMAND_SH);
}
public boolean isRoot() {
return mRoot;
}
protected abstract void init(String initialCommand);
public abstract void exec(String command);
public abstract void exit();
public void SetTouchDevice(int touchDevice) {
mTouchDevice = touchDevice;
}
public void SendEvent(int type, int code, int value){
SendEvent(mTouchDevice, type, code, value);
}
public void SendEvent(int device, int type, int code, int value){
exec(TextUtils.join("", new Object[]{"sendevent /dev/input/event", device, " ", type, " ", code, " ", value}));
}
public void SetScreenScale(int width, int height){
mScreenWidth = width;
mScreenHeight = height;
}
public void Touch(int x, int y){
TouchX(x);
TouchY(y);
}
public void TouchX(int x) {
SendEvent(mTouchDevice, 3, 53, scaleX(x));
}
private int scaleX(int x) {
int screenWidth = ScreenMetrics.getScreenWidth();
if(screenWidth == mScreenWidth){
return x;
}
return x * screenWidth / mScreenWidth;
}
public void TouchY(int y) {
SendEvent(mTouchDevice, 3, 54, scaleY(y));
}
private int scaleY(int y) {
int screenHeight = ScreenMetrics.getScreenHeight();
if(screenHeight == mScreenHeight){
return y;
}
return y * screenHeight / mScreenHeight;
}
public void KeyCode(int keyCode) {
exec("input keyevent " + keyCode);
}
@@ -77,4 +164,6 @@ public abstract class AbstractShell {
public void Text(String text) {
exec("input text " + text);
}
public abstract void exitAndWaitFor();
}

View File

@@ -0,0 +1,176 @@
package com.stardust.autojs.runtime.api;
import com.stardust.pio.UncheckedIOException;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Created by Stardust on 2017/1/20.
* <p>
* 来自网络~~
*/
public class ProcessShell extends AbstractShell implements AutoCloseable {
private static final String TAG = "ProcessShell";
private Process mProcess;
private DataOutputStream mCommandOutputStream;
private BufferedReader mSucceedReader;
private BufferedReader mErrorReader;
private StringBuilder mSucceedOutput = new StringBuilder();
private StringBuilder mErrorOutput = new StringBuilder();
public ProcessShell() {
}
public ProcessShell(boolean root) {
super(root);
}
@Override
protected void init(String initialCommand) {
try {
mProcess = new ProcessBuilder(initialCommand).redirectErrorStream(true).start();
mCommandOutputStream = new DataOutputStream(mProcess.getOutputStream());
mSucceedReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
mErrorReader = new BufferedReader(new InputStreamReader(mProcess.getErrorStream()));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void exec(String command) {
try {
mCommandOutputStream.writeBytes(command);
if (!command.endsWith(COMMAND_LINE_END)) {
mCommandOutputStream.writeBytes(COMMAND_LINE_END);
}
mCommandOutputStream.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void exit() {
if(mProcess != null) {
mProcess.destroy();
mProcess = null;
}
if(mSucceedReader != null){
try{
mSucceedReader.close();
}catch (IOException ignored){
}
mSucceedReader = null;
}
if(mErrorReader != null){
try{
mErrorReader.close();
}catch (IOException ignored){
}
mErrorReader = null;
}
}
@Override
public void close() {
exit();
}
@Override
public void exitAndWaitFor() {
exec(COMMAND_EXIT);
waitFor();
exit();
}
public int waitFor() {
try {
return mProcess.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public ProcessShell readAll() {
return readSucceedOutput().readErrorOutput();
}
public ProcessShell readSucceedOutput() {
try {
while (mSucceedReader.ready()) {
String line = mSucceedReader.readLine();
mSucceedOutput.append(line).append("\n");
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return this;
}
public ProcessShell readErrorOutput() {
String line;
try {
while ((line = mErrorReader.readLine()) != null) {
mErrorOutput.append(line).append("\n");
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return this;
}
public StringBuilder getSucceedOutput() {
return mSucceedOutput;
}
public StringBuilder getErrorOutput() {
return mErrorOutput;
}
public Process getProcess() {
return mProcess;
}
public BufferedReader getSucceedReader() {
return mSucceedReader;
}
public BufferedReader getErrorReader() {
return mErrorReader;
}
public static Result exec(String command, boolean isRoot) {
String[] commands = command.split("\n");
return exec(commands, isRoot);
}
public static Result exec(String[] commands, boolean isRoot) {
try(ProcessShell shell = new ProcessShell(isRoot)){
for(String command : commands){
shell.exec(command);
}
shell.exec(COMMAND_EXIT);
Result result = new Result();
result.code = shell.waitFor();
shell.readAll();
result.error = shell.getErrorOutput().toString();
result.result = shell.getSucceedOutput().toString();
shell.exit();
return result;
}
}
}

View File

@@ -1,28 +0,0 @@
package com.stardust.autojs.runtime.api;
import com.stardust.util.Shell;
/**
* Created by Stardust on 2017/3/7.
*/
public class SlowShell extends AbstractShell {
private Shell mShell;
public SlowShell(boolean root) {
super(root);
}
@Override
protected void init(String initialCommand) {
mShell = new Shell(initialCommand);
}
@Override
public void exec(String command) {
mShell.execute(command);
}
}

View File

@@ -8,6 +8,7 @@ import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import com.stardust.autojs.runtime.AbstractScriptRuntime;
import com.stardust.autojs.runtime.AccessibilityBridge;
import com.stardust.autojs.runtime.JavascriptInterface;
import com.stardust.autojs.runtime.ScriptRuntime;
@@ -45,9 +46,9 @@ public class SimpleActionAutomator {
}
private AccessibilityBridge mAccessibilityBridge;
private ScriptRuntime mScriptRuntime;
private AbstractScriptRuntime mScriptRuntime;
public SimpleActionAutomator(AccessibilityBridge accessibilityBridge, ScriptRuntime scriptRuntime) {
public SimpleActionAutomator(AccessibilityBridge accessibilityBridge, AbstractScriptRuntime scriptRuntime) {
mAccessibilityBridge = accessibilityBridge;
mScriptRuntime = scriptRuntime;
}

View File

@@ -1,33 +0,0 @@
package com.stardust.autojs.script;
/**
* Created by Stardust on 2017/4/2.
*/
public class MultiScriptSource extends ScriptSource {
private String mScript;
private FileScriptSource mFileScriptSource;
public MultiScriptSource(StringScriptSource stringScriptSource, FileScriptSource fileScriptSource) {
super(fileScriptSource.getName());
mFileScriptSource = fileScriptSource;
StringBuilder stringBuilder = new StringBuilder();
if (stringScriptSource.getScript() != null)
stringBuilder.append(stringScriptSource.getScript()).append("\n");
stringBuilder.append(fileScriptSource.getScript());
mScript = stringBuilder.toString();
}
@Override
public String getScript() {
return mScript;
}
@Override
public String toString() {
return mFileScriptSource.toString();
}
}

View File

@@ -0,0 +1,33 @@
package com.stardust.autojs.script;
/**
* Created by Stardust on 2017/4/2.
*/
public class ScriptSourceWithInit extends ScriptSource {
private String mScript;
private ScriptSource mMainScriptSource;
public ScriptSourceWithInit(ScriptSource initScriptSource, ScriptSource mainScriptSource) {
super(mainScriptSource.getName());
mMainScriptSource = mainScriptSource;
StringBuilder stringBuilder = new StringBuilder();
if (initScriptSource.getScript() != null)
stringBuilder.append(initScriptSource.getScript()).append("\n");
stringBuilder.append(mainScriptSource.getScript());
mScript = stringBuilder.toString();
}
@Override
public String getScript() {
return mScript;
}
@Override
public String toString() {
return mMainScriptSource.toString();
}
}