From 7473d7c6a5173b94c25d6a1cfa1644efeb51e9a2 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Wed, 3 May 2017 01:20:29 +0800 Subject: [PATCH] Add floating console support --- app/build.gradle | 2 +- .../stardust/scriptdroid/autojs/AutoJs.java | 41 +---- .../autojs/ScriptExecutionGlobalListener.java | 41 +++++ .../console/ConsoleFloaty.java | 83 ---------- .../console/FloatingConsole.java | 17 -- .../console/FloatingConsoleService.java | 8 - .../console/FloatingConsoleView.java | 40 ----- .../menu/HoverMenuService.java | 2 + .../layout_inspector/LayoutInspector.java | 3 +- .../service/AccessibilityWatchDogService.java | 10 +- .../scriptdroid/ui/console/ConsoleFloaty.java | 133 ++++++++++++++++ .../scriptdroid/ui/console/ConsoleView.java | 147 ++++++++++++++++++ .../ui/console/StardustConsole.java | 108 +++++++++++++ .../scriptdroid/ui/console/TimberConsole.java | 15 +- .../scriptdroid/ui/edit/EditActivity.java | 40 ++++- .../ui/edit/completion/CodeCompletion.java | 2 +- .../ui/main/SlideMenuFragment.java | 25 ++- .../main/operation/ScriptFileOperation.java | 25 ++- .../ui/main/task/TaskListRecyclerView.java | 38 ++++- .../main/res/drawable/circle_cool_black.xml | 8 + .../res/drawable/debug_console_icon_128.png | Bin 0 -> 1522 bytes .../drawable/floating_console_bg_bottom.xml | 6 +- .../res/drawable/floating_console_bg_top.xml | 2 +- .../res/drawable/ic_remove_white_24dp.png | Bin 90 -> 82 bytes app/src/main/res/layout/console_view.xml | 16 ++ .../res/layout/floating_console_expand.xml | 100 ++++++------ .../res/layout/floating_window_collapse.xml | 11 +- app/src/main/res/menu/menu_editor.xml | 6 + app/src/main/res/values/strings.xml | 2 + .../autojs/RunnableScriptExecution.java | 37 ----- .../stardust/autojs/ScriptEngineService.java | 67 ++++---- .../autojs/ScriptEngineServiceBuilder.java | 13 +- .../autojs/ScriptExecutionListener.java | 19 --- .../stardust/autojs/ScriptExecutionTask.java | 81 ---------- .../autojs/SimpleScriptExecutionListener.java | 26 ---- .../engine/JavaScriptEngineManager.java | 1 - .../autojs/engine/RhinoJavaScriptEngine.java | 22 ++- .../autojs/engine/ScriptExecuteActivity.java | 15 +- .../{ => execution}/ExecutionConfig.java | 2 +- .../execution/RunnableScriptExecution.java | 69 ++++++++ .../{ => execution}/ScriptExecution.java | 6 +- .../execution/ScriptExecutionListener.java | 16 ++ .../execution/ScriptExecutionObserver.java | 70 +++++++++ .../autojs/execution/ScriptExecutionTask.java | 38 +++++ .../SimpleScriptExecutionListener.java | 23 +++ .../rhino_android/AndroidContextFactory.java | 5 +- .../autojs/runtime/AbstractConsole.java | 19 +-- .../runtime/ScriptInterrupptedException.java | 10 -- .../runtime/ScriptInterruptedException.java | 13 ++ .../autojs/runtime/ScriptRuntime.java | 30 ++-- .../stardust/autojs/runtime/api/Console.java | 4 + .../runtime/api/InjectableWebClient.java | 7 +- .../autojs/runtime/api/UiSelector.java | 4 +- .../stardust/autojs/script/JsBeautifier.java | 28 +++- .../stardust/pio/PRandomAccessBinaryFile.java | 1 + .../com/stardust/pio/PReadableTextFile.java | 3 +- .../com/stardust/pio/PWritableTextFile.java | 3 +- .../java/com/stardust/util/UiHandler.java | 43 +++++ .../com/stardust/util/UnderuseExecutors.java | 21 +++ .../main/java/com/stardust/util/ViewUtil.java | 6 + 60 files changed, 1072 insertions(+), 561 deletions(-) create mode 100644 app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java delete mode 100644 app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/ConsoleFloaty.java delete mode 100644 app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsole.java delete mode 100644 app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleService.java delete mode 100644 app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleView.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleFloaty.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleView.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/console/StardustConsole.java create mode 100644 app/src/main/res/drawable/circle_cool_black.xml create mode 100644 app/src/main/res/drawable/debug_console_icon_128.png create mode 100644 app/src/main/res/layout/console_view.xml delete mode 100644 autojs/src/main/java/com/stardust/autojs/RunnableScriptExecution.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/ScriptExecutionListener.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/ScriptExecutionTask.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/SimpleScriptExecutionListener.java rename autojs/src/main/java/com/stardust/autojs/{ => execution}/ExecutionConfig.java (92%) create mode 100644 autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java rename autojs/src/main/java/com/stardust/autojs/{ => execution}/ScriptExecution.java (86%) create mode 100644 autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionListener.java create mode 100644 autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionObserver.java create mode 100644 autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionTask.java create mode 100644 autojs/src/main/java/com/stardust/autojs/execution/SimpleScriptExecutionListener.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterrupptedException.java create mode 100644 autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterruptedException.java create mode 100644 common/src/main/java/com/stardust/util/UiHandler.java create mode 100644 common/src/main/java/com/stardust/util/UnderuseExecutors.java diff --git a/app/build.gradle b/app/build.gradle index 2d88e03b..a5f7e761 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,7 +74,7 @@ dependencies { compile 'me.zhanghai.android.materialprogressbar:library:1.3.0' compile group:'com.twofortyfouram', name:'android-plugin-client-sdk-for-locale', version:'[4.0.2, 5.0[' compile 'com.android.volley:volley:1.0.0' - compile 'com.github.hyb1996:EnhancedFloaty:0.12' + compile 'com.github.hyb1996:EnhancedFloaty:0.15' compile 'com.flurry.android:analytics:7.0.0@aar' compile 'com.android.support:multidex:1.0.1' compile(name: 'libtermexec-release', ext: 'aar') diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java index f4884a6f..b268ed6d 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java @@ -2,24 +2,21 @@ package com.stardust.scriptdroid.autojs; import android.accessibilityservice.AccessibilityService; import android.content.Context; -import android.os.Handler; import android.support.annotation.Nullable; -import com.flurry.android.FlurryAgent; import com.stardust.autojs.ScriptEngineService; import com.stardust.autojs.ScriptEngineServiceBuilder; -import com.stardust.autojs.ScriptExecutionListener; -import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.engine.NodeJsJavaScriptEngineManager; import com.stardust.autojs.runtime.*; -import com.stardust.autojs.script.ScriptSource; import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.automator.simple_action.SimpleActionPerformHost; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.scripts.StorageScriptProvider; +import com.stardust.scriptdroid.ui.console.StardustConsole; import com.stardust.util.Supplier; +import com.stardust.util.UiHandler; import com.stardust.view.accessibility.AccessibilityInfoProvider; import com.stardust.scriptdroid.layout_inspector.LayoutInspector; import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder; @@ -51,54 +48,32 @@ public class AutoJs implements AccessibilityBridge { private final LayoutInspector mLayoutInspector = new LayoutInspector(); private final ScriptEngineService mScriptEngineService; private final AccessibilityInfoProvider mAccessibilityInfoProvider; - private final Handler mUiHandler; + private final UiHandler mUiHandler; private AutoJs(final Context context) { - mUiHandler = new Handler(context.getMainLooper()); + mUiHandler = new UiHandler(context); mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager()); NodeJsJavaScriptEngineManager manager = new NodeJsJavaScriptEngineManager(context); manager.setRequirePath(StorageScriptProvider.DEFAULT_DIRECTORY_PATH); mScriptEngineService = new ScriptEngineServiceBuilder() - .context(context) + .uiHandler(mUiHandler) + .globalConsole(new TimberConsole()) .engineManger(manager) .runtime(new Supplier() { @Override public ScriptRuntime get() { - return new ScriptRuntime(context, mUiHandler, new TimberConsole(), AutoJs.this); + return new ScriptRuntime(mUiHandler, new StardustConsole(mUiHandler), AutoJs.this); } }) .build(); addAccessibilityServiceDelegates(); - setDefaultScriptExecutionListener(mScriptEngineService); - } - - - private static void setDefaultScriptExecutionListener(ScriptEngineService scriptEngineService) { - final ScriptExecutionListener listener = scriptEngineService.getDefaultScriptExecutionListener(); - scriptEngineService.setDefaultScriptExecutionListener(new ScriptExecutionListener() { - @Override - public void onStart(JavaScriptEngine engine, ScriptSource source) { - listener.onStart(engine, source); - FlurryAgent.logEvent("EXEC:" + source.toString()); - } - - @Override - public void onSuccess(JavaScriptEngine engine, ScriptSource source, Object result) { - listener.onSuccess(engine, source, result); - } - - @Override - public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) { - listener.onException(engine, source, e); - } - }); + mScriptEngineService.registerGlobalScriptExecutionListener(new ScriptExecutionGlobalListener()); } private void addAccessibilityServiceDelegates() { AccessibilityWatchDogService.addDelegate(100, mAccessibilityInfoProvider); - // AccessibilityWatchDogService.addDelegate(200, mLayoutInspector); AccessibilityWatchDogService.addDelegate(300, mAccessibilityActionRecorder); // AccessibilityWatchDogService.addDelegate(400, mSimpleActionPerformHost); //AccessibilityWatchDogService.addDelegate(500, mAccessibilityEventCommandHost); diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java new file mode 100644 index 00000000..1d981ba3 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java @@ -0,0 +1,41 @@ +package com.stardust.scriptdroid.autojs; + +import com.flurry.android.FlurryAgent; +import com.stardust.autojs.ScriptEngineService; +import com.stardust.autojs.execution.ScriptExecution; +import com.stardust.autojs.execution.ScriptExecutionListener; +import com.stardust.autojs.runtime.ScriptInterruptedException; +import com.stardust.scriptdroid.App; +import com.stardust.scriptdroid.R; + +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * Created by Stardust on 2017/5/3. + */ + +public class ScriptExecutionGlobalListener implements ScriptExecutionListener { + private static final String ENGINE_TAG_START_TIME = "com.stardust.scriptdroid.autojs.Goodbye, World"; + + @Override + public void onStart(ScriptExecution execution) { + execution.getEngine().setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis()); + FlurryAgent.logEvent("EXEC:" + execution.getSource().toString()); + } + + @Override + public void onSuccess(ScriptExecution execution, Object result) { + onFinish(execution); + } + + private void onFinish(ScriptExecution execution) { + long millis = System.currentTimeMillis() - (long) execution.getEngine().getTag(ENGINE_TAG_START_TIME); + execution.getRuntime().console.verbose(App.getApp().getString(R.string.text_execution_finished), execution.getSource().toString(), (double) millis / 1000); + } + + @Override + public void onException(ScriptExecution execution, Exception e) { + onFinish(execution); + } + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/ConsoleFloaty.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/ConsoleFloaty.java deleted file mode 100644 index a58dfff5..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/ConsoleFloaty.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.stardust.scriptdroid.external.floating_window.console; - -import android.content.Context; -import android.content.ContextWrapper; -import android.support.annotation.Nullable; -import android.view.ContextThemeWrapper; -import android.view.View; - -import com.stardust.enhancedfloaty.ResizableExpandableFloaty; -import com.stardust.enhancedfloaty.ResizableExpandableFloatyService; -import com.stardust.enhancedfloaty.ResizableFloaty; -import com.stardust.enhancedfloaty.ResizableFloatyService; - -import com.stardust.scriptdroid.R; - -/** - * Created by Stardust on 2017/4/20. - */ - -public class ConsoleFloaty extends ResizableExpandableFloaty { - - private ContextWrapper mContextWrapper; - private View mResizer, mMoveCursor; - - public ConsoleFloaty() { - setShouldRequestFocusWhenExpand(false); - } - - @Override - public View inflateCollapsedView(ResizableExpandableFloatyService service) { - ensureContextWrapper(service); - return View.inflate(mContextWrapper, R.layout.floating_window_collapse, null); - } - - private void ensureContextWrapper(Context context) { - if (mContextWrapper == null) { - mContextWrapper = new ContextThemeWrapper(context, R.style.AppTheme); - } - } - - @Override - public View inflateExpandedView(ResizableExpandableFloatyService service) { - ensureContextWrapper(service); - View view = View.inflate(mContextWrapper, R.layout.floating_console_expand, null); - setListeners(view, service); - return view; - } - - private void setListeners(final View view, final ResizableExpandableFloatyService service) { - view.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - service.stopSelf(); - } - }); - view.findViewById(R.id.move_or_resize).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mMoveCursor.getVisibility() == View.VISIBLE) { - mMoveCursor.setVisibility(View.GONE); - mResizer.setVisibility(View.GONE); - } else { - mMoveCursor.setVisibility(View.VISIBLE); - mResizer.setVisibility(View.VISIBLE); - } - } - }); - } - - @Nullable - @Override - public View getResizerView(View expandedView) { - mResizer = expandedView.findViewById(R.id.resizer); - return mResizer; - } - - @Nullable - @Override - public View getMoveCursorView(View expandedView) { - mMoveCursor = expandedView.findViewById(R.id.move_cursor); - return mMoveCursor; - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsole.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsole.java deleted file mode 100644 index e58baaf7..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsole.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.stardust.scriptdroid.external.floating_window.console; - -import android.content.Context; - -import com.stardust.enhancedfloaty.ResizableExpandableFloatyService; -import com.stardust.enhancedfloaty.ResizableFloatyService; - -/** - * Created by Stardust on 2017/4/18. - */ - -public class FloatingConsole { - - public static void startFloatingService(Context context) { - ResizableExpandableFloatyService.startService(context, new ConsoleFloaty()); - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleService.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleService.java deleted file mode 100644 index 31b52789..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.stardust.scriptdroid.external.floating_window.console; - -/** - * Created by Stardust on 2017/4/30. - */ - -public class FloatingConsoleService { -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleView.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleView.java deleted file mode 100644 index 7a2e38d2..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/console/FloatingConsoleView.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.stardust.scriptdroid.external.floating_window.console; - -import android.content.Context; -import android.graphics.Color; -import android.util.AttributeSet; -import android.widget.TextView; - -import com.jraska.console.Console; -import com.stardust.scriptdroid.R; - -/** - * Created by Stardust on 2017/4/30. - */ - -public class FloatingConsoleView extends Console { - public FloatingConsoleView(Context context) { - super(context); - init(); - } - - public FloatingConsoleView(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public FloatingConsoleView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - public FloatingConsoleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(); - } - - private void init() { - findViewById(R.id.console_scroll_view).setBackground(getBackground()); - ((TextView) findViewById(R.id.console_text)).setTextIsSelectable(true); - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/HoverMenuService.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/HoverMenuService.java index 01b026ad..e433a622 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/HoverMenuService.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/HoverMenuService.java @@ -181,6 +181,8 @@ public class HoverMenuService extends Service { if (eventBus.isRegistered(this)) eventBus.unregister(this); setIsRunning(false); + mWindowViewController.removeView(mFloatingLayoutBoundsView); + mWindowViewController.removeView(mFloatingLayoutHierarchyView); } diff --git a/app/src/main/java/com/stardust/scriptdroid/layout_inspector/LayoutInspector.java b/app/src/main/java/com/stardust/scriptdroid/layout_inspector/LayoutInspector.java index dcb6af97..f1e64b2f 100644 --- a/app/src/main/java/com/stardust/scriptdroid/layout_inspector/LayoutInspector.java +++ b/app/src/main/java/com/stardust/scriptdroid/layout_inspector/LayoutInspector.java @@ -6,6 +6,7 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import com.stardust.scriptdroid.service.AccessibilityWatchDogService; +import com.stardust.util.UnderuseExecutors; import com.stardust.view.accessibility.AccessibilityDelegate; import java.util.Set; @@ -20,7 +21,7 @@ public class LayoutInspector { private volatile NodeInfo mCapture; private volatile boolean mDumping = false; - private Executor mExecutor = Executors.newSingleThreadExecutor(); + private Executor mExecutor = UnderuseExecutors.getExecutor(); public void captureCurrentWindow() { AccessibilityService service = AccessibilityWatchDogService.getInstance(); diff --git a/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java index 499c364e..e2a6e5be 100644 --- a/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java +++ b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java @@ -3,26 +3,18 @@ package com.stardust.scriptdroid.service; import android.os.Build; import android.util.Log; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import com.stardust.autojs.runtime.JavascriptInterface; -import com.stardust.view.accessibility.AccessibilityDelegate; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; +import com.stardust.view.accessibility.AccessibilityDelegate; import com.stardust.view.accessibility.AccessibilityService; import com.stardust.view.accessibility.AccessibilityServiceUtils; -import org.greenrobot.eventbus.EventBus; - -import java.lang.ref.WeakReference; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; /** * Created by Stardust on 2017/2/14. diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleFloaty.java b/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleFloaty.java new file mode 100644 index 00000000..fc1428bc --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleFloaty.java @@ -0,0 +1,133 @@ +package com.stardust.scriptdroid.ui.console; + +import android.content.Context; +import android.content.ContextWrapper; +import android.support.annotation.Nullable; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.widget.TextView; + +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.enhancedfloaty.ResizableExpandableFloaty; +import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow; +import com.stardust.scriptdroid.R; +import com.stardust.util.ViewUtil; + +/** + * Created by Stardust on 2017/4/20. + */ + +public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableExpandableFloaty { + + private ContextWrapper mContextWrapper; + private View mResizer, mMoveCursor; + private TextView mTitleView; + private StardustConsole mConsole; + private CharSequence mTitle; + + public ConsoleFloaty(StardustConsole console) { + mConsole = console; + setShouldRequestFocusWhenExpand(false); + setInitialX(100); + setInitialY(1000); + } + + @Override + public View inflateCollapsedView(FloatyService service, final ResizableExpandableFloatyWindow window) { + ensureContextWrapper(service); + View view = View.inflate(mContextWrapper, R.layout.floating_window_collapse, null); + view.post(new Runnable() { + @Override + public void run() { + window.expand(); + } + }); + return view; + } + + private void ensureContextWrapper(Context context) { + if (mContextWrapper == null) { + mContextWrapper = new ContextThemeWrapper(context, R.style.AppTheme); + } + } + + @Override + public View inflateExpandedView(FloatyService service, ResizableExpandableFloatyWindow window) { + ensureContextWrapper(service); + View view = View.inflate(mContextWrapper, R.layout.floating_console_expand, null); + ((ConsoleView) view.findViewById(R.id.console)).setConsole(mConsole); + setListeners(view, window); + initConsoleTitle(view); + setInitialMeasure(view); + return view; + } + + private void setInitialMeasure(final View view) { + view.post(new Runnable() { + @Override + public void run() { + ViewUtil.setViewMeasure(view, 800, 800); + } + }); + } + + private void initConsoleTitle(View view) { + mTitleView = (TextView) view.findViewById(R.id.title); + if (mTitle != null) { + mTitleView.setText(mTitle); + } + } + + private void setListeners(final View view, final ResizableExpandableFloatyWindow window) { + view.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + window.close(); + } + }); + view.findViewById(R.id.move_or_resize).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mMoveCursor.getVisibility() == View.VISIBLE) { + mMoveCursor.setVisibility(View.GONE); + mResizer.setVisibility(View.GONE); + } else { + mMoveCursor.setVisibility(View.VISIBLE); + mResizer.setVisibility(View.VISIBLE); + } + } + }); + view.findViewById(R.id.minimize).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + window.collapse(); + } + }); + } + + @Nullable + @Override + public View getResizerView(View expandedView) { + mResizer = expandedView.findViewById(R.id.resizer); + return mResizer; + } + + @Nullable + @Override + public View getMoveCursorView(View expandedView) { + mMoveCursor = expandedView.findViewById(R.id.move_cursor); + return mMoveCursor; + } + + public void setTitle(final CharSequence title) { + mTitle = title; + if (mTitleView != null) { + mTitleView.post(new Runnable() { + @Override + public void run() { + mTitleView.setText(title); + } + }); + } + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleView.java b/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleView.java new file mode 100644 index 00000000..ba0e9a06 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleView.java @@ -0,0 +1,147 @@ +package com.stardust.scriptdroid.ui.console; + +import android.content.Context; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; +import android.support.v7.widget.AppCompatTextView; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.method.ScrollingMovementMethod; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.util.Log; +import android.util.SparseArray; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.stardust.scriptdroid.R; +import com.stardust.util.MapEntries; +import com.stardust.util.SparseArrayEntries; + +import java.io.Closeable; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Stardust on 2017/5/2. + */ + +public class ConsoleView extends LinearLayout implements StardustConsole.LogListener { + + private static final SparseArray COLORS = new SparseArrayEntries() + .entry(Log.VERBOSE, 0xdfc0c0c0) + .entry(Log.DEBUG, 0xdfffffff) + .entry(Log.INFO, 0xff64dd17) + .entry(Log.WARN, 0xff2962ff) + .entry(Log.ERROR, 0xffd50000) + .entry(Log.ASSERT, 0xffff534e) + .sparseArray(); + + private StardustConsole mConsole; + private TextView mTextView; + private EditText mEditText; + + public ConsoleView(Context context) { + super(context); + init(); + } + + public ConsoleView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(); + } + + public ConsoleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + inflate(getContext(), R.layout.console_view, this); + mTextView = (TextView) findViewById(R.id.textView); + } + + private void initEditText() { + //mEditText = (EditText) findViewById(R.id.ediText); + mEditText.setFocusableInTouchMode(true); + mTextView.setMovementMethod(new ScrollingMovementMethod()); + setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + }); + } + + public void setConsole(StardustConsole console) { + mConsole = console; + mConsole.setLogListener(this); + } + + @Override + public void onNewLog(StardustConsole.Log log) { + log(log.level, log.content); + log(log.level, "\n"); + } + + private void log(int level, CharSequence log) { + int color = getColorForLevel(level); + final Spannable spannable = buildColorSpannable(log, color); + post(new Runnable() { + @Override + public void run() { + mTextView.append(spannable); + } + + }); + } + + private void scrollToBottom() { + mTextView.post(new Runnable() { + @Override + public void run() { + mTextView.scrollTo(0, mTextView.getLayout().getLineTop(mTextView.getLineCount())); + } + }); + } + + private Spannable buildColorSpannable(CharSequence log, int color) { + Spannable spannable = new SpannableString(log); + spannable.setSpan(new ForegroundColorSpan(color), 0, log.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + return spannable; + } + + private int getColorForLevel(int level) { + return COLORS.get(level); + } + + @Override + public void onLogClear() { + mTextView.setText(""); + } + + @Override + protected void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + if (visibility == VISIBLE) { + refreshLog(); + } + } + + private void refreshLog() { + if (mConsole != null) { + mTextView.setText(""); + for (StardustConsole.Log log : mConsole.getLogs()) { + onNewLog(log); + } + } + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/console/StardustConsole.java b/app/src/main/java/com/stardust/scriptdroid/ui/console/StardustConsole.java new file mode 100644 index 00000000..743b1d00 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/console/StardustConsole.java @@ -0,0 +1,108 @@ +package com.stardust.scriptdroid.ui.console; + +import android.content.Context; +import android.content.Intent; + +import com.stardust.autojs.runtime.AbstractConsole; +import com.stardust.autojs.runtime.api.Console; +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow; +import com.stardust.scriptdroid.autojs.AutoJs; +import com.stardust.util.UiHandler; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Stardust on 2017/5/2. + */ + +public class StardustConsole extends AbstractConsole { + + public static class Log { + + public int level; + public CharSequence content; + + public Log(int level, CharSequence content) { + this.level = level; + this.content = content; + } + } + + public interface LogListener { + void onNewLog(Log log); + + void onLogClear(); + } + + private final Console GLOBAL_CONSOLE = AutoJs.getInstance().getScriptEngineService().getGlobalConsole(); + private List mLogs = new ArrayList<>(); + private ResizableExpandableFloatyWindow mFloatyWindow; + private ConsoleFloaty mConsoleFloaty; + private LogListener mLogListener; + private UiHandler mUiHandler; + + public StardustConsole(UiHandler uiHandler) { + mUiHandler = uiHandler; + mConsoleFloaty = new ConsoleFloaty(this); + mFloatyWindow = new ResizableExpandableFloatyWindow(mConsoleFloaty); + } + + public void setLogListener(LogListener logListener) { + mLogListener = logListener; + } + + public List getLogs() { + return mLogs; + } + + @Override + public void println(int level, CharSequence charSequence) { + Log log = new Log(level, charSequence); + mLogs.add(log); + GLOBAL_CONSOLE.println(level, charSequence); + if (mLogListener != null) { + mLogListener.onNewLog(log); + } + } + + + @Override + public void clear() { + mLogs.clear(); + if (mLogListener != null) { + mLogListener.onLogClear(); + } + } + + @Override + public void show() { + startFloatyService(); + mUiHandler.post(new Runnable() { + @Override + public void run() { + FloatyService.addWindow(mFloatyWindow); + } + }); + } + + private void startFloatyService() { + Context context = mUiHandler.getContext(); + context.startService(new Intent(context, FloatyService.class)); + } + + @Override + public void hide() { + try { + mFloatyWindow.close(); + } catch (IllegalArgumentException ignored) { + + } + } + + @Override + public void setTitle(CharSequence title) { + mConsoleFloaty.setTitle(title); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/console/TimberConsole.java b/app/src/main/java/com/stardust/scriptdroid/ui/console/TimberConsole.java index c501d703..ba0e50d7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/console/TimberConsole.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/console/TimberConsole.java @@ -26,16 +26,16 @@ public class TimberConsole extends AbstractConsole { Timber.plant(new ConsoleTree.Builder() .minPriority(Log.VERBOSE) .verboseColor(0xff909090) - .debugColor(0xffc88b48) - .infoColor(0xffc9c9c9) - .warnColor(0xffa97db6) + .debugColor(0xdf000000) + .infoColor(0xdf4caf50) + .warnColor(0xff2196f3) .errorColor(0xffff534e) - .assertColor(0xffff5540) + .assertColor(0xffff534e) .build()); } @Override - protected void log(int level, CharSequence charSequence) { + public void println(int level, CharSequence charSequence) { if (level == Log.DEBUG) { SpannableString spannable = new SpannableString(charSequence); spannable.setSpan(new ForegroundColorSpan(0xdd000000), 0, charSequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -60,4 +60,9 @@ public class TimberConsole extends AbstractConsole { public void hide() { throw new UnsupportedOperationException(); } + + @Override + public void setTitle(CharSequence title) { + + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java index 998e501e..d41d6c9f 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java @@ -11,6 +11,7 @@ import android.util.SparseArray; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.Toast; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; @@ -20,16 +21,16 @@ import com.jecelyin.editor.v2.core.widget.TextView; import com.jecelyin.editor.v2.ui.EditorDelegate; import com.jecelyin.editor.v2.view.EditorView; import com.jecelyin.editor.v2.view.menu.MenuDef; +import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.script.FileScriptSource; import com.stardust.autojs.script.JsBeautifier; import com.stardust.autojs.script.StringScriptSource; import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floating_window.console.FloatingConsole; +import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.scripts.ScriptFile; import com.stardust.scriptdroid.tool.JsBeautifierFactory; import com.stardust.scriptdroid.tool.MaterialDialogFactory; import com.stardust.scriptdroid.ui.BaseActivity; -import com.stardust.scriptdroid.ui.console.ConsoleActivity; import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhanceBar; import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity; import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils; @@ -109,6 +110,7 @@ public class EditActivity extends Editor920Activity { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ACTION_ON_RUN_FINISHED)) { + mScriptExecution = null; setMenuStatus(R.id.run, MenuDef.STATUS_NORMAL); String msg = intent.getStringExtra(EXTRA_EXCEPTION_MESSAGE); if (msg != null) { @@ -119,6 +121,7 @@ public class EditActivity extends Editor920Activity { } }; private JsBeautifier mJsBeautifier = JsBeautifierFactory.getJsBeautify(); + private ScriptExecution mScriptExecution; public void onCreate(Bundle b) { super.onCreate(b); @@ -209,9 +212,9 @@ public class EditActivity extends Editor920Activity { Snackbar.make(mView, R.string.text_start_running, Snackbar.LENGTH_SHORT).show(); setMenuStatus(R.id.run, MenuDef.STATUS_DISABLED); if (mFile != null) { - ScriptFileOperation.runOnEditView(new FileScriptSource(mName, mFile)); + mScriptExecution = ScriptFileOperation.runOnEditView(new FileScriptSource(mName, mFile)); } else { - ScriptFileOperation.runOnEditView(new StringScriptSource(mName, mEditorDelegate.getText())); + mScriptExecution = ScriptFileOperation.runOnEditView(new StringScriptSource(mName, mEditorDelegate.getText())); } } @@ -261,7 +264,7 @@ public class EditActivity extends Editor920Activity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_console: - startActivity(new Intent(getContext(), ConsoleActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + showConsole(); return true; case R.id.action_help: HelpCatalogueActivity.showMainCatalogue(this); @@ -272,10 +275,27 @@ public class EditActivity extends Editor920Activity { case R.id.action_open_by_other_apps: openByOtherApps(); return true; + case R.id.action_force_stop: + forceStop(); + return true; } return super.onOptionsItemSelected(item); } + private void showConsole() { + if (mScriptExecution != null) { + mScriptExecution.getRuntime().console.show(); + } else { + AutoJs.getInstance().getScriptEngineService().getGlobalConsole().show(); + } + } + + private void forceStop() { + if (mScriptExecution != null) { + mScriptExecution.getEngine().forceStop(); + } + } + private void openByOtherApps() { if (mFile != null) ScriptFileOperation.openByOtherApps(mFile.getPath()); @@ -297,9 +317,15 @@ public class EditActivity extends Editor920Activity { } @Override - public void onException(Exception e) { - dialog.dismiss(); + public void onException(final Exception e) { e.printStackTrace(); + runOnUiThread(new Runnable() { + @Override + public void run() { + dialog.dismiss(); + Toast.makeText(EditActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); + } + }); } }); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java index dc0ac7c2..b8686bbe 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletion.java @@ -106,7 +106,7 @@ public class CodeCompletion implements TextWatcher { mFunctions = functions; } - private String[] mFunctions = {"toast", "launchPackage", "launch", "launchApp", "click", "longClick", "scrollUp", "scrollDown", "select", "focus", "paste", "input", "sleep", "isStopped", "notStopped", "println", "err", "openConsole", "clearConsole", "shell", "getTexts", "getPackageName", "getActivityName", "setClip", "addAccessibilityDelegate"}; + private String[] mFunctions = {"toast", "launchPackage", "launch", "launchApp", "click", "longClick", "scrollUp", "scrollDown", "select", "focus", "paste", "input", "sleep", "isStopped", "notStopped", "printf", "err", "openConsole", "clearConsole", "shell", "getTexts", "getPackageName", "getActivityName", "setClip", "addAccessibilityDelegate"}; private boolean searchCodeCompletion(String str) { Collection c = searchWordCompletion(str); diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java index 8bd92dfe..a41c42a2 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java @@ -19,12 +19,15 @@ import com.stardust.scriptdroid.service.AccessibilityWatchDogService; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.scriptdroid.ui.console.ConsoleActivity; import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity; +import com.stardust.util.UnderuseExecutors; import com.stardust.view.ViewBinder; import com.stardust.view.ViewBinding; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.util.concurrent.Executor; + /** * Created by Stardust on 2017/1/30. @@ -38,7 +41,8 @@ public class SlideMenuFragment extends Fragment { activity.getSupportFragmentManager().beginTransaction().replace(viewId, fragment).commit(); } - private SwitchCompat mAutoOperateServiceSwitch, mFloatingWindowSwitch; + private SwitchCompat mAccessibilityServiceSwitch, mFloatingWindowSwitch; + private Executor mExecutor = UnderuseExecutors.getExecutor(); @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -67,17 +71,28 @@ public class SlideMenuFragment extends Fragment { private void syncSwitchState() { - mAutoOperateServiceSwitch.postDelayed(new Runnable() { + mAccessibilityServiceSwitch.postDelayed(new Runnable() { @Override public void run() { - mAutoOperateServiceSwitch.setChecked(AccessibilityWatchDogService.isEnable()); + mExecutor.execute(new Runnable() { + @Override + public void run() { + final boolean checked = AccessibilityWatchDogService.isEnable(); + mAccessibilityServiceSwitch.post(new Runnable() { + @Override + public void run() { + mAccessibilityServiceSwitch.setChecked(checked); + } + }); + } + }); } }, 450); mFloatingWindowSwitch.setChecked(FloatingWindowManger.isFloatingWindowShowing()); } private void setUpSwitchCompat() { - mAutoOperateServiceSwitch = $(R.id.sw_auto_operate_service); + mAccessibilityServiceSwitch = $(R.id.sw_auto_operate_service); mFloatingWindowSwitch = $(R.id.sw_floating_window); } @@ -94,7 +109,7 @@ public class SlideMenuFragment extends Fragment { @ViewBinding.Click(R.id.auto_operate_service) private void clickAutoOperateServiceSwitch() { - mAutoOperateServiceSwitch.toggle(); + mAccessibilityServiceSwitch.toggle(); } @ViewBinding.Check(R.id.sw_auto_operate_service) diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java index d3b0b9a5..1b475a2d 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java @@ -4,8 +4,10 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; -import com.stardust.autojs.ScriptExecutionListener; -import com.stardust.autojs.engine.JavaScriptEngine; +import com.stardust.autojs.execution.ScriptExecution; +import com.stardust.autojs.execution.ScriptExecutionListener; +import com.stardust.autojs.execution.SimpleScriptExecutionListener; +import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.autojs.script.FileScriptSource; import com.stardust.autojs.script.ScriptSource; import com.stardust.autojs.script.StringScriptSource; @@ -30,23 +32,20 @@ public abstract class ScriptFileOperation { public static final String EXTRA_EXCEPTION_MESSAGE = "EXTRA_EXCEPTION_MESSAGE"; - private static final ScriptExecutionListener SCRIPT_EXECUTION_LISTENER = new ScriptExecutionListener() { + private static final ScriptExecutionListener RUN_ON_EDIT_VIEW_SCRIPT_EXECUTION_LISTENER = new SimpleScriptExecutionListener() { @Override - public void onStart(JavaScriptEngine engine, ScriptSource source) { - AutoJs.getInstance().getScriptEngineService().getDefaultScriptExecutionListener().onStart(engine, source); - } - - @Override - public void onSuccess(JavaScriptEngine engine, ScriptSource source, Object result) { + public void onSuccess(ScriptExecution execution, Object result) { App.getApp().sendBroadcast(new Intent(ACTION_ON_RUN_FINISHED)); } @Override - public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) { + public void onException(ScriptExecution execution, Exception e) { + if (ScriptInterruptedException.causedByInterrupted(e)) { + return; + } App.getApp().sendBroadcast(new Intent(ACTION_ON_RUN_FINISHED) .putExtra(EXTRA_EXCEPTION_MESSAGE, e.getMessage())); - e.printStackTrace(); } }; @@ -78,8 +77,8 @@ public abstract class ScriptFileOperation { AutoJs.getInstance().getScriptEngineService().execute(new StringScriptSource(file.name, AssetsCache.get(context.getAssets(), file.path))); } - public static void runOnEditView(ScriptSource scriptSource) { - AutoJs.getInstance().getScriptEngineService().execute(scriptSource, SCRIPT_EXECUTION_LISTENER); + public static ScriptExecution runOnEditView(ScriptSource scriptSource) { + return AutoJs.getInstance().getScriptEngineService().execute(scriptSource, RUN_ON_EDIT_VIEW_SCRIPT_EXECUTION_LISTENER); } } \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java index 896ddedd..f0c2df22 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java @@ -1,9 +1,7 @@ package com.stardust.scriptdroid.ui.main.task; import android.content.Context; -import android.support.annotation.IntDef; import android.support.annotation.Nullable; -import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.ThemeColorRecyclerView; import android.util.AttributeSet; @@ -14,6 +12,9 @@ import android.widget.TextView; import android.workground.WrapContentLinearLayoutManager; import com.stardust.autojs.ScriptEngineService; +import com.stardust.autojs.execution.ScriptExecution; +import com.stardust.autojs.execution.ScriptExecutionListener; +import com.stardust.autojs.execution.SimpleScriptExecutionListener; import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.engine.JavaScriptEngineManager; import com.stardust.autojs.script.ScriptSource; @@ -22,7 +23,6 @@ import com.stardust.scriptdroid.autojs.AutoJs; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; /** @@ -51,6 +51,23 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Java private final List mScriptEngines = new ArrayList<>(); private Adapter mAdapter; private final ScriptEngineService mScriptEngineService = AutoJs.getInstance().getScriptEngineService(); + private ScriptExecutionListener mScriptExecutionListener = new SimpleScriptExecutionListener() { + @Override + public void onStart(final ScriptExecution execution) { + post(new Runnable() { + @Override + public void run() { + int position = mScriptEngines.indexOf(execution.getEngine()); + if (position >= 0) { + mAdapter.notifyItemChanged(position); + } else { + updateEngineList(); + } + } + }); + + } + }; public TaskListRecyclerView(Context context) { super(context); @@ -89,18 +106,22 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Java protected void onAttachedToWindow() { super.onAttachedToWindow(); mScriptEngineService.registerEngineLifecycleCallback(this); + AutoJs.getInstance().getScriptEngineService().registerGlobalScriptExecutionListener(mScriptExecutionListener); } @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); - updateEngineList(); + if (visibility == VISIBLE) { + updateEngineList(); + } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mScriptEngineService.unregisterEngineLifecycleCallback(this); + AutoJs.getInstance().getScriptEngineService().unregisterGlobalScriptExecutionListener(mScriptExecutionListener); } @Override @@ -122,8 +143,13 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Java @Override public void run() { final int i = mScriptEngines.indexOf(engine); - mScriptEngines.remove(i); - mAdapter.notifyItemRemoved(i); + if (i >= 0) { + mScriptEngines.remove(i); + mAdapter.notifyItemRemoved(i); + } else { + updateEngineList(); + } + } }); } diff --git a/app/src/main/res/drawable/circle_cool_black.xml b/app/src/main/res/drawable/circle_cool_black.xml new file mode 100644 index 00000000..398541c8 --- /dev/null +++ b/app/src/main/res/drawable/circle_cool_black.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/debug_console_icon_128.png b/app/src/main/res/drawable/debug_console_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..90dfbe3b263be3447cae808a763c2d685afc60e4 GIT binary patch literal 1522 zcmZvcdpOez7{`Ab8-}SJmpE!2NsT!s&9N?SbDNzZmt4yfQyCd)4w+df>9{Y(TpmP; z^0bsJTDg?0+FwLhEF~&x9=Ov z=9u3xRAK3EMmc^n+hSszt!kv#w%Z@_(j!|}Cw%sC|a z3=i6@5dcOnB^xdD7-QgEnsmWbov0%a9tM>$RnoA6nFh6;m(mCSrIUqcH)Fc(Js@nKruN@${lry z4aHxNYbTC~JYTF&bHOF!u&M2_!ChoTzvUEzj*L=}>j27KRU73178#MNv_s5*zwhXH zn3Y+nR8xW-NP=Q`qk_#V_ignG1xLi|M7jQy-`+JYy0!$TX%!6T0?-1Ng0UA$coJF3 zfRO`bYLYJ1oGYkLAdwRmwF`ucCYYjq8OBy4PLZo|cU#raZsm>zfmK#193Rl0dT_W0 z6<&tqG|DldiVaUb}%>wq#uN+b3aU3!2FhsXqt} z>(y@V7Nx?qPfj!(0R?p`-~mB#gk%{qgNRKXZ2$}y=UPzq#hsH4)6zO!$b6U#nMq_{ zcn6t3CL2B>ODSBrG1F$aeubeiDKrqk$b?(+MKa80R{S;%S#Q=0BU7Y#WLeWAJ69UA zJs`B$DuQAMSlpL;=5ON_8C!s^XHMQ$86&+}c0UEy0#t-c`4@9vA6fwm4c19Ji&s9M zRM4h+k4lHnI}5g1@omF0an-upXC=WE3&V^gnz|%laZ~glY+zO*{}!Xju@&FYqu0R) zbgu#jH5BJQ^Nx3b^INOx&8A@Es3>+UX@b(C4-M7 zaKl`h!6UJZf-T+4Qqt6u2K2~Q#~#!=E2>x24_?0d;*d(OCzKHMgTkK^wSni)7o~y>#B0rT zxKWBfg`!tl#1A+&AiTL?nddZAI!ewW?J5;~MErVGow|f#ciqW9MkzNu4R$4p&lGc- z=4}hR21*BS7L*~Q!E$2E1B4BgqD5!_$%=aZ9@E|UY-|$4n-!=vv=7RaWLs_g&8wAf zUz~Y17i`vu)6&2KLaK$tiAnYjt>nw=R%y&~LHM)1h*9HiVIY99wmzE_8ykzlaQCpC zc&|lv=kL3M?|~{za-H63^Pm(RfvEpb$i5V`!|trNTbettQB&3NAh9j95#q8#rBLFM z*3zWk-}){*k6&4vXd$ueZu#&@VeM?$H~o@2cOoSEDo0c4me0A2KEHeHSDd=mT|-gg z^|x$mQ>?F5FoasY`>_F;W`}T}BzYYeT~=CcOMcS1##Z><6Swd$&zSTPPFtH>nWWLC jF7rL>;X91}6Ltl;EwtVR?=7y}C~<(`?BR6Nk<9uR27 - + - + \ No newline at end of file diff --git a/app/src/main/res/drawable/floating_console_bg_top.xml b/app/src/main/res/drawable/floating_console_bg_top.xml index 7aee34aa..dd3152b2 100644 --- a/app/src/main/res/drawable/floating_console_bg_top.xml +++ b/app/src/main/res/drawable/floating_console_bg_top.xml @@ -1,7 +1,7 @@ - + ?JWtgtJB>h^JYD@<);T3K0RVYT7<&K! diff --git a/app/src/main/res/layout/console_view.xml b/app/src/main/res/layout/console_view.xml new file mode 100644 index 00000000..ba164bb5 --- /dev/null +++ b/app/src/main/res/layout/console_view.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/floating_console_expand.xml b/app/src/main/res/layout/floating_console_expand.xml index ed66f5ef..d7b26e2f 100644 --- a/app/src/main/res/layout/floating_console_expand.xml +++ b/app/src/main/res/layout/floating_console_expand.xml @@ -10,61 +10,65 @@ android:layout_margin="12dp" android:orientation="vertical"> - + android:orientation="horizontal"> - + - + - + - + - - - + + - + - + android:src="@drawable/debug_console_icon_128"/> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_editor.xml b/app/src/main/res/menu/menu_editor.xml index 11d167a2..f7c87ce2 100644 --- a/app/src/main/res/menu/menu_editor.xml +++ b/app/src/main/res/menu/menu_editor.xml @@ -14,6 +14,12 @@ android:title="@string/text_console" app:showAsAction="never"/> + + key_guard_mode 控制台悬浮窗 布局分析中,请稍后点击 + 强制停止 + \n------------\n[%s]运行结束,用时%f秒 diff --git a/autojs/src/main/java/com/stardust/autojs/RunnableScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/RunnableScriptExecution.java deleted file mode 100644 index 03f2dd09..00000000 --- a/autojs/src/main/java/com/stardust/autojs/RunnableScriptExecution.java +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java b/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java index c7cf3dee..9d50ab78 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java +++ b/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java @@ -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 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() { diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java b/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java index 12632ae2..f8286a2b 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java +++ b/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java @@ -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 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); } diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptExecutionListener.java b/autojs/src/main/java/com/stardust/autojs/ScriptExecutionListener.java deleted file mode 100644 index 2ab43a6b..00000000 --- a/autojs/src/main/java/com/stardust/autojs/ScriptExecutionListener.java +++ /dev/null @@ -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); -} diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptExecutionTask.java b/autojs/src/main/java/com/stardust/autojs/ScriptExecutionTask.java deleted file mode 100644 index 6c6f5994..00000000 --- a/autojs/src/main/java/com/stardust/autojs/ScriptExecutionTask.java +++ /dev/null @@ -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; - } - } -} diff --git a/autojs/src/main/java/com/stardust/autojs/SimpleScriptExecutionListener.java b/autojs/src/main/java/com/stardust/autojs/SimpleScriptExecutionListener.java deleted file mode 100644 index 980bd607..00000000 --- a/autojs/src/main/java/com/stardust/autojs/SimpleScriptExecutionListener.java +++ /dev/null @@ -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) { - - } -} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngineManager.java b/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngineManager.java index b8f91a85..eecf4444 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngineManager.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngineManager.java @@ -114,7 +114,6 @@ public abstract class JavaScriptEngineManager { for (JavaScriptEngine engine : mEngines) { engine.forceStop(); } - mEngines.clear(); return n; } } diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java index 5605326e..96719a20 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java @@ -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 mTags = new Hashtable<>(); - private boolean mDestroyed = false; + private Map 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(); } } diff --git a/autojs/src/main/java/com/stardust/autojs/engine/ScriptExecuteActivity.java b/autojs/src/main/java/com/stardust/autojs/engine/ScriptExecuteActivity.java index 06f0feb3..2761c10e 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/ScriptExecuteActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/ScriptExecuteActivity.java @@ -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; diff --git a/autojs/src/main/java/com/stardust/autojs/ExecutionConfig.java b/autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java similarity index 92% rename from autojs/src/main/java/com/stardust/autojs/ExecutionConfig.java rename to autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java index 6f62396d..c5b36b5d 100644 --- a/autojs/src/main/java/com/stardust/autojs/ExecutionConfig.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java @@ -1,4 +1,4 @@ -package com.stardust.autojs; +package com.stardust.autojs.execution; import java.io.Serializable; diff --git a/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java new file mode 100644 index 00000000..3638fbdd --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java @@ -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; + } +} \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java similarity index 86% rename from autojs/src/main/java/com/stardust/autojs/ScriptExecution.java rename to autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java index 9a5da044..009876bc 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptExecution.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java @@ -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; } diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionListener.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionListener.java new file mode 100644 index 00000000..cd10dc82 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionListener.java @@ -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); +} diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionObserver.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionObserver.java new file mode 100644 index 00000000..b92ffdf9 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionObserver.java @@ -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 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); + } + } + +} diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionTask.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionTask.java new file mode 100644 index 00000000..c900c8df --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecutionTask.java @@ -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; + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/execution/SimpleScriptExecutionListener.java b/autojs/src/main/java/com/stardust/autojs/execution/SimpleScriptExecutionListener.java new file mode 100644 index 00000000..f38e484c --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/execution/SimpleScriptExecutionListener.java @@ -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) { + + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/rhino_android/AndroidContextFactory.java b/autojs/src/main/java/com/stardust/autojs/rhino_android/AndroidContextFactory.java index 26afb9e1..b3e27207 100644 --- a/autojs/src/main/java/com/stardust/autojs/rhino_android/AndroidContextFactory.java +++ b/autojs/src/main/java/com/stardust/autojs/rhino_android/AndroidContextFactory.java @@ -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(); } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractConsole.java b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractConsole.java index 42f82706..7b3453cf 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractConsole.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractConsole.java @@ -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))); } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterrupptedException.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterrupptedException.java deleted file mode 100644 index 947cc741..00000000 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterrupptedException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.stardust.autojs.runtime; - -/** - * Created by Stardust on 2017/4/30. - */ - -public class ScriptInterrupptedException extends ScriptStopException { - - -} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterruptedException.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterruptedException.java new file mode 100644 index 00000000..a694478c --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptInterruptedException.java @@ -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; + } + +} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java index 977d0cd9..50e32cc1 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -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)); } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java index a19fac44..ea044275 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Console.java @@ -36,4 +36,8 @@ public interface Console { @JavascriptInterface void hide(); + + void println(int level, CharSequence charSequence); + + void setTitle(CharSequence title); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebClient.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebClient.java index 361c00b4..cd98205e 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebClient.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/InjectableWebClient.java @@ -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; diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java index 536b3b39..1d64e6db 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/UiSelector.java @@ -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); diff --git a/autojs/src/main/java/com/stardust/autojs/script/JsBeautifier.java b/autojs/src/main/java/com/stardust/autojs/script/JsBeautifier.java index 8eafd267..b63055f0 100644 --- a/autojs/src/main/java/com/stardust/autojs/script/JsBeautifier.java +++ b/autojs/src/main/java/com/stardust/autojs/script/JsBeautifier.java @@ -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), "", 1, null); } catch (IOException e) { + exitContext(); throw new UncheckedIOException(e); } } diff --git a/common/src/main/java/com/stardust/pio/PRandomAccessBinaryFile.java b/common/src/main/java/com/stardust/pio/PRandomAccessBinaryFile.java index 09007503..f1d81311 100644 --- a/common/src/main/java/com/stardust/pio/PRandomAccessBinaryFile.java +++ b/common/src/main/java/com/stardust/pio/PRandomAccessBinaryFile.java @@ -1,5 +1,6 @@ package com.stardust.pio; +import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/common/src/main/java/com/stardust/pio/PReadableTextFile.java b/common/src/main/java/com/stardust/pio/PReadableTextFile.java index 30da11b2..3c552bc6 100644 --- a/common/src/main/java/com/stardust/pio/PReadableTextFile.java +++ b/common/src/main/java/com/stardust/pio/PReadableTextFile.java @@ -8,7 +8,7 @@ import java.util.List; * Created by Stardust on 2017/4/1. */ -public class PReadableTextFile extends PFile { +public class PReadableTextFile extends PFile implements Closeable { private BufferedReader mBufferedReader; private FileInputStream mFileInputStream; @@ -91,6 +91,7 @@ public class PReadableTextFile extends PFile { } } + @Override public void close() { try { if (mBufferedReader != null) { diff --git a/common/src/main/java/com/stardust/pio/PWritableTextFile.java b/common/src/main/java/com/stardust/pio/PWritableTextFile.java index cc7fa80b..c48716e6 100644 --- a/common/src/main/java/com/stardust/pio/PWritableTextFile.java +++ b/common/src/main/java/com/stardust/pio/PWritableTextFile.java @@ -1,6 +1,7 @@ package com.stardust.pio; import java.io.BufferedWriter; +import java.io.Closeable; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -13,7 +14,7 @@ import java.util.List; * Created by Stardust on 2017/4/1. */ -public class PWritableTextFile extends PFile { +public class PWritableTextFile extends PFile implements Closeable { public static PWritableTextFile open(String path, String encoding, int bufferSize) { return new PWritableTextFile(path, encoding, bufferSize, false); diff --git a/common/src/main/java/com/stardust/util/UiHandler.java b/common/src/main/java/com/stardust/util/UiHandler.java new file mode 100644 index 00000000..31234a0b --- /dev/null +++ b/common/src/main/java/com/stardust/util/UiHandler.java @@ -0,0 +1,43 @@ +package com.stardust.util; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.widget.Toast; + +/** + * Created by Stardust on 2017/5/2. + */ + +public class UiHandler extends Handler { + + + private Context mContext; + + public UiHandler(Context context) { + super(Looper.getMainLooper()); + mContext = context; + } + + public Context getContext() { + return mContext; + } + + public void toast(final String message) { + post(new Runnable() { + @Override + public void run() { + Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show(); + } + }); + } + + public void toast(final int resId) { + post(new Runnable() { + @Override + public void run() { + Toast.makeText(mContext, resId, Toast.LENGTH_SHORT).show(); + } + }); + } +} diff --git a/common/src/main/java/com/stardust/util/UnderuseExecutors.java b/common/src/main/java/com/stardust/util/UnderuseExecutors.java new file mode 100644 index 00000000..76154ec6 --- /dev/null +++ b/common/src/main/java/com/stardust/util/UnderuseExecutors.java @@ -0,0 +1,21 @@ +package com.stardust.util; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +/** + * Created by Stardust on 2017/5/2. + */ + +public class UnderuseExecutors { + + private static Executor mExecutor = Executors.newSingleThreadExecutor(); + + public static void execute(Runnable runnable) { + mExecutor.execute(runnable); + } + + public static Executor getExecutor() { + return mExecutor; + } +} diff --git a/common/src/main/java/com/stardust/util/ViewUtil.java b/common/src/main/java/com/stardust/util/ViewUtil.java index 8443f958..cbbda6f5 100644 --- a/common/src/main/java/com/stardust/util/ViewUtil.java +++ b/common/src/main/java/com/stardust/util/ViewUtil.java @@ -41,4 +41,10 @@ public class ViewUtil { } + public static void setViewMeasure(View view, int width, int height) { + ViewGroup.LayoutParams params = view.getLayoutParams(); + params.width = width; + params.height = height; + view.setLayoutParams(params); + } }