fix: root_automator cannot be force stopped
This commit is contained in:
@@ -80,19 +80,15 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupListeners() {
|
private void setupListeners() {
|
||||||
mWindow.setOnActionViewClickListener(new View.OnClickListener() {
|
mWindow.setOnActionViewClickListener(v -> {
|
||||||
@Override
|
if (mState == STATE_RECORDING) {
|
||||||
public void onClick(View v) {
|
stopRecord();
|
||||||
if (mState == STATE_RECORDING) {
|
} else if (mWindow.isExpanded()) {
|
||||||
stopRecord();
|
mWindow.collapse();
|
||||||
} else if (mWindow.isExpanded()) {
|
} else {
|
||||||
mWindow.collapse();
|
AutoJs.getInstance().getLayoutInspector().captureCurrentWindow();
|
||||||
} else {
|
mWindow.expand();
|
||||||
AutoJs.getInstance().getLayoutInspector().captureCurrentWindow();
|
|
||||||
mWindow.expand();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,12 +126,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener {
|
|||||||
.customView(listView, false)
|
.customView(listView, false)
|
||||||
.positiveText(R.string.cancel)
|
.positiveText(R.string.cancel)
|
||||||
.build();
|
.build();
|
||||||
listView.setOnItemOperatedListener(new ScriptListView.OnItemOperatedListener() {
|
listView.setOnItemOperatedListener(file -> dialog.dismiss());
|
||||||
@Override
|
|
||||||
public void OnItemOperated(ScriptFile file) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
DialogUtils.showDialog(dialog);
|
DialogUtils.showDialog(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -307,7 +307,6 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
|||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(BindableViewHolder<?> holder, int position) {
|
public void onBindViewHolder(BindableViewHolder<?> holder, int position) {
|
||||||
int positionOfCategoryFile = positionOfCategoryFile();
|
int positionOfCategoryFile = positionOfCategoryFile();
|
||||||
Log.d(LOG_TAG, String.format("view holder = %s, pos = %d, posOfCategory = %d, size = %d", holder.getClass().toString(), position, positionOfCategoryFile, mScriptList.count()));
|
|
||||||
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
|
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
|
||||||
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
|
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
|
||||||
// FIXME: 2017/10/20 java.lang.ClassCastException: java.lang.Boolean cannot be cast to com.stardust.scriptdroid.model.script.ScriptFile
|
// FIXME: 2017/10/20 java.lang.ClassCastException: java.lang.Boolean cannot be cast to com.stardust.scriptdroid.model.script.ScriptFile
|
||||||
@@ -323,17 +322,14 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
int viewType;
|
|
||||||
int positionOfCategoryFile = positionOfCategoryFile();
|
int positionOfCategoryFile = positionOfCategoryFile();
|
||||||
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
|
if (position == positionOfCategoryDir || position == positionOfCategoryFile) {
|
||||||
viewType = VIEW_TYPE_CATEGORY;
|
return VIEW_TYPE_CATEGORY;
|
||||||
} else if (position < positionOfCategoryFile) {
|
} else if (position < positionOfCategoryFile) {
|
||||||
viewType = VIEW_TYPE_DIRECTORY;
|
return VIEW_TYPE_DIRECTORY;
|
||||||
} else {
|
} else {
|
||||||
viewType = VIEW_TYPE_FILE;
|
return VIEW_TYPE_FILE;
|
||||||
}
|
}
|
||||||
Log.d(LOG_TAG, String.format("view type = %d, pos = %d, posOfCategory = %d, size = %d", viewType, position, positionOfCategoryFile, mScriptList.count()));
|
|
||||||
return viewType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.stardust.scriptdroid;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.annotations.NonNull;
|
import io.reactivex.annotations.NonNull;
|
||||||
@@ -20,28 +22,10 @@ public class ExampleUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
Observable.fromCallable(new Callable<String>() {
|
Matcher matcher = Pattern.compile("[0-9]+").matcher("2937Finish!");
|
||||||
@Override
|
if (matcher.find()) {
|
||||||
public String call() throws Exception {
|
System.out.println(matcher.group());
|
||||||
System.out.println(Thread.currentThread());
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(Schedulers.newThread())
|
|
||||||
.doOnComplete(new Action() {
|
|
||||||
@Override
|
|
||||||
public void run() throws Exception {
|
|
||||||
System.out.println(Thread.currentThread());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.observeOn(Schedulers.newThread())
|
|
||||||
.subscribe(new Consumer<String>() {
|
|
||||||
@Override
|
|
||||||
public void accept(@NonNull String s) throws Exception {
|
|
||||||
System.out.println(Thread.currentThread());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.stardust.enhancedfloaty.FloatyService;
|
|||||||
import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow;
|
import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
@@ -67,7 +68,7 @@ public class StardustConsole extends AbstractConsole {
|
|||||||
private LogListener mLogListener;
|
private LogListener mLogListener;
|
||||||
private UiHandler mUiHandler;
|
private UiHandler mUiHandler;
|
||||||
private BlockingQueue<String> mInput = new ArrayBlockingQueue<>(1);
|
private BlockingQueue<String> mInput = new ArrayBlockingQueue<>(1);
|
||||||
private ConsoleView mConsoleView;
|
private WeakReference<ConsoleView> mConsoleView;
|
||||||
private volatile boolean mShown = false;
|
private volatile boolean mShown = false;
|
||||||
|
|
||||||
public StardustConsole(UiHandler uiHandler) {
|
public StardustConsole(UiHandler uiHandler) {
|
||||||
@@ -88,7 +89,7 @@ public class StardustConsole extends AbstractConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setConsoleView(ConsoleView consoleView) {
|
public void setConsoleView(ConsoleView consoleView) {
|
||||||
mConsoleView = consoleView;
|
mConsoleView = new WeakReference<>(consoleView);
|
||||||
setLogListener(consoleView);
|
setLogListener(consoleView);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
this.notify();
|
this.notify();
|
||||||
@@ -177,13 +178,13 @@ public class StardustConsole extends AbstractConsole {
|
|||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
public String rawInput() {
|
public String rawInput() {
|
||||||
if (mConsoleView == null) {
|
if (mConsoleView == null || mConsoleView.get() == null) {
|
||||||
if (!mShown) {
|
if (!mShown) {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
waitForConsoleView();
|
waitForConsoleView();
|
||||||
}
|
}
|
||||||
mConsoleView.showEditText();
|
mConsoleView.get().showEditText();
|
||||||
try {
|
try {
|
||||||
return mInput.take();
|
return mInput.take();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class InputEventToAutoFileRecorder extends InputEventRecorder {
|
|||||||
public void recordInputEvent(@NonNull InputEventObserver.InputEvent event) {
|
public void recordInputEvent(@NonNull InputEventObserver.InputEvent event) {
|
||||||
try {
|
try {
|
||||||
convertEventOrThrow(event);
|
convertEventOrThrow(event);
|
||||||
//Log.d(LOG_TAG, "recordInputEvent: " + event);
|
Log.d(LOG_TAG, "recordInputEvent: " + event);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,23 @@ package com.stardust.autojs.engine;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Patterns;
|
||||||
|
|
||||||
import com.stardust.autojs.runtime.api.AbstractShell;
|
import com.stardust.autojs.runtime.api.AbstractShell;
|
||||||
import com.stardust.autojs.runtime.api.ProcessShell;
|
import com.stardust.autojs.runtime.api.ProcessShell;
|
||||||
import com.stardust.autojs.core.inputevent.InputDevices;
|
import com.stardust.autojs.core.inputevent.InputDevices;
|
||||||
|
import com.stardust.autojs.runtime.exception.ScriptException;
|
||||||
|
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||||
import com.stardust.autojs.script.AutoFileSource;
|
import com.stardust.autojs.script.AutoFileSource;
|
||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/8/1.
|
* Created by Stardust on 2017/8/1.
|
||||||
@@ -22,6 +31,7 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
|||||||
|
|
||||||
private static final String KEY_TOUCH_DEVICE = RootAutomatorEngine.class.getName() + ".touch_device";
|
private static final String KEY_TOUCH_DEVICE = RootAutomatorEngine.class.getName() + ".touch_device";
|
||||||
private static final String LOG_TAG = "RootAutomatorEngine";
|
private static final String LOG_TAG = "RootAutomatorEngine";
|
||||||
|
private static final Pattern PID_PATTERN = Pattern.compile("[0-9]{2,}");
|
||||||
|
|
||||||
private static int sTouchDevice = -1;
|
private static int sTouchDevice = -1;
|
||||||
private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator";
|
private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator";
|
||||||
@@ -30,6 +40,8 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
|||||||
private String mDeviceNameOrPath;
|
private String mDeviceNameOrPath;
|
||||||
private Thread mThread;
|
private Thread mThread;
|
||||||
private String mExecutablePath;
|
private String mExecutablePath;
|
||||||
|
private String mPid;
|
||||||
|
private Process mProcess;
|
||||||
|
|
||||||
public RootAutomatorEngine(Context context, String deviceNameOrPath) {
|
public RootAutomatorEngine(Context context, String deviceNameOrPath) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -44,11 +56,49 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
|||||||
public void execute(String autoFile) {
|
public void execute(String autoFile) {
|
||||||
mExecutablePath = getExecutablePath(mContext);
|
mExecutablePath = getExecutablePath(mContext);
|
||||||
Log.d(LOG_TAG, "exec: " + autoFile);
|
Log.d(LOG_TAG, "exec: " + autoFile);
|
||||||
AbstractShell.Result result = ProcessShell.execCommand(new String[]{
|
final String[] commands = {
|
||||||
"chmod 777 " + mExecutablePath,
|
"chmod 755 " + mExecutablePath,
|
||||||
mExecutablePath + " \"" + autoFile + "\" -d " + mDeviceNameOrPath
|
String.format("\"%s\" \"%s\" -d \"%s\" &", mExecutablePath, autoFile, mDeviceNameOrPath), // to run root_automator
|
||||||
}, true);
|
"echo $!", // to print the root_automator pid
|
||||||
Log.d(LOG_TAG, "result = " + result);
|
"exit", // to exit su
|
||||||
|
"exit" // to exit shell
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
mProcess = Runtime.getRuntime().exec("su");
|
||||||
|
executeCommands(mProcess, commands);
|
||||||
|
mPid = readPid(mProcess);
|
||||||
|
mProcess.waitFor();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ScriptException(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new ScriptInterruptedException();
|
||||||
|
} finally {
|
||||||
|
mProcess.destroy();
|
||||||
|
mProcess = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readPid(Process process) throws IOException {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
Matcher matcher = PID_PATTERN.matcher(line);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeCommands(Process process, String[] commands) throws IOException {
|
||||||
|
DataOutputStream os = new DataOutputStream(process.getOutputStream());
|
||||||
|
for (String command : commands) {
|
||||||
|
if (command != null) {
|
||||||
|
os.write(command.getBytes());
|
||||||
|
os.writeBytes("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +146,9 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
|||||||
@Override
|
@Override
|
||||||
public void forceStop() {
|
public void forceStop() {
|
||||||
mThread.interrupt();
|
mThread.interrupt();
|
||||||
ProcessShell.exec("killall " + mExecutablePath, true);
|
if (mPid != null) {
|
||||||
|
ProcessShell.exec("kill " + mPid, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public class ProcessShell extends AbstractShell {
|
|||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
builder.append(line);
|
builder.append(line).append('\n');
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user