From 2f5573d9c2d72d5433a66f77261e92d9caeb567d Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Thu, 3 Aug 2017 13:06:55 +0800 Subject: [PATCH] refactor(module autojs): to support .auto record file --- app/build.gradle | 4 +- .../statics/SQLiteStaticsStorageTest.java | 12 +- app/src/main/AndroidManifest.xml | 2 +- .../stardust/scriptdroid/autojs/AutoJs.java | 70 +++++--- .../autojs/ScriptExecutionGlobalListener.java | 4 +- .../scriptdroid/external/CommonUtils.java | 5 +- .../menu/content/RecordNavigatorContent.java | 13 +- .../external/open/RunIntentActivity.java | 9 - .../external/shortcut/ShortcutActivity.java | 2 - .../scriptdroid/script/ScriptFile.java | 31 +++- .../stardust/scriptdroid/script/Scripts.java | 11 +- .../ui/common/ScriptOperations.java | 58 ++++--- .../scriptdroid/ui/edit/EditActivity.java | 7 +- .../ui/edit/ViewSampleActivity.java | 4 +- .../scriptdroid/ui/main/MainActivity.java | 28 +-- .../script_list/MyScriptListFragment.java | 7 +- .../ScriptAndFolderListRecyclerView.java | 11 ++ .../ui/main/task/TaskListRecyclerView.java | 9 +- app/src/main/res/drawable/autojs_material.png | Bin 0 -> 90957 bytes .../main/res/drawable/background_splash.xml | 2 +- app/src/main/res/drawable/record_icon_18.png | Bin 0 -> 20392 bytes app/src/main/res/layout/activity_about.xml | 2 +- app/src/main/res/layout/activity_splash.xml | 2 +- autojs/src/main/assets/binary/root_automator | Bin 13612 -> 13620 bytes .../stardust/autojs/ScriptEngineService.java | 65 ++++--- .../autojs/ScriptEngineServiceBuilder.java | 7 - .../engine/AbstractScriptEngineManager.java | 86 --------- .../autojs/engine/JavaScriptEngine.java | 25 +++ .../engine/LoopBasedJavaScriptEngine.java | 8 +- .../autojs/engine/RhinoJavaScriptEngine.java | 73 ++++---- .../engine/RhinoJavaScriptEngineManager.java | 65 ------- .../autojs/engine/RootAutomatorEngine.java | 101 +++++++++++ .../stardust/autojs/engine/ScriptEngine.java | 63 ++++++- .../autojs/engine/ScriptEngineFactory.java | 89 ++++++++++ .../autojs/engine/ScriptEngineManager.java | 129 ++++++++++++-- .../preprocess/RootAutomatorEngine.java | 8 - .../autojs/execution/ExecutionConfig.java | 2 +- .../execution/RootedScriptExecution.java | 34 ---- .../execution/RunnableScriptExecution.java | 38 ++-- .../execution/ScriptExecuteActivity.java | 66 +++---- .../autojs/execution/ScriptExecution.java | 5 - .../autojs/runtime/api/AbstractShell.java | 3 +- .../autojs/runtime/api/ProcessShell.java | 16 +- .../autojs/runtime/api/RootAutomator.java | 28 +-- .../record/inputevent/InputDevice.java | 8 - .../record/inputevent/InputDevices.java | 31 ++++ .../InputEventToAutoFileConverter.java | 104 +++++++++++ .../InputEventToRootAutomatorConverter.java | 2 +- .../record/inputevent/TouchRecorder.java | 2 +- .../autojs/script/AutoFileSource.java | 38 ++++ ...tSource.java => JavaScriptFileSource.java} | 16 +- .../autojs/script/JavaScriptSource.java | 90 ++++++++++ .../stardust/autojs/script/ScriptSource.java | 59 +------ .../autojs/script/SequenceScriptSource.java | 8 +- .../autojs/script/StringScriptSource.java | 2 +- .../java/com/stardust/auojs/inrt/App.java | 3 - .../com/stardust/auojs/inrt/MainActivity.java | 4 +- .../com/stardust/auojs/inrt/rt/AutoJs.java | 163 ------------------ 58 files changed, 981 insertions(+), 753 deletions(-) create mode 100644 app/src/main/res/drawable/autojs_material.png create mode 100644 app/src/main/res/drawable/record_icon_18.png delete mode 100644 autojs/src/main/java/com/stardust/autojs/engine/AbstractScriptEngineManager.java create mode 100644 autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngine.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java create mode 100644 autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java create mode 100644 autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineFactory.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/engine/preprocess/RootAutomatorEngine.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/execution/RootedScriptExecution.java delete mode 100644 autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevice.java create mode 100644 autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevices.java create mode 100644 autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToAutoFileConverter.java create mode 100644 autojs/src/main/java/com/stardust/autojs/script/AutoFileSource.java rename autojs/src/main/java/com/stardust/autojs/script/{FileScriptSource.java => JavaScriptFileSource.java} (74%) create mode 100644 autojs/src/main/java/com/stardust/autojs/script/JavaScriptSource.java delete mode 100644 inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java diff --git a/app/build.gradle b/app/build.gradle index 75d6bb69..feb37d82 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 17 targetSdkVersion 23 - versionCode 156 - versionName "2.0.15 Alpha4" + versionCode 157 + versionName "2.0.16 Alpha" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { diff --git a/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java b/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java index 0c9a9199..4366b90f 100644 --- a/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java +++ b/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java @@ -2,7 +2,7 @@ package com.stardust.scriptdroid.statics; import android.support.test.InstrumentationRegistry; -import com.stardust.autojs.script.FileScriptSource; +import com.stardust.autojs.script.JavaScriptFileSource; import com.stardust.autojs.script.ScriptSource; import com.stardust.autojs.script.StringScriptSource; import com.stardust.util.MapEntries; @@ -46,7 +46,7 @@ public class SQLiteStaticsStorageTest { public void testTwoRecord() { mStorage.clear(); mStorage.record(new StringScriptSource("Name", "Script")); - mStorage.record(new FileScriptSource("/test/test.js")); + mStorage.record(new JavaScriptFileSource("/test/test.js")); assertEquals(mStorage.getAll(), new MapEntries() .entry("Name.js", "1") .entry("/test/test.js", "1") @@ -56,10 +56,10 @@ public class SQLiteStaticsStorageTest { @Test public void testRepeatedRecord() { mStorage.clear(); - mStorage.record(new FileScriptSource("/test/test.js")); + mStorage.record(new JavaScriptFileSource("/test/test.js")); mStorage.record(new StringScriptSource("Name", "Script")); - mStorage.record(new FileScriptSource("/test/test.js")); - mStorage.record(new FileScriptSource("/test/test.js")); + mStorage.record(new JavaScriptFileSource("/test/test.js")); + mStorage.record(new JavaScriptFileSource("/test/test.js")); assertEquals(mStorage.getAll(), new MapEntries() .entry("Name.js", "1") .entry("/test/test.js", "3") @@ -70,7 +70,7 @@ public class SQLiteStaticsStorageTest { @Test public void getMax() throws Exception { mStorage.clear(); - put(new FileScriptSource("/test/test.js"), 50); + put(new JavaScriptFileSource("/test/test.js"), 50); put(new StringScriptSource("Name4", "Script"), 10); put(new StringScriptSource("Name5", "Script"), 5); put(new StringScriptSource("Name6", "Script"), 4); diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 291f9110..2e44777c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ xmlns:tools="http://schemas.android.com/tools" android:name=".App" android:allowBackup="false" - android:icon="@drawable/ic_android_eat_js" + android:icon="@drawable/autojs_material" android:label="@string/_app_name" android:supportsRtl="true" android:theme="@style/AppTheme" 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 d32bf329..7e7b8986 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java @@ -1,7 +1,6 @@ package com.stardust.scriptdroid.autojs; import android.app.Activity; -import android.app.Notification; import android.content.Context; import android.os.Build; import android.os.Bundle; @@ -12,7 +11,10 @@ import com.stardust.app.OnActivityResultDelegate; import com.stardust.app.SimpleActivityLifecycleCallbacks; import com.stardust.autojs.ScriptEngineService; import com.stardust.autojs.ScriptEngineServiceBuilder; -import com.stardust.autojs.engine.RhinoJavaScriptEngineManager; +import com.stardust.autojs.engine.LoopBasedJavaScriptEngine; +import com.stardust.autojs.engine.RhinoJavaScriptEngine; +import com.stardust.autojs.engine.RootAutomatorEngine; +import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.engine.ScriptEngineManager; import com.stardust.autojs.runtime.AccessibilityBridge; import com.stardust.autojs.runtime.ScriptRuntime; @@ -21,6 +23,8 @@ import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.autojs.runtime.api.AppUtils; import com.stardust.autojs.runtime.api.Console; import com.stardust.autojs.runtime.api.image.ScreenCaptureRequester; +import com.stardust.autojs.script.AutoFileSource; +import com.stardust.autojs.script.JavaScriptSource; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; @@ -58,6 +62,7 @@ public class AutoJs { private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder(); private final NotificationListener.Observer mNotificationObserver; + private ScriptEngineManager mScriptEngineManager; private final LayoutInspector mLayoutInspector = new LayoutInspector(); private final Context mContext; private final UiHandler mUiHandler; @@ -65,12 +70,14 @@ public class AutoJs { private final AccessibilityInfoProvider mAccessibilityInfoProvider; private final ScreenCaptureRequester mScreenCaptureRequester = new ScreenCaptureRequesterImpl(); private final ScriptEngineService mScriptEngineService; + private final Console mGlobalConsole; private AutoJs(final Context context) { mContext = context; mUiHandler = new UiHandler(context); mAppUtils = new AppUtils(context); + mGlobalConsole = new JraskaConsole(); mNotificationObserver = new NotificationListener.Observer(context); mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager()); mScriptEngineService = buildScriptEngineService(); @@ -80,33 +87,44 @@ public class AutoJs { } private ScriptEngineService buildScriptEngineService() { - ScriptEngineManager manager = createScriptEngineManager(mContext); - final Console globalConsole = new JraskaConsole(); + initScriptEngineManager(); return new ScriptEngineServiceBuilder() .uiHandler(mUiHandler) - .globalConsole(globalConsole) - .engineManger(manager) - .runtime(new Supplier() { - - @Override - public com.stardust.autojs.runtime.ScriptRuntime get() { - return new ScriptRuntime.Builder() - .setConsole(new StardustConsole(mUiHandler, globalConsole)) - .setScreenCaptureRequester(mScreenCaptureRequester) - .setAccessibilityBridge(new AccessibilityBridgeImpl()) - .setUiHandler(mUiHandler) - .setAppUtils(mAppUtils) - .setShellSupplier(new Supplier() { - @Override - public AbstractShell get() { - return new Shell(mContext, true); - } - }).build(); - } - }) + .globalConsole(mGlobalConsole) + .engineManger(mScriptEngineManager) .build(); } + private void initScriptEngineManager() { + mScriptEngineManager = new ScriptEngineManager(mContext); + mScriptEngineManager.registerEngine(JavaScriptSource.ENGINE, new Supplier() { + @Override + public ScriptEngine get() { + LoopBasedJavaScriptEngine engine = new LoopBasedJavaScriptEngine(mContext); + engine.setRuntime(new ScriptRuntime.Builder() + .setConsole(new StardustConsole(mUiHandler, mGlobalConsole)) + .setScreenCaptureRequester(mScreenCaptureRequester) + .setAccessibilityBridge(new AccessibilityBridgeImpl()) + .setUiHandler(mUiHandler) + .setAppUtils(mAppUtils) + .setShellSupplier(new Supplier() { + @Override + public AbstractShell get() { + return new Shell(mContext, true); + } + }).build()); + return engine; + } + }); + mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, new Supplier() { + @Override + public ScriptEngine get() { + return new RootAutomatorEngine(mContext); + } + }); + + } + private void registerActivityLifecycleCallbacks() { App.getApp().registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() { @@ -128,10 +146,6 @@ public class AutoJs { }); } - private ScriptEngineManager createScriptEngineManager(Context context) { - return new RhinoJavaScriptEngineManager(context); - } - private void addAccessibilityServiceDelegates() { AccessibilityService.addDelegate(100, mAccessibilityInfoProvider); AccessibilityService.addDelegate(200, mNotificationObserver); diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java index 48780a48..cd56a2c8 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java @@ -1,5 +1,6 @@ package com.stardust.scriptdroid.autojs; +import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.execution.ScriptExecutionListener; import com.stardust.scriptdroid.App; @@ -29,7 +30,8 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener { if (millis == null) return; double seconds = (System.currentTimeMillis() - millis) / 1000.0; - execution.getRuntime().console.verbose(App.getApp().getString(R.string.text_execution_finished), execution.getSource().toString(), seconds); + AutoJs.getInstance().getScriptEngineService().getGlobalConsole() + .verbose(App.getApp().getString(R.string.text_execution_finished), execution.getSource().toString(), seconds); } @Override diff --git a/app/src/main/java/com/stardust/scriptdroid/external/CommonUtils.java b/app/src/main/java/com/stardust/scriptdroid/external/CommonUtils.java index 1b8e850a..e2669bf0 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/CommonUtils.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/CommonUtils.java @@ -3,9 +3,8 @@ package com.stardust.scriptdroid.external; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.widget.Toast; -import com.stardust.autojs.script.FileScriptSource; +import com.stardust.autojs.script.JavaScriptFileSource; import com.stardust.autojs.script.ScriptSource; import com.stardust.autojs.script.SequenceScriptSource; import com.stardust.autojs.script.StringScriptSource; @@ -36,7 +35,7 @@ public class CommonUtils { if (path == null && script != null) { source = new StringScriptSource(script); } else if (path != null && new PathChecker(context).checkAndToastError(path)) { - ScriptSource fileScriptSource = new FileScriptSource(path); + JavaScriptFileSource fileScriptSource = new JavaScriptFileSource(path); if (script != null) { source = new SequenceScriptSource(fileScriptSource.getName(), new StringScriptSource(script), fileScriptSource); } else { diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java index 3a67226d..84b73bc2 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java @@ -159,9 +159,10 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat mStopRecord.setVisibility(state == Recorder.STATE_STOPPED ? View.GONE : View.VISIBLE); mDiscardRecord.setVisibility(state == Recorder.STATE_STOPPED ? View.GONE : View.VISIBLE); mStartOrPauseRecordIcon.setImageResource(state == Recorder.STATE_RECORDING ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_48dp); - //我知道这样写代码会被打 但我懒... - mStartOrPauseRecordText.setText(state == Recorder.STATE_RECORDING ? R.string.text_pause_record : - state == Recorder.STATE_PAUSED ? R.string.text_resume_record : R.string.text_start_record); + mStartOrPauseRecordText.setText( + state == Recorder.STATE_RECORDING ? R.string.text_pause_record : + state == Recorder.STATE_PAUSED ? R.string.text_resume_record : + R.string.text_start_record); } @@ -206,7 +207,11 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat @Override public void onStop() { if (!mDiscard) { - MainActivity.onRecordStop(mContext, mRecorder.getCode()); + if (mRecorder instanceof TouchRecorder) { + MainActivity.importScriptFile(mContext, mRecorder.getCode()); + } else { + MainActivity.onRecordStop(mContext, mRecorder.getCode()); + } } mRecorder = null; } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/open/RunIntentActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/open/RunIntentActivity.java index 3190786f..4deda444 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/open/RunIntentActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/open/RunIntentActivity.java @@ -1,21 +1,12 @@ package com.stardust.scriptdroid.external.open; import android.app.Activity; -import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.widget.Toast; -import com.stardust.scriptdroid.script.PathChecker; -import com.stardust.autojs.script.FileScriptSource; -import com.stardust.autojs.script.SequenceScriptSource; -import com.stardust.autojs.script.ScriptSource; -import com.stardust.autojs.script.StringScriptSource; import com.stardust.scriptdroid.external.CommonUtils; import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.script.Scripts; - -import java.io.File; /** * Created by Stardust on 2017/2/22. diff --git a/app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java index 866e181f..b96ea505 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java @@ -4,9 +4,7 @@ import android.app.Activity; import android.os.Bundle; import android.widget.Toast; -import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.script.PathChecker; -import com.stardust.autojs.script.FileScriptSource; import com.stardust.scriptdroid.external.CommonUtils; import com.stardust.scriptdroid.script.ScriptFile; import com.stardust.scriptdroid.script.Scripts; diff --git a/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java b/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java index 0a247555..87714d18 100644 --- a/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java +++ b/app/src/main/java/com/stardust/scriptdroid/script/ScriptFile.java @@ -1,7 +1,11 @@ package com.stardust.scriptdroid.script; import android.os.Environment; +import android.renderscript.Script; +import com.stardust.autojs.script.AutoFileSource; +import com.stardust.autojs.script.JavaScriptFileSource; +import com.stardust.autojs.script.ScriptSource; import com.stardust.pio.PFile; import java.io.File; @@ -15,9 +19,16 @@ import java.util.ArrayList; public class ScriptFile extends File { + public static final int TYPE_UNKNOWN = 0; + public static final int TYPE_AUTO = 1; + public static final int TYPE_JAVA_SCRIPT = 2; + + private int mType = -1; + private String mSimplifyPath; private String mSimplifiedName; + public ScriptFile(String path) { super(path); init(); @@ -51,6 +62,15 @@ public class ScriptFile extends File { return mSimplifyPath; } + public int getType() { + if (mType == -1) { + mType = getName().endsWith(".js") ? TYPE_JAVA_SCRIPT : + getName().endsWith(".auto") ? TYPE_AUTO : + TYPE_UNKNOWN; + } + return mType; + } + @Override public ScriptFile getParentFile() { String p = this.getParent(); @@ -64,7 +84,8 @@ public class ScriptFile extends File { return listFiles(new FileFilter() { @Override public boolean accept(File file) { - return (file.isDirectory() || file.getName().endsWith(".js")) && !file.getName().startsWith("."); + return (file.getName().endsWith(".js") || file.getName().endsWith(".auto") || + file.isDirectory()) && !file.getName().startsWith("."); } }); } @@ -101,4 +122,12 @@ public class ScriptFile extends File { public boolean moveTo(ScriptFile to) { return renameTo(new File(to, getName())); } + + public ScriptSource toSource(){ + if(getType() == TYPE_JAVA_SCRIPT){ + return new JavaScriptFileSource(this); + }else { + return new AutoFileSource(this); + } + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/script/Scripts.java b/app/src/main/java/com/stardust/scriptdroid/script/Scripts.java index 7fb2075f..488d8c35 100644 --- a/app/src/main/java/com/stardust/scriptdroid/script/Scripts.java +++ b/app/src/main/java/com/stardust/scriptdroid/script/Scripts.java @@ -2,7 +2,6 @@ package com.stardust.scriptdroid.script; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.net.Uri; import com.stardust.autojs.execution.ExecutionConfig; @@ -10,12 +9,10 @@ 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.JavaScriptFileSource; import com.stardust.autojs.script.ScriptSource; -import com.stardust.autojs.script.SequenceScriptSource; import com.stardust.autojs.script.StringScriptSource; import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.BuildConfig; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.external.CommonUtils; @@ -27,8 +24,6 @@ import com.stardust.util.AssetsCache; import java.io.File; -import javax.xml.parsers.DocumentBuilderFactory; - /** * Created by Stardust on 2017/5/3. */ @@ -85,7 +80,7 @@ public class Scripts { } public static ScriptExecution run(ScriptFile file) { - return run(new FileScriptSource(file), file.getParent()); + return run(file.toSource(), file.getParent()); } public static ScriptExecution run(ScriptSource source, String directoryPath) { @@ -114,7 +109,7 @@ public class Scripts { } public static ScriptExecution runRepeatedly(ScriptFile scriptFile, int loopTimes, long delay, long interval) { - ScriptSource source = new FileScriptSource(scriptFile); + ScriptSource source = new JavaScriptFileSource(scriptFile); String directoryPath = scriptFile.getParent(); return AutoJs.getInstance().getScriptEngineService().execute(source, new ExecutionConfig() .requirePath(directoryPath, StorageScriptProvider.DEFAULT_DIRECTORY_PATH) diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java index dc275fe1..ec1e189b 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java @@ -2,6 +2,7 @@ package com.stardust.scriptdroid.ui.common; import android.app.Activity; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; import android.support.v4.widget.DrawerLayout; import android.text.InputType; @@ -64,11 +65,11 @@ public class ScriptOperations { } public void newScriptFileForScript(final String script) { - showFileNameInputDialog("") + showFileNameInputDialog("", "js") .subscribe(new Consumer() { @Override public void accept(@io.reactivex.annotations.NonNull String input) throws Exception { - createScriptFile(getCurrentDirectoryPath() + input + ".js", script); + createScriptFile(getCurrentDirectoryPath() + input + ".js", script, false); } }); } @@ -81,7 +82,7 @@ public class ScriptOperations { return mCurrentDirectory; } - public void createScriptFile(String path, String script) { + public void createScriptFile(String path, String script, boolean edit) { if (PFile.createIfNotExists(path)) { if (script != null) { try { @@ -91,7 +92,8 @@ public class ScriptOperations { } } notifyScriptFileChanged(); - Scripts.edit(path); + if (edit) + Scripts.edit(path); } else { Snackbar.make(mView, R.string.text_create_fail, Snackbar.LENGTH_LONG).show(); } @@ -102,16 +104,25 @@ public class ScriptOperations { } public Observable importFile(final String pathFrom) { - try { - return importFile(PFile.getNameWithoutExtension(pathFrom), new FileInputStream(pathFrom)); - } catch (FileNotFoundException e) { - showMessage(R.string.file_not_exists); - return Observable.error(e); - } + return showFileNameInputDialog(PFile.getNameWithoutExtension(pathFrom), PFile.getExtension(pathFrom)) + .observeOn(Schedulers.io()) + .map(new Function() { + @Override + public String apply(@io.reactivex.annotations.NonNull String s) throws Exception { + final String pathTo = getCurrentDirectoryPath() + s + "." + PFile.getExtension(pathFrom); + if (PFile.copy(pathFrom, pathTo)) { + showMessage(R.string.text_import_succeed); + } else { + showMessage(R.string.text_import_fail); + } + notifyScriptFileChanged(); + return pathTo; + } + }); } public Observable importFile(String prefix, final InputStream inputStream) { - return showFileNameInputDialog(PFile.getNameWithoutExtension(prefix)) + return showFileNameInputDialog(PFile.getNameWithoutExtension(prefix), "js") .observeOn(Schedulers.io()) .map(new Function() { @Override @@ -130,7 +141,7 @@ public class ScriptOperations { public void newDirectory() { - showNameInputDialog("", new InputCallback(true)) + showNameInputDialog("", new InputCallback()) .subscribe(new Consumer() { @Override public void accept(@io.reactivex.annotations.NonNull String path) throws Exception { @@ -158,8 +169,8 @@ public class ScriptOperations { } - private Observable showFileNameInputDialog(String prefix) { - return showNameInputDialog(prefix, new InputCallback(false)); + private Observable showFileNameInputDialog(String prefix, String ext) { + return showNameInputDialog(prefix, new InputCallback(ext)); } private Observable showNameInputDialog(String prefix, MaterialDialog.InputCallback textWatcher) { @@ -196,7 +207,8 @@ public class ScriptOperations { public Observable rename(final ScriptFile file) { String originalName = file.getSimplifiedName(); - return showNameInputDialog(originalName, new InputCallback(file.isDirectory(), originalName)) + return showNameInputDialog(originalName, new InputCallback(file.isDirectory() ? null : PFile.getExtension(file.getName()), + originalName)) .map(new Function() { @Override public Boolean apply(@io.reactivex.annotations.NonNull String newName) throws Exception { @@ -207,17 +219,21 @@ public class ScriptOperations { private class InputCallback implements MaterialDialog.InputCallback { - private boolean mIsDirectory = false; private String mExcluded; private boolean mIsFirstTextChanged = true; + private String mExtension; - InputCallback(boolean isDirectory, String excluded) { - mIsDirectory = isDirectory; + InputCallback(@Nullable String ext, String excluded) { + mExtension = "." + ext; mExcluded = excluded; } - InputCallback(boolean isDirectory) { - mIsDirectory = isDirectory; + InputCallback(String ext) { + this(ext, null); + } + + public InputCallback() { + this(null); } @Override @@ -233,7 +249,7 @@ public class ScriptOperations { if (input == null || input.length() == 0) { errorResId = R.string.text_name_should_not_be_empty; } else if (!input.equals(mExcluded)) { - if (new File(getCurrentDirectory(), mIsDirectory ? input.toString() : input.toString() + ".js").exists()) { + if (new File(getCurrentDirectory(), mExtension == null ? input.toString() : input.toString() + mExtension).exists()) { errorResId = R.string.text_file_exists; } } 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 aa1f7768..f6e2f0ae 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 @@ -22,8 +22,9 @@ 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.app.OnActivityResultDelegate; +import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.execution.ScriptExecution; -import com.stardust.autojs.script.FileScriptSource; +import com.stardust.autojs.script.JavaScriptFileSource; import com.stardust.autojs.script.JsBeautifier; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; @@ -211,7 +212,7 @@ public class EditActivity extends Editor920Activity implements OnActivityResultD private void run() { Snackbar.make(mView, R.string.text_start_running, Snackbar.LENGTH_SHORT).show(); setMenuStatus(R.id.run, MenuDef.STATUS_DISABLED); - mScriptExecution = Scripts.runWithBroadcastSender(new FileScriptSource(mName, mFile), mFile.getParent()); + mScriptExecution = Scripts.runWithBroadcastSender(new JavaScriptFileSource(mName, mFile), mFile.getParent()); } @@ -288,7 +289,7 @@ public class EditActivity extends Editor920Activity implements OnActivityResultD private void showConsole() { if (mScriptExecution != null) { - mScriptExecution.getRuntime().console.show(); + ((JavaScriptEngine) mScriptExecution.getEngine()).getRuntime().console.show(); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/ViewSampleActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/ViewSampleActivity.java index a0bcef59..fe660e12 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/ViewSampleActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/ViewSampleActivity.java @@ -16,6 +16,7 @@ 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.app.OnActivityResultDelegate; +import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.script.StringScriptSource; import com.stardust.scriptdroid.R; @@ -27,7 +28,6 @@ import com.stardust.scriptdroid.ui.common.ScriptOperations; import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity; import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils; import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity; -import com.stardust.scriptdroid.ui.main.MainActivity; import com.stardust.theme.ThemeColorManager; import com.stardust.util.AssetsCache; import com.stardust.util.SparseArrayEntries; @@ -182,7 +182,7 @@ public class ViewSampleActivity extends Editor920Activity implements OnActivityR private void showConsole() { if (mScriptExecution != null) { - mScriptExecution.getRuntime().console.show(); + ((JavaScriptEngine) mScriptExecution.getEngine()).getRuntime().console.show(); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java index 1a5eefca..d469bd2e 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java @@ -9,8 +9,6 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; @@ -36,10 +34,8 @@ import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger; -import com.stardust.scriptdroid.external.open.ImportIntentActivity; import com.stardust.scriptdroid.script.ScriptFile; import com.stardust.scriptdroid.script.StorageScriptProvider; -import com.stardust.scriptdroid.script.sample.Sample; import com.stardust.scriptdroid.ui.common.ScriptOperations; import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_; import com.stardust.util.IntentExtras; @@ -54,7 +50,6 @@ import com.stardust.scriptdroid.ui.settings.SettingsActivity_; import com.stardust.scriptdroid.ui.update.VersionGuard; import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; import com.stardust.util.BackPressedHandler; -import com.stardust.util.Callback; import com.stardust.util.MessageEvent; import com.stardust.view.DrawerAutoClose; import com.stardust.view.accessibility.AccessibilityServiceUtils; @@ -68,8 +63,6 @@ import org.androidannotations.annotations.ViewById; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; -import java.io.File; -import java.io.IOException; import java.io.InputStream; @EActivity(R.layout.activity_main) @@ -80,13 +73,14 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega private static final String LOG_TAG = "MainActivity"; private static final String EXTRA_ACTION = "EXTRA_ACTION"; - private static final String ACTION_ON_ACTION_RECORD_STOPPED = "ACTION_ON_ACTION_RECORD_STOPPED"; + private static final String ACTION_ON_RECORD_STOP = "ACTION_ON_RECORD_STOP"; private static final String ACTION_IMPORT_SCRIPT = "ACTION_IMPORT_SCRIPT"; private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT"; private static final String ARGUMENT_PATH = "ARGUMENT_PATH"; private static final String ACTION_IMPORT_SAMPLE = "I cannot find the way back to you...Eating...17.4.29"; private static final String ARGUMENT_SAMPLE = "Take a chance on me...ok...?"; private static final String ARGUMENT_INPUT_STREAM = "17.7.12, Hi...could we start all over again..."; + private static final String ACTION_ON_ROOT_RECORD_STOP = "ACTION_ON_ROOT_RECORD_STOP"; @ViewById(R.id.drawer_layout) @@ -111,6 +105,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega mVersionGuard = new VersionGuard(this); showAnnunciationIfNeeded(); //Stop download service of ad sdk + // FIXME: 2017/8/1 Service not stopped! stopService(new Intent(this, DownloadService.class)); } @@ -305,7 +300,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega if (action == null) return; switch (action) { - case ACTION_ON_ACTION_RECORD_STOPPED: + case ACTION_ON_RECORD_STOP: IntentExtras extras = IntentExtras.fromIntent(intent); String script = extras.get(ARGUMENT_SCRIPT); extras.clear(); @@ -321,12 +316,14 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega String path = intent.getStringExtra(ARGUMENT_PATH); if (path != null) { new ScriptOperations(MainActivity.this, mDrawerLayout) - .importFile(intent.getStringExtra(ARGUMENT_PATH)); + .importFile(intent.getStringExtra(ARGUMENT_PATH)) + .subscribe(); return; } InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM); new ScriptOperations(MainActivity.this, mDrawerLayout) - .importFile("", inputStream); + .importFile("", inputStream) + .subscribe(); } private void handleRecordedScript(final String script) { @@ -416,7 +413,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega public static void onRecordStop(Context context, String script) { Intent intent = new Intent(context, MainActivity_.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(EXTRA_ACTION, ACTION_ON_ACTION_RECORD_STOPPED); + .putExtra(EXTRA_ACTION, ACTION_ON_RECORD_STOP); IntentExtras.newExtras() .put(ARGUMENT_SCRIPT, script) .putInIntent(intent); @@ -424,4 +421,11 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega } + public static void onRootRecordStop(Context context, String path) { + Intent intent = new Intent(context, MainActivity_.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(EXTRA_ACTION, ACTION_ON_ROOT_RECORD_STOP) + .putExtra(ARGUMENT_PATH, path); + context.startActivity(intent); + } } \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/MyScriptListFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/MyScriptListFragment.java index d64c012b..301093c4 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/MyScriptListFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/MyScriptListFragment.java @@ -94,7 +94,12 @@ public class MyScriptListFragment extends Fragment { mScriptListRecyclerView.setOnItemClickListener(new ScriptAndFolderListRecyclerView.OnScriptFileClickListener() { @Override public void onClick(ScriptFile file, int position) { - EditActivity.editFile(getContext(), file); + if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) { + Scripts.edit(file); + } else { + mSelectedScriptFile = file; + mScriptFileOperationDialog.show(); + } } }); mScriptListRecyclerView.setOnItemLongClickListener(new ScriptAndFolderListRecyclerView.OnScriptFileLongClickListener() { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/ScriptAndFolderListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/ScriptAndFolderListRecyclerView.java index 6e8525c0..ee66c75d 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/ScriptAndFolderListRecyclerView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/script_list/ScriptAndFolderListRecyclerView.java @@ -11,6 +11,7 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.workground.WrapContentLinearLayoutManager; @@ -412,14 +413,24 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView { private class FileViewHolder extends DefaultViewHolder { + private ImageView mIcon; + FileViewHolder(View itemView) { super(itemView); + mIcon = (ImageView) itemView.findViewById(R.id.icon); if (mScriptFileOperationEnabled) { itemView.findViewById(R.id.run).setOnClickListener(mOnRunClickListener); } else { itemView.findViewById(R.id.run).setVisibility(GONE); } } + + @Override + public void bind(ScriptFile file) { + super.bind(file); + mIcon.setImageResource(file.getType() == ScriptFile.TYPE_AUTO ? R.drawable.record_icon_18 + : R.drawable.ic_node_js_black); + } } } 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 0750f619..12b940f8 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,7 +1,6 @@ package com.stardust.scriptdroid.ui.main.task; import android.content.Context; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.ThemeColorRecyclerView; @@ -12,14 +11,12 @@ import android.view.ViewGroup; import android.widget.TextView; import android.workground.WrapContentLinearLayoutManager; -import com.afollestad.materialdialogs.DialogAction; -import com.afollestad.materialdialogs.MaterialDialog; import com.stardust.autojs.ScriptEngineService; +import com.stardust.autojs.engine.ScriptEngineManager; import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.execution.ScriptExecutionListener; import com.stardust.autojs.execution.SimpleScriptExecutionListener; import com.stardust.autojs.engine.ScriptEngine; -import com.stardust.autojs.engine.AbstractScriptEngineManager; import com.stardust.autojs.script.ScriptSource; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; @@ -32,7 +29,7 @@ import java.util.List; * Created by Stardust on 2017/3/24. */ -public class TaskListRecyclerView extends ThemeColorRecyclerView implements AbstractScriptEngineManager.EngineLifecycleCallback { +public class TaskListRecyclerView extends ThemeColorRecyclerView implements ScriptEngineManager.EngineLifecycleCallback { private final OnClickListener mOnItemClickListenerProxy = new OnClickListener() { @@ -184,7 +181,7 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Abst @Override public void onBindViewHolder(ViewHolder holder, int position) { - holder.bind((ScriptSource) mScriptEngines.get(position).getTag("script")); + holder.bind((ScriptSource) mScriptEngines.get(position).getTag(ScriptEngine.TAG_SOURCE)); } @Override diff --git a/app/src/main/res/drawable/autojs_material.png b/app/src/main/res/drawable/autojs_material.png new file mode 100644 index 0000000000000000000000000000000000000000..0160a1f80cd0f4e0f01b9e0e66d1ddfb03d04c9d GIT binary patch literal 90957 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 E02mb1ng9R* literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/background_splash.xml b/app/src/main/res/drawable/background_splash.xml index c3d3a375..209db7fa 100644 --- a/app/src/main/res/drawable/background_splash.xml +++ b/app/src/main/res/drawable/background_splash.xml @@ -6,7 +6,7 @@ sQgV{NmCk~LdGQX!Qs*+MEyyCq}` zSwbkvlJFbVU2}KWXYSv1egB-fuJ_E#InUSgywBsj&YAZ=Bf-?4EZ75nOI;5d@*!R0OT%jHQkJwUC}Dy>JZjXt;?5BHSCH z+547hCcSQ$bRRjh12Kw>(J}+PY9|QRXerJcH2o8n&gCSDV;6Ef88~^V# zU*F$m24c;TKWFya0Rt_<{E=XDWFR^SgFxcsLchC(K&(zMZc5(~{RbnRV5A@Rw^nY5 zA3pv;7@x18-4I};57HNx5{RP!`R!c%J<(WnpeOnd0DpA<5hE7m{s$I&J%3C?hNAwE zw%7A5?Q2baTWV!oA;YvVNH`Xau|T7JRKJz0>ECw`($e}`o*)rxl%E?qBv4ct{AgdWrWgvgs;-&uE7KuRxBi(c{Xy31U+#ik!MDA@J6~Vvv&W}Uk zdm((?d@$5+rmCZ;E3G9j{pb7nSL)CE!I>+6>vsF&Of?8O!9Qq>| z6z*7u`{1$KTfzSy%)ha~y9t~dZWujOAa4JJ;f=pH@4dtIC^F!mt$%m;p#I~+{8%2` zkp_b!_Kt1UKsau3mBC++xxd?f-qg2@y@9?7ez&IoseJ#H{^v15Jdu9CZ1;a`)o)f` zRev@KM7v`{;25Na2X06Fmy_t5>p#=}Y>)7S`*|SURKb6f`@7-S6lL(<()pnNxpLoH z|GA)l7vaAPK-moeb4O!*;aF9aFWdtO_V@Ep2LEjQIi~WD?*f<>+6RrnooGl^+~M)N zX1uJuZ-Kq~#-W0LEehPh@UOOC^)`FE-zVs+UI8kNdx0T)@847LyMIl!{okqh-M^;( z%(V1FVO62uNBgB2FKh3s>KlxsxW_Z3s=S<>jGQv~*XCa{Oi`go9~*5H?m!LP+a|cF zeNXze=eL=*f6T<|`JVZ$81NpYzShdOR@{Rc?imsM<00{%W%Ofr{vQWFr}TepjBiIA z1fK@Mn23uYB76Z67d{PwF%cI*MEC+CE_@mUVGL5f?rUf-w;nK}7fhA})Ly1Y;sDf{5@1L|phZ2*yNQ1QFp2h`8`+5R8eq2qMB4 z5OLwtAQ%&I5k!P9AmYNOK`rw)FCE&X(jc1-%h8N;pmvD#=WJuv zr$9>pRtnZaBuUM8`CdlqYYZi=2#u>n^7Db|l=uKl(LUI!{Z6-@Y5I)b!b@A3 z2p)0p!o^k=^5eE*mA_+KWw|T$M*4xK#+8k`3~>!&k0Z1>IfDANY3zHvuZc;x#l|VeVQBn! z6UgFMFm!5J5ez(XmgHJI{Wb-Qx?WC#0{Sulr8Qh;gOa!ZG8Dc&hI1DKXlBal~IrgE63Y~X!K3M={N zKMc~N1cw(MBZPHTEWN#CFGuT98mOXkNHd2rxb#}-ZhYu1_8zZG=-VZ^&+Q;*(RTK; zSmvc8t-sl+{Ib->(HkHmq}2P}Y44g?H9-s2+L) zxj)s~S=~0}=$Lr+!>e>%x(^g_r3yYByrPJ+Nar3^F#pkcDQtQ30f6OA&?HssopW-a z5Chd`6*=&g8|CD5kKZt-voxc9-P9f+)XH}l^|8@*m?QU6WfMb8GH4Yqw)T=tbBm|} z82H51Zwk2tXq?C>E$wrkvdj?evgd3uPCdA#)yH1E;TxY@R3V%is6r`#a?1&sUZ136 zqsQ&D%cWG>wwkSS=bY~J2)G{iyWy_6{xOJJ@7DS$9jJWz4~hSZ3gocGF`5^ZdKEswl<)-J^FkwF;R5im!^(uQLfNyL(_f9 z86P`B8`Ew(i0fVIScPWPr_*#^U^IE;XMP3}E!w4%&?3i9Uupv7;A69zJj>c1uXO#w zx%IFMG$PCSM(R>oY3x%#JA+u~maGj(m>Gi&T)^Ih!0dJM~bY&7O8Y z-6PNIV^qO>`63ITvc|2WNr_Pj(Nt|*eO{i$@dpu6X9F&;bY8|(ZwM_!KA8#-V7g1a zWl!I!L`};ZIV>8`5zI=$$g zWS*~YUbSz*KG$hD5;bJw=X^YR==Ev7c`_z9T?Gpm6HDR!`<}ag92`0@k9&FP8Xc1& ze5U$Q_w-c4?v$T4ql*+nll!6NK)0@#<%@=B#Txncd>$IZ2;Zx^oxP;=;#G7_$blOc zFDjX8(1*I$u9d2UsZGozb>@ZXS%YKbu)9)GmbZ$-AKqrvc{7|_sJS@NSfa91&5`kW zO)NYVZ1!3;3h7+$^?&Ae1ZdwfO6mFX3 zhr1{s_KoC_Fk2)zjl^J|U40Wh&>Q^0Qg47~_n!DA%+dv#{-&tz=uq#V|1oA*hYOfIZrP-y+&XzjtJkV6aS&?3pKMl#x7p^Kt3Tt-y6k=K#@{11-sw1tShUyO-XMN7}?r zZ-qny;uy3ZM$p8s`Dlgj?+zLTL$};!1w&K~YgTQsSk}3>?GkFVy^Rs?=bVKu@(K&B zJPdN_Ts(7XU9h}3fh71T)J;iqpzg#g`tbFd7!Abw>$dT%7HxmvTSklJElL@+54^<) zt8KNHSuL@Z$96{-*cbfO$O=x;HlVqCUR?;BC&OYns$E3;bX`JIata!+0d#8?_2XK? zE~W-HOUzHVFRNeY*(e*M^1h|F#GoNfd4 zp+m0w53aP-8mejz3-gOEQG3Tczvc11ef_c!S$2MylRB4ERZo6hbLd?$l?`)=$WqbC z{#OR-?Oef+jN6!fPbKagag13@W-M3YU7>6&b(fVn({D6>X*Of#X`DSxXNuis+Xqb0 z4#a3@5eB7>KAoChf9}PTF7KSp4`}GdmG%4M0wpz@U}Noje_>}~x=Di8?QnO0^Q=o&q)=4gox{t`sT209$vG|AYic{>zWYy=u#>~4joD4T(JtgKq z&*k_oxd%EV}PTu4&m2_B~^`ON!_ED&5Hs_i%dEI5jyvKz$cSVPm0)2DXt z=o|HoS&>%tvNdcR&QLgZzgBq|mLerhYu(;HpA}N4X}@U@h4d)g79OSHV*0drV5qvl z^L22@Xd}H!9e3HHG^~A4>kiv!NAj5Vba^0k!7J9?QziVoTsc{hDcs!Fl* zGS12QRkW~%GrGs>3Ook_v+HR&x4Q>WEgx?|Xsv8=qUy1u@1=!8jzr~v@ zW3}j|*RlP&shrg*wgGd%WAn&q!_A3ZU=5?n0B zo9I~6k46>f*LYA($h2VXpK{*Paer=-x16AZ;ff8S%+(R6QBZ4d_2|d#xfwL;U0TR$ zX8%0^wN(r0BESD&;o6I^f`-IA-y;eO9L5irPPsXJ>T|KQjAxz8$?~3X)DJ!%{>0S& z)Dfv%XX9yP7ULoX>HW zde3*oxes@1mytNeOhksOq#9VY>b!&0biEUTEJ+9nkVigRc8mEXWil_Mjm~~%D0-UA;&+0Jm-Y=+X(}5}Jh@kwTelsQ zKR{x~MC5}<(>6Hbly^|rRr#2^=EzL@%0oo_LKv&vHzL-PP4}yF*;e>m|Yz6tWkkcDM8#i2T8Bf7`pPQXe3~*z6}u(>r0zfB$FHLtDE_rHdvEu*x34Dh{=O}IUJxz z>+u}7W0&MSQ{~rS5-xdE3<2KfjVS)oT(O)^Owv&q?x`{{Yrdqfs=1q-Fp`=xzP*0= zOIF!wHj1kykD0e-x_qno8yFIes&c&mx^6UmJ4x3cHI@6{+me&re~PE{5$VP(DWJCE zF<-e&XjLbxk7@P+(_&Doxx2P-L0Lu@X#K2n-rG@L8c;Ix2Tu*(FtiCT@R$ZLu-)8| zYzS7X*WbVm5rX?PcR%o9I&6t#hzPp%s#&Gg_b3T<>$MRoCN;yAvd5IdAFnr&iX5gl zVu<%Yt~z|LLf%1QxWq4kLbiDS&}H*PXSJk5|kRQ_VD zfZC>mbEhcnArO9!Z7%4<*2;L_#WcacI=NSUwp7Q(kJ3=Lo;I{)4!6h(r>lG3J~dd> zY{fn4`{7)~>ejn{?$3*PnWZ;b=@y!}PYTOP~%cRsq-MjkpB42C9NRwhG}ve zmqg)@q=+JBP}38m2;?zSA{30(D1{xd% zJhugoOFm_)$}G7wVmI_zOATRedq8VBw&9JW{6bb=`57)8$k_0;nCFe9qeJ2zWRjB6>E;h{CnAEE~m zp`sp|N14=4BIN$mBNAL=7n*LlwQVmVWcMa`z+JCBrq!Ig{Y0R~U2PpNXA6wH_62fn zWqIxGxs?)$4c7hT92qUK2_BeaVGtmsu)LS+bykGmo%3bhT4{Ca@07+q)sM}WUJx`c z6ZhT76*_d$oc+qIisbZY>zzY}p6S~SiB$25_UCtXmF_rQ00!85lg8MU8O|GZ=@_NS zs6Vx;J?CKB#5vM=LBzbMn+wQlx8iar-sLGOhEdWIhK$Gt1vzJ# z6bj3!){KRzStzD9ju$j=f8-_Q(+*?2#EYbPBuc%S&Ri}Nac=7M{Rh3tTM;TE!;G~9 zj#d+O&bh9gA6JGK*G#~@5k_RtySR(K^CRw(1@%6b1+@%6-rWZ%HGzaMyj#Dz_rLV? MbxgExYPv-IKW_4dTmS$7 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 010fed27..00f7bf03 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -47,7 +47,7 @@ android:layout_width="90dp" android:layout_height="90dp" android:layout_centerInParent="true" - android:src="@drawable/ic_android_eat_js"/> + android:src="@drawable/autojs_material"/> + android:src="@drawable/autojs_material"> diff --git a/autojs/src/main/assets/binary/root_automator b/autojs/src/main/assets/binary/root_automator index 341611a486b343bb87ef451eb1880837d0aefeaf..052a22d0a2e3b1097b15dd62173798b5deeb03b8 100644 GIT binary patch literal 13620 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 literal 13612 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 F{{_Nhuvh>9 diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java b/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java index cb2260dd..08d735aa 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java +++ b/autojs/src/main/java/com/stardust/autojs/ScriptEngineService.java @@ -2,12 +2,12 @@ package com.stardust.autojs; import android.content.Context; -import com.stardust.autojs.engine.AbstractScriptEngineManager; +import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.engine.ScriptEngineManager; -import com.stardust.autojs.execution.ScriptExecuteActivity; import com.stardust.autojs.execution.ExecutionConfig; import com.stardust.autojs.execution.RunnableScriptExecution; +import com.stardust.autojs.execution.ScriptExecuteActivity; import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.execution.ScriptExecutionListener; import com.stardust.autojs.execution.ScriptExecutionObserver; @@ -15,9 +15,9 @@ import com.stardust.autojs.execution.ScriptExecutionTask; import com.stardust.autojs.execution.SimpleScriptExecutionListener; import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.runtime.api.Console; +import com.stardust.autojs.script.JavaScriptSource; import com.stardust.autojs.script.ScriptSource; import com.stardust.lang.ThreadCompat; -import com.stardust.util.Supplier; import com.stardust.util.UiHandler; import org.greenrobot.eventbus.EventBus; @@ -44,7 +44,10 @@ public class ScriptEngineService { private static final ScriptExecutionListener GLOBAL_LISTENER = new SimpleScriptExecutionListener() { @Override public void onStart(ScriptExecution execution) { - execution.getRuntime().console.setTitle(execution.getSource().getName()); + if (execution.getEngine() instanceof JavaScriptEngine) { + ((JavaScriptEngine) execution.getEngine()).getRuntime() + .console.setTitle(execution.getSource().getName()); + } EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_START, execution.getSource().toString())); } @@ -54,7 +57,9 @@ public class ScriptEngineService { } private void onFinish(ScriptExecution execution) { - execution.getRuntime().onExit(); + if (execution.getEngine() instanceof JavaScriptEngine) { + ((JavaScriptEngine) execution.getEngine()).getRuntime().onExit(); + } } @Override @@ -62,14 +67,16 @@ public class ScriptEngineService { e.printStackTrace(); onFinish(execution); if (!causedByInterrupted(e)) { - execution.getRuntime().console.error(getScriptTrace(e)); + if (execution.getEngine() instanceof JavaScriptEngine) { + ((JavaScriptEngine) execution.getEngine()).getRuntime() + .console.error(getScriptTrace(e)); + } EVENT_BUS.post(new ScriptExecutionEvent(ScriptExecutionEvent.ON_EXCEPTION, e.getMessage())); } } }; - private final Supplier mRuntimeSupplier; private final Context mContext; private UiHandler mUiHandler; private final Console mGlobalConsole; @@ -78,7 +85,6 @@ public class ScriptEngineService { private ScriptExecutionObserver mScriptExecutionObserver = new ScriptExecutionObserver(); ScriptEngineService(ScriptEngineServiceBuilder builder) { - mRuntimeSupplier = builder.mRuntimeSupplier; mUiHandler = builder.mUiHandler; mContext = mUiHandler.getContext(); mScriptEngineManager = builder.mScriptEngineManager; @@ -94,20 +100,11 @@ public class ScriptEngineService { return mGlobalConsole; } - public ScriptEngine createScriptEngine() { - ScriptEngine engine = mScriptEngineManager.createEngine(); - return engine; - } - - public ScriptRuntime createScriptRuntime() { - return mRuntimeSupplier.get(); - } - - public void registerEngineLifecycleCallback(AbstractScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) { + public void registerEngineLifecycleCallback(ScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) { mEngineLifecycleObserver.registerCallback(engineLifecycleCallback); } - public void unregisterEngineLifecycleCallback(AbstractScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) { + public void unregisterEngineLifecycleCallback(ScriptEngineManager.EngineLifecycleCallback engineLifecycleCallback) { mEngineLifecycleObserver.unregisterCallback(engineLifecycleCallback); } @@ -125,23 +122,23 @@ public class ScriptEngineService { } else { task.setExecutionListener(mScriptExecutionObserver); } - if (isUiMode(task)) { - return ScriptExecuteActivity.execute(mContext, this, task); + ScriptSource source = task.getSource(); + if (source instanceof JavaScriptSource && isUiMode((JavaScriptSource) source)) { + return ScriptExecuteActivity.execute(mContext, mScriptEngineManager, task); } else { - RunnableScriptExecution scriptExecution = new RunnableScriptExecution(this, task); + RunnableScriptExecution r = new RunnableScriptExecution(mScriptEngineManager, task); if (task.getConfig().runInNewThread) { - new ThreadCompat(scriptExecution).start(); + new ThreadCompat(r).start(); } else { - scriptExecution.run(); + r.run(); } - return scriptExecution; + return r; } } - private boolean isUiMode(ScriptExecutionTask task) { - ScriptSource source = task.getSource(); + private boolean isUiMode(JavaScriptSource source) { int mode = source.getExecutionMode(); - return (mode & ScriptSource.EXECUTION_MODE_UI) != 0; + return (mode & JavaScriptSource.EXECUTION_MODE_UI) != 0; } public ScriptExecution execute(ScriptSource source, ScriptExecutionListener listener, ExecutionConfig config) { @@ -186,14 +183,14 @@ public class ScriptEngineService { return mScriptEngineManager.getEngines(); } - private static class EngineLifecycleObserver implements AbstractScriptEngineManager.EngineLifecycleCallback { + private static class EngineLifecycleObserver implements ScriptEngineManager.EngineLifecycleCallback { - private final Set mEngineLifecycleCallbacks = new LinkedHashSet<>(); + private final Set mEngineLifecycleCallbacks = new LinkedHashSet<>(); @Override public void onEngineCreate(ScriptEngine engine) { synchronized (mEngineLifecycleCallbacks) { - for (AbstractScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) { + for (ScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) { callback.onEngineCreate(engine); } } @@ -202,20 +199,20 @@ public class ScriptEngineService { @Override public void onEngineRemove(ScriptEngine engine) { synchronized (mEngineLifecycleCallbacks) { - for (AbstractScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) { + for (ScriptEngineManager.EngineLifecycleCallback callback : mEngineLifecycleCallbacks) { callback.onEngineRemove(engine); } } } - void registerCallback(AbstractScriptEngineManager.EngineLifecycleCallback callback) { + void registerCallback(ScriptEngineManager.EngineLifecycleCallback callback) { synchronized (mEngineLifecycleCallbacks) { mEngineLifecycleCallbacks.add(callback); } } - void unregisterCallback(AbstractScriptEngineManager.EngineLifecycleCallback callback) { + void unregisterCallback(ScriptEngineManager.EngineLifecycleCallback callback) { synchronized (mEngineLifecycleCallbacks) { mEngineLifecycleCallbacks.remove(callback); } diff --git a/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java b/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java index 457c8764..1fa96f2a 100644 --- a/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java +++ b/autojs/src/main/java/com/stardust/autojs/ScriptEngineServiceBuilder.java @@ -1,6 +1,5 @@ package com.stardust.autojs; -import com.stardust.autojs.engine.AbstractScriptEngineManager; import com.stardust.autojs.engine.ScriptEngineManager; import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.runtime.api.Console; @@ -13,7 +12,6 @@ import com.stardust.util.UiHandler; public class ScriptEngineServiceBuilder { - Supplier mRuntimeSupplier; ScriptEngineManager mScriptEngineManager; Console mGlobalConsole; UiHandler mUiHandler; @@ -22,11 +20,6 @@ public class ScriptEngineServiceBuilder { } - public ScriptEngineServiceBuilder runtime(Supplier runtimeSupplier) { - mRuntimeSupplier = runtimeSupplier; - return this; - } - public ScriptEngineServiceBuilder uiHandler(UiHandler uiHandler) { mUiHandler = uiHandler; return this; diff --git a/autojs/src/main/java/com/stardust/autojs/engine/AbstractScriptEngineManager.java b/autojs/src/main/java/com/stardust/autojs/engine/AbstractScriptEngineManager.java deleted file mode 100644 index 739a8770..00000000 --- a/autojs/src/main/java/com/stardust/autojs/engine/AbstractScriptEngineManager.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.stardust.autojs.engine; - -import android.content.Context; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Created by Stardust on 2017/1/27. - */ - -public abstract class AbstractScriptEngineManager implements ScriptEngineManager { - - private static final String TAG = "AbstractScriptEngineManager"; - - private Map mGlobalVariableMap = new HashMap<>(); - private final Set mEngines = new HashSet<>(); - private EngineLifecycleCallback mEngineLifecycleCallback; - - private android.content.Context mAndroidContext; - - public AbstractScriptEngineManager(Context androidContext) { - mAndroidContext = androidContext; - } - - public ScriptEngine createEngine() { - ScriptEngine engine = createEngineInner(); - putProperties(engine); - addEngine(engine); - return engine; - } - - private void addEngine(ScriptEngine engine) { - synchronized (mEngines) { - mEngines.add(engine); - if (mEngineLifecycleCallback != null) { - mEngineLifecycleCallback.onEngineCreate(engine); - } - } - } - - public void putGlobal(String varName, Object value) { - mGlobalVariableMap.put(varName, value); - } - - public void setEngineLifecycleCallback(EngineLifecycleCallback engineLifecycleCallback) { - mEngineLifecycleCallback = engineLifecycleCallback; - } - - public Set getEngines() { - return mEngines; - } - - protected abstract ScriptEngine createEngineInner(); - - public android.content.Context getAndroidContext() { - return mAndroidContext; - } - - protected void putProperties(ScriptEngine engine) { - for (Map.Entry variable : mGlobalVariableMap.entrySet()) { - engine.put(variable.getKey(), variable.getValue()); - } - } - - public void removeEngine(ScriptEngine engine) { - synchronized (mEngines) { - if (mEngines.remove(engine) && mEngineLifecycleCallback != null) { - mEngineLifecycleCallback.onEngineRemove(engine); - } - } - } - - - public int stopAll() { - synchronized (mEngines) { - int n = mEngines.size(); - for (ScriptEngine engine : mEngines) { - engine.forceStop(); - } - return n; - } - } -} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngine.java new file mode 100644 index 00000000..c1f5c811 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/engine/JavaScriptEngine.java @@ -0,0 +1,25 @@ +package com.stardust.autojs.engine; + +import com.stardust.autojs.execution.ScriptExecution; +import com.stardust.autojs.runtime.ScriptRuntime; +import com.stardust.autojs.script.JavaScriptSource; + +/** + * Created by Stardust on 2017/8/3. + */ + +public abstract class JavaScriptEngine extends ScriptEngine.AbstractScriptEngine { + private ScriptRuntime mRuntime; + + + public ScriptRuntime getRuntime() { + return mRuntime; + } + + public void setRuntime(ScriptRuntime runtime) { + mRuntime = runtime; + put("__runtime__", runtime); + } + + +} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java index b89692b1..b3ef23b9 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java @@ -1,10 +1,12 @@ package com.stardust.autojs.engine; +import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; import com.stardust.autojs.runtime.api.Loopers; +import com.stardust.autojs.script.JavaScriptSource; import com.stardust.autojs.script.ScriptSource; /** @@ -16,12 +18,12 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine { private Handler mHandler; private boolean mLooping = false; - public LoopBasedJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) { - super(engineManager); + public LoopBasedJavaScriptEngine(Context context) { + super(context); } @Override - public Object execute(final ScriptSource source) { + public Object execute(final JavaScriptSource source) { Runnable r = new Runnable() { @Override public void run() { 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 e6db9469..c3fdfa5a 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,14 @@ package com.stardust.autojs.engine; -import android.os.Looper; import android.util.Log; +import com.stardust.autojs.BuildConfig; import com.stardust.autojs.rhino.AndroidContextFactory; import com.stardust.autojs.rhino.RhinoAndroidHelper; import com.stardust.autojs.runtime.ScriptInterruptedException; -import com.stardust.autojs.runtime.api.Events; -import com.stardust.autojs.runtime.api.Timers; -import com.stardust.autojs.script.ScriptSource; +import com.stardust.autojs.script.JavaScriptSource; +import com.stardust.autojs.script.StringScriptSource; +import com.stardust.pio.PFile; import com.stardust.pio.UncheckedIOException; import org.mozilla.javascript.Context; @@ -25,30 +25,26 @@ import java.io.Reader; import java.net.URI; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * Created by Stardust on 2017/4/2. */ -public class RhinoJavaScriptEngine implements ScriptEngine { +public class RhinoJavaScriptEngine extends JavaScriptEngine { private static final String LOG_TAG = "RhinoJavaScriptEngine"; private static int contextCount = 0; + private static StringScriptSource sInitScript; private String[] mRequirePath = new String[0]; private Context mContext; private Scriptable mScriptable; private Thread mThread; - private RhinoJavaScriptEngineManager mEngineManager; - private Map mTags = new ConcurrentHashMap<>(); - private volatile boolean mDestroyed = false; + private android.content.Context mAndroidContext; - public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) { - mEngineManager = engineManager; - mThread = Thread.currentThread(); + public RhinoJavaScriptEngine(android.content.Context context) { + mAndroidContext = context; mContext = createContext(); mScriptable = createScope(mContext); } @@ -59,7 +55,7 @@ public class RhinoJavaScriptEngine implements ScriptEngine { } @Override - public Object execute(ScriptSource source) { + public Object execute(JavaScriptSource source) { Reader reader = source.getNonNullScriptReader(); try { reader = preprocess(reader); @@ -79,33 +75,14 @@ public class RhinoJavaScriptEngine implements ScriptEngine { mThread.interrupt(); } - public RhinoJavaScriptEngineManager getEngineManager() { - return mEngineManager; - } @Override public synchronized void destroy() { + super.destroy(); Log.d(LOG_TAG, "on destroy"); Context.exit(); contextCount--; Log.d(LOG_TAG, "contextCount = " + contextCount); - mEngineManager.removeEngine(this); - mDestroyed = true; - } - - @Override - public boolean isDestroyed() { - return mDestroyed; - } - - @Override - public synchronized void setTag(String key, Object value) { - mTags.put(key, value); - } - - @Override - public synchronized Object getTag(String key) { - return mTags.get(key); } public Thread getThread() { @@ -114,15 +91,25 @@ public class RhinoJavaScriptEngine implements ScriptEngine { @Override public void init() { - ScriptableObject.putProperty(mScriptable, "__engine_name__", "rhino"); + mThread = Thread.currentThread(); ScriptableObject.putProperty(mScriptable, "__engine__", this); - mRequirePath = (String[]) getTag("__require_path__"); + mRequirePath = (String[]) getTag(TAG_PATH); initRequireBuilder(mContext, mScriptable); - mContext.evaluateString(mScriptable, mEngineManager.getInitScript().getScript(), "", 1, null); + mContext.evaluateString(mScriptable, getInitScript().getScript(), "", 1, null); } - public void setRequirePath(String... requirePath) { - setTag("__require_path__", requirePath); + private JavaScriptSource getInitScript() { + if (sInitScript == null || BuildConfig.DEBUG) + sInitScript = new StringScriptSource(readInitScript()); + return sInitScript; + } + + private String readInitScript() { + try { + return PFile.read(mAndroidContext.getAssets().open("javascript_engine_init.js")); + } catch (IOException e) { + throw new RuntimeException(e); + } } void initRequireBuilder(Context context, Scriptable scope) { @@ -130,10 +117,10 @@ public class RhinoJavaScriptEngine implements ScriptEngine { for (String path : mRequirePath) { list.add(new File(path).toURI()); } - AssetAndUrlModuleSourceProvider provider = new AssetAndUrlModuleSourceProvider(getEngineManager().getAndroidContext(), list); + AssetAndUrlModuleSourceProvider provider = new AssetAndUrlModuleSourceProvider(mAndroidContext, list); new RequireBuilder() .setModuleScriptProvider(new SoftCachingModuleScriptProvider(provider)) - .setSandboxed(false) + .setSandboxed(true) .createRequire(context, scope) .install(scope); } @@ -154,9 +141,9 @@ public class RhinoJavaScriptEngine implements ScriptEngine { protected Context createContext() { if (!ContextFactory.hasExplicitGlobal()) { - ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mEngineManager.getAndroidContext().getCacheDir(), "classes"))); + ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mAndroidContext.getCacheDir(), "classes"))); } - Context context = new RhinoAndroidHelper(mEngineManager.getAndroidContext()).enterContext(); + Context context = new RhinoAndroidHelper(mAndroidContext).enterContext(); contextCount++; context.setOptimizationLevel(-1); context.setLanguageVersion(Context.VERSION_ES6); diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java deleted file mode 100644 index 6df23686..00000000 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngineManager.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.stardust.autojs.engine; - - -import com.stardust.autojs.BuildConfig; -import com.stardust.autojs.script.ScriptSource; -import com.stardust.autojs.script.SequenceScriptSource; -import com.stardust.autojs.script.StringScriptSource; -import com.stardust.pio.PFile; - -import java.io.IOException; - -/** - * Created by Stardust on 2017/3/1. - */ - -public class RhinoJavaScriptEngineManager extends AbstractScriptEngineManager { - - private String[] mFunctions; - - private ScriptSource mCustomInitScript; - private ScriptSource mInitScript; - - public RhinoJavaScriptEngineManager(android.content.Context context) { - super(context); - } - - protected RhinoJavaScriptEngine createEngineInner() { - RhinoJavaScriptEngine engine = new LoopBasedJavaScriptEngine(this); - return engine; - } - - public void setInitScript(String script) { - setInitScriptSource(new StringScriptSource(script)); - } - - public void setInitScriptSource(ScriptSource initScriptSource) { - if (BuildConfig.DEBUG) { - mCustomInitScript = initScriptSource; - } else { - mInitScript = new SequenceScriptSource("", new StringScriptSource(readInitScript()), initScriptSource); - } - } - - private String readInitScript() { - try { - return PFile.read(getAndroidContext().getAssets().open("javascript_engine_init.js")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - ScriptSource getInitScript() { - if (mInitScript == null || BuildConfig.DEBUG) { - // 调试时不缓存INIT_SCRIPT否则修改javascript_engine_init.js后不会更新 - if (mCustomInitScript != null) { - mInitScript = new SequenceScriptSource("", new StringScriptSource(readInitScript()), mCustomInitScript); - } else { - mInitScript = new StringScriptSource(readInitScript()); - } - } - return mInitScript; - } - - -} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java new file mode 100644 index 00000000..b92d335d --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/engine/RootAutomatorEngine.java @@ -0,0 +1,101 @@ +package com.stardust.autojs.engine; + +import android.content.Context; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.stardust.autojs.runtime.api.AbstractShell; +import com.stardust.autojs.runtime.api.ProcessShell; +import com.stardust.autojs.runtime.record.inputevent.InputDevices; +import com.stardust.autojs.script.AutoFileSource; +import com.stardust.autojs.script.JavaScriptFileSource; +import com.stardust.autojs.script.ScriptSource; +import com.stardust.pio.PFile; + +import java.io.File; + +/** + * Created by Stardust on 2017/8/1. + */ + +public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine { + + public static final int VERSION = 1; + + private static final String KEY_TOUCH_DEVICE = RootAutomatorEngine.class.getName() + ".touch_device"; + private static final String LOG_TAG = "RootAutomatorEngine"; + + private static int sTouchDevice = -1; + private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator"; + + private Context mContext; + private String mDeviceNameOrPath; + private Thread mThread; + + public RootAutomatorEngine(Context context, String deviceNameOrPath) { + mContext = context; + if (sTouchDevice < 0) { + sTouchDevice = PreferenceManager.getDefaultSharedPreferences(context).getInt(KEY_TOUCH_DEVICE, -1); + } + if (sTouchDevice >= 0) { + mDeviceNameOrPath = "/dev/input/event" + sTouchDevice; + PreferenceManager.getDefaultSharedPreferences(context) + .edit() + .putInt(KEY_TOUCH_DEVICE, sTouchDevice) + .apply(); + } else { + mDeviceNameOrPath = deviceNameOrPath; + } + } + + + public RootAutomatorEngine(Context context) { + this(context, InputDevices.getTouchDeviceName()); + } + + public AbstractShell.Result execute(String autoFile) { + String executablePath = getExecutablePath(mContext); + AbstractShell.Result r = ProcessShell.execCommand(new String[]{ + "chmod 777 " + executablePath, + executablePath + " " + autoFile + " -d " + mDeviceNameOrPath + }, true); + Log.d(LOG_TAG, "exec: " + autoFile + " result:" + r); + return r; + } + + private static String getExecutablePath(Context context) { + File tmp = new File(context.getCacheDir(), "root_automator"); + PFile.copyAsset(context, ROOT_AUTOMATOR_EXECUTABLE_ASSET, tmp.getAbsolutePath()); + return tmp.getAbsolutePath(); + } + + public static void setTouchDevice(int device) { + sTouchDevice = device; + } + + public static int getTouchDevice(Context context) { + if (sTouchDevice >= 0) + return sTouchDevice; + return PreferenceManager.getDefaultSharedPreferences(context).getInt(KEY_TOUCH_DEVICE, -1); + } + + @Override + public void put(String name, Object value) { + + } + + @Override + public Object execute(AutoFileSource source) { + return execute(source.getFile().getAbsolutePath()); + } + + @Override + public void forceStop() { + mThread.interrupt(); + } + + @Override + public void init() { + mThread = Thread.currentThread(); + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java index 25506830..51beaeaa 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngine.java @@ -1,13 +1,18 @@ package com.stardust.autojs.engine; +import android.support.annotation.CallSuper; + import com.stardust.autojs.runtime.ScriptException; import com.stardust.autojs.script.ScriptSource; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + /** * Created by Stardust on 2017/4/2. *

*

- * A ScriptEngine is created by {@link AbstractScriptEngineManager#createEngine()}, and then can be + * A ScriptEngine is created by {@link ScriptEngineManager#createEngine(String)} ()}, and then can be * used to execute script with {@link ScriptEngine#execute(ScriptSource)} in the **same** thread. * When the execution finish successfully, the engine should be destroy in the thread that created it. *

@@ -15,12 +20,15 @@ import com.stardust.autojs.script.ScriptSource; * It will throw a {@link ScriptException}. */ -public interface ScriptEngine { +public interface ScriptEngine { + String TAG_PATH = "execute_path"; + String TAG_SOURCE = "source"; + void put(String name, Object value); - Object execute(ScriptSource scriptSource); + Object execute(S scriptSource); void forceStop(); @@ -32,8 +40,57 @@ public interface ScriptEngine { Object getTag(String key); + + /** + * @hide + */ + void setOnDestroyListener(OnDestroyListener listener); + /** * @hide */ void init(); + + interface OnDestroyListener { + void onDestroy(ScriptEngine engine); + } + + abstract class AbstractScriptEngine implements ScriptEngine { + + + private Map mTags = new ConcurrentHashMap<>(); + private OnDestroyListener mOnDestroyListener; + private boolean mDestroyed = false; + + + @Override + public synchronized void setTag(String key, Object value) { + mTags.put(key, value); + } + + @Override + public synchronized Object getTag(String key) { + return mTags.get(key); + } + + @Override + public synchronized boolean isDestroyed() { + return mDestroyed; + } + + @CallSuper + @Override + public synchronized void destroy() { + mDestroyed = true; + if (mOnDestroyListener != null) { + mOnDestroyListener.onDestroy(this); + } + } + + public void setOnDestroyListener(OnDestroyListener onDestroyListener) { + if (mOnDestroyListener != null) + throw new SecurityException("setOnDestroyListener can be called only once"); + mOnDestroyListener = onDestroyListener; + } + } } diff --git a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineFactory.java b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineFactory.java new file mode 100644 index 00000000..34eedf72 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineFactory.java @@ -0,0 +1,89 @@ +package com.stardust.autojs.engine; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.stardust.autojs.script.ScriptSource; +import com.stardust.util.Supplier; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Stardust on 2017/8/2. + */ + +public class ScriptEngineFactory { + + public static class EngineNotFoundException extends RuntimeException { + + public EngineNotFoundException(String s) { + super(s); + } + } + + private static ScriptEngineFactory sInstance = new ScriptEngineFactory(); + private Map> mEngines = new HashMap<>(); + private Map mGlobalVariableMap = new HashMap<>(); + + ScriptEngineFactory() { + + } + + public static ScriptEngineFactory getInstance() { + return sInstance; + } + + public void putGlobal(String varName, Object value) { + mGlobalVariableMap.put(varName, value); + } + + protected void putProperties(ScriptEngine engine) { + for (Map.Entry variable : mGlobalVariableMap.entrySet()) { + engine.put(variable.getKey(), variable.getValue()); + } + } + + + @Nullable + public ScriptEngine createEngine(String name) { + Supplier s = mEngines.get(name); + if (s == null) { + return null; + } + ScriptEngine engine = s.get(); + putProperties(engine); + return engine; + } + + @Nullable + public ScriptEngine createEngineOfSource(ScriptSource source) { + return createEngine(source.getEngineName()); + } + + + @NonNull + public ScriptEngine createEngineByNameOrThrow(String name) { + ScriptEngine engine = createEngine(name); + if (engine == null) + throw new EngineNotFoundException("name: " + name); + return engine; + } + + @NonNull + public ScriptEngine createEngineOfSourceOrThrow(ScriptSource source) { + ScriptEngine engine = createEngineOfSource(source); + if (engine == null) + throw new EngineNotFoundException("source: " + source.toString()); + return engine; + } + + public void registerEngine(String name, Supplier supplier) { + mEngines.put(name, supplier); + } + + public void unregisterEngine(String name) { + mEngines.remove(name); + } + +} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineManager.java b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineManager.java index 913cd5b2..c73a8cda 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineManager.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/ScriptEngineManager.java @@ -1,31 +1,140 @@ package com.stardust.autojs.engine; +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.stardust.autojs.script.ScriptSource; +import com.stardust.util.Supplier; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Set; /** - * Created by Stardust on 2017/5/7. + * Created by Stardust on 2017/1/27. */ -public interface ScriptEngineManager { +public class ScriptEngineManager { - - interface EngineLifecycleCallback { + public interface EngineLifecycleCallback { void onEngineCreate(ScriptEngine engine); void onEngineRemove(ScriptEngine engine); } - ScriptEngine createEngine(); + private static final String TAG = "ScriptEngineManager"; - void putGlobal(String varName, Object value); + private final Set mEngines = new HashSet<>(); + private EngineLifecycleCallback mEngineLifecycleCallback; + private Map> mEngineSuppliers = new HashMap<>(); + private Map mGlobalVariableMap = new HashMap<>(); + private android.content.Context mAndroidContext; + private ScriptEngine.OnDestroyListener mOnEngineDestroyListener = new ScriptEngine.OnDestroyListener() { + @Override + public void onDestroy(ScriptEngine engine) { + removeEngine(engine); + } + }; - void setEngineLifecycleCallback(EngineLifecycleCallback engineLifecycleCallback); + public ScriptEngineManager(Context androidContext) { + mAndroidContext = androidContext; + } - void removeEngine(ScriptEngine engine); + private void addEngine(ScriptEngine engine) { + engine.setOnDestroyListener(mOnEngineDestroyListener); + synchronized (mEngines) { + mEngines.add(engine); + if (mEngineLifecycleCallback != null) { + mEngineLifecycleCallback.onEngineCreate(engine); + } + } + } - Set getEngines(); + public void setEngineLifecycleCallback(EngineLifecycleCallback engineLifecycleCallback) { + mEngineLifecycleCallback = engineLifecycleCallback; + } - int stopAll(); + public Set getEngines() { + return mEngines; + } + + public android.content.Context getAndroidContext() { + return mAndroidContext; + } + + public void removeEngine(ScriptEngine engine) { + synchronized (mEngines) { + if (mEngines.remove(engine) && mEngineLifecycleCallback != null) { + mEngineLifecycleCallback.onEngineRemove(engine); + } + } + } + + public int stopAll() { + synchronized (mEngines) { + int n = mEngines.size(); + for (ScriptEngine engine : mEngines) { + engine.forceStop(); + } + return n; + } + } + + + public void putGlobal(String varName, Object value) { + mGlobalVariableMap.put(varName, value); + } + + protected void putProperties(ScriptEngine engine) { + for (Map.Entry variable : mGlobalVariableMap.entrySet()) { + engine.put(variable.getKey(), variable.getValue()); + } + } + + + @Nullable + public ScriptEngine createEngine(String name) { + Supplier s = mEngineSuppliers.get(name); + if (s == null) { + return null; + } + ScriptEngine engine = s.get(); + putProperties(engine); + addEngine(engine); + return engine; + } + + @Nullable + public ScriptEngine createEngineOfSource(ScriptSource source) { + return createEngine(source.getEngineName()); + } + + + @NonNull + public ScriptEngine createEngineByNameOrThrow(String name) { + ScriptEngine engine = createEngine(name); + if (engine == null) + throw new ScriptEngineFactory.EngineNotFoundException("name: " + name); + return engine; + } + + @NonNull + public ScriptEngine createEngineOfSourceOrThrow(ScriptSource source) { + ScriptEngine engine = createEngineOfSource(source); + if (engine == null) + throw new ScriptEngineFactory.EngineNotFoundException("source: " + source.toString()); + return engine; + } + + public void registerEngine(String name, Supplier supplier) { + mEngineSuppliers.put(name, supplier); + } + + public void unregisterEngine(String name) { + mEngineSuppliers.remove(name); + } } diff --git a/autojs/src/main/java/com/stardust/autojs/engine/preprocess/RootAutomatorEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/preprocess/RootAutomatorEngine.java deleted file mode 100644 index 5d4ee3f2..00000000 --- a/autojs/src/main/java/com/stardust/autojs/engine/preprocess/RootAutomatorEngine.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.stardust.autojs.engine.preprocess; - -/** - * Created by Stardust on 2017/8/1. - */ - -public class RootAutomatorEngine { -} diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java b/autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java index 0aa070d9..9990e839 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ExecutionConfig.java @@ -29,7 +29,7 @@ public class ExecutionConfig implements Serializable { return this; } - public String[] getRequirePath() { + public String[] getExecutePath() { return mRequirePath; } diff --git a/autojs/src/main/java/com/stardust/autojs/execution/RootedScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/RootedScriptExecution.java deleted file mode 100644 index befbc6f7..00000000 --- a/autojs/src/main/java/com/stardust/autojs/execution/RootedScriptExecution.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.stardust.autojs.execution; - -import com.stardust.autojs.ScriptEngineService; -import com.stardust.autojs.engine.ScriptEngine; -import com.stardust.autojs.runtime.ScriptRuntime; -import com.stardust.autojs.runtime.api.AbstractShell; -import com.stardust.autojs.runtime.api.ProcessShell; -import com.stardust.util.IntentExtras; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by Stardust on 2017/7/16. - */ - -public class RootedScriptExecution extends RunnableScriptExecution { - - private static int count = 0; - private static Map arguments = new HashMap<>(); - - public RootedScriptExecution(ScriptEngineService service, ScriptExecutionTask task) { - super(service, task); - } - - @Override - public void run() { - } - - - public static void main(String[] args) { - } - -} diff --git a/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java index 20966488..6070297f 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/RunnableScriptExecution.java @@ -2,27 +2,24 @@ package com.stardust.autojs.execution; import android.util.Log; -import com.stardust.autojs.ScriptEngineService; -import com.stardust.autojs.engine.RhinoJavaScriptEngine; import com.stardust.autojs.engine.ScriptEngine; +import com.stardust.autojs.engine.ScriptEngineManager; import com.stardust.autojs.runtime.ScriptInterruptedException; -import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.script.ScriptSource; /** * Created by Stardust on 2017/5/1. */ -public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecution implements ScriptExecution, Runnable { +public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecution implements Runnable { - private static final String TAG = "RunnableScriptExecution"; + private static final String TAG = "RunnableJSExecution"; private ScriptEngine mScriptEngine; - private ScriptRuntime mScriptRuntime; - private ScriptEngineService mScriptEngineService; + private ScriptEngineManager mScriptEngineManager; - public RunnableScriptExecution(ScriptEngineService service, ScriptExecutionTask task) { + public RunnableScriptExecution(ScriptEngineManager manager, ScriptExecutionTask task) { super(task); - mScriptEngineService = service; + mScriptEngineManager = manager; } @Override @@ -31,14 +28,13 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu } public Object execute() { - mScriptEngine = mScriptEngineService.createScriptEngine(); - mScriptRuntime = mScriptEngineService.createScriptRuntime(); - return execute(mScriptRuntime, mScriptEngine); + mScriptEngine = mScriptEngineManager.createEngineOfSourceOrThrow(getSource()); + return execute(mScriptEngine); } - private Object execute(ScriptRuntime runtime, ScriptEngine engine) { + private Object execute(ScriptEngine engine) { try { - prepare(runtime, engine); + prepare(engine); return doExecution(engine); } catch (Exception e) { e.printStackTrace(); @@ -50,17 +46,13 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu return null; } - private void prepare(ScriptRuntime runtime, ScriptEngine engine) { - if ((getSource().getExecutionMode() & ScriptSource.EXECUTION_MODE_AUTO) != 0) { - runtime.ensureAccessibilityServiceEnabled(); - } - engine.put("__runtime__", runtime); - engine.setTag("__require_path__", getConfig().getRequirePath()); + private void prepare(ScriptEngine engine) { + engine.setTag(ScriptEngine.TAG_PATH, getConfig().getExecutePath()); engine.init(); } private Object doExecution(ScriptEngine engine) { - engine.setTag("script", getSource()); + engine.setTag(ScriptEngine.TAG_SOURCE, getSource()); getListener().onStart(this); Object result = null; long delay = getConfig().delay; @@ -95,8 +87,4 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu return mScriptEngine; } - @Override - public ScriptRuntime getRuntime() { - return mScriptRuntime; - } } \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java index 7ae23709..7b7def70 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java @@ -1,17 +1,14 @@ package com.stardust.autojs.execution; -import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; -import com.stardust.autojs.R; -import com.stardust.autojs.ScriptEngineService; import com.stardust.autojs.engine.ScriptEngine; -import com.stardust.autojs.runtime.ScriptRuntime; +import com.stardust.autojs.engine.ScriptEngineManager; import com.stardust.autojs.script.ScriptSource; +import com.stardust.util.IntentExtras; /** * Created by Stardust on 2017/2/5. @@ -20,33 +17,36 @@ import com.stardust.autojs.script.ScriptSource; public class ScriptExecuteActivity extends AppCompatActivity { - private static ActivityScriptExecution execution; + private static final String EXTRA_EXECUTION = ScriptExecuteActivity.class.getName() + ".execution"; private Object mResult; private ScriptEngine mScriptEngine; private ScriptExecutionListener mExecutionListener; private ScriptSource mScriptSource; + private ScriptExecution mScriptExecution; - public static ActivityScriptExecution execute(Context context, ScriptEngineService service, ScriptExecutionTask task) { - if (execution != null) { - return null; - } - - execution = new ActivityScriptExecution(service, task); - context.startActivity(new Intent(context, ScriptExecuteActivity.class) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + public static ActivityScriptExecution execute(Context context, ScriptEngineManager manager, ScriptExecutionTask task) { + ActivityScriptExecution execution = new ActivityScriptExecution(manager, task); + Intent i = new Intent(context, ScriptExecuteActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + IntentExtras.newExtras() + .put(EXTRA_EXECUTION, execution) + .putInIntent(i); + context.startActivity(i); return execution; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (execution == null) { + IntentExtras extras = IntentExtras.fromIntent(getIntent()); + if (extras == null || extras.get(EXTRA_EXECUTION) == null) { finish(); return; } - mScriptSource = execution.getSource(); - mScriptEngine = execution.getEngine(); - mExecutionListener = execution.getListener(); + mScriptExecution = extras.get(EXTRA_EXECUTION); + mScriptSource = mScriptExecution.getSource(); + mScriptEngine = mScriptExecution.getEngine(); + mExecutionListener = mScriptExecution.getListener(); runScript(); } @@ -55,27 +55,26 @@ public class ScriptExecuteActivity extends AppCompatActivity { prepare(); doExecution(); } catch (Exception e) { - mExecutionListener.onException(execution, e); + mExecutionListener.onException(mScriptExecution, e); super.finish(); } } private void doExecution() { - mScriptEngine.setTag("script", mScriptSource); - mExecutionListener.onStart(execution); + mScriptEngine.setTag(ScriptEngine.TAG_SOURCE, mScriptSource); + mExecutionListener.onStart(mScriptExecution); mResult = mScriptEngine.execute(mScriptSource); } private void prepare() { mScriptEngine.put("activity", this); - mScriptEngine.put("__runtime__", execution.getRuntime()); - mScriptEngine.setTag("__require_path__", execution.getConfig().getRequirePath()); + mScriptEngine.setTag(ScriptEngine.TAG_PATH, mScriptExecution.getConfig().getExecutePath()); mScriptEngine.init(); } @Override public void finish() { - mExecutionListener.onSuccess(execution, mResult); + mExecutionListener.onSuccess(mScriptExecution, mResult); super.finish(); } @@ -84,36 +83,27 @@ public class ScriptExecuteActivity extends AppCompatActivity { super.onDestroy(); mScriptEngine.put("activity", null); mScriptEngine.destroy(); - execution = null; + mScriptExecution = null; } private static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution { private ScriptEngine mScriptEngine; - private ScriptRuntime mScriptRuntime; - private ScriptEngineService mScriptEngineService; + private ScriptEngineManager mScriptEngineManager; - ActivityScriptExecution(ScriptEngineService service, ScriptExecutionTask task) { + ActivityScriptExecution(ScriptEngineManager manager, ScriptExecutionTask task) { super(task); - mScriptEngineService = service; + mScriptEngineManager = manager; } @Override public ScriptEngine getEngine() { if (mScriptEngine == null) { - mScriptEngine = mScriptEngineService.createScriptEngine(); + mScriptEngine = mScriptEngineManager.createEngineOfSourceOrThrow(getSource()); } return mScriptEngine; } - @Override - public ScriptRuntime getRuntime() { - if (mScriptRuntime == null) { - mScriptRuntime = mScriptEngineService.createScriptRuntime(); - } - return mScriptRuntime; - } - } diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java index 1ed33dac..a7625b94 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecution.java @@ -12,8 +12,6 @@ public interface ScriptExecution { ScriptEngine getEngine(); - ScriptRuntime getRuntime(); - ScriptSource getSource(); ScriptExecutionListener getListener(); @@ -31,9 +29,6 @@ public interface ScriptExecution { @Override public abstract ScriptEngine getEngine(); - @Override - public abstract ScriptRuntime getRuntime(); - @Override public ScriptSource getSource() { return mScriptExecutionTask.getSource(); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java index c37ddae9..73e7b299 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/AbstractShell.java @@ -106,7 +106,6 @@ public abstract class AbstractShell { private int scaleY(int y) { return mScreenMetrics.scaleY(y); - } public void Tap(int x, int y) { @@ -114,7 +113,7 @@ public abstract class AbstractShell { } public void Swipe(int x1, int y1, int x2, int y2) { - exec(com.stardust.util.TextUtils.join(" ", "input", "tap", scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2))); + exec(com.stardust.util.TextUtils.join(" ", "input", "swipe", scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2))); } public void Swipe(int x1, int y1, int x2, int y2, int time) { diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ProcessShell.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ProcessShell.java index 0167841e..d990ff50 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/ProcessShell.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ProcessShell.java @@ -17,7 +17,7 @@ import java.io.Reader; * 来自网络~~ */ -public class ProcessShell extends AbstractShell implements AutoCloseable { +public class ProcessShell extends AbstractShell { private static final String TAG = "ProcessShell"; @@ -87,11 +87,6 @@ public class ProcessShell extends AbstractShell implements AutoCloseable { } - @Override - public void close() { - exit(); - } - @Override public void exitAndWaitFor() { exec(COMMAND_EXIT); @@ -158,7 +153,9 @@ public class ProcessShell extends AbstractShell implements AutoCloseable { } public static Result exec(String[] commands, boolean isRoot) { - try (ProcessShell shell = new ProcessShell(isRoot)) { + ProcessShell shell = null; + try { + shell = new ProcessShell(isRoot); for (String command : commands) { shell.exec(command); } @@ -170,6 +167,10 @@ public class ProcessShell extends AbstractShell implements AutoCloseable { result.result = shell.getSucceedOutput().toString(); shell.exit(); return result; + } finally { + if (shell != null) { + shell.exit(); + } } } @@ -195,7 +196,6 @@ public class ProcessShell extends AbstractShell implements AutoCloseable { os.writeBytes(COMMAND_EXIT); os.flush(); commandResult.code = process.waitFor(); - //获取错误信息 successMsg = new StringBuilder(); errorMsg = new StringBuilder(); successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java index 426f84d6..f9f7253b 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/RootAutomator.java @@ -2,7 +2,7 @@ package com.stardust.autojs.runtime.api; import android.content.Context; -import com.stardust.pio.PFile; +import com.stardust.autojs.engine.RootAutomatorEngine; import com.stardust.pio.UncheckedIOException; import com.stardust.util.ScreenMetrics; @@ -18,10 +18,9 @@ import java.io.IOException; public class RootAutomator { - private static final int DATA_TYPE_SLEEP = 0; - private static final int DATA_TYPE_EVENT = 1; + public static final byte DATA_TYPE_SLEEP = 0; + public static final byte DATA_TYPE_EVENT = 1; - private static final String ROOT_AUTOMATOR_EXECUTABLE_ASSET = "binary/root_automator"; private DataOutputStream mTmpFileOutputStream; private File mEventTmpFile; private ScreenMetrics mScreenMetrics; @@ -88,24 +87,11 @@ public class RootAutomator { } public AbstractShell.Result writeToDevice(Context context) { - try { - mTmpFileOutputStream.close(); - } catch (IOException e) { - e.printStackTrace(); + if (mDevicePath == null) { + return new RootAutomatorEngine(context).execute(mEventTmpFile.getAbsolutePath()); + } else { + return new RootAutomatorEngine(context, mDevicePath).execute(mEventTmpFile.getAbsolutePath()); } - String executablePath = getExecutablePath(context); - return ProcessShell.execCommand(new String[]{ - "chmod 777 " + executablePath, - executablePath + " " + mEventTmpFile.getAbsolutePath() + " " + mDevicePath - }, true); - } - - public static String getExecutablePath(Context context) { - File tmp = new File(context.getCacheDir(), "root_automator"); - if (!tmp.exists()) { - PFile.copyAsset(context, ROOT_AUTOMATOR_EXECUTABLE_ASSET, tmp.getAbsolutePath()); - } - return tmp.getAbsolutePath(); } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevice.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevice.java deleted file mode 100644 index 6e9369f3..00000000 --- a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevice.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.stardust.autojs.runtime.record.inputevent; - -/** - * Created by Stardust on 2017/8/1. - */ - -public class InputDevice { -} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevices.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevices.java new file mode 100644 index 00000000..304dc5a8 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputDevices.java @@ -0,0 +1,31 @@ +package com.stardust.autojs.runtime.record.inputevent; + +import android.content.Context; +import android.hardware.input.InputManager; +import android.support.annotation.Nullable; +import android.util.Log; +import android.view.InputDevice; + +/** + * Created by Stardust on 2017/8/1. + */ + +public class InputDevices { + + @Nullable + public static String getTouchDeviceName() { + for (int id : InputDevice.getDeviceIds()) { + InputDevice device = InputDevice.getDevice(id); + if (supportSource(device, InputDevice.SOURCE_TOUCHSCREEN) || supportSource(device, InputDevice.SOURCE_TOUCHPAD)) { + return device.getName(); + } + } + return null; + } + + private static boolean supportSource(InputDevice device, int source) { + return (device.getSources() & source) == source; + } + + +} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToAutoFileConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToAutoFileConverter.java new file mode 100644 index 00000000..deb2979a --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToAutoFileConverter.java @@ -0,0 +1,104 @@ +package com.stardust.autojs.runtime.record.inputevent; + +import android.support.annotation.NonNull; + +import com.stardust.autojs.engine.RootAutomatorEngine; +import com.stardust.autojs.runtime.api.RootAutomator; +import com.stardust.pio.UncheckedIOException; +import com.stardust.util.ScreenMetrics; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * Created by Stardust on 2017/8/2. + */ + +public class InputEventToAutoFileConverter extends InputEventConverter { + + private double mLastEventTime; + private int mTouchDevice = -1; + private DataOutputStream mDataOutputStream; + private File mTmpFile; + + public InputEventToAutoFileConverter() { + try { + mTmpFile = File.createTempFile("Record" + System.currentTimeMillis(), ".auto"); + mDataOutputStream = new DataOutputStream(new FileOutputStream(mTmpFile)); + writeFileHeader(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private void writeFileHeader() throws IOException { + mDataOutputStream.writeInt(0x00B87B6D); + mDataOutputStream.writeInt(RootAutomatorEngine.VERSION); + mDataOutputStream.writeInt(ScreenMetrics.getDeviceScreenWidth()); + mDataOutputStream.writeInt(ScreenMetrics.getDeviceScreenHeight()); + for (int i = 0; i < 240; i++) { + mDataOutputStream.writeByte(0); + } + } + + + @Override + public void convertEvent(@NonNull InputEventConverter.Event event) { + try { + convertEventOrThrow(event); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + private void convertEventOrThrow(Event event) throws IOException { + if (mLastEventTime == 0) { + mLastEventTime = event.time; + } else if (event.time - mLastEventTime > 0.001) { + mDataOutputStream.writeByte(RootAutomator.DATA_TYPE_SLEEP); + int n = (int) (1000L * (event.time - mLastEventTime)); + mDataOutputStream.writeInt(n); + mLastEventTime = event.time; + } + int device = parseDeviceNumber(event.device); + short type = (short) Long.parseLong(event.type, 16); + short code = (short) Long.parseLong(event.code, 16); + int value = (int) Long.parseLong(event.value, 16); + if (type == 3) { + if (code == 53 || code == 54) { + mTouchDevice = device; + RootAutomatorEngine.setTouchDevice(device); + } + } + if (device != mTouchDevice) { + return; + } + mDataOutputStream.writeByte(RootAutomator.DATA_TYPE_EVENT); + mDataOutputStream.writeShort(type); + mDataOutputStream.writeShort(code); + mDataOutputStream.writeInt(value); + } + + + @Override + public String getGetEventCommand() { + return "getevent -t"; + } + + public String getCode() { + return mTmpFile.getAbsolutePath(); + } + + @Override + public void stop() { + super.stop(); + try { + mDataOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToRootAutomatorConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToRootAutomatorConverter.java index 4aa0d032..9322f398 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToRootAutomatorConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/InputEventToRootAutomatorConverter.java @@ -32,7 +32,7 @@ public class InputEventToRootAutomatorConverter extends InputEventConverter { public void convertEvent(@NonNull Event event) { if (mLastEventTime == 0) { mLastEventTime = event.time; - } else if (event.time - mLastEventTime > 0.005) { + } else if (event.time - mLastEventTime > 0.001) { mCode.append("ra.sleep(").append((long) (1000L * (event.time - mLastEventTime))).append(");\n"); mLastEventTime = event.time; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java index 92080228..e63a44ee 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/record/inputevent/TouchRecorder.java @@ -9,7 +9,7 @@ import android.content.Context; public class TouchRecorder extends InputEventRecorder { public TouchRecorder(Context context) { - super(context, new InputEventToRootAutomatorConverter()); + super(context, new InputEventToAutoFileConverter()); listen(); } diff --git a/autojs/src/main/java/com/stardust/autojs/script/AutoFileSource.java b/autojs/src/main/java/com/stardust/autojs/script/AutoFileSource.java new file mode 100644 index 00000000..34fb4f87 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/script/AutoFileSource.java @@ -0,0 +1,38 @@ +package com.stardust.autojs.script; + +import android.support.annotation.NonNull; + +import com.stardust.pio.PFile; + +import java.io.File; +import java.io.Reader; + +/** + * Created by Stardust on 2017/8/2. + */ + +public class AutoFileSource extends ScriptSource { + + public static final String ENGINE = AutoFileSource.class.getName() + ".Engine"; + private File mFile; + + public AutoFileSource(File file) { + super(PFile.getNameWithoutExtension(file.getAbsolutePath())); + mFile = file; + } + + public AutoFileSource(String path) { + this(new File(path)); + } + + + @Override + public String getEngineName() { + return ENGINE; + } + + public File getFile() { + return mFile; + } + +} diff --git a/autojs/src/main/java/com/stardust/autojs/script/FileScriptSource.java b/autojs/src/main/java/com/stardust/autojs/script/JavaScriptFileSource.java similarity index 74% rename from autojs/src/main/java/com/stardust/autojs/script/FileScriptSource.java rename to autojs/src/main/java/com/stardust/autojs/script/JavaScriptFileSource.java index 1bf8208a..81730e65 100644 --- a/autojs/src/main/java/com/stardust/autojs/script/FileScriptSource.java +++ b/autojs/src/main/java/com/stardust/autojs/script/JavaScriptFileSource.java @@ -1,6 +1,7 @@ package com.stardust.autojs.script; -import com.stardust.autojs.script.ScriptSource; +import android.support.annotation.NonNull; + import com.stardust.pio.PFile; import com.stardust.pio.UncheckedIOException; @@ -13,25 +14,26 @@ import java.io.Reader; * Created by Stardust on 2017/4/2. */ -public class FileScriptSource extends ScriptSource { +public class JavaScriptFileSource extends JavaScriptSource { private File mFile; private String mScript; - public FileScriptSource(File file) { + public JavaScriptFileSource(File file) { super(PFile.getNameWithoutExtension(file.getName())); mFile = file; } - public FileScriptSource(String path) { + public JavaScriptFileSource(String path) { this(new File(path)); } - public FileScriptSource(String name, File file) { + public JavaScriptFileSource(String name, File file) { super(name); mFile = file; } + @NonNull @Override public String getScript() { if (mScript == null) @@ -48,6 +50,10 @@ public class FileScriptSource extends ScriptSource { } } + public File getFile() { + return mFile; + } + @Override public String toString() { return mFile.toString(); diff --git a/autojs/src/main/java/com/stardust/autojs/script/JavaScriptSource.java b/autojs/src/main/java/com/stardust/autojs/script/JavaScriptSource.java new file mode 100644 index 00000000..70f20a60 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/script/JavaScriptSource.java @@ -0,0 +1,90 @@ +package com.stardust.autojs.script; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.stardust.util.MapEntries; + +import java.io.Reader; +import java.io.StringReader; +import java.util.Map; + +/** + * Created by Stardust on 2017/8/2. + */ + +public abstract class JavaScriptSource extends ScriptSource { + + public static final String ENGINE = "com.stardust.autojs.script.JavaScriptSource.Engine"; + + public static final int EXECUTION_MODE_NORMAL = 0; + public static final int EXECUTION_MODE_UI = 0x00000001; + public static final int EXECUTION_MODE_AUTO = 0x00000002; + + private static final Map EXECUTION_MODES = new MapEntries() + .entry("ui", EXECUTION_MODE_UI) + .entry("auto", EXECUTION_MODE_AUTO) + .map(); + private static final int EXECUTION_MODE_STRING_MAX_LENGTH = 7; + + private int mExecutionMode = -1; + + public JavaScriptSource(String name) { + super(name); + } + + @NonNull + public abstract String getScript(); + + @Nullable + public abstract Reader getScriptReader(); + + @NonNull + public Reader getNonNullScriptReader() { + Reader reader = getScriptReader(); + if (reader == null) { + return new StringReader(getScript()); + } + return reader; + } + + public String toString() { + return getName() + ".js"; + } + + + public int getExecutionMode() { + if (mExecutionMode == -1) { + mExecutionMode = parseExecutionMode(getScript()); + } + return mExecutionMode; + } + + private int parseExecutionMode(String script) { + if (script == null || script.length() == 0 || script.charAt(0) != '"') + return EXECUTION_MODE_NORMAL; + int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2); + if (i == -1) + return EXECUTION_MODE_NORMAL; + String modeString = script.substring(1, i); + return parseExecutionMode(modeString.split(" ")); + } + + private int parseExecutionMode(String[] modeStrings) { + int mode = 0; + for (String modeString : modeStrings) { + Integer i = EXECUTION_MODES.get(modeString); + if (i != null) { + mode |= i; + } + } + return mode; + } + + @Override + public String getEngineName() { + return ENGINE; + } + + +} diff --git a/autojs/src/main/java/com/stardust/autojs/script/ScriptSource.java b/autojs/src/main/java/com/stardust/autojs/script/ScriptSource.java index 78719a10..53303a1a 100644 --- a/autojs/src/main/java/com/stardust/autojs/script/ScriptSource.java +++ b/autojs/src/main/java/com/stardust/autojs/script/ScriptSource.java @@ -19,17 +19,6 @@ import java.util.Map; public abstract class ScriptSource implements Serializable { - public static final int EXECUTION_MODE_NORMAL = 0; - public static final int EXECUTION_MODE_UI = 0x00000001; - public static final int EXECUTION_MODE_AUTO = 0x00000002; - - private static final Map EXECUTION_MODES = new MapEntries() - .entry("ui", EXECUTION_MODE_UI) - .entry("auto", EXECUTION_MODE_AUTO) - .map(); - private static final int EXECUTION_MODE_STRING_MAX_LENGTH = 7; - - private int mExecutionMode = -1; private String mName; public ScriptSource(String name) { @@ -40,51 +29,5 @@ public abstract class ScriptSource implements Serializable { return mName; } - @NonNull - public abstract String getScript(); - - @Nullable - public abstract Reader getScriptReader(); - - @NonNull - public Reader getNonNullScriptReader() { - Reader reader = getScriptReader(); - if (reader == null) { - return new StringReader(getScript()); - } - return reader; - } - - public int getExecutionMode() { - if (mExecutionMode == -1) { - mExecutionMode = parseExecutionMode(getScript()); - } - return mExecutionMode; - } - - private int parseExecutionMode(String script) { - if (script == null || script.length() == 0 || script.charAt(0) != '"') - return EXECUTION_MODE_NORMAL; - int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2); - if (i == -1) - return EXECUTION_MODE_NORMAL; - String modeString = script.substring(1, i); - return parseExecutionMode(modeString.split(" ")); - } - - private int parseExecutionMode(String[] modeStrings) { - int mode = 0; - for (String modeString : modeStrings) { - Integer i = EXECUTION_MODES.get(modeString); - if (i != null) { - mode |= i; - } - } - return mode; - } - - @Override - public String toString() { - return mName + ".js"; - } + public abstract String getEngineName(); } diff --git a/autojs/src/main/java/com/stardust/autojs/script/SequenceScriptSource.java b/autojs/src/main/java/com/stardust/autojs/script/SequenceScriptSource.java index a5d9aea8..fa37db35 100644 --- a/autojs/src/main/java/com/stardust/autojs/script/SequenceScriptSource.java +++ b/autojs/src/main/java/com/stardust/autojs/script/SequenceScriptSource.java @@ -12,14 +12,14 @@ import java.io.StringReader; * Created by Stardust on 2017/4/2. */ -public class SequenceScriptSource extends ScriptSource { +public class SequenceScriptSource extends JavaScriptSource { private String mScript; - private ScriptSource mSecondScriptSource; - private ScriptSource mFirstScriptSource; + private JavaScriptSource mSecondScriptSource; + private JavaScriptSource mFirstScriptSource; - public SequenceScriptSource(String name, ScriptSource firstScriptSource, ScriptSource secondScriptSource) { + public SequenceScriptSource(String name, JavaScriptSource firstScriptSource, JavaScriptSource secondScriptSource) { super(name); mSecondScriptSource = secondScriptSource; mFirstScriptSource = firstScriptSource; diff --git a/autojs/src/main/java/com/stardust/autojs/script/StringScriptSource.java b/autojs/src/main/java/com/stardust/autojs/script/StringScriptSource.java index 43def31c..c8b672d5 100644 --- a/autojs/src/main/java/com/stardust/autojs/script/StringScriptSource.java +++ b/autojs/src/main/java/com/stardust/autojs/script/StringScriptSource.java @@ -9,7 +9,7 @@ import java.io.Reader; * Created by Stardust on 2017/4/2. */ -public class StringScriptSource extends ScriptSource { +public class StringScriptSource extends JavaScriptSource { private String mScript; diff --git a/inrt/src/main/java/com/stardust/auojs/inrt/App.java b/inrt/src/main/java/com/stardust/auojs/inrt/App.java index 12551ef8..7cf3505d 100644 --- a/inrt/src/main/java/com/stardust/auojs/inrt/App.java +++ b/inrt/src/main/java/com/stardust/auojs/inrt/App.java @@ -2,8 +2,6 @@ package com.stardust.auojs.inrt; import android.app.Application; -import com.stardust.auojs.inrt.rt.AutoJs; - /** * Created by Stardust on 2017/7/1. */ @@ -13,6 +11,5 @@ public class App extends Application { @Override public void onCreate() { super.onCreate(); - AutoJs.initInstance(this); } } diff --git a/inrt/src/main/java/com/stardust/auojs/inrt/MainActivity.java b/inrt/src/main/java/com/stardust/auojs/inrt/MainActivity.java index b03d9189..8ae3fe42 100644 --- a/inrt/src/main/java/com/stardust/auojs/inrt/MainActivity.java +++ b/inrt/src/main/java/com/stardust/auojs/inrt/MainActivity.java @@ -3,8 +3,6 @@ package com.stardust.auojs.inrt; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; -import com.stardust.auojs.inrt.rt.AutoJs; -import com.stardust.autojs.execution.ExecutionConfig; import com.stardust.autojs.script.StringScriptSource; import java.io.IOException; @@ -21,7 +19,7 @@ public class MainActivity extends AppCompatActivity { is.read(data); String js = new String(data); StringScriptSource source = new StringScriptSource("