Add floating console support

This commit is contained in:
hyb1996
2017-05-03 01:20:29 +08:00
parent 68706fbd98
commit 7473d7c6a5
60 changed files with 1072 additions and 561 deletions

View File

@@ -1,37 +0,0 @@
package com.stardust.autojs;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
/**
* Created by Stardust on 2017/5/1.
*/
public class RunnableScriptExecution extends ScriptExecution.AbstarctScriptExecution implements ScriptExecution, Runnable {
private JavaScriptEngine mJavaScriptEngine;
private ScriptRuntime mScriptRuntime;
private ScriptEngineService mScriptEngineService;
public RunnableScriptExecution(ScriptEngineService service, ScriptExecutionTask task) {
super(task);
mScriptEngineService = service;
}
@Override
public void run() {
mJavaScriptEngine = mScriptEngineService.createScriptEngine();
mScriptRuntime = mScriptEngineService.createScriptRuntime();
mScriptExecutionTask.execute(mScriptRuntime, mJavaScriptEngine);
}
@Override
public JavaScriptEngine getEngine() {
return mJavaScriptEngine;
}
@Override
public ScriptRuntime getRuntime() {
return mScriptRuntime;
}
}

View File

@@ -6,12 +6,19 @@ 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.execution.ExecutionConfig;
import com.stardust.autojs.execution.RunnableScriptExecution;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.ScriptExecutionObserver;
import com.stardust.autojs.execution.ScriptExecutionTask;
import com.stardust.autojs.execution.SimpleScriptExecutionListener;
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 com.stardust.util.Supplier;
import com.stardust.util.UiHandler;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -21,7 +28,10 @@ import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.microedition.khronos.opengles.GL;
import static com.stardust.autojs.runtime.ScriptInterruptedException.causedByInterrupted;
/**
* Created by Stardust on 2017/1/23.
@@ -31,15 +41,18 @@ public class ScriptEngineService {
private static final String LOG_TAG = "ScriptEngineService";
private static final EventBus EVENT_BUS = new EventBus();
private static final ScriptExecutionListener DEFAULT_LISTENER = new SimpleScriptExecutionListener() {
private static final ScriptExecutionListener GLOBAL_LISTENER = new SimpleScriptExecutionListener() {
@Override
public void onStart(JavaScriptEngine engine, ScriptSource source) {
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_START, source.toString()));
public void onStart(ScriptExecution execution) {
execution.getRuntime().console.setTitle(execution.getSource().getName());
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_START, execution.getSource().toString()));
}
@Override
public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) {
public void onException(ScriptExecution execution, Exception e) {
e.printStackTrace();
if (!causedByInterrupted(e)) {
execution.getRuntime().console.error(e.getMessage());
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_EXCEPTION, e.getMessage()));
}
}
@@ -48,19 +61,20 @@ public class ScriptEngineService {
private final Supplier<ScriptRuntime> mRuntimeSupplier;
private final Context mContext;
private ScriptRuntime mGlobalScriptRuntime;
private UiHandler mUiHandler;
private final Console mGlobalConsole;
private final JavaScriptEngineManager mJavaScriptEngineManager;
private final EngineLifecycleObserver mEngineLifecycleObserver = new EngineLifecycleObserver();
private ScriptExecutionListener mDefaultScriptExecutionListener = DEFAULT_LISTENER;
private ScriptExecutionObserver mScriptExecutionObserver = new ScriptExecutionObserver();
ScriptEngineService(ScriptEngineServiceBuilder builder) {
mRuntimeSupplier = builder.mRuntimeSupplier;
mContext = builder.mContext;
mUiHandler = builder.mUiHandler;
mContext = mUiHandler.getContext();
mJavaScriptEngineManager = builder.mJavaScriptEngineManager;
mGlobalScriptRuntime = mRuntimeSupplier.get();
mGlobalConsole = mGlobalScriptRuntime.console;
mGlobalConsole = builder.mGlobalConsole;
mJavaScriptEngineManager.setEngineLifecycleCallback(mEngineLifecycleObserver);
mScriptExecutionObserver.registerScriptExecutionListener(GLOBAL_LISTENER);
EVENT_BUS.register(this);
}
@@ -68,17 +82,8 @@ public class ScriptEngineService {
return mGlobalConsole;
}
public ScriptExecutionListener getDefaultScriptExecutionListener() {
return mDefaultScriptExecutionListener;
}
public void setDefaultScriptExecutionListener(ScriptExecutionListener defaultScriptExecutionListener) {
mDefaultScriptExecutionListener = defaultScriptExecutionListener;
}
public JavaScriptEngine createScriptEngine() {
JavaScriptEngine engine = mJavaScriptEngineManager.createEngine();
Log.d(LOG_TAG, Arrays.toString(Thread.currentThread().getStackTrace()));
return engine;
}
@@ -94,12 +99,20 @@ public class ScriptEngineService {
mEngineLifecycleObserver.unregisterCallback(engineLifecycleCallback);
}
public static boolean causedByInterrupted(Throwable e) {
return e instanceof ScriptInterrupptedException || e.getCause() instanceof ScriptInterrupptedException;
public boolean registerGlobalScriptExecutionListener(ScriptExecutionListener listener) {
return mScriptExecutionObserver.registerScriptExecutionListener(listener);
}
public boolean unregisterGlobalScriptExecutionListener(ScriptExecutionListener listener) {
return mScriptExecutionObserver.removeScriptExecutionListener(listener);
}
public ScriptExecution execute(ScriptExecutionTask task) {
task.setDefaultListenerIfNeeded(mDefaultScriptExecutionListener);
if (task.getListener() != null) {
task.setExecutionListener(new ScriptExecutionObserver.Wrapper(mScriptExecutionObserver, task.getListener()));
} else {
task.setExecutionListener(mScriptExecutionObserver);
}
if (isUiMode(task)) {
return ScriptExecuteActivity.execute(mContext, this, task);
} else {
@@ -128,7 +141,7 @@ public class ScriptEngineService {
}
public ScriptExecution execute(ScriptSource source) {
return execute(source, mDefaultScriptExecutionListener, ExecutionConfig.getDefault());
return execute(source, null, ExecutionConfig.getDefault());
}
@Subscribe
@@ -136,7 +149,7 @@ public class ScriptEngineService {
if (event.getCode() == ScriptExecutionEvent.ON_START) {
mGlobalConsole.verbose(DateFormat.getTimeInstance().format(new Date()) + " " + mContext.getString(R.string.text_start_running) + " " + event.getMessage());
} else if (event.getCode() == ScriptExecutionEvent.ON_EXCEPTION) {
mGlobalScriptRuntime.toast(mContext.getString(R.string.text_error) + ": " + event.getMessage());
mUiHandler.toast(mContext.getString(R.string.text_error) + ": " + event.getMessage());
mGlobalConsole.error(event.getMessage());
}
}
@@ -149,9 +162,9 @@ public class ScriptEngineService {
public void stopAllAndToast() {
int n = stopAll();
if (n > 0)
mGlobalScriptRuntime.toast(String.format(mContext.getString(R.string.text_already_stop_n_scripts), n));
mUiHandler.toast(String.format(mContext.getString(R.string.text_already_stop_n_scripts), n));
else
mGlobalScriptRuntime.toast(mContext.getString(R.string.text_no_running_script));
mUiHandler.toast(mContext.getString(R.string.text_no_running_script));
}
public String[] getGlobalFunctions() {

View File

@@ -6,6 +6,7 @@ import com.stardust.autojs.engine.JavaScriptEngineManager;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.util.Supplier;
import com.stardust.util.UiHandler;
/**
* Created by Stardust on 2017/4/2.
@@ -14,8 +15,9 @@ import com.stardust.util.Supplier;
public class ScriptEngineServiceBuilder {
Supplier<ScriptRuntime> mRuntimeSupplier;
Context mContext;
JavaScriptEngineManager mJavaScriptEngineManager;
Console mGlobalConsole;
UiHandler mUiHandler;
public ScriptEngineServiceBuilder() {
@@ -26,8 +28,8 @@ public class ScriptEngineServiceBuilder {
return this;
}
public ScriptEngineServiceBuilder context(Context context) {
mContext = context;
public ScriptEngineServiceBuilder uiHandler(UiHandler uiHandler) {
mUiHandler = uiHandler;
return this;
}
@@ -36,6 +38,11 @@ public class ScriptEngineServiceBuilder {
return this;
}
public ScriptEngineServiceBuilder globalConsole(Console console) {
mGlobalConsole = console;
return this;
}
public ScriptEngineService build() {
return new ScriptEngineService(this);
}

View File

@@ -1,19 +0,0 @@
package com.stardust.autojs;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.script.ScriptSource;
import java.io.Serializable;
/**
* Created by Stardust on 2017/4/2.
*/
public interface ScriptExecutionListener extends Serializable {
void onStart(JavaScriptEngine engine, ScriptSource source);
void onSuccess(JavaScriptEngine engine, ScriptSource source, Object result);
void onException(JavaScriptEngine engine, ScriptSource source, Exception e);
}

View File

@@ -1,81 +0,0 @@
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;
import java.io.Serializable;
/**
* Created by Stardust on 2017/4/2.
*/
public class ScriptExecutionTask implements Serializable {
private static final String TAG = "ScriptExecutionTask";
private ScriptSource mScriptSource;
private ScriptExecutionListener mExecutionListener;
private ExecutionConfig mExecutionConfig;
public ScriptExecutionTask(ScriptSource source, ScriptExecutionListener listener, ExecutionConfig config) {
mScriptSource = source;
mExecutionListener = listener;
mExecutionConfig = config;
}
public ScriptSource getSource() {
return mScriptSource;
}
public ScriptExecutionListener getListener() {
return mExecutionListener;
}
public ExecutionConfig getConfig() {
return mExecutionConfig;
}
public void execute(ScriptRuntime runtime, JavaScriptEngine engine) {
try {
prepare(runtime, engine);
doExecution(engine);
} catch (Exception e) {
e.printStackTrace();
mExecutionListener.onException(engine, mScriptSource, e);
} finally {
Log.d(TAG, "Engine destroy");
engine.destroy();
}
}
private void prepare(ScriptRuntime runtime, JavaScriptEngine engine) {
if ((mScriptSource.getExecutionMode() & ScriptSource.EXECUTION_MODE_AUTO) != 0) {
runtime.ensureAccessibilityServiceEnabled();
}
engine.put("__runtime__", runtime);
engine.init();
}
private void doExecution(JavaScriptEngine engine) {
engine.setTag("script", mScriptSource);
mExecutionListener.onStart(engine, mScriptSource);
mExecutionListener.onSuccess(engine, mScriptSource, engine.execute(mScriptSource));
}
public ScriptExecutionListener getExecutionListenerOrDefault(ScriptExecutionListener defaultListener) {
if (mExecutionListener == null)
return defaultListener;
return mExecutionListener;
}
public void setDefaultListenerIfNeeded(ScriptExecutionListener defaultScriptExecutionListener) {
if (mExecutionListener == null) {
mExecutionListener = defaultScriptExecutionListener;
}
}
}

View File

@@ -1,26 +0,0 @@
package com.stardust.autojs;
import com.stardust.autojs.ScriptExecutionListener;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.script.ScriptSource;
/**
* Created by Stardust on 2017/4/2.
*/
public class SimpleScriptExecutionListener implements ScriptExecutionListener {
@Override
public void onStart(JavaScriptEngine engine, ScriptSource source) {
}
@Override
public void onSuccess(JavaScriptEngine engine, ScriptSource source, Object result) {
}
@Override
public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) {
}
}

View File

@@ -114,7 +114,6 @@ public abstract class JavaScriptEngineManager {
for (JavaScriptEngine engine : mEngines) {
engine.forceStop();
}
mEngines.clear();
return n;
}
}

View File

@@ -1,14 +1,11 @@
package com.stardust.autojs.engine;
import android.os.Looper;
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.runtime.ScriptInterruptedException;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
@@ -17,11 +14,9 @@ import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import java.io.File;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Stardust on 2017/4/2.
@@ -31,12 +26,13 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
private static final String LOG_TAG = "RhinoJavaScriptEngine";
private static int contextCount = 0;
private Context mContext;
private Scriptable mScriptable;
private Thread mThread;
private RhinoJavaScriptEngineManager mEngineManager;
private Map<String, Object> mTags = new Hashtable<>();
private boolean mDestroyed = false;
private Map<String, Object> mTags = new ConcurrentHashMap<>();
public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) {
mEngineManager = engineManager;
@@ -69,6 +65,8 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
public synchronized void destroy() {
Log.d(LOG_TAG, "on destroy");
Context.exit();
contextCount--;
Log.d(LOG_TAG, "contextCount = " + contextCount);
mEngineManager.removeEngine(this);
}
@@ -108,8 +106,9 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mEngineManager.getContext().getCacheDir(), "classes")));
}
Context context = new RhinoAndroidHelper(mEngineManager.getContext()).enterContext();
contextCount++;
context.setOptimizationLevel(-1);
context.setLanguageVersion(Context.VERSION_1_7);
context.setLanguageVersion(Context.VERSION_ES6);
return context;
}
@@ -122,8 +121,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
if (Thread.currentThread().isInterrupted()) {
Context.exit();
throw new ScriptInterrupptedException();
throw new ScriptInterruptedException();
}
}

View File

@@ -5,11 +5,10 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.stardust.autojs.ExecutionConfig;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.ScriptExecution;
import com.stardust.autojs.ScriptExecutionListener;
import com.stardust.autojs.ScriptExecutionTask;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.ScriptExecutionTask;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.ScriptSource;
@@ -50,14 +49,14 @@ public class ScriptExecuteActivity extends Activity {
prepare();
doExecution();
} catch (Exception e) {
mExecutionListener.onException(mJavaScriptEngine, mScriptSource, e);
mExecutionListener.onException(execution, e);
super.finish();
}
}
private void doExecution() {
mJavaScriptEngine.setTag("script", mScriptSource);
mExecutionListener.onStart(mJavaScriptEngine, mScriptSource);
mExecutionListener.onStart(execution);
mResult = mJavaScriptEngine.execute(mScriptSource);
}
@@ -69,7 +68,7 @@ public class ScriptExecuteActivity extends Activity {
@Override
public void finish() {
mExecutionListener.onSuccess(mJavaScriptEngine, mScriptSource, mResult);
mExecutionListener.onSuccess(execution, mResult);
super.finish();
}
@@ -81,7 +80,7 @@ public class ScriptExecuteActivity extends Activity {
execution = null;
}
private static class ActivityScriptExecution extends ScriptExecution.AbstarctScriptExecution {
private static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution {
private JavaScriptEngine mJavaScriptEngine;
private ScriptRuntime mScriptRuntime;

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs;
package com.stardust.autojs.execution;
import java.io.Serializable;

View File

@@ -0,0 +1,69 @@
package com.stardust.autojs.execution;
import android.util.Log;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.ScriptSource;
/**
* Created by Stardust on 2017/5/1.
*/
public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecution implements ScriptExecution, Runnable {
private static final String TAG = "RunnableScriptExecution";
private JavaScriptEngine mJavaScriptEngine;
private ScriptRuntime mScriptRuntime;
private ScriptEngineService mScriptEngineService;
public RunnableScriptExecution(ScriptEngineService service, ScriptExecutionTask task) {
super(task);
mScriptEngineService = service;
}
@Override
public void run() {
mJavaScriptEngine = mScriptEngineService.createScriptEngine();
mScriptRuntime = mScriptEngineService.createScriptRuntime();
execute(mScriptRuntime, mJavaScriptEngine);
}
private void execute(ScriptRuntime runtime, JavaScriptEngine engine) {
try {
prepare(runtime, engine);
doExecution(engine);
} catch (Exception e) {
e.printStackTrace();
getListener().onException(this, e);
} finally {
Log.d(TAG, "Engine destroy");
engine.destroy();
}
}
private void prepare(ScriptRuntime runtime, JavaScriptEngine engine) {
if ((getSource().getExecutionMode() & ScriptSource.EXECUTION_MODE_AUTO) != 0) {
runtime.ensureAccessibilityServiceEnabled();
}
engine.put("__runtime__", runtime);
engine.init();
}
private void doExecution(JavaScriptEngine engine) {
engine.setTag("script", getSource());
getListener().onStart(this);
getListener().onSuccess(this, engine.execute(getSource()));
}
@Override
public JavaScriptEngine getEngine() {
return mJavaScriptEngine;
}
@Override
public ScriptRuntime getRuntime() {
return mScriptRuntime;
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs;
package com.stardust.autojs.execution;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
@@ -20,11 +20,11 @@ public interface ScriptExecution {
ExecutionConfig getConfig();
abstract class AbstarctScriptExecution implements ScriptExecution {
abstract class AbstractScriptExecution implements ScriptExecution {
protected ScriptExecutionTask mScriptExecutionTask;
public AbstarctScriptExecution(ScriptExecutionTask task) {
public AbstractScriptExecution(ScriptExecutionTask task) {
mScriptExecutionTask = task;
}

View File

@@ -0,0 +1,16 @@
package com.stardust.autojs.execution;
import java.io.Serializable;
/**
* Created by Stardust on 2017/4/2.
*/
public interface ScriptExecutionListener extends Serializable {
void onStart(ScriptExecution execution);
void onSuccess(ScriptExecution execution, Object result);
void onException(ScriptExecution execution, Exception e);
}

View File

@@ -0,0 +1,70 @@
package com.stardust.autojs.execution;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Created by Stardust on 2017/5/3.
*/
public class ScriptExecutionObserver implements ScriptExecutionListener {
private CopyOnWriteArraySet<ScriptExecutionListener> mScriptExecutionListeners = new CopyOnWriteArraySet<>();
@Override
public void onStart(ScriptExecution execution) {
for (ScriptExecutionListener listener : mScriptExecutionListeners) {
listener.onStart(execution);
}
}
@Override
public void onSuccess(ScriptExecution execution, Object result) {
for (ScriptExecutionListener listener : mScriptExecutionListeners) {
listener.onSuccess(execution, result);
}
}
@Override
public void onException(ScriptExecution execution, Exception e) {
for (ScriptExecutionListener listener : mScriptExecutionListeners) {
listener.onException(execution, e);
}
}
public boolean registerScriptExecutionListener(ScriptExecutionListener listener) {
return mScriptExecutionListeners.add(listener);
}
public boolean removeScriptExecutionListener(ScriptExecutionListener listener) {
return mScriptExecutionListeners.remove(listener);
}
public static class Wrapper implements ScriptExecutionListener {
private final ScriptExecutionObserver mScriptExecutionObserver;
private final ScriptExecutionListener mScriptExecutionListener;
public Wrapper(ScriptExecutionObserver scriptExecutionObserver, ScriptExecutionListener scriptExecutionListener) {
mScriptExecutionObserver = scriptExecutionObserver;
mScriptExecutionListener = scriptExecutionListener;
}
@Override
public void onStart(ScriptExecution execution) {
mScriptExecutionListener.onStart(execution);
mScriptExecutionObserver.onStart(execution);
}
@Override
public void onSuccess(ScriptExecution execution, Object result) {
mScriptExecutionListener.onSuccess(execution, result);
mScriptExecutionObserver.onSuccess(execution, result);
}
@Override
public void onException(ScriptExecution execution, Exception e) {
mScriptExecutionListener.onException(execution, e);
mScriptExecutionObserver.onException(execution, e);
}
}
}

View File

@@ -0,0 +1,38 @@
package com.stardust.autojs.execution;
import com.stardust.autojs.script.ScriptSource;
import java.io.Serializable;
/**
* Created by Stardust on 2017/4/2.
*/
public class ScriptExecutionTask implements Serializable {
private ScriptSource mScriptSource;
private ScriptExecutionListener mExecutionListener;
private ExecutionConfig mExecutionConfig;
public ScriptExecutionTask(ScriptSource source, ScriptExecutionListener listener, ExecutionConfig config) {
mScriptSource = source;
mExecutionListener = listener;
mExecutionConfig = config;
}
public ScriptSource getSource() {
return mScriptSource;
}
public ScriptExecutionListener getListener() {
return mExecutionListener;
}
public ExecutionConfig getConfig() {
return mExecutionConfig;
}
public void setExecutionListener(ScriptExecutionListener executionListener) {
mExecutionListener = executionListener;
}
}

View File

@@ -0,0 +1,23 @@
package com.stardust.autojs.execution;
/**
* Created by Stardust on 2017/4/2.
*/
public class SimpleScriptExecutionListener implements ScriptExecutionListener {
@Override
public void onStart(ScriptExecution execution) {
}
@Override
public void onSuccess(ScriptExecution execution, Object result) {
}
@Override
public void onException(ScriptExecution execution, Exception e) {
}
}

View File

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

View File

@@ -2,7 +2,6 @@ package com.stardust.autojs.runtime;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;
import com.stardust.autojs.runtime.api.Console;
@@ -12,10 +11,8 @@ import com.stardust.autojs.runtime.api.Console;
public abstract class AbstractConsole implements Console {
protected abstract void log(int level, CharSequence charSequence);
public void println(int level, @Nullable Object data, Object... options) {
log(level, format(data, options));
public void printf(int level, @Nullable Object data, Object... options) {
println(level, format(data, options));
}
public CharSequence format(@Nullable Object data, Object... options) {
@@ -29,33 +26,33 @@ public abstract class AbstractConsole implements Console {
@Override
public void verbose(@Nullable Object data, Object... options) {
println(Log.VERBOSE, data, options);
printf(Log.VERBOSE, data, options);
}
@Override
public void log(@Nullable Object data, Object... options) {
println(Log.DEBUG, data, options);
printf(Log.DEBUG, data, options);
}
@Override
public void info(@Nullable Object data, Object... options) {
println(Log.INFO, data, options);
printf(Log.INFO, data, options);
}
@Override
public void warn(@Nullable Object data, Object... options) {
println(Log.WARN, data, options);
printf(Log.WARN, data, options);
}
@Override
public void error(@Nullable Object data, Object... options) {
println(Log.ERROR, data, options);
printf(Log.ERROR, data, options);
}
@Override
public void assertTrue(boolean value, @Nullable Object data, Object... options) {
if (!value) {
println(Log.ASSERT, data, options);
printf(Log.ASSERT, data, options);
throw new ScriptStopException(new AssertionError(format(data, options)));
}
}

View File

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

View File

@@ -0,0 +1,13 @@
package com.stardust.autojs.runtime;
/**
* Created by Stardust on 2017/4/30.
*/
public class ScriptInterruptedException extends ScriptStopException {
public static boolean causedByInterrupted(Throwable e) {
return e instanceof ScriptInterruptedException || e.getCause() instanceof ScriptInterruptedException;
}
}

View File

@@ -1,9 +1,6 @@
package com.stardust.autojs.runtime;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.widget.Toast;
import com.stardust.autojs.R;
import com.stardust.autojs.engine.JavaScriptEngine;
@@ -18,8 +15,8 @@ import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ClipboardUtil;
import com.stardust.util.SdkVersionUtil;
import com.stardust.util.Shell;
import com.stardust.util.UiHandler;
import com.stardust.view.accessibility.AccessibilityInfoProvider;
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
import org.mozilla.javascript.ContextFactory;
@@ -35,8 +32,7 @@ public class ScriptRuntime {
private static final String TAG = "ScriptRuntime";
private Handler mUIHandler;
private Context mContext;
private UiHandler mUiHandler;
private AccessibilityBridge mAccessibilityBridge;
@JavascriptField
@@ -53,11 +49,10 @@ public class ScriptRuntime {
private AbstractShell mRootShell;
public ScriptRuntime(Context context, Handler uiHandler, Console console, AccessibilityBridge accessibilityBridge) {
mContext = context;
public ScriptRuntime(UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge) {
mAccessibilityBridge = accessibilityBridge;
mUIHandler = uiHandler;
app = new AppUtils(context);
mUiHandler = uiHandler;
app = new AppUtils(uiHandler.getContext());
info = accessibilityBridge.getInfoProvider();
this.console = console;
automator = new SimpleActionAutomator(accessibilityBridge, this);
@@ -65,12 +60,7 @@ public class ScriptRuntime {
@JavascriptInterface
public void toast(final String text) {
mUIHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
}
});
mUiHandler.toast(text);
}
@JavascriptInterface
@@ -78,16 +68,16 @@ public class ScriptRuntime {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new ScriptInterrupptedException();
throw new ScriptInterruptedException();
}
}
@JavascriptInterface
public void setClip(final String text) {
mUIHandler.post(new Runnable() {
mUiHandler.post(new Runnable() {
@Override
public void run() {
ClipboardUtil.setClip(mContext, text);
ClipboardUtil.setClip(mUiHandler.getContext(), text);
}
});
}
@@ -119,7 +109,7 @@ public class ScriptRuntime {
@JavascriptInterface
public void requiresApi(int i) {
if (Build.VERSION.SDK_INT < i) {
throw new ScriptStopException(mContext.getString(R.string.text_requires_sdk_version_to_run_the_script) + SdkVersionUtil.sdkIntToString(i));
throw new ScriptStopException(mUiHandler.getContext().getString(R.string.text_requires_sdk_version_to_run_the_script) + SdkVersionUtil.sdkIntToString(i));
}
}

View File

@@ -36,4 +36,8 @@ public interface Console {
@JavascriptInterface
void hide();
void println(int level, CharSequence charSequence);
void setTitle(CharSequence title);
}

View File

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

View File

@@ -8,7 +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.ScriptInterruptedException;
import com.stardust.automator.AccessibilityEventCommandHost;
import com.stardust.automator.ActionArgument;
import com.stardust.automator.UiGlobalSelector;
@@ -118,7 +118,7 @@ public class UiSelector extends UiGlobalSelector {
do {
if (Thread.currentThread().isInterrupted()) {
Log.d(TAG, "Thread isInterrupted");
throw new ScriptInterrupptedException();
throw new ScriptInterruptedException();
}
uiObjectCollection = find();
} while (uiObjectCollection == null || uiObjectCollection.size() == 0);

View File

@@ -29,8 +29,8 @@ public class JsBeautifier {
private Executor mExecutor = Executors.newSingleThreadExecutor();
private Context mContext;
private org.mozilla.javascript.Context mScriptContext;
private Function mJsBeautifyFunction;
private org.mozilla.javascript.Context mScriptContext;
private Scriptable mScriptable;
private final String mBeautifyJsPath;
@@ -45,16 +45,33 @@ public class JsBeautifier {
public void run() {
try {
prepareIfNeeded();
enterContext();
Object beautifiedCode = mJsBeautifyFunction.call(mScriptContext, mScriptable, mScriptable, new Object[]{code});
callback.onSuccess(beautifiedCode.toString());
} catch (Exception e) {
callback.onException(e);
} finally {
exitContext();
}
}
});
}
private void exitContext() {
if (mScriptContext != null) {
org.mozilla.javascript.Context.exit();
mScriptContext = null;
}
}
private void enterContext() {
if (mScriptContext == null) {
mScriptContext = org.mozilla.javascript.Context.enter();
mScriptContext.setOptimizationLevel(-1);
}
}
public void prepare() {
mExecutor.execute(new Runnable() {
@Override
@@ -71,19 +88,20 @@ public class JsBeautifier {
private void prepareIfNeeded() {
if (mScriptContext != null)
if (mJsBeautifyFunction != null)
return;
RhinoAndroidHelper helper = new RhinoAndroidHelper(mContext);
mScriptContext = helper.enterContext();
compile();
}
private void compile() {
try {
enterContext();
InputStream is = mContext.getAssets().open(mBeautifyJsPath);
mScriptable = mScriptContext.initSafeStandardObjects();
if (mScriptable == null)
mScriptable = mScriptContext.initSafeStandardObjects();
mJsBeautifyFunction = mScriptContext.compileFunction(mScriptable, PFile.read(is), "<js_beautify>", 1, null);
} catch (IOException e) {
exitContext();
throw new UncheckedIOException(e);
}
}