mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-24 21:33:16 +08:00
修复 ui线程下ui.xxx.on等函数不存在的问题
修复 非ui线程下ui.xxx.on等函数报错的问题 新增 注册ui.xxx支持增加成员 修复 多线程环境没有调用Context.exit()可能造成的内存泄漏
This commit is contained in:
parent
d2e0899c8b
commit
4dcb19e4fe
@ -42,23 +42,6 @@ function wrap(value){
|
||||
return value;
|
||||
}
|
||||
|
||||
bridges.asArray = function (list) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < list.size(); i++) {
|
||||
arr.push(list.get(i));
|
||||
}
|
||||
for (var key in list) {
|
||||
if (typeof (key) == 'number')
|
||||
continue;
|
||||
var v = list[key];
|
||||
if (typeof (v) == 'function') {
|
||||
arr[key] = v.bind(list);
|
||||
} else {
|
||||
arr[key] = v;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
bridges.toArray = function (iterable) {
|
||||
var iterator = iterable.iterator();
|
||||
var arr = [];
|
||||
|
||||
@ -13,7 +13,6 @@ import com.stardust.app.SimpleActivityLifecycleCallbacks;
|
||||
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
|
||||
import com.stardust.autojs.core.console.GlobalStardustConsole;
|
||||
import com.stardust.autojs.core.console.StardustConsole;
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity;
|
||||
import com.stardust.autojs.core.image.capture.ScreenCaptureRequester;
|
||||
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
|
||||
@ -21,10 +20,10 @@ import com.stardust.autojs.core.util.Shell;
|
||||
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
|
||||
import com.stardust.autojs.engine.RootAutomatorEngine;
|
||||
import com.stardust.autojs.engine.ScriptEngineManager;
|
||||
import com.stardust.autojs.rhino.InterruptibleAndroidContextFactory;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
|
||||
import com.stardust.autojs.runtime.api.AppUtils;
|
||||
import com.stardust.autojs.runtime.api.Console;
|
||||
import com.stardust.autojs.script.AutoFileSource;
|
||||
import com.stardust.autojs.script.JavaScriptSource;
|
||||
import com.stardust.util.ScreenMetrics;
|
||||
@ -34,8 +33,10 @@ import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||
import com.stardust.view.accessibility.AccessibilityService;
|
||||
import com.stardust.view.accessibility.LayoutInspector;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.mozilla.javascript.ContextFactory;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/11/29.
|
||||
@ -105,11 +106,15 @@ public abstract class AutoJs {
|
||||
engine.setRuntime(createRuntime());
|
||||
return engine;
|
||||
});
|
||||
LoopBasedJavaScriptEngine.initEngine();
|
||||
initContextFactory();
|
||||
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, () -> new RootAutomatorEngine(mContext));
|
||||
|
||||
}
|
||||
|
||||
protected void initContextFactory() {
|
||||
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mContext.getCacheDir(), "classes")));
|
||||
}
|
||||
|
||||
protected ScriptRuntime createRuntime() {
|
||||
return new ScriptRuntime.Builder()
|
||||
.setConsole(new StardustConsole(mUiHandler, mGlobalConsole))
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
package com.stardust.autojs.core.looper;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.lang.ThreadCompat;
|
||||
|
||||
|
||||
@ -4,16 +4,12 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.CallSuper;
|
||||
|
||||
import com.stardust.autojs.ScriptEngineService;
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
import com.stardust.autojs.runtime.ScriptBridges;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.concurrent.VolatileBox;
|
||||
import com.stardust.lang.ThreadCompat;
|
||||
|
||||
import org.mozilla.javascript.NativeArray;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -43,6 +39,7 @@ public class TimerThread extends ThreadCompat {
|
||||
mRuntime.loopers.prepare();
|
||||
mTimer = new Timer(mRuntime, mMaxCallbackUptimeMillisForAllThreads);
|
||||
sTimerMap.put(Thread.currentThread(), mTimer);
|
||||
((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).enterContext();
|
||||
notifyRunning();
|
||||
new Handler().post(mTarget);
|
||||
try {
|
||||
@ -54,6 +51,7 @@ public class TimerThread extends ThreadCompat {
|
||||
} finally {
|
||||
onExit();
|
||||
mTimer = null;
|
||||
org.mozilla.javascript.Context.exit();
|
||||
sTimerMap.remove(Thread.currentThread(), mTimer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.stardust.autojs.core.ui;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.autojs.R;
|
||||
@ -13,6 +14,7 @@ import org.mozilla.javascript.Scriptable;
|
||||
|
||||
public class ViewExtras {
|
||||
|
||||
private static final String LOG_TAG = "ViewExtras";
|
||||
private NativeView mNativeView;
|
||||
|
||||
private ViewAttributes mViewAttributes;
|
||||
@ -20,6 +22,7 @@ public class ViewExtras {
|
||||
public static ViewExtras get(View view) {
|
||||
ViewExtras extras;
|
||||
Object tag = view.getTag(R.id.view_tag_view_extras);
|
||||
Log.d(LOG_TAG, "view = " + view + ", tag = " + tag);
|
||||
if (tag instanceof ViewExtras) {
|
||||
extras = (ViewExtras) tag;
|
||||
} else {
|
||||
@ -34,7 +37,7 @@ public class ViewExtras {
|
||||
ViewExtras extras = get(view);
|
||||
ViewAttributes attributes = extras.getViewAttributes();
|
||||
if (attributes == null) {
|
||||
attributes = ViewAttributesFactory.create(parser, view);
|
||||
attributes = ViewAttributesFactory.create(parser, view);
|
||||
extras.setViewAttributes(attributes);
|
||||
}
|
||||
return attributes;
|
||||
|
||||
@ -11,7 +11,6 @@ public class ResourceParser {
|
||||
|
||||
private final Drawables mDrawables;
|
||||
|
||||
|
||||
public ResourceParser(Drawables drawables) {
|
||||
mDrawables = drawables;
|
||||
}
|
||||
|
||||
@ -25,8 +25,4 @@ public class JsTabLayout extends TabLayout {
|
||||
public JsTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public void setupWithViewPager(NativeObject viewPager) {
|
||||
setupWithViewPager(UI.unwrapJsViewObject(viewPager, ViewPager.class));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,12 +8,8 @@ import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.R;
|
||||
import com.stardust.autojs.runtime.api.UI;
|
||||
|
||||
import org.mozilla.javascript.NativeObject;
|
||||
|
||||
public class JsToolbar extends Toolbar {
|
||||
|
||||
@ -47,9 +43,4 @@ public class JsToolbar extends Toolbar {
|
||||
}
|
||||
return (Activity) context;
|
||||
}
|
||||
|
||||
public void setupWithDrawer(NativeObject object) {
|
||||
setupWithDrawer(UI.unwrapJsViewObject(object, DrawerLayout.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -88,9 +88,5 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
|
||||
super.init();
|
||||
}
|
||||
|
||||
public static void initEngine(){
|
||||
RhinoJavaScriptEngine.initEngine();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,25 +1,23 @@
|
||||
package com.stardust.autojs.engine;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import com.stardust.autojs.BuildConfig;
|
||||
import com.stardust.autojs.core.ui.ViewExtras;
|
||||
import com.stardust.autojs.core.ui.nativeview.NativeView;
|
||||
import com.stardust.autojs.rhino.AndroidContextFactory;
|
||||
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.autojs.rhino.TopLevelScope;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.script.JavaScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.automator.UiObjectCollection;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.ContextFactory;
|
||||
import org.mozilla.javascript.ImporterTopLevel;
|
||||
import org.mozilla.javascript.NativeArray;
|
||||
import org.mozilla.javascript.NativeJavaObject;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
import org.mozilla.javascript.commonjs.module.RequireBuilder;
|
||||
@ -28,9 +26,10 @@ import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptPr
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -44,18 +43,17 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
private static final String LOG_TAG = "RhinoJavaScriptEngine";
|
||||
|
||||
private static final String MODULES_PATH = "modules";
|
||||
private static int contextCount = 0;
|
||||
private static StringScriptSource sInitScript;
|
||||
private static final ConcurrentHashMap<Context, RhinoJavaScriptEngine> sContextEngineMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Context mContext;
|
||||
private Scriptable mScriptable;
|
||||
private TopLevelScope mScriptable;
|
||||
private Thread mThread;
|
||||
private android.content.Context mAndroidContext;
|
||||
|
||||
public RhinoJavaScriptEngine(android.content.Context context) {
|
||||
mAndroidContext = context;
|
||||
mContext = createContext();
|
||||
mContext = enterContext();
|
||||
mScriptable = createScope(mContext);
|
||||
}
|
||||
|
||||
@ -92,8 +90,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
Log.d(LOG_TAG, "on destroy");
|
||||
sContextEngineMap.remove(getContext());
|
||||
Context.exit();
|
||||
contextCount--;
|
||||
Log.d(LOG_TAG, "contextCount = " + contextCount);
|
||||
}
|
||||
|
||||
public Thread getThread() {
|
||||
@ -142,15 +138,14 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
return mScriptable;
|
||||
}
|
||||
|
||||
protected Scriptable createScope(Context context) {
|
||||
ImporterTopLevel importerTopLevel = new ImporterTopLevel();
|
||||
importerTopLevel.initStandardObjects(context, false);
|
||||
return importerTopLevel;
|
||||
protected TopLevelScope createScope(Context context) {
|
||||
TopLevelScope topLevelScope = new TopLevelScope();
|
||||
topLevelScope.initStandardObjects(context, false);
|
||||
return topLevelScope;
|
||||
}
|
||||
|
||||
public Context createContext() {
|
||||
public Context enterContext() {
|
||||
Context context = new RhinoAndroidHelper(mAndroidContext).enterContext();
|
||||
contextCount++;
|
||||
setupContext(context);
|
||||
sContextEngineMap.put(context, this);
|
||||
return context;
|
||||
@ -163,12 +158,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
context.setWrapFactory(new WrapFactory());
|
||||
}
|
||||
|
||||
public static void initEngine() {
|
||||
if (!ContextFactory.hasExplicitGlobal()) {
|
||||
android.content.Context context = GlobalAppContext.get();
|
||||
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(context.getCacheDir(), "classes")));
|
||||
}
|
||||
}
|
||||
|
||||
public static RhinoJavaScriptEngine getEngineOfContext(Context context) {
|
||||
return sContextEngineMap.get(context);
|
||||
@ -178,43 +167,34 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
|
||||
@Override
|
||||
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
|
||||
Object result;
|
||||
if (obj instanceof String) {
|
||||
return getRuntime().bridges.toString(obj.toString());
|
||||
result = getRuntime().bridges.toString(obj.toString());
|
||||
} else if (staticType == UiObjectCollection.class) {
|
||||
UiObjectCollection collection = (UiObjectCollection) obj;
|
||||
Object[] array = new Object[collection.size()];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = wrapAsJavaObject(cx, scope, collection.get(i), UiObject.class);
|
||||
}
|
||||
NativeArray nativeArray = new NativeArray(array);
|
||||
nativeArray.setPrototype(new NativeJavaObject(scope, collection, staticType));
|
||||
result = nativeArray;
|
||||
} else {
|
||||
result = super.wrap(cx, scope, obj, staticType);
|
||||
}
|
||||
if (staticType == UiObjectCollection.class) {
|
||||
return getRuntime().bridges.asArray(obj);
|
||||
}
|
||||
return super.wrap(cx, scope, obj, staticType);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class<?> staticType) {
|
||||
Scriptable result;
|
||||
if (javaObject instanceof View) {
|
||||
return ViewExtras.getNativeView(scope, (View) javaObject, staticType, getRuntime());
|
||||
result = ViewExtras.getNativeView(scope, (View) javaObject, staticType, getRuntime());
|
||||
} else {
|
||||
result = super.wrapAsJavaObject(cx, scope, javaObject, staticType);
|
||||
}
|
||||
return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InterruptibleAndroidContextFactory extends AndroidContextFactory {
|
||||
|
||||
public InterruptibleAndroidContextFactory(File cacheDirectory) {
|
||||
super(cacheDirectory);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void observeInstructionCount(Context cx, int instructionCount) {
|
||||
if (Thread.currentThread().isInterrupted() && Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new ScriptInterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Context makeContext() {
|
||||
Context cx = super.makeContext();
|
||||
cx.setInstructionObserverThreshold(10000);
|
||||
return cx;
|
||||
//Log.d(LOG_TAG, "wrapAsJavaObject: java = " + javaObject + ", result = " + result + ", scope = " + scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -230,10 +230,6 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
public void setSupportActionBar(@Nullable NativeObject toolbar) {
|
||||
super.setSupportActionBar(UI.unwrapJsViewObject(toolbar, Toolbar.class));
|
||||
}
|
||||
|
||||
private static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution {
|
||||
|
||||
private ScriptEngine mScriptEngine;
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
package com.stardust.autojs.rhino;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class InterruptibleAndroidContextFactory extends AndroidContextFactory {
|
||||
|
||||
private AtomicInteger mContextCount = new AtomicInteger();
|
||||
private static final String LOG_TAG = "ContextFactory";
|
||||
|
||||
/**
|
||||
* Create a new factory. It will cache generated code in the given directory
|
||||
*
|
||||
* @param cacheDirectory the cache directory
|
||||
*/
|
||||
public InterruptibleAndroidContextFactory(File cacheDirectory) {
|
||||
super(cacheDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void observeInstructionCount(Context cx, int instructionCount) {
|
||||
if (Thread.currentThread().isInterrupted() && Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new ScriptInterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Context makeContext() {
|
||||
Context cx = super.makeContext();
|
||||
cx.setInstructionObserverThreshold(10000);
|
||||
return cx;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContextCreated(Context cx) {
|
||||
super.onContextCreated(cx);
|
||||
int i = mContextCount.incrementAndGet();
|
||||
Log.d(LOG_TAG, "onContextCreated: count = " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContextReleased(Context cx) {
|
||||
super.onContextReleased(cx);
|
||||
int i = mContextCount.decrementAndGet();
|
||||
Log.d(LOG_TAG, "onContextReleased: count = " + i);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
package com.stardust.autojs.rhino;
|
||||
|
||||
import org.mozilla.javascript.ImporterTopLevel;
|
||||
|
||||
public class TopLevelScope extends ImporterTopLevel {
|
||||
}
|
||||
@ -19,8 +19,6 @@ public class ScriptBridges {
|
||||
|
||||
Object toArray(Iterable o);
|
||||
|
||||
Object asArray(Object o);
|
||||
|
||||
Object toString(Object obj);
|
||||
|
||||
}
|
||||
@ -47,12 +45,6 @@ public class ScriptBridges {
|
||||
return mBridges.toArray(c);
|
||||
}
|
||||
|
||||
public Object asArray(Object o) {
|
||||
checkBridges();
|
||||
return mBridges.asArray(o);
|
||||
}
|
||||
|
||||
|
||||
public Object toString(Object obj) {
|
||||
checkBridges();
|
||||
return mBridges.toString(obj);
|
||||
|
||||
@ -1,20 +1,14 @@
|
||||
package com.stardust.autojs.runtime.api;
|
||||
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import com.stardust.autojs.ScriptEngineService;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.execution.ExecutionConfig;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.script.AutoFileSource;
|
||||
import com.stardust.autojs.script.JavaScriptFileSource;
|
||||
import com.stardust.autojs.script.JavaScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/4.
|
||||
*/
|
||||
@ -22,7 +16,7 @@ import java.util.List;
|
||||
public class Engines {
|
||||
|
||||
private ScriptEngineService mEngineService;
|
||||
private ScriptEngine<JavaScriptSource> mScriptEngine;
|
||||
private JavaScriptEngine mScriptEngine;
|
||||
private ScriptRuntime mScriptRuntime;
|
||||
|
||||
public Engines(ScriptEngineService engineService, ScriptRuntime scriptRuntime) {
|
||||
@ -55,13 +49,13 @@ public class Engines {
|
||||
}
|
||||
|
||||
|
||||
public void setCurrentEngine(ScriptEngine<JavaScriptSource> engine) {
|
||||
public void setCurrentEngine(JavaScriptEngine engine) {
|
||||
if (mScriptEngine != null)
|
||||
throw new IllegalStateException();
|
||||
mScriptEngine = engine;
|
||||
}
|
||||
|
||||
public ScriptEngine<JavaScriptSource> myEngine() {
|
||||
public JavaScriptEngine myEngine() {
|
||||
return mScriptEngine;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.stardust.autojs.runtime.api;
|
||||
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.pio.PFileInterface;
|
||||
import com.stardust.pio.PFiles;
|
||||
@ -22,6 +21,7 @@ public class Files {
|
||||
mRuntime = runtime;
|
||||
}
|
||||
|
||||
// FIXME: 2018/10/16 is not correct in sub-directory?
|
||||
public String path(String relativePath) {
|
||||
String cwd = cwd();
|
||||
if (cwd == null || relativePath == null || relativePath.startsWith("/"))
|
||||
|
||||
@ -4,7 +4,6 @@ import android.support.annotation.NonNull;
|
||||
|
||||
import com.stardust.autojs.core.looper.MainThreadProxy;
|
||||
import com.stardust.autojs.core.looper.TimerThread;
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.concurrent.VolatileDispose;
|
||||
|
||||
@ -56,10 +55,7 @@ public class Threads {
|
||||
@NonNull
|
||||
private TimerThread createThread(Runnable runnable) {
|
||||
return new TimerThread(mRuntime, mRuntime.timers.getMaxCallbackUptimeMillisForAllThreads(),
|
||||
() -> {
|
||||
((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).createContext();
|
||||
runnable.run();
|
||||
}
|
||||
runnable
|
||||
) {
|
||||
@Override
|
||||
protected void onExit() {
|
||||
|
||||
@ -63,21 +63,6 @@ public class UI extends ProxyObject {
|
||||
return mResourceParser;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <V extends View> V unwrapJsViewObject(@Nullable NativeObject object, Class<V> c) {
|
||||
if (object == null)
|
||||
return null;
|
||||
if (!object.containsKey("__javaObject__")) {
|
||||
throw new ClassCastException("object " + object + " cannot be cast to " + c.getName());
|
||||
}
|
||||
Object view = object.get("__javaObject__");
|
||||
if (!c.isInstance(view)) {
|
||||
throw new ClassCastException("object " + object + " cannot be cast to " + c.getName());
|
||||
}
|
||||
return (V) view;
|
||||
|
||||
}
|
||||
|
||||
public Object getBindingContext() {
|
||||
return mProperties.get("bindingContext");
|
||||
}
|
||||
|
||||
238
autojs/src/main/java/org/mozilla/javascript/ContextWrapper.java
Normal file
238
autojs/src/main/java/org/mozilla/javascript/ContextWrapper.java
Normal file
@ -0,0 +1,238 @@
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import org.mozilla.javascript.debug.DebuggableScript;
|
||||
import org.mozilla.javascript.xml.XMLLib;
|
||||
|
||||
public class ContextWrapper extends Context {
|
||||
private final Context mContext;
|
||||
|
||||
public ContextWrapper(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public static Context getCurrentContext() {
|
||||
return Context.getCurrentContext();
|
||||
}
|
||||
|
||||
public static Context enter() {
|
||||
return Context.enter();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Context enter(Context cx) {
|
||||
return Context.enter(cx);
|
||||
}
|
||||
|
||||
public static void exit() {
|
||||
Context.exit();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Object call(ContextAction action) {
|
||||
return Context.call(action);
|
||||
}
|
||||
|
||||
public static Object call(ContextFactory factory, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args) {
|
||||
return Context.call(factory, callable, scope, thisObj, args);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void addContextListener(ContextListener listener) {
|
||||
Context.addContextListener(listener);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void removeContextListener(ContextListener listener) {
|
||||
Context.removeContextListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLanguageVersion(int version) {
|
||||
mContext.setLanguageVersion(version);
|
||||
}
|
||||
|
||||
public static boolean isValidLanguageVersion(int version) {
|
||||
return Context.isValidLanguageVersion(version);
|
||||
}
|
||||
|
||||
public static void checkLanguageVersion(int version) {
|
||||
Context.checkLanguageVersion(version);
|
||||
}
|
||||
|
||||
public static void reportWarning(String message, String sourceName, int lineno, String lineSource, int lineOffset) {
|
||||
Context.reportWarning(message, sourceName, lineno, lineSource, lineOffset);
|
||||
}
|
||||
|
||||
public static void reportWarning(String message) {
|
||||
Context.reportWarning(message);
|
||||
}
|
||||
|
||||
public static void reportWarning(String message, Throwable t) {
|
||||
Context.reportWarning(message, t);
|
||||
}
|
||||
|
||||
public static void reportError(String message, String sourceName, int lineno, String lineSource, int lineOffset) {
|
||||
Context.reportError(message, sourceName, lineno, lineSource, lineOffset);
|
||||
}
|
||||
|
||||
public static void reportError(String message) {
|
||||
Context.reportError(message);
|
||||
}
|
||||
|
||||
public static EvaluatorException reportRuntimeError(String message, String sourceName, int lineno, String lineSource, int lineOffset) {
|
||||
return Context.reportRuntimeError(message, sourceName, lineno, lineSource, lineOffset);
|
||||
}
|
||||
|
||||
public static EvaluatorException reportRuntimeError(String message) {
|
||||
return Context.reportRuntimeError(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptableObject initStandardObjects(ScriptableObject scope, boolean sealed) {
|
||||
return mContext.initStandardObjects(scope, sealed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptableObject initSafeStandardObjects(ScriptableObject scope, boolean sealed) {
|
||||
return mContext.initSafeStandardObjects(scope, sealed);
|
||||
}
|
||||
|
||||
public static Object getUndefinedValue() {
|
||||
return Context.getUndefinedValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object executeScriptWithContinuations(Script script, Scriptable scope) throws ContinuationPending {
|
||||
return mContext.executeScriptWithContinuations(script, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object callFunctionWithContinuations(Callable function, Scriptable scope, Object[] args) throws ContinuationPending {
|
||||
return mContext.callFunctionWithContinuations(function, scope, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContinuationPending captureContinuation() {
|
||||
return mContext.captureContinuation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resumeContinuation(Object continuation, Scriptable scope, Object functionResult) throws ContinuationPending {
|
||||
return mContext.resumeContinuation(continuation, scope, functionResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable newObject(Scriptable scope) {
|
||||
return mContext.newObject(scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable newObject(Scriptable scope, String constructorName) {
|
||||
return mContext.newObject(scope, constructorName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable newObject(Scriptable scope, String constructorName, Object[] args) {
|
||||
return mContext.newObject(scope, constructorName, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable newArray(Scriptable scope, int length) {
|
||||
return mContext.newArray(scope, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scriptable newArray(Scriptable scope, Object[] elements) {
|
||||
return mContext.newArray(scope, elements);
|
||||
}
|
||||
|
||||
public static boolean toBoolean(Object value) {
|
||||
return Context.toBoolean(value);
|
||||
}
|
||||
|
||||
public static double toNumber(Object value) {
|
||||
return Context.toNumber(value);
|
||||
}
|
||||
|
||||
public static String toString(Object value) {
|
||||
return Context.toString(value);
|
||||
}
|
||||
|
||||
public static Scriptable toObject(Object value, Scriptable scope) {
|
||||
return Context.toObject(value, scope);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Scriptable toObject(Object value, Scriptable scope, Class<?> staticType) {
|
||||
return Context.toObject(value, scope, staticType);
|
||||
}
|
||||
|
||||
public static Object javaToJS(Object value, Scriptable scope) {
|
||||
return Context.javaToJS(value, scope);
|
||||
}
|
||||
|
||||
public static Object jsToJava(Object value, Class<?> desiredType) throws EvaluatorException {
|
||||
return Context.jsToJava(value, desiredType);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Object toType(Object value, Class<?> desiredType) throws IllegalArgumentException {
|
||||
return Context.toType(value, desiredType);
|
||||
}
|
||||
|
||||
public static RuntimeException throwAsScriptRuntimeEx(Throwable e) {
|
||||
return Context.throwAsScriptRuntimeEx(e);
|
||||
}
|
||||
|
||||
public static boolean isValidOptimizationLevel(int optimizationLevel) {
|
||||
return Context.isValidOptimizationLevel(optimizationLevel);
|
||||
}
|
||||
|
||||
public static void checkOptimizationLevel(int optimizationLevel) {
|
||||
Context.checkOptimizationLevel(optimizationLevel);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void setCachingEnabled(boolean cachingEnabled) {
|
||||
Context.setCachingEnabled(cachingEnabled);
|
||||
}
|
||||
|
||||
public static DebuggableScript getDebuggableView(Script script) {
|
||||
return Context.getDebuggableView(script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFeature(int featureIndex) {
|
||||
return mContext.hasFeature(featureIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLLib.Factory getE4xImplementationFactory() {
|
||||
return mContext.getE4xImplementationFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenerateObserverCount(boolean generateObserverCount) {
|
||||
mContext.setGenerateObserverCount(generateObserverCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void observeInstructionCount(int instructionCount) {
|
||||
mContext.observeInstructionCount(instructionCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeneratedClassLoader createClassLoader(ClassLoader parent) {
|
||||
return mContext.createClassLoader(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActivationName(String name) {
|
||||
mContext.addActivationName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeActivationName(String name) {
|
||||
mContext.removeActivationName(name);
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,8 @@ package org.mozilla.javascript;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
|
||||
import org.mozilla.javascript.jdk15.VMBridge_jdk15;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
@ -19,6 +21,9 @@ public class VMBridge_custom extends VMBridge_jdk15 {
|
||||
|
||||
@Override
|
||||
protected Object newInterfaceProxy(Object proxyHelper, ContextFactory cf, InterfaceAdapter adapter, Object target, Scriptable topScope) {
|
||||
Context context = Context.getCurrentContext();
|
||||
InterfaceAdapterWrapper adapterWrapper = new InterfaceAdapterWrapper(adapter, context);
|
||||
RhinoJavaScriptEngine engine = RhinoJavaScriptEngine.getEngineOfContext(context);
|
||||
// --- The following code is copied from super class --
|
||||
Constructor<?> c = (Constructor) proxyHelper;
|
||||
InvocationHandler handler = (proxy, method, args) -> {
|
||||
@ -43,25 +48,19 @@ public class VMBridge_custom extends VMBridge_jdk15 {
|
||||
// If so, catch any exception of invoking
|
||||
// Because an exception on ui thread will cause the whole app to crash
|
||||
try {
|
||||
Object result = adapter.invoke(cf, target, topScope, proxy, method, args);
|
||||
Object result = adapterWrapper.invoke(cf, target, topScope, proxy, method, args);
|
||||
return castReturnValue(method, result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// notify the script thread to exit
|
||||
Object jsRuntime = topScope.get("runtime", null);
|
||||
Log.d(LOG_TAG, "jsRuntime = " + jsRuntime);
|
||||
if (jsRuntime instanceof NativeJavaObject) {
|
||||
Object runtime = ((NativeJavaObject) jsRuntime).unwrap();
|
||||
Log.d(LOG_TAG, "runtime = " + runtime);
|
||||
if(runtime instanceof com.stardust.autojs.runtime.ScriptRuntime){
|
||||
((com.stardust.autojs.runtime.ScriptRuntime) runtime).exit(e);
|
||||
}
|
||||
}
|
||||
com.stardust.autojs.runtime.ScriptRuntime runtime = engine.getRuntime();
|
||||
Log.d(LOG_TAG, "runtime = " + runtime);
|
||||
runtime.exit(e);
|
||||
// even if we caught the exception, we must return a value to for the method call.
|
||||
return defaultValue(method.getReturnType());
|
||||
}
|
||||
} else {
|
||||
return castReturnValue(method, adapter.invoke(cf, target, topScope, proxy, method, args));
|
||||
return castReturnValue(method, adapterWrapper.invoke(cf, target, topScope, proxy, method, args));
|
||||
}
|
||||
};
|
||||
|
||||
@ -115,4 +114,36 @@ public class VMBridge_custom extends VMBridge_jdk15 {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class InterfaceAdapterWrapper {
|
||||
|
||||
private final InterfaceAdapter mInterfaceAdapter;
|
||||
private final Context mCallerContext;
|
||||
|
||||
private InterfaceAdapterWrapper(InterfaceAdapter interfaceAdapter, Context callerContext) {
|
||||
mInterfaceAdapter = interfaceAdapter;
|
||||
mCallerContext = callerContext;
|
||||
}
|
||||
|
||||
public Object invoke(ContextFactory cf, Object target, Scriptable topScope, Object thisObject, Method method, Object[] args) {
|
||||
ContextAction action = cx -> invokeImpl(cx, target, topScope, thisObject, method, args);
|
||||
return call(cf, action);
|
||||
}
|
||||
|
||||
private Object call(ContextFactory cf, ContextAction action) {
|
||||
Context cx = Context.enter(null, cf);
|
||||
//TODO null check
|
||||
cx.setWrapFactory(mCallerContext.getWrapFactory());
|
||||
try {
|
||||
return action.run(cx);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object invokeImpl(Context cx, Object target, Scriptable topScope, Object thisObject, Method method, Object[] args) {
|
||||
return mInterfaceAdapter.invokeImpl(cx, target, topScope, thisObject, method, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,7 +446,9 @@ public class UiGlobalSelector {
|
||||
for (ListFilter filter : mFilters) {
|
||||
str.append(filter.toString()).append(".");
|
||||
}
|
||||
str.deleteCharAt(str.length() - 1);
|
||||
if(str.length() > 0){
|
||||
str.deleteCharAt(str.length() - 1);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ public class UiObjectCollection {
|
||||
}
|
||||
|
||||
public UiObject[] toArray(){
|
||||
return mNodes.toArray(new UiObject[mNodes.size()]);
|
||||
return mNodes.toArray(new UiObject[0]);
|
||||
}
|
||||
|
||||
public boolean performAction(int action) {
|
||||
|
||||
@ -60,7 +60,7 @@ public class AccessibilityInfoProvider implements AccessibilityDelegate {
|
||||
return;
|
||||
try {
|
||||
ComponentName componentName = new ComponentName(latestPackageStr, latestClassStr);
|
||||
mLatestActivity = mPackageManager.getActivityInfo(componentName, 0).name;
|
||||
mLatestActivity = mPackageManager.getActivityInfo(componentName, PackageManager.MATCH_DEFAULT_ONLY).name;
|
||||
} catch (PackageManager.NameNotFoundException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":430,"versionName":"4.0.4 Alpha","enabled":true,"outputFile":"commonRelease-4.0.4 Alpha.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.4 Alpha.apk","properties":{}}]
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":431,"versionName":"4.0.4 Alpha2","enabled":true,"outputFile":"commonRelease-4.0.4 Alpha2.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.4 Alpha2.apk","properties":{}}]
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"appVersionCode": 430,
|
||||
"appVersionName": "4.0.4 Alpha",
|
||||
"appVersionCode": 431,
|
||||
"appVersionName": "4.0.4 Alpha2",
|
||||
"target": 28,
|
||||
"mini": 17,
|
||||
"compile": 28,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user