Dying again

This commit is contained in:
hyb1996
2017-04-30 18:20:59 +08:00
parent 5a0095f70d
commit 37b5108637
51 changed files with 569 additions and 146 deletions

View File

@@ -33,6 +33,7 @@ dependencies {
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.github.hyb1996:node-android-lib:1.0.14'
compile 'org.greenrobot:eventbus:3.0.0'
compile project(path: ':common')
compile project(path: ':automator')
}

View File

@@ -6,9 +6,14 @@ import android.util.Log;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.engine.JavaScriptEngineManager;
import com.stardust.autojs.engine.ScriptExecuteActivity;
import com.stardust.autojs.runtime.ScriptInterrupptedException;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.lang.ThreadCompat;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.text.DateFormat;
import java.util.Arrays;
@@ -23,6 +28,7 @@ import java.util.Set;
public class ScriptEngineService {
private static final String LOG_TAG = "ScriptEngineService";
private static final EventBus EVENT_BUS = new EventBus();
private static ScriptEngineService instance;
public static ScriptEngineService getInstance() {
@@ -33,27 +39,26 @@ public class ScriptEngineService {
instance = service;
}
private static final ScriptExecutionListener DEFAULT_LISTENER = new SimpleScriptExecutionListener() {
@Override
public void onStart(JavaScriptEngine engine, ScriptSource source) {
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_START, source.toString()));
}
@Override
public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) {
if (!causedByInterrupted(e)) {
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_EXCEPTION, e.getMessage()));
}
}
};
private final ScriptRuntime mRuntime;
private final Context mContext;
private final Console mConsole;
private final JavaScriptEngineManager mJavaScriptEngineManager;
private final EngineLifecycleObserver mEngineLifecycleObserver = new EngineLifecycleObserver();
private final ScriptExecutionListener mDefaultListener = new SimpleScriptExecutionListener() {
@Override
public void onStart(JavaScriptEngine engine, ScriptSource source) {
mConsole.v(DateFormat.getTimeInstance().format(new Date()) + " " + mContext.getString(R.string.text_start_running) + " " + source);
}
@Override
public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) {
if (!causedByInterruptedException(e)) {
mRuntime.toast(mContext.getString(R.string.text_error) + ": " + e.getMessage());
mConsole.e(e.getMessage());
}
}
};
ScriptEngineService(ScriptEngineServiceBuilder builder) {
mRuntime = builder.mRuntime;
@@ -61,6 +66,7 @@ public class ScriptEngineService {
mJavaScriptEngineManager = builder.mJavaScriptEngineManager;
mConsole = builder.mConsole;
mJavaScriptEngineManager.setEngineLifecycleCallback(mEngineLifecycleObserver);
EVENT_BUS.register(this);
}
public ScriptRuntime getRuntime() {
@@ -72,12 +78,12 @@ public class ScriptEngineService {
}
public ScriptExecutionListener getDefaultListener() {
return mDefaultListener;
return DEFAULT_LISTENER;
}
public JavaScriptEngine createScriptEngine() {
JavaScriptEngine engine = mJavaScriptEngineManager.createEngine();
Log.i(LOG_TAG, Arrays.toString(Thread.currentThread().getStackTrace()));
Log.d(LOG_TAG, Arrays.toString(Thread.currentThread().getStackTrace()));
return engine;
}
@@ -89,18 +95,12 @@ public class ScriptEngineService {
mEngineLifecycleObserver.unregisterCallback(engineLifecycleCallback);
}
public static boolean causedByInterruptedException(Throwable e) {
while (e != null) {
if (e instanceof InterruptedException) {
return true;
}
e = e.getCause();
}
return false;
public static boolean causedByInterrupted(Throwable e) {
return e.getCause() instanceof ScriptInterrupptedException;
}
public ScriptExecution execute(ScriptExecutionTask task) {
ScriptExecutionListener listener = task.getExecutionListenerOrDefault(mDefaultListener);
ScriptExecutionListener listener = task.getExecutionListenerOrDefault(DEFAULT_LISTENER);
ScriptSource source = task.getSource();
int mode = source.getExecutionMode();
if ((mode & ScriptSource.EXECUTION_MODE_UI) != 0) {
@@ -109,7 +109,7 @@ public class ScriptEngineService {
} else {
RunnableScriptExecution scriptExecution = new RunnableScriptExecution(source, listener, task.getConfig());
if (task.getConfig().runInNewThread) {
new Thread(scriptExecution).start();
new ThreadCompat(scriptExecution).start();
} else {
scriptExecution.run();
}
@@ -126,7 +126,17 @@ public class ScriptEngineService {
}
public ScriptExecution execute(ScriptSource source) {
return execute(source, mDefaultListener, ExecutionConfig.getDefault());
return execute(source, DEFAULT_LISTENER, ExecutionConfig.getDefault());
}
@Subscribe
public void onScriptExecution(ScriptExecutionEvent event) {
if (event.getCode() == ScriptExecutionEvent.ON_START) {
mConsole.v(DateFormat.getTimeInstance().format(new Date()) + " " + mContext.getString(R.string.text_start_running) + " " + event.getMessage());
} else if (event.getCode() == ScriptExecutionEvent.ON_EXCEPTION) {
mRuntime.toast(mContext.getString(R.string.text_error) + ": " + event.getMessage());
mConsole.e(event.getMessage());
}
}
public int stopAll() {
@@ -209,4 +219,28 @@ public class ScriptEngineService {
}
}
}
private static class ScriptExecutionEvent {
static final int ON_START = "Eating...".hashCode();
static final int ON_SUCCESS = "I...lov...".hashCode();
static final int ON_EXCEPTION = "...Sorry...I should not have said it...".hashCode();
private final int mCode;
private final String mMessage;
ScriptExecutionEvent(int code, String message) {
mCode = code;
mMessage = message;
}
public int getCode() {
return mCode;
}
public String getMessage() {
return mMessage;
}
}
}

View File

@@ -1,5 +1,7 @@
package com.stardust.autojs;
import android.util.Log;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.ScriptSource;
@@ -12,6 +14,8 @@ import java.io.Serializable;
public class ScriptExecutionTask implements Serializable {
private static final String TAG = "ScriptExecutionTask";
private ScriptSource mScriptSource;
private ScriptExecutionListener mExecutionListener;
private ExecutionConfig mExecutionConfig;
@@ -43,8 +47,10 @@ public class ScriptExecutionTask implements Serializable {
engine.setTag("script", mScriptSource);
mExecutionListener.onSuccess(engine, mScriptSource, engine.execute(mScriptSource));
} catch (Exception e) {
e.printStackTrace();
mExecutionListener.onException(engine, mScriptSource, e);
} finally {
Log.d(TAG, "Engine destroy");
engine.destroy();
}
}

View File

@@ -5,6 +5,7 @@ import android.util.Log;
import com.stardust.autojs.rhino_android.AndroidContextFactory;
import com.stardust.autojs.rhino_android.RhinoAndroidHelper;
import com.stardust.autojs.runtime.ScriptInterrupptedException;
import com.stardust.autojs.runtime.ScriptStopException;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
@@ -59,6 +60,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
@Override
public void forceStop() {
Log.d(LOG_TAG, "forceStop: interrupt Thread: " + mThread);
mThread.interrupt();
}
@@ -68,6 +70,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
@Override
public synchronized void destroy() {
Log.d(LOG_TAG, "on destroy");
Context.exit();
// TODO: 2017/4/6 XXX :在这里回收内存池并不好
final AccessibilityNodeInfoAllocator allocator = (AccessibilityNodeInfoAllocator) getTag("allocator");
@@ -138,7 +141,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
protected void observeInstructionCount(Context cx, int instructionCount) {
if (Thread.currentThread().isInterrupted()) {
Context.exit();
throw new ScriptStopException(new InterruptedException());
throw new ScriptInterrupptedException();
}
}

View File

@@ -1,6 +1,7 @@
package com.stardust.autojs.rhino_android;
import com.stardust.autojs.runtime.ScriptInterrupptedException;
import com.stardust.autojs.runtime.ScriptStopException;
import org.mozilla.javascript.Context;
@@ -39,7 +40,7 @@ public class AndroidContextFactory extends ContextFactory {
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
if (Thread.currentThread().isInterrupted()) {
throw new ScriptStopException(new InterruptedException());
throw new ScriptInterrupptedException();
}
}

View File

@@ -0,0 +1,10 @@
package com.stardust.autojs.runtime;
/**
* Created by Stardust on 2017/4/30.
*/
public class ScriptInterrupptedException extends ScriptStopException {
}

View File

@@ -78,7 +78,7 @@ public class ScriptRuntime {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new ScriptStopException(e);
throw new ScriptInterrupptedException();
}
}
@@ -142,10 +142,6 @@ public class ScriptRuntime {
Thread.interrupted();
}
public void stoppedByInterrupted(InterruptedException e) {
throw new ScriptStopException(e);
}
public void ensureAccessibilityServiceEnabled() {
mAccessibilityBridge.ensureServiceEnabled();
}

View File

@@ -10,6 +10,7 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.stardust.autojs.runtime.ScriptInterrupptedException;
import com.stardust.autojs.runtime.ScriptStopException;
import org.mozilla.javascript.Context;
@@ -107,7 +108,7 @@ public class InjectableWebClient extends WebViewClient {
try {
ScriptBridge.this.wait();
} catch (InterruptedException e) {
throw new ScriptStopException(e);
throw new ScriptInterrupptedException();
}
}
return result.toString();
@@ -131,7 +132,7 @@ public class InjectableWebClient extends WebViewClient {
try {
this.wait();
} catch (InterruptedException e) {
throw new ScriptStopException(e);
throw new ScriptInterrupptedException();
}
}
return result;

View File

@@ -8,6 +8,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import com.stardust.autojs.runtime.AccessibilityBridge;
import com.stardust.autojs.runtime.JavascriptInterface;
import com.stardust.autojs.runtime.ScriptInterrupptedException;
import com.stardust.autojs.runtime.ScriptStopException;
import com.stardust.automator.AccessibilityEventCommandHost;
import com.stardust.automator.ActionArgument;
@@ -118,7 +119,7 @@ public class UiSelector extends UiGlobalSelector {
do {
if (Thread.currentThread().isInterrupted()) {
Log.d(TAG, "Thread isInterrupted");
throw new ScriptStopException(new InterruptedException());
throw new ScriptInterrupptedException();
}
uiObjectCollection = find();
} while (uiObjectCollection == null || uiObjectCollection.size() == 0);

View File

@@ -189,7 +189,7 @@ public class SimpleActionAutomator {
private boolean performAction(SimpleAction simpleAction) {
ensureAccessibilityServiceEnabled();
if (AutomatorConfig.isUnintendedGuardEnabled() && isRunningPackageSelf()) {
Log.i(TAG, "performAction: running package is self. return false");
Log.d(TAG, "performAction: running package is self. return false");
return false;
}
AccessibilityService service = mAccessibilityBridge.getService();
@@ -200,7 +200,7 @@ public class SimpleActionAutomator {
return false;
AccessibilityNodeInfoAllocator allocator = new AccessibilityNodeInfoAllocator();
simpleAction.setAllocator(allocator);
Log.i("Automator", "performAction: " + simpleAction + " root = " + root);
Log.v(TAG, "performAction: " + simpleAction + " root = " + root);
boolean result = simpleAction.perform(root);
allocator.recycleAll();
return result;