refactor(module autojs): to support .auto record file

This commit is contained in:
hyb1996
2017-08-03 13:06:55 +08:00
parent 6a3392cfe6
commit 2f5573d9c2
58 changed files with 981 additions and 753 deletions

View File

@@ -2,12 +2,12 @@ package com.stardust.autojs;
import android.content.Context;
import com.stardust.autojs.engine.AbstractScriptEngineManager;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.execution.ScriptExecuteActivity;
import com.stardust.autojs.execution.ExecutionConfig;
import com.stardust.autojs.execution.RunnableScriptExecution;
import com.stardust.autojs.execution.ScriptExecuteActivity;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.ScriptExecutionObserver;
@@ -15,9 +15,9 @@ 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.JavaScriptSource;
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;
@@ -44,7 +44,10 @@ public class ScriptEngineService {
private static final ScriptExecutionListener GLOBAL_LISTENER = new SimpleScriptExecutionListener() {
@Override
public void onStart(ScriptExecution execution) {
execution.getRuntime().console.setTitle(execution.getSource().getName());
if (execution.getEngine() instanceof JavaScriptEngine) {
((JavaScriptEngine) execution.getEngine()).getRuntime()
.console.setTitle(execution.getSource().getName());
}
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_START, execution.getSource().toString()));
}
@@ -54,7 +57,9 @@ public class ScriptEngineService {
}
private void onFinish(ScriptExecution execution) {
execution.getRuntime().onExit();
if (execution.getEngine() instanceof JavaScriptEngine) {
((JavaScriptEngine) execution.getEngine()).getRuntime().onExit();
}
}
@Override
@@ -62,14 +67,16 @@ public class ScriptEngineService {
e.printStackTrace();
onFinish(execution);
if (!causedByInterrupted(e)) {
execution.getRuntime().console.error(getScriptTrace(e));
if (execution.getEngine() instanceof JavaScriptEngine) {
((JavaScriptEngine) execution.getEngine()).getRuntime()
.console.error(getScriptTrace(e));
}
EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_EXCEPTION, e.getMessage()));
}
}
};
private final Supplier<? extends ScriptRuntime> mRuntimeSupplier;
private final Context mContext;
private UiHandler mUiHandler;
private final Console mGlobalConsole;
@@ -78,7 +85,6 @@ public class ScriptEngineService {
private ScriptExecutionObserver mScriptExecutionObserver = new ScriptExecutionObserver();
ScriptEngineService(ScriptEngineServiceBuilder builder) {
mRuntimeSupplier = builder.mRuntimeSupplier;
mUiHandler = builder.mUiHandler;
mContext = mUiHandler.getContext();
mScriptEngineManager = builder.mScriptEngineManager;
@@ -94,20 +100,11 @@ public class ScriptEngineService {
return mGlobalConsole;
}
public ScriptEngine createScriptEngine() {
ScriptEngine engine = mScriptEngineManager.createEngine();
return engine;
}
public ScriptRuntime createScriptRuntime() {
return mRuntimeSupplier.get();
}
public void registerEngineLifecycleCallback(AbstractScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) {
public void registerEngineLifecycleCallback(ScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) {
mEngineLifecycleObserver.registerCallback(engineLifecycleCallback);
}
public void unregisterEngineLifecycleCallback(AbstractScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) {
public void unregisterEngineLifecycleCallback(ScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) {
mEngineLifecycleObserver.unregisterCallback(engineLifecycleCallback);
}
@@ -125,23 +122,23 @@ public class ScriptEngineService {
} else {
task.setExecutionListener(mScriptExecutionObserver);
}
if (isUiMode(task)) {
return ScriptExecuteActivity.execute(mContext, this, task);
ScriptSource source = task.getSource();
if (source instanceof JavaScriptSource && isUiMode((JavaScriptSource) source)) {
return ScriptExecuteActivity.execute(mContext, mScriptEngineManager, task);
} else {
RunnableScriptExecution scriptExecution = new RunnableScriptExecution(this, task);
RunnableScriptExecution r = new RunnableScriptExecution(mScriptEngineManager, task);
if (task.getConfig().runInNewThread) {
new ThreadCompat(scriptExecution).start();
new ThreadCompat(r).start();
} else {
scriptExecution.run();
r.run();
}
return scriptExecution;
return r;
}
}
private boolean isUiMode(ScriptExecutionTask task) {
ScriptSource source = task.getSource();
private boolean isUiMode(JavaScriptSource source) {
int mode = source.getExecutionMode();
return (mode & ScriptSource.EXECUTION_MODE_UI) != 0;
return (mode & JavaScriptSource.EXECUTION_MODE_UI) != 0;
}
public ScriptExecution execute(ScriptSource source, ScriptExecutionListener listener, ExecutionConfig config) {
@@ -186,14 +183,14 @@ public class ScriptEngineService {
return mScriptEngineManager.getEngines();
}
private static class EngineLifecycleObserver implements AbstractScriptEngineManager.EngineLifecycleCallback {
private static class EngineLifecycleObserver implements ScriptEngineManager.EngineLifecycleCallback {
private final Set<AbstractScriptEngineManager.EngineLifecycleCallback> mEngineLifecycleCallbacks = new LinkedHashSet<>();
private final Set<ScriptEngineManager.EngineLifecycleCallback> mEngineLifecycleCallbacks = new LinkedHashSet<>();
@Override
public void onEngineCreate(ScriptEngine engine) {
synchronized (mEngineLifecycleCallbacks) {
for (AbstractScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) {
for (ScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) {
callback.onEngineCreate(engine);
}
}
@@ -202,20 +199,20 @@ public class ScriptEngineService {
@Override
public void onEngineRemove(ScriptEngine engine) {
synchronized (mEngineLifecycleCallbacks) {
for (AbstractScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) {
for (ScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) {
callback.onEngineRemove(engine);
}
}
}
void registerCallback(AbstractScriptEngineManager.EngineLifecycleCallback callback) {
void registerCallback(ScriptEngineManager.EngineLifecycleCallback callback) {
synchronized (mEngineLifecycleCallbacks) {
mEngineLifecycleCallbacks.add(callback);
}
}
void unregisterCallback(AbstractScriptEngineManager.EngineLifecycleCallback callback) {
void unregisterCallback(ScriptEngineManager.EngineLifecycleCallback callback) {
synchronized (mEngineLifecycleCallbacks) {
mEngineLifecycleCallbacks.remove(callback);
}

View File

@@ -1,6 +1,5 @@
package com.stardust.autojs;
import com.stardust.autojs.engine.AbstractScriptEngineManager;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.Console;
@@ -13,7 +12,6 @@ import com.stardust.util.UiHandler;
public class ScriptEngineServiceBuilder {
Supplier<? extends ScriptRuntime> mRuntimeSupplier;
ScriptEngineManager mScriptEngineManager;
Console mGlobalConsole;
UiHandler mUiHandler;
@@ -22,11 +20,6 @@ public class ScriptEngineServiceBuilder {
}
public ScriptEngineServiceBuilder runtime(Supplier<? extends ScriptRuntime> runtimeSupplier) {
mRuntimeSupplier = runtimeSupplier;
return this;
}
public ScriptEngineServiceBuilder uiHandler(UiHandler uiHandler) {
mUiHandler = uiHandler;
return this;

View File

@@ -1,86 +0,0 @@
package com.stardust.autojs.engine;
import android.content.Context;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by Stardust on 2017/1/27.
*/
public abstract class AbstractScriptEngineManager implements ScriptEngineManager {
private static final String TAG = "AbstractScriptEngineManager";
private Map<String, Object> mGlobalVariableMap = new HashMap<>();
private final Set<ScriptEngine> mEngines = new HashSet<>();
private EngineLifecycleCallback mEngineLifecycleCallback;
private android.content.Context mAndroidContext;
public AbstractScriptEngineManager(Context androidContext) {
mAndroidContext = androidContext;
}
public ScriptEngine createEngine() {
ScriptEngine engine = createEngineInner();
putProperties(engine);
addEngine(engine);
return engine;
}
private void addEngine(ScriptEngine engine) {
synchronized (mEngines) {
mEngines.add(engine);
if (mEngineLifecycleCallback != null) {
mEngineLifecycleCallback.onEngineCreate(engine);
}
}
}
public void putGlobal(String varName, Object value) {
mGlobalVariableMap.put(varName, value);
}
public void setEngineLifecycleCallback(EngineLifecycleCallback engineLifecycleCallback) {
mEngineLifecycleCallback = engineLifecycleCallback;
}
public Set<ScriptEngine> getEngines() {
return mEngines;
}
protected abstract ScriptEngine createEngineInner();
public android.content.Context getAndroidContext() {
return mAndroidContext;
}
protected void putProperties(ScriptEngine engine) {
for (Map.Entry<String, Object> variable : mGlobalVariableMap.entrySet()) {
engine.put(variable.getKey(), variable.getValue());
}
}
public void removeEngine(ScriptEngine engine) {
synchronized (mEngines) {
if (mEngines.remove(engine) && mEngineLifecycleCallback != null) {
mEngineLifecycleCallback.onEngineRemove(engine);
}
}
}
public int stopAll() {
synchronized (mEngines) {
int n = mEngines.size();
for (ScriptEngine engine : mEngines) {
engine.forceStop();
}
return n;
}
}
}

View File

@@ -0,0 +1,25 @@
package com.stardust.autojs.engine;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.JavaScriptSource;
/**
* Created by Stardust on 2017/8/3.
*/
public abstract class JavaScriptEngine extends ScriptEngine.AbstractScriptEngine<JavaScriptSource> {
private ScriptRuntime mRuntime;
public ScriptRuntime getRuntime() {
return mRuntime;
}
public void setRuntime(ScriptRuntime runtime) {
mRuntime = runtime;
put("__runtime__", runtime);
}
}

View File

@@ -1,10 +1,12 @@
package com.stardust.autojs.engine;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;
import com.stardust.autojs.runtime.api.Loopers;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.ScriptSource;
/**
@@ -16,12 +18,12 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
private Handler mHandler;
private boolean mLooping = false;
public LoopBasedJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) {
super(engineManager);
public LoopBasedJavaScriptEngine(Context context) {
super(context);
}
@Override
public Object execute(final ScriptSource source) {
public Object execute(final JavaScriptSource source) {
Runnable r = new Runnable() {
@Override
public void run() {

View File

@@ -1,14 +1,14 @@
package com.stardust.autojs.engine;
import android.os.Looper;
import android.util.Log;
import com.stardust.autojs.BuildConfig;
import com.stardust.autojs.rhino.AndroidContextFactory;
import com.stardust.autojs.rhino.RhinoAndroidHelper;
import com.stardust.autojs.runtime.ScriptInterruptedException;
import com.stardust.autojs.runtime.api.Events;
import com.stardust.autojs.runtime.api.Timers;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.pio.PFile;
import com.stardust.pio.UncheckedIOException;
import org.mozilla.javascript.Context;
@@ -25,30 +25,26 @@ import java.io.Reader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Stardust on 2017/4/2.
*/
public class RhinoJavaScriptEngine implements ScriptEngine {
public class RhinoJavaScriptEngine extends JavaScriptEngine {
private static final String LOG_TAG = "RhinoJavaScriptEngine";
private static int contextCount = 0;
private static StringScriptSource sInitScript;
private String[] mRequirePath = new String[0];
private Context mContext;
private Scriptable mScriptable;
private Thread mThread;
private RhinoJavaScriptEngineManager mEngineManager;
private Map<String, Object> mTags = new ConcurrentHashMap<>();
private volatile boolean mDestroyed = false;
private android.content.Context mAndroidContext;
public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) {
mEngineManager = engineManager;
mThread = Thread.currentThread();
public RhinoJavaScriptEngine(android.content.Context context) {
mAndroidContext = context;
mContext = createContext();
mScriptable = createScope(mContext);
}
@@ -59,7 +55,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
}
@Override
public Object execute(ScriptSource source) {
public Object execute(JavaScriptSource source) {
Reader reader = source.getNonNullScriptReader();
try {
reader = preprocess(reader);
@@ -79,33 +75,14 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
mThread.interrupt();
}
public RhinoJavaScriptEngineManager getEngineManager() {
return mEngineManager;
}
@Override
public synchronized void destroy() {
super.destroy();
Log.d(LOG_TAG, "on destroy");
Context.exit();
contextCount--;
Log.d(LOG_TAG, "contextCount = " + contextCount);
mEngineManager.removeEngine(this);
mDestroyed = true;
}
@Override
public boolean isDestroyed() {
return mDestroyed;
}
@Override
public synchronized void setTag(String key, Object value) {
mTags.put(key, value);
}
@Override
public synchronized Object getTag(String key) {
return mTags.get(key);
}
public Thread getThread() {
@@ -114,15 +91,25 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
@Override
public void init() {
ScriptableObject.putProperty(mScriptable, "__engine_name__", "rhino");
mThread = Thread.currentThread();
ScriptableObject.putProperty(mScriptable, "__engine__", this);
mRequirePath = (String[]) getTag("__require_path__");
mRequirePath = (String[]) getTag(TAG_PATH);
initRequireBuilder(mContext, mScriptable);
mContext.evaluateString(mScriptable, mEngineManager.getInitScript().getScript(), "<init>", 1, null);
mContext.evaluateString(mScriptable, getInitScript().getScript(), "<init>", 1, null);
}
public void setRequirePath(String... requirePath) {
setTag("__require_path__", requirePath);
private JavaScriptSource getInitScript() {
if (sInitScript == null || BuildConfig.DEBUG)
sInitScript = new StringScriptSource(readInitScript());
return sInitScript;
}
private String readInitScript() {
try {
return PFile.read(mAndroidContext.getAssets().open("javascript_engine_init.js"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
void initRequireBuilder(Context context, Scriptable scope) {
@@ -130,10 +117,10 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
for (String path : mRequirePath) {
list.add(new File(path).toURI());
}
AssetAndUrlModuleSourceProvider provider = new AssetAndUrlModuleSourceProvider(getEngineManager().getAndroidContext(), list);
AssetAndUrlModuleSourceProvider provider = new AssetAndUrlModuleSourceProvider(mAndroidContext, list);
new RequireBuilder()
.setModuleScriptProvider(new SoftCachingModuleScriptProvider(provider))
.setSandboxed(false)
.setSandboxed(true)
.createRequire(context, scope)
.install(scope);
}
@@ -154,9 +141,9 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
protected Context createContext() {
if (!ContextFactory.hasExplicitGlobal()) {
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mEngineManager.getAndroidContext().getCacheDir(), "classes")));
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mAndroidContext.getCacheDir(), "classes")));
}
Context context = new RhinoAndroidHelper(mEngineManager.getAndroidContext()).enterContext();
Context context = new RhinoAndroidHelper(mAndroidContext).enterContext();
contextCount++;
context.setOptimizationLevel(-1);
context.setLanguageVersion(Context.VERSION_ES6);

View File

@@ -1,65 +0,0 @@
package com.stardust.autojs.engine;
import com.stardust.autojs.BuildConfig;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.autojs.script.SequenceScriptSource;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.pio.PFile;
import java.io.IOException;
/**
* Created by Stardust on 2017/3/1.
*/
public class RhinoJavaScriptEngineManager extends AbstractScriptEngineManager {
private String[] mFunctions;
private ScriptSource mCustomInitScript;
private ScriptSource mInitScript;
public RhinoJavaScriptEngineManager(android.content.Context context) {
super(context);
}
protected RhinoJavaScriptEngine createEngineInner() {
RhinoJavaScriptEngine engine = new LoopBasedJavaScriptEngine(this);
return engine;
}
public void setInitScript(String script) {
setInitScriptSource(new StringScriptSource(script));
}
public void setInitScriptSource(ScriptSource initScriptSource) {
if (BuildConfig.DEBUG) {
mCustomInitScript = initScriptSource;
} else {
mInitScript = new SequenceScriptSource("<init>", new StringScriptSource(readInitScript()), initScriptSource);
}
}
private String readInitScript() {
try {
return PFile.read(getAndroidContext().getAssets().open("javascript_engine_init.js"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ScriptSource getInitScript() {
if (mInitScript == null || BuildConfig.DEBUG) {
// 调试时不缓存INIT_SCRIPT否则修改javascript_engine_init.js后不会更新
if (mCustomInitScript != null) {
mInitScript = new SequenceScriptSource("<init>", new StringScriptSource(readInitScript()), mCustomInitScript);
} else {
mInitScript = new StringScriptSource(readInitScript());
}
}
return mInitScript;
}
}

View File

@@ -0,0 +1,101 @@
package com.stardust.autojs.engine;
import android.content.Context;
import android.preference.PreferenceManager;
import android.util.Log;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.ProcessShell;
import com.stardust.autojs.runtime.record.inputevent.InputDevices;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.autojs.script.JavaScriptFileSource;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.pio.PFile;
import java.io.File;
/**
* Created by Stardust on 2017/8/1.
*/
public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoFileSource> {
public static final int VERSION = 1;
private static final String KEY_TOUCH_DEVICE = RootAutomatorEngine.class.getName() + ".touch_device";
private static final String LOG_TAG = "RootAutomatorEngine";
private static int sTouchDevice = -1;
private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator";
private Context mContext;
private String mDeviceNameOrPath;
private Thread mThread;
public RootAutomatorEngine(Context context, String deviceNameOrPath) {
mContext = context;
if (sTouchDevice < 0) {
sTouchDevice = PreferenceManager.getDefaultSharedPreferences(context).getInt(KEY_TOUCH_DEVICE, -1);
}
if (sTouchDevice >= 0) {
mDeviceNameOrPath = "/dev/input/event" + sTouchDevice;
PreferenceManager.getDefaultSharedPreferences(context)
.edit()
.putInt(KEY_TOUCH_DEVICE, sTouchDevice)
.apply();
} else {
mDeviceNameOrPath = deviceNameOrPath;
}
}
public RootAutomatorEngine(Context context) {
this(context, InputDevices.getTouchDeviceName());
}
public AbstractShell.Result execute(String autoFile) {
String executablePath = getExecutablePath(mContext);
AbstractShell.Result r = ProcessShell.execCommand(new String[]{
"chmod 777 " + executablePath,
executablePath + " " + autoFile + " -d " + mDeviceNameOrPath
}, true);
Log.d(LOG_TAG, "exec: " + autoFile + " result:" + r);
return r;
}
private 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();
}
public static void setTouchDevice(int device) {
sTouchDevice = device;
}
public static int getTouchDevice(Context context) {
if (sTouchDevice >= 0)
return sTouchDevice;
return PreferenceManager.getDefaultSharedPreferences(context).getInt(KEY_TOUCH_DEVICE, -1);
}
@Override
public void put(String name, Object value) {
}
@Override
public Object execute(AutoFileSource source) {
return execute(source.getFile().getAbsolutePath());
}
@Override
public void forceStop() {
mThread.interrupt();
}
@Override
public void init() {
mThread = Thread.currentThread();
}
}

View File

@@ -1,13 +1,18 @@
package com.stardust.autojs.engine;
import android.support.annotation.CallSuper;
import com.stardust.autojs.runtime.ScriptException;
import com.stardust.autojs.script.ScriptSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Stardust on 2017/4/2.
* <p>
* <p>
* A ScriptEngine is created by {@link AbstractScriptEngineManager#createEngine()}, and then can be
* A ScriptEngine is created by {@link ScriptEngineManager#createEngine(String)} ()}, and then can be
* used to execute script with {@link ScriptEngine#execute(ScriptSource)} in the **same** thread.
* When the execution finish successfully, the engine should be destroy in the thread that created it.
* <p>
@@ -15,12 +20,15 @@ import com.stardust.autojs.script.ScriptSource;
* It will throw a {@link ScriptException}.
*/
public interface ScriptEngine {
public interface ScriptEngine<S extends ScriptSource> {
String TAG_PATH = "execute_path";
String TAG_SOURCE = "source";
void put(String name, Object value);
Object execute(ScriptSource scriptSource);
Object execute(S scriptSource);
void forceStop();
@@ -32,8 +40,57 @@ public interface ScriptEngine {
Object getTag(String key);
/**
* @hide
*/
void setOnDestroyListener(OnDestroyListener listener);
/**
* @hide
*/
void init();
interface OnDestroyListener {
void onDestroy(ScriptEngine engine);
}
abstract class AbstractScriptEngine<S extends ScriptSource> implements ScriptEngine<S> {
private Map<String, Object> mTags = new ConcurrentHashMap<>();
private OnDestroyListener mOnDestroyListener;
private boolean mDestroyed = false;
@Override
public synchronized void setTag(String key, Object value) {
mTags.put(key, value);
}
@Override
public synchronized Object getTag(String key) {
return mTags.get(key);
}
@Override
public synchronized boolean isDestroyed() {
return mDestroyed;
}
@CallSuper
@Override
public synchronized void destroy() {
mDestroyed = true;
if (mOnDestroyListener != null) {
mOnDestroyListener.onDestroy(this);
}
}
public void setOnDestroyListener(OnDestroyListener onDestroyListener) {
if (mOnDestroyListener != null)
throw new SecurityException("setOnDestroyListener can be called only once");
mOnDestroyListener = onDestroyListener;
}
}
}

View File

@@ -0,0 +1,89 @@
package com.stardust.autojs.engine;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.util.Supplier;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Stardust on 2017/8/2.
*/
public class ScriptEngineFactory {
public static class EngineNotFoundException extends RuntimeException {
public EngineNotFoundException(String s) {
super(s);
}
}
private static ScriptEngineFactory sInstance = new ScriptEngineFactory();
private Map<String, Supplier<ScriptEngine>> mEngines = new HashMap<>();
private Map<String, Object> mGlobalVariableMap = new HashMap<>();
ScriptEngineFactory() {
}
public static ScriptEngineFactory getInstance() {
return sInstance;
}
public void putGlobal(String varName, Object value) {
mGlobalVariableMap.put(varName, value);
}
protected void putProperties(ScriptEngine engine) {
for (Map.Entry<String, Object> variable : mGlobalVariableMap.entrySet()) {
engine.put(variable.getKey(), variable.getValue());
}
}
@Nullable
public ScriptEngine createEngine(String name) {
Supplier<ScriptEngine> s = mEngines.get(name);
if (s == null) {
return null;
}
ScriptEngine engine = s.get();
putProperties(engine);
return engine;
}
@Nullable
public ScriptEngine createEngineOfSource(ScriptSource source) {
return createEngine(source.getEngineName());
}
@NonNull
public ScriptEngine createEngineByNameOrThrow(String name) {
ScriptEngine engine = createEngine(name);
if (engine == null)
throw new EngineNotFoundException("name: " + name);
return engine;
}
@NonNull
public ScriptEngine createEngineOfSourceOrThrow(ScriptSource source) {
ScriptEngine engine = createEngineOfSource(source);
if (engine == null)
throw new EngineNotFoundException("source: " + source.toString());
return engine;
}
public void registerEngine(String name, Supplier<ScriptEngine> supplier) {
mEngines.put(name, supplier);
}
public void unregisterEngine(String name) {
mEngines.remove(name);
}
}

View File

@@ -1,31 +1,140 @@
package com.stardust.autojs.engine;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.util.Supplier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by Stardust on 2017/5/7.
* Created by Stardust on 2017/1/27.
*/
public interface ScriptEngineManager {
public class ScriptEngineManager {
interface EngineLifecycleCallback {
public interface EngineLifecycleCallback {
void onEngineCreate(ScriptEngine engine);
void onEngineRemove(ScriptEngine engine);
}
ScriptEngine createEngine();
private static final String TAG = "ScriptEngineManager";
void putGlobal(String varName, Object value);
private final Set<ScriptEngine> mEngines = new HashSet<>();
private EngineLifecycleCallback mEngineLifecycleCallback;
private Map<String, Supplier<ScriptEngine>> mEngineSuppliers = new HashMap<>();
private Map<String, Object> mGlobalVariableMap = new HashMap<>();
private android.content.Context mAndroidContext;
private ScriptEngine.OnDestroyListener mOnEngineDestroyListener = new ScriptEngine.OnDestroyListener() {
@Override
public void onDestroy(ScriptEngine engine) {
removeEngine(engine);
}
};
void setEngineLifecycleCallback(EngineLifecycleCallback engineLifecycleCallback);
public ScriptEngineManager(Context androidContext) {
mAndroidContext = androidContext;
}
void removeEngine(ScriptEngine engine);
private void addEngine(ScriptEngine engine) {
engine.setOnDestroyListener(mOnEngineDestroyListener);
synchronized (mEngines) {
mEngines.add(engine);
if (mEngineLifecycleCallback != null) {
mEngineLifecycleCallback.onEngineCreate(engine);
}
}
}
Set<ScriptEngine> getEngines();
public void setEngineLifecycleCallback(EngineLifecycleCallback engineLifecycleCallback) {
mEngineLifecycleCallback = engineLifecycleCallback;
}
int stopAll();
public Set<ScriptEngine> getEngines() {
return mEngines;
}
public android.content.Context getAndroidContext() {
return mAndroidContext;
}
public void removeEngine(ScriptEngine engine) {
synchronized (mEngines) {
if (mEngines.remove(engine) && mEngineLifecycleCallback != null) {
mEngineLifecycleCallback.onEngineRemove(engine);
}
}
}
public int stopAll() {
synchronized (mEngines) {
int n = mEngines.size();
for (ScriptEngine engine : mEngines) {
engine.forceStop();
}
return n;
}
}
public void putGlobal(String varName, Object value) {
mGlobalVariableMap.put(varName, value);
}
protected void putProperties(ScriptEngine engine) {
for (Map.Entry<String, Object> variable : mGlobalVariableMap.entrySet()) {
engine.put(variable.getKey(), variable.getValue());
}
}
@Nullable
public ScriptEngine createEngine(String name) {
Supplier<ScriptEngine> s = mEngineSuppliers.get(name);
if (s == null) {
return null;
}
ScriptEngine engine = s.get();
putProperties(engine);
addEngine(engine);
return engine;
}
@Nullable
public ScriptEngine createEngineOfSource(ScriptSource source) {
return createEngine(source.getEngineName());
}
@NonNull
public ScriptEngine createEngineByNameOrThrow(String name) {
ScriptEngine engine = createEngine(name);
if (engine == null)
throw new ScriptEngineFactory.EngineNotFoundException("name: " + name);
return engine;
}
@NonNull
public ScriptEngine createEngineOfSourceOrThrow(ScriptSource source) {
ScriptEngine engine = createEngineOfSource(source);
if (engine == null)
throw new ScriptEngineFactory.EngineNotFoundException("source: " + source.toString());
return engine;
}
public void registerEngine(String name, Supplier<ScriptEngine> supplier) {
mEngineSuppliers.put(name, supplier);
}
public void unregisterEngine(String name) {
mEngineSuppliers.remove(name);
}
}

View File

@@ -1,8 +0,0 @@
package com.stardust.autojs.engine.preprocess;
/**
* Created by Stardust on 2017/8/1.
*/
public class RootAutomatorEngine {
}

View File

@@ -29,7 +29,7 @@ public class ExecutionConfig implements Serializable {
return this;
}
public String[] getRequirePath() {
public String[] getExecutePath() {
return mRequirePath;
}

View File

@@ -1,34 +0,0 @@
package com.stardust.autojs.execution;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.ProcessShell;
import com.stardust.util.IntentExtras;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Stardust on 2017/7/16.
*/
public class RootedScriptExecution extends RunnableScriptExecution {
private static int count = 0;
private static Map<String, ScriptExecutionTask> arguments = new HashMap<>();
public RootedScriptExecution(ScriptEngineService service, ScriptExecutionTask task) {
super(service, task);
}
@Override
public void run() {
}
public static void main(String[] args) {
}
}

View File

@@ -2,27 +2,24 @@ package com.stardust.autojs.execution;
import android.util.Log;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.runtime.ScriptInterruptedException;
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 {
public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecution implements Runnable {
private static final String TAG = "RunnableScriptExecution";
private static final String TAG = "RunnableJSExecution";
private ScriptEngine mScriptEngine;
private ScriptRuntime mScriptRuntime;
private ScriptEngineService mScriptEngineService;
private ScriptEngineManager mScriptEngineManager;
public RunnableScriptExecution(ScriptEngineService service, ScriptExecutionTask task) {
public RunnableScriptExecution(ScriptEngineManager manager, ScriptExecutionTask task) {
super(task);
mScriptEngineService = service;
mScriptEngineManager = manager;
}
@Override
@@ -31,14 +28,13 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
}
public Object execute() {
mScriptEngine = mScriptEngineService.createScriptEngine();
mScriptRuntime = mScriptEngineService.createScriptRuntime();
return execute(mScriptRuntime, mScriptEngine);
mScriptEngine = mScriptEngineManager.createEngineOfSourceOrThrow(getSource());
return execute(mScriptEngine);
}
private Object execute(ScriptRuntime runtime, ScriptEngine engine) {
private Object execute(ScriptEngine engine) {
try {
prepare(runtime, engine);
prepare(engine);
return doExecution(engine);
} catch (Exception e) {
e.printStackTrace();
@@ -50,17 +46,13 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
return null;
}
private void prepare(ScriptRuntime runtime, ScriptEngine engine) {
if ((getSource().getExecutionMode() & ScriptSource.EXECUTION_MODE_AUTO) != 0) {
runtime.ensureAccessibilityServiceEnabled();
}
engine.put("__runtime__", runtime);
engine.setTag("__require_path__", getConfig().getRequirePath());
private void prepare(ScriptEngine engine) {
engine.setTag(ScriptEngine.TAG_PATH, getConfig().getExecutePath());
engine.init();
}
private Object doExecution(ScriptEngine engine) {
engine.setTag("script", getSource());
engine.setTag(ScriptEngine.TAG_SOURCE, getSource());
getListener().onStart(this);
Object result = null;
long delay = getConfig().delay;
@@ -95,8 +87,4 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
return mScriptEngine;
}
@Override
public ScriptRuntime getRuntime() {
return mScriptRuntime;
}
}

View File

@@ -1,17 +1,14 @@
package com.stardust.autojs.execution;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.stardust.autojs.R;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.util.IntentExtras;
/**
* Created by Stardust on 2017/2/5.
@@ -20,33 +17,36 @@ import com.stardust.autojs.script.ScriptSource;
public class ScriptExecuteActivity extends AppCompatActivity {
private static ActivityScriptExecution execution;
private static final String EXTRA_EXECUTION = ScriptExecuteActivity.class.getName() + ".execution";
private Object mResult;
private ScriptEngine mScriptEngine;
private ScriptExecutionListener mExecutionListener;
private ScriptSource mScriptSource;
private ScriptExecution mScriptExecution;
public static ActivityScriptExecution execute(Context context, ScriptEngineService service, ScriptExecutionTask task) {
if (execution != null) {
return null;
}
execution = new ActivityScriptExecution(service, task);
context.startActivity(new Intent(context, ScriptExecuteActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
public static ActivityScriptExecution execute(Context context, ScriptEngineManager manager, ScriptExecutionTask task) {
ActivityScriptExecution execution = new ActivityScriptExecution(manager, task);
Intent i = new Intent(context, ScriptExecuteActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
IntentExtras.newExtras()
.put(EXTRA_EXECUTION, execution)
.putInIntent(i);
context.startActivity(i);
return execution;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (execution == null) {
IntentExtras extras = IntentExtras.fromIntent(getIntent());
if (extras == null || extras.get(EXTRA_EXECUTION) == null) {
finish();
return;
}
mScriptSource = execution.getSource();
mScriptEngine = execution.getEngine();
mExecutionListener = execution.getListener();
mScriptExecution = extras.get(EXTRA_EXECUTION);
mScriptSource = mScriptExecution.getSource();
mScriptEngine = mScriptExecution.getEngine();
mExecutionListener = mScriptExecution.getListener();
runScript();
}
@@ -55,27 +55,26 @@ public class ScriptExecuteActivity extends AppCompatActivity {
prepare();
doExecution();
} catch (Exception e) {
mExecutionListener.onException(execution, e);
mExecutionListener.onException(mScriptExecution, e);
super.finish();
}
}
private void doExecution() {
mScriptEngine.setTag("script", mScriptSource);
mExecutionListener.onStart(execution);
mScriptEngine.setTag(ScriptEngine.TAG_SOURCE, mScriptSource);
mExecutionListener.onStart(mScriptExecution);
mResult = mScriptEngine.execute(mScriptSource);
}
private void prepare() {
mScriptEngine.put("activity", this);
mScriptEngine.put("__runtime__", execution.getRuntime());
mScriptEngine.setTag("__require_path__", execution.getConfig().getRequirePath());
mScriptEngine.setTag(ScriptEngine.TAG_PATH, mScriptExecution.getConfig().getExecutePath());
mScriptEngine.init();
}
@Override
public void finish() {
mExecutionListener.onSuccess(execution, mResult);
mExecutionListener.onSuccess(mScriptExecution, mResult);
super.finish();
}
@@ -84,36 +83,27 @@ public class ScriptExecuteActivity extends AppCompatActivity {
super.onDestroy();
mScriptEngine.put("activity", null);
mScriptEngine.destroy();
execution = null;
mScriptExecution = null;
}
private static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution {
private ScriptEngine mScriptEngine;
private ScriptRuntime mScriptRuntime;
private ScriptEngineService mScriptEngineService;
private ScriptEngineManager mScriptEngineManager;
ActivityScriptExecution(ScriptEngineService service, ScriptExecutionTask task) {
ActivityScriptExecution(ScriptEngineManager manager, ScriptExecutionTask task) {
super(task);
mScriptEngineService = service;
mScriptEngineManager = manager;
}
@Override
public ScriptEngine getEngine() {
if (mScriptEngine == null) {
mScriptEngine = mScriptEngineService.createScriptEngine();
mScriptEngine = mScriptEngineManager.createEngineOfSourceOrThrow(getSource());
}
return mScriptEngine;
}
@Override
public ScriptRuntime getRuntime() {
if (mScriptRuntime == null) {
mScriptRuntime = mScriptEngineService.createScriptRuntime();
}
return mScriptRuntime;
}
}

View File

@@ -12,8 +12,6 @@ public interface ScriptExecution {
ScriptEngine getEngine();
ScriptRuntime getRuntime();
ScriptSource getSource();
ScriptExecutionListener getListener();
@@ -31,9 +29,6 @@ public interface ScriptExecution {
@Override
public abstract ScriptEngine getEngine();
@Override
public abstract ScriptRuntime getRuntime();
@Override
public ScriptSource getSource() {
return mScriptExecutionTask.getSource();

View File

@@ -106,7 +106,6 @@ public abstract class AbstractShell {
private int scaleY(int y) {
return mScreenMetrics.scaleY(y);
}
public void Tap(int x, int y) {
@@ -114,7 +113,7 @@ public abstract class AbstractShell {
}
public void Swipe(int x1, int y1, int x2, int y2) {
exec(com.stardust.util.TextUtils.join(" ", "input", "tap", scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2)));
exec(com.stardust.util.TextUtils.join(" ", "input", "swipe", scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2)));
}
public void Swipe(int x1, int y1, int x2, int y2, int time) {

View File

@@ -17,7 +17,7 @@ import java.io.Reader;
* 来自网络~~
*/
public class ProcessShell extends AbstractShell implements AutoCloseable {
public class ProcessShell extends AbstractShell {
private static final String TAG = "ProcessShell";
@@ -87,11 +87,6 @@ public class ProcessShell extends AbstractShell implements AutoCloseable {
}
@Override
public void close() {
exit();
}
@Override
public void exitAndWaitFor() {
exec(COMMAND_EXIT);
@@ -158,7 +153,9 @@ public class ProcessShell extends AbstractShell implements AutoCloseable {
}
public static Result exec(String[] commands, boolean isRoot) {
try (ProcessShell shell = new ProcessShell(isRoot)) {
ProcessShell shell = null;
try {
shell = new ProcessShell(isRoot);
for (String command : commands) {
shell.exec(command);
}
@@ -170,6 +167,10 @@ public class ProcessShell extends AbstractShell implements AutoCloseable {
result.result = shell.getSucceedOutput().toString();
shell.exit();
return result;
} finally {
if (shell != null) {
shell.exit();
}
}
}
@@ -195,7 +196,6 @@ public class ProcessShell extends AbstractShell implements AutoCloseable {
os.writeBytes(COMMAND_EXIT);
os.flush();
commandResult.code = process.waitFor();
//获取错误信息
successMsg = new StringBuilder();
errorMsg = new StringBuilder();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));

View File

@@ -2,7 +2,7 @@ package com.stardust.autojs.runtime.api;
import android.content.Context;
import com.stardust.pio.PFile;
import com.stardust.autojs.engine.RootAutomatorEngine;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ScreenMetrics;
@@ -18,10 +18,9 @@ import java.io.IOException;
public class RootAutomator {
private static final int DATA_TYPE_SLEEP = 0;
private static final int DATA_TYPE_EVENT = 1;
public static final byte DATA_TYPE_SLEEP = 0;
public static final byte DATA_TYPE_EVENT = 1;
private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator";
private DataOutputStream mTmpFileOutputStream;
private File mEventTmpFile;
private ScreenMetrics mScreenMetrics;
@@ -88,24 +87,11 @@ public class RootAutomator {
}
public AbstractShell.Result writeToDevice(Context context) {
try {
mTmpFileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
if (mDevicePath == null) {
return new RootAutomatorEngine(context).execute(mEventTmpFile.getAbsolutePath());
} else {
return new RootAutomatorEngine(context, mDevicePath).execute(mEventTmpFile.getAbsolutePath());
}
String executablePath = getExecutablePath(context);
return ProcessShell.execCommand(new String[]{
"chmod 777 " + executablePath,
executablePath + " " + mEventTmpFile.getAbsolutePath() + " " + mDevicePath
}, true);
}
public static String getExecutablePath(Context context) {
File tmp = new File(context.getCacheDir(), "root_automator");
if (!tmp.exists()) {
PFile.copyAsset(context, ROOT_AUTOMATOR_EXECUTABLE_ASSET, tmp.getAbsolutePath());
}
return tmp.getAbsolutePath();
}
}

View File

@@ -1,8 +0,0 @@
package com.stardust.autojs.runtime.record.inputevent;
/**
* Created by Stardust on 2017/8/1.
*/
public class InputDevice {
}

View File

@@ -0,0 +1,31 @@
package com.stardust.autojs.runtime.record.inputevent;
import android.content.Context;
import android.hardware.input.InputManager;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.InputDevice;
/**
* Created by Stardust on 2017/8/1.
*/
public class InputDevices {
@Nullable
public static String getTouchDeviceName() {
for (int id : InputDevice.getDeviceIds()) {
InputDevice device = InputDevice.getDevice(id);
if (supportSource(device, InputDevice.SOURCE_TOUCHSCREEN) || supportSource(device, InputDevice.SOURCE_TOUCHPAD)) {
return device.getName();
}
}
return null;
}
private static boolean supportSource(InputDevice device, int source) {
return (device.getSources() & source) == source;
}
}

View File

@@ -0,0 +1,104 @@
package com.stardust.autojs.runtime.record.inputevent;
import android.support.annotation.NonNull;
import com.stardust.autojs.engine.RootAutomatorEngine;
import com.stardust.autojs.runtime.api.RootAutomator;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ScreenMetrics;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by Stardust on 2017/8/2.
*/
public class InputEventToAutoFileConverter extends InputEventConverter {
private double mLastEventTime;
private int mTouchDevice = -1;
private DataOutputStream mDataOutputStream;
private File mTmpFile;
public InputEventToAutoFileConverter() {
try {
mTmpFile = File.createTempFile("Record" + System.currentTimeMillis(), ".auto");
mDataOutputStream = new DataOutputStream(new FileOutputStream(mTmpFile));
writeFileHeader();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private void writeFileHeader() throws IOException {
mDataOutputStream.writeInt(0x00B87B6D);
mDataOutputStream.writeInt(RootAutomatorEngine.VERSION);
mDataOutputStream.writeInt(ScreenMetrics.getDeviceScreenWidth());
mDataOutputStream.writeInt(ScreenMetrics.getDeviceScreenHeight());
for (int i = 0; i < 240; i++) {
mDataOutputStream.writeByte(0);
}
}
@Override
public void convertEvent(@NonNull InputEventConverter.Event event) {
try {
convertEventOrThrow(event);
} catch (IOException e) {
e.printStackTrace();
}
}
private void convertEventOrThrow(Event event) throws IOException {
if (mLastEventTime == 0) {
mLastEventTime = event.time;
} else if (event.time - mLastEventTime > 0.001) {
mDataOutputStream.writeByte(RootAutomator.DATA_TYPE_SLEEP);
int n = (int) (1000L * (event.time - mLastEventTime));
mDataOutputStream.writeInt(n);
mLastEventTime = event.time;
}
int device = parseDeviceNumber(event.device);
short type = (short) Long.parseLong(event.type, 16);
short code = (short) Long.parseLong(event.code, 16);
int value = (int) Long.parseLong(event.value, 16);
if (type == 3) {
if (code == 53 || code == 54) {
mTouchDevice = device;
RootAutomatorEngine.setTouchDevice(device);
}
}
if (device != mTouchDevice) {
return;
}
mDataOutputStream.writeByte(RootAutomator.DATA_TYPE_EVENT);
mDataOutputStream.writeShort(type);
mDataOutputStream.writeShort(code);
mDataOutputStream.writeInt(value);
}
@Override
public String getGetEventCommand() {
return "getevent -t";
}
public String getCode() {
return mTmpFile.getAbsolutePath();
}
@Override
public void stop() {
super.stop();
try {
mDataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -32,7 +32,7 @@ public class InputEventToRootAutomatorConverter extends InputEventConverter {
public void convertEvent(@NonNull Event event) {
if (mLastEventTime == 0) {
mLastEventTime = event.time;
} else if (event.time - mLastEventTime > 0.005) {
} else if (event.time - mLastEventTime > 0.001) {
mCode.append("ra.sleep(").append((long) (1000L * (event.time - mLastEventTime))).append(");\n");
mLastEventTime = event.time;
}

View File

@@ -9,7 +9,7 @@ import android.content.Context;
public class TouchRecorder extends InputEventRecorder {
public TouchRecorder(Context context) {
super(context, new InputEventToRootAutomatorConverter());
super(context, new InputEventToAutoFileConverter());
listen();
}

View File

@@ -0,0 +1,38 @@
package com.stardust.autojs.script;
import android.support.annotation.NonNull;
import com.stardust.pio.PFile;
import java.io.File;
import java.io.Reader;
/**
* Created by Stardust on 2017/8/2.
*/
public class AutoFileSource extends ScriptSource {
public static final String ENGINE = AutoFileSource.class.getName() + ".Engine";
private File mFile;
public AutoFileSource(File file) {
super(PFile.getNameWithoutExtension(file.getAbsolutePath()));
mFile = file;
}
public AutoFileSource(String path) {
this(new File(path));
}
@Override
public String getEngineName() {
return ENGINE;
}
public File getFile() {
return mFile;
}
}

View File

@@ -1,6 +1,7 @@
package com.stardust.autojs.script;
import com.stardust.autojs.script.ScriptSource;
import android.support.annotation.NonNull;
import com.stardust.pio.PFile;
import com.stardust.pio.UncheckedIOException;
@@ -13,25 +14,26 @@ import java.io.Reader;
* Created by Stardust on 2017/4/2.
*/
public class FileScriptSource extends ScriptSource {
public class JavaScriptFileSource extends JavaScriptSource {
private File mFile;
private String mScript;
public FileScriptSource(File file) {
public JavaScriptFileSource(File file) {
super(PFile.getNameWithoutExtension(file.getName()));
mFile = file;
}
public FileScriptSource(String path) {
public JavaScriptFileSource(String path) {
this(new File(path));
}
public FileScriptSource(String name, File file) {
public JavaScriptFileSource(String name, File file) {
super(name);
mFile = file;
}
@NonNull
@Override
public String getScript() {
if (mScript == null)
@@ -48,6 +50,10 @@ public class FileScriptSource extends ScriptSource {
}
}
public File getFile() {
return mFile;
}
@Override
public String toString() {
return mFile.toString();

View File

@@ -0,0 +1,90 @@
package com.stardust.autojs.script;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.stardust.util.MapEntries;
import java.io.Reader;
import java.io.StringReader;
import java.util.Map;
/**
* Created by Stardust on 2017/8/2.
*/
public abstract class JavaScriptSource extends ScriptSource {
public static final String ENGINE = "com.stardust.autojs.script.JavaScriptSource.Engine";
public static final int EXECUTION_MODE_NORMAL = 0;
public static final int EXECUTION_MODE_UI = 0x00000001;
public static final int EXECUTION_MODE_AUTO = 0x00000002;
private static final Map<String, Integer> EXECUTION_MODES = new MapEntries<String, Integer>()
.entry("ui", EXECUTION_MODE_UI)
.entry("auto", EXECUTION_MODE_AUTO)
.map();
private static final int EXECUTION_MODE_STRING_MAX_LENGTH = 7;
private int mExecutionMode = -1;
public JavaScriptSource(String name) {
super(name);
}
@NonNull
public abstract String getScript();
@Nullable
public abstract Reader getScriptReader();
@NonNull
public Reader getNonNullScriptReader() {
Reader reader = getScriptReader();
if (reader == null) {
return new StringReader(getScript());
}
return reader;
}
public String toString() {
return getName() + ".js";
}
public int getExecutionMode() {
if (mExecutionMode == -1) {
mExecutionMode = parseExecutionMode(getScript());
}
return mExecutionMode;
}
private int parseExecutionMode(String script) {
if (script == null || script.length() == 0 || script.charAt(0) != '"')
return EXECUTION_MODE_NORMAL;
int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2);
if (i == -1)
return EXECUTION_MODE_NORMAL;
String modeString = script.substring(1, i);
return parseExecutionMode(modeString.split(" "));
}
private int parseExecutionMode(String[] modeStrings) {
int mode = 0;
for (String modeString : modeStrings) {
Integer i = EXECUTION_MODES.get(modeString);
if (i != null) {
mode |= i;
}
}
return mode;
}
@Override
public String getEngineName() {
return ENGINE;
}
}

View File

@@ -19,17 +19,6 @@ import java.util.Map;
public abstract class ScriptSource implements Serializable {
public static final int EXECUTION_MODE_NORMAL = 0;
public static final int EXECUTION_MODE_UI = 0x00000001;
public static final int EXECUTION_MODE_AUTO = 0x00000002;
private static final Map<String, Integer> EXECUTION_MODES = new MapEntries<String, Integer>()
.entry("ui", EXECUTION_MODE_UI)
.entry("auto", EXECUTION_MODE_AUTO)
.map();
private static final int EXECUTION_MODE_STRING_MAX_LENGTH = 7;
private int mExecutionMode = -1;
private String mName;
public ScriptSource(String name) {
@@ -40,51 +29,5 @@ public abstract class ScriptSource implements Serializable {
return mName;
}
@NonNull
public abstract String getScript();
@Nullable
public abstract Reader getScriptReader();
@NonNull
public Reader getNonNullScriptReader() {
Reader reader = getScriptReader();
if (reader == null) {
return new StringReader(getScript());
}
return reader;
}
public int getExecutionMode() {
if (mExecutionMode == -1) {
mExecutionMode = parseExecutionMode(getScript());
}
return mExecutionMode;
}
private int parseExecutionMode(String script) {
if (script == null || script.length() == 0 || script.charAt(0) != '"')
return EXECUTION_MODE_NORMAL;
int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2);
if (i == -1)
return EXECUTION_MODE_NORMAL;
String modeString = script.substring(1, i);
return parseExecutionMode(modeString.split(" "));
}
private int parseExecutionMode(String[] modeStrings) {
int mode = 0;
for (String modeString : modeStrings) {
Integer i = EXECUTION_MODES.get(modeString);
if (i != null) {
mode |= i;
}
}
return mode;
}
@Override
public String toString() {
return mName + ".js";
}
public abstract String getEngineName();
}

View File

@@ -12,14 +12,14 @@ import java.io.StringReader;
* Created by Stardust on 2017/4/2.
*/
public class SequenceScriptSource extends ScriptSource {
public class SequenceScriptSource extends JavaScriptSource {
private String mScript;
private ScriptSource mSecondScriptSource;
private ScriptSource mFirstScriptSource;
private JavaScriptSource mSecondScriptSource;
private JavaScriptSource mFirstScriptSource;
public SequenceScriptSource(String name, ScriptSource firstScriptSource, ScriptSource secondScriptSource) {
public SequenceScriptSource(String name, JavaScriptSource firstScriptSource, JavaScriptSource secondScriptSource) {
super(name);
mSecondScriptSource = secondScriptSource;
mFirstScriptSource = firstScriptSource;

View File

@@ -9,7 +9,7 @@ import java.io.Reader;
* Created by Stardust on 2017/4/2.
*/
public class StringScriptSource extends ScriptSource {
public class StringScriptSource extends JavaScriptSource {
private String mScript;