add: apk builder plugin support; fix: inrt AutoJs.ensureServiceEnabled
This commit is contained in:
3
.idea/modules.xml
generated
3
.idea/modules.xml
generated
@@ -2,7 +2,8 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/Auto.js.iml" filepath="$PROJECT_DIR$/Auto.js.iml" />
|
<module fileurl="file://E:\YiBin\AndroidStudioProjects\NoRootScriptDroid\Auto.js.iml" filepath="E:\YiBin\AndroidStudioProjects\NoRootScriptDroid\Auto.js.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/NoRootScriptDroid.iml" filepath="$PROJECT_DIR$/NoRootScriptDroid.iml" />
|
||||||
<module fileurl="file://C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" filepath="C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" />
|
<module fileurl="file://C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" filepath="C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/autojs/autojs.iml" filepath="$PROJECT_DIR$/autojs/autojs.iml" />
|
<module fileurl="file://$PROJECT_DIR$/autojs/autojs.iml" filepath="$PROJECT_DIR$/autojs/autojs.iml" />
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "com.stardust.scriptdroid"
|
applicationId "com.stardust.scriptdroid"
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 23
|
targetSdkVersion 23
|
||||||
versionCode 224
|
versionCode 226
|
||||||
versionName "3.0.0 Alpha2"
|
versionName "3.0.0 Alpha26"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
ndk {
|
ndk {
|
||||||
@@ -83,8 +83,6 @@ dependencies {
|
|||||||
compile('com.afollestad.material-dialogs:core:0.9.2.3', {
|
compile('com.afollestad.material-dialogs:core:0.9.2.3', {
|
||||||
exclude group: 'com.android.support'
|
exclude group: 'com.android.support'
|
||||||
})
|
})
|
||||||
// Gson
|
|
||||||
compile 'com.google.code.gson:gson:2.8.0'
|
|
||||||
// Common Markdown
|
// Common Markdown
|
||||||
compile 'com.github.atlassian:commonmark-java:commonmark-parent-0.9.0'
|
compile 'com.github.atlassian:commonmark-java:commonmark-parent-0.9.0'
|
||||||
// AlipayZeroSdk
|
// AlipayZeroSdk
|
||||||
|
|||||||
9
app/src/main/assets/sample/HTTP网络请求/获取网页.js
Normal file
9
app/src/main/assets/sample/HTTP网络请求/获取网页.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
var url = "www.baidu.com";
|
||||||
|
var res = http.get(url);
|
||||||
|
if(res.statusCode == 200){
|
||||||
|
toast("请求成功");
|
||||||
|
console.show();
|
||||||
|
log(res.body.string());
|
||||||
|
}else{
|
||||||
|
toast("请求失败:" + res.statusMessage);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.stardust.scriptdroid.autojs;
|
package com.stardust.scriptdroid.autojs;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -52,7 +53,7 @@ import org.opencv.android.OpenCVLoader;
|
|||||||
* Created by Stardust on 2017/4/2.
|
* Created by Stardust on 2017/4/2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AutoJs {
|
public class AutoJs extends com.stardust.autojs.AutoJs {
|
||||||
|
|
||||||
private static AutoJs instance;
|
private static AutoJs instance;
|
||||||
|
|
||||||
@@ -64,24 +65,15 @@ public class AutoJs {
|
|||||||
instance = new AutoJs(context);
|
instance = new AutoJs(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
|
||||||
private final AccessibilityNotificationObserver mNotificationObserver;
|
|
||||||
private ScriptEngineManager mScriptEngineManager;
|
|
||||||
private final LayoutInspector mLayoutInspector = new LayoutInspector();
|
|
||||||
private final Context mContext;
|
|
||||||
private final UiHandler mUiHandler;
|
|
||||||
private final AppUtils mAppUtils;
|
|
||||||
private final AccessibilityInfoProvider mAccessibilityInfoProvider;
|
|
||||||
private final ScreenCaptureRequester mScreenCaptureRequester = new ScreenCaptureRequesterImpl();
|
|
||||||
private final ScriptEngineService mScriptEngineService;
|
|
||||||
private final Console mGlobalConsole;
|
|
||||||
|
|
||||||
|
|
||||||
private AutoJs(final Context context) {
|
private AutoJs(final Context context) {
|
||||||
mContext = context;
|
super(context);
|
||||||
mUiHandler = new UiHandler(context);
|
getScriptEngineService().registerGlobalScriptExecutionListener(new ScriptExecutionGlobalListener());
|
||||||
mAppUtils = new AppUtils(context);
|
}
|
||||||
mGlobalConsole = new GlobalStardustConsole(mUiHandler) {
|
|
||||||
|
@Override
|
||||||
|
protected Console createGlobalConsole() {
|
||||||
|
return new GlobalStardustConsole(getUiHandler()) {
|
||||||
@Override
|
@Override
|
||||||
public String println(int level, CharSequence charSequence) {
|
public String println(int level, CharSequence charSequence) {
|
||||||
String log = super.println(level, charSequence);
|
String log = super.println(level, charSequence);
|
||||||
@@ -89,172 +81,33 @@ public class AutoJs {
|
|||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mNotificationObserver = new AccessibilityNotificationObserver(context);
|
|
||||||
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
|
||||||
mScriptEngineService = buildScriptEngineService();
|
|
||||||
addAccessibilityServiceDelegates();
|
|
||||||
mScriptEngineService.registerGlobalScriptExecutionListener(new ScriptExecutionGlobalListener());
|
|
||||||
registerActivityLifecycleCallbacks();
|
|
||||||
InputEventObserver.initGlobal(context);
|
|
||||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, context, new BaseLoaderCallback(context) {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScriptEngineService buildScriptEngineService() {
|
|
||||||
initScriptEngineManager();
|
|
||||||
return new ScriptEngineServiceBuilder()
|
|
||||||
.uiHandler(mUiHandler)
|
|
||||||
.globalConsole(mGlobalConsole)
|
|
||||||
.engineManger(mScriptEngineManager)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initScriptEngineManager() {
|
|
||||||
mScriptEngineManager = new ScriptEngineManager(mContext);
|
|
||||||
mScriptEngineManager.registerEngine(JavaScriptSource.ENGINE, new Supplier<ScriptEngine>() {
|
|
||||||
@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)
|
|
||||||
.setEngineService(mScriptEngineService)
|
|
||||||
.setShellSupplier(new Supplier<AbstractShell>() {
|
|
||||||
@Override
|
|
||||||
public AbstractShell get() {
|
|
||||||
return new Shell(mContext, true);
|
|
||||||
}
|
|
||||||
}).build());
|
|
||||||
return engine;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, new Supplier<ScriptEngine>() {
|
|
||||||
@Override
|
|
||||||
public ScriptEngine get() {
|
|
||||||
return new RootAutomatorEngine(mContext);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerActivityLifecycleCallbacks() {
|
|
||||||
App.getApp().registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
|
||||||
ScreenMetrics.initIfNeeded(activity);
|
|
||||||
mAppUtils.setCurrentActivity(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityPaused(Activity activity) {
|
|
||||||
mAppUtils.setCurrentActivity(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResumed(Activity activity) {
|
|
||||||
mAppUtils.setCurrentActivity(activity);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addAccessibilityServiceDelegates() {
|
|
||||||
AccessibilityService.addDelegate(100, mAccessibilityInfoProvider);
|
|
||||||
AccessibilityService.addDelegate(200, mNotificationObserver);
|
|
||||||
AccessibilityService.addDelegate(300, mAccessibilityActionRecorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccessibilityActionRecorder getAccessibilityActionRecorder() {
|
|
||||||
return mAccessibilityActionRecorder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppUtils getAppUtils() {
|
|
||||||
return mAppUtils;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UiHandler getUiHandler() {
|
|
||||||
return mUiHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LayoutInspector getLayoutInspector() {
|
|
||||||
return mLayoutInspector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Console getGlobalConsole() {
|
|
||||||
return mGlobalConsole;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptEngineService getScriptEngineService() {
|
|
||||||
return mScriptEngineService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccessibilityInfoProvider getInfoProvider() {
|
|
||||||
return mAccessibilityInfoProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ensureAccessibilityServiceEnabled() {
|
public void ensureAccessibilityServiceEnabled() {
|
||||||
if (AccessibilityService.getInstance() == null) {
|
if (AccessibilityService.getInstance() != null) {
|
||||||
String errorMessage = null;
|
return;
|
||||||
if (AccessibilityServiceTool.isAccessibilityServiceEnabled(App.getApp())) {
|
}
|
||||||
errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
|
String errorMessage = null;
|
||||||
} else {
|
if (AccessibilityServiceTool.isAccessibilityServiceEnabled(App.getApp())) {
|
||||||
if (Pref.enableAccessibilityServiceByRoot()) {
|
errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
|
||||||
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(2000)) {
|
} else {
|
||||||
errorMessage = App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
|
if (Pref.enableAccessibilityServiceByRoot()) {
|
||||||
}
|
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(2000)) {
|
||||||
} else {
|
errorMessage = App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
|
||||||
errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (errorMessage != null) {
|
|
||||||
AccessibilityServiceTool.goToAccessibilitySetting();
|
|
||||||
throw new ScriptException(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class AccessibilityBridgeImpl extends AccessibilityBridge {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ensureServiceEnabled() {
|
|
||||||
AutoJs.this.ensureAccessibilityServiceEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public AccessibilityService getService() {
|
|
||||||
return AccessibilityService.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessibilityInfoProvider getInfoProvider() {
|
|
||||||
return mAccessibilityInfoProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessibilityNotificationObserver getNotificationObserver() {
|
|
||||||
return mNotificationObserver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester {
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
|
||||||
public void request() {
|
|
||||||
Activity activity = mAppUtils.getCurrentActivity();
|
|
||||||
if (activity instanceof OnActivityResultDelegate.DelegateHost) {
|
|
||||||
ScreenCaptureRequester requester = new ActivityScreenCaptureRequester(
|
|
||||||
((OnActivityResultDelegate.DelegateHost) activity).getOnActivityResultDelegateMediator(), activity);
|
|
||||||
requester.setOnActivityResultCallback(mCallback);
|
|
||||||
requester.request();
|
|
||||||
} else {
|
} else {
|
||||||
ScreenCaptureRequestActivity.request(mContext, mCallback);
|
errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (errorMessage != null) {
|
||||||
|
AccessibilityServiceTool.goToAccessibilitySetting();
|
||||||
|
throw new ScriptException(errorMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Application getApplication() {
|
||||||
|
return App.getApp();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.stardust.scriptdroid.build;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import com.stardust.pio.UncheckedIOException;
|
||||||
|
import com.stardust.util.DeveloperUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/11/29.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ApkBuilderPluginHelper {
|
||||||
|
|
||||||
|
private static final String PLUGIN_PACKAGE_NAME = "org.autojs.apkbuilderplugin";
|
||||||
|
private static final String TEMPLATE_APK_PATH = "template.apk";
|
||||||
|
|
||||||
|
public static boolean checkPlugin(Context context) {
|
||||||
|
return DeveloperUtils.checkSignature(context, PLUGIN_PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream openTemplateApk(Context context) {
|
||||||
|
try {
|
||||||
|
return context.getPackageManager().getResourcesForApplication(PLUGIN_PACKAGE_NAME)
|
||||||
|
.getAssets().open(TEMPLATE_APK_PATH);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ import io.reactivex.subjects.PublishSubject;
|
|||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/11/27.
|
* Created by Stardust on 2017/11/27.
|
||||||
*/
|
*/
|
||||||
|
//TODO rx
|
||||||
public class TimedTaskManager {
|
public class TimedTaskManager {
|
||||||
|
|
||||||
|
|
||||||
@@ -75,23 +75,6 @@ public class TimedTaskManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Flowable<TimedTask> getTaskById(int id) {
|
|
||||||
return RXSQLite.rx(SQLite.select()
|
|
||||||
.from(TimedTask.class)
|
|
||||||
.where(TimedTask_Table.id.is(id)))
|
|
||||||
.queryStreamResults()
|
|
||||||
.subscribeOn(Schedulers.io());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Completable removeTask(int id) {
|
|
||||||
return RXSQLite.rx(SQLite.delete(TimedTaskDatabase.class)
|
|
||||||
.where(TimedTask_Table.id.is(id)))
|
|
||||||
.execute()
|
|
||||||
.subscribeOn(Schedulers.io());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelTask(TimedTask timedTask) {
|
public void cancelTask(TimedTask timedTask) {
|
||||||
TimedTaskScheduler.cancel(mContext, timedTask);
|
TimedTaskScheduler.cancel(mContext, timedTask);
|
||||||
mTimedTaskModelAdapter.delete(timedTask);
|
mTimedTaskModelAdapter.delete(timedTask);
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package com.stardust.scriptdroid.ui.build;
|
package com.stardust.scriptdroid.ui.build;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.afollestad.materialdialogs.DialogAction;
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.autojs.build.AutoJsApkBuilder;
|
import com.stardust.scriptdroid.autojs.build.AutoJsApkBuilder;
|
||||||
|
import com.stardust.scriptdroid.build.ApkBuilderPluginHelper;
|
||||||
|
import com.stardust.scriptdroid.network.download.DownloadManager;
|
||||||
import com.stardust.scriptdroid.storage.file.StorageFileProvider;
|
import com.stardust.scriptdroid.storage.file.StorageFileProvider;
|
||||||
import com.stardust.scriptdroid.model.script.ScriptFile;
|
import com.stardust.scriptdroid.model.script.ScriptFile;
|
||||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||||
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
|
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
|
||||||
|
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||||
import com.stardust.util.IntentUtil;
|
import com.stardust.util.IntentUtil;
|
||||||
|
|
||||||
import org.androidannotations.annotations.AfterViews;
|
import org.androidannotations.annotations.AfterViews;
|
||||||
@@ -20,6 +25,7 @@ import org.androidannotations.annotations.EActivity;
|
|||||||
import org.androidannotations.annotations.ViewById;
|
import org.androidannotations.annotations.ViewById;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
@@ -61,9 +67,28 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
|||||||
if (sourcePath != null) {
|
if (sourcePath != null) {
|
||||||
setupWithSourceFile(new ScriptFile(sourcePath));
|
setupWithSourceFile(new ScriptFile(sourcePath));
|
||||||
}
|
}
|
||||||
|
showPluginDownloadDialogIfNeeded();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPluginDownloadDialogIfNeeded() {
|
||||||
|
if (ApkBuilderPluginHelper.checkPlugin(this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new ThemeColorMaterialDialogBuilder(this)
|
||||||
|
.content(R.string.no_apk_builder_plugin)
|
||||||
|
.positiveText(R.string.ok)
|
||||||
|
.negativeText(R.string.text_exit)
|
||||||
|
.onPositive((dialog, which) -> downloadPlugin())
|
||||||
|
.onNegative((dialog, which) -> finish())
|
||||||
|
.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadPlugin() {
|
||||||
|
// TODO: 2017/11/29
|
||||||
|
}
|
||||||
|
|
||||||
private void setupWithSourceFile(ScriptFile file) {
|
private void setupWithSourceFile(ScriptFile file) {
|
||||||
mSourcePath.setText(file.getPath());
|
mSourcePath.setText(file.getPath());
|
||||||
mOutputPath.setText(file.getParent());
|
mOutputPath.setText(file.getParent());
|
||||||
@@ -102,6 +127,14 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
|||||||
|
|
||||||
@Click(R.id.fab)
|
@Click(R.id.fab)
|
||||||
void buildApk() {
|
void buildApk() {
|
||||||
|
if (!ApkBuilderPluginHelper.checkPlugin(this)) {
|
||||||
|
Toast.makeText(this, R.string.text_apk_builder_plugin_unavailable, Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doBuildingApk();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doBuildingApk() {
|
||||||
String jsPath = mSourcePath.getText().toString();
|
String jsPath = mSourcePath.getText().toString();
|
||||||
String versionName = mVersionName.getText().toString();
|
String versionName = mVersionName.getText().toString();
|
||||||
int versionCode = Integer.parseInt(mVersionCode.getText().toString());
|
int versionCode = Integer.parseInt(mVersionCode.getText().toString());
|
||||||
@@ -110,20 +143,21 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
|||||||
File outApk = new File(mOutputPath.getText().toString(),
|
File outApk = new File(mOutputPath.getText().toString(),
|
||||||
String.format("%s_v%s.apk", appName, versionName));
|
String.format("%s_v%s.apk", appName, versionName));
|
||||||
showProgressDialog();
|
showProgressDialog();
|
||||||
Observable.fromCallable(() ->
|
Observable.fromCallable(() -> {
|
||||||
new AutoJsApkBuilder(getAssets().open("template.apk"), outApk, tmpDir.getPath())
|
InputStream templateApk = ApkBuilderPluginHelper.openTemplateApk(BuildActivity.this);
|
||||||
.setProgressCallback(BuildActivity.this)
|
return new AutoJsApkBuilder(templateApk, outApk, tmpDir.getPath())
|
||||||
.prepare()
|
.setProgressCallback(BuildActivity.this)
|
||||||
.withConfig(new AutoJsApkBuilder.AppConfig(appName, versionName, versionCode, jsPath))
|
.prepare()
|
||||||
.build()
|
.withConfig(new AutoJsApkBuilder.AppConfig(appName, versionName, versionCode, jsPath))
|
||||||
.sign()
|
.build()
|
||||||
.cleanWorkspace()
|
.sign()
|
||||||
|
.cleanWorkspace();
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(apkBuilder -> onBuildSuccessful(outApk),
|
.subscribe(apkBuilder -> onBuildSuccessful(outApk),
|
||||||
this::onBuildFailed);
|
this::onBuildFailed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showProgressDialog() {
|
private void showProgressDialog() {
|
||||||
|
|||||||
@@ -330,4 +330,6 @@
|
|||||||
<string name="text_day6">六</string>
|
<string name="text_day6">六</string>
|
||||||
<string name="text_day7">日</string>
|
<string name="text_day7">日</string>
|
||||||
<string name="text_weekly_task_should_check_day_of_week">至少选择一周中的一天</string>
|
<string name="text_weekly_task_should_check_day_of_week">至少选择一周中的一天</string>
|
||||||
|
<string name="no_apk_builder_plugin">没有安装打包插件,是否立即下载?</string>
|
||||||
|
<string name="text_apk_builder_plugin_unavailable">打包插件不可用</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ dependencies {
|
|||||||
compile 'com.android.support:appcompat-v7:25.4.0'
|
compile 'com.android.support:appcompat-v7:25.4.0'
|
||||||
compile 'com.github.hyb1996:EnhancedFloaty:0.17'
|
compile 'com.github.hyb1996:EnhancedFloaty:0.17'
|
||||||
compile 'com.github.hyb1996:OpenCvLib:2.4.13.4-imgproc'
|
compile 'com.github.hyb1996:OpenCvLib:2.4.13.4-imgproc'
|
||||||
|
// Gson
|
||||||
|
compile 'com.google.code.gson:gson:2.8.0'
|
||||||
// Terminal emulator
|
// Terminal emulator
|
||||||
compile(name: 'libtermexec-release', ext: 'aar')
|
compile(name: 'libtermexec-release', ext: 'aar')
|
||||||
compile(name: 'emulatorview-release', ext: 'aar')
|
compile(name: 'emulatorview-release', ext: 'aar')
|
||||||
|
|||||||
217
autojs/src/main/java/com/stardust/autojs/AutoJs.java
Normal file
217
autojs/src/main/java/com/stardust/autojs/AutoJs.java
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
package com.stardust.autojs;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.stardust.app.OnActivityResultDelegate;
|
||||||
|
import com.stardust.app.SimpleActivityLifecycleCallbacks;
|
||||||
|
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
|
||||||
|
import com.stardust.autojs.core.console.GlobalStardustConsole;
|
||||||
|
import com.stardust.autojs.core.console.StardustConsole;
|
||||||
|
import com.stardust.autojs.core.image.ScreenCaptureRequestActivity;
|
||||||
|
import com.stardust.autojs.core.image.ScreenCaptureRequester;
|
||||||
|
import com.stardust.autojs.core.inputevent.InputEventObserver;
|
||||||
|
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
|
||||||
|
import com.stardust.autojs.core.util.Shell;
|
||||||
|
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
|
||||||
|
import com.stardust.autojs.engine.RootAutomatorEngine;
|
||||||
|
import com.stardust.autojs.engine.ScriptEngine;
|
||||||
|
import com.stardust.autojs.engine.ScriptEngineManager;
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
|
import com.stardust.autojs.runtime.api.AppUtils;
|
||||||
|
import com.stardust.autojs.runtime.api.Console;
|
||||||
|
import com.stardust.autojs.runtime.exception.ScriptException;
|
||||||
|
import com.stardust.autojs.script.AutoFileSource;
|
||||||
|
import com.stardust.autojs.script.JavaScriptSource;
|
||||||
|
import com.stardust.util.ScreenMetrics;
|
||||||
|
import com.stardust.util.Supplier;
|
||||||
|
import com.stardust.util.UiHandler;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
|
import com.stardust.view.accessibility.LayoutInspector;
|
||||||
|
|
||||||
|
import org.opencv.android.BaseLoaderCallback;
|
||||||
|
import org.opencv.android.OpenCVLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/11/29.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class AutoJs {
|
||||||
|
|
||||||
|
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
||||||
|
private final AccessibilityNotificationObserver mNotificationObserver;
|
||||||
|
private ScriptEngineManager mScriptEngineManager;
|
||||||
|
private final LayoutInspector mLayoutInspector = new LayoutInspector();
|
||||||
|
private final Context mContext;
|
||||||
|
private final UiHandler mUiHandler;
|
||||||
|
private final AppUtils mAppUtils;
|
||||||
|
private final AccessibilityInfoProvider mAccessibilityInfoProvider;
|
||||||
|
private final ScreenCaptureRequester mScreenCaptureRequester = new ScreenCaptureRequesterImpl();
|
||||||
|
private final ScriptEngineService mScriptEngineService;
|
||||||
|
private final Console mGlobalConsole;
|
||||||
|
|
||||||
|
|
||||||
|
protected AutoJs(final Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mUiHandler = new UiHandler(context);
|
||||||
|
mAppUtils = new AppUtils(context);
|
||||||
|
mGlobalConsole = createGlobalConsole();
|
||||||
|
mNotificationObserver = new AccessibilityNotificationObserver(context);
|
||||||
|
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
||||||
|
mScriptEngineService = buildScriptEngineService();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Console createGlobalConsole() {
|
||||||
|
return new GlobalStardustConsole(mUiHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init() {
|
||||||
|
addAccessibilityServiceDelegates();
|
||||||
|
registerActivityLifecycleCallbacks();
|
||||||
|
InputEventObserver.initGlobal(mContext);
|
||||||
|
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void ensureAccessibilityServiceEnabled();
|
||||||
|
|
||||||
|
protected abstract Application getApplication();
|
||||||
|
|
||||||
|
protected ScriptEngineService buildScriptEngineService() {
|
||||||
|
initScriptEngineManager();
|
||||||
|
return new ScriptEngineServiceBuilder()
|
||||||
|
.uiHandler(mUiHandler)
|
||||||
|
.globalConsole(mGlobalConsole)
|
||||||
|
.engineManger(mScriptEngineManager)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initScriptEngineManager() {
|
||||||
|
mScriptEngineManager = new ScriptEngineManager(mContext);
|
||||||
|
mScriptEngineManager.registerEngine(JavaScriptSource.ENGINE, () -> {
|
||||||
|
LoopBasedJavaScriptEngine engine = new LoopBasedJavaScriptEngine(mContext);
|
||||||
|
engine.setRuntime(new ScriptRuntime.Builder()
|
||||||
|
.setConsole(new StardustConsole(mUiHandler, mGlobalConsole))
|
||||||
|
.setScreenCaptureRequester(mScreenCaptureRequester)
|
||||||
|
.setAccessibilityBridge(new AccessibilityBridgeImpl())
|
||||||
|
.setUiHandler(mUiHandler)
|
||||||
|
.setAppUtils(mAppUtils)
|
||||||
|
.setEngineService(mScriptEngineService)
|
||||||
|
.setShellSupplier(() -> new Shell(mContext, true)).build());
|
||||||
|
return engine;
|
||||||
|
});
|
||||||
|
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, new Supplier<ScriptEngine>() {
|
||||||
|
@Override
|
||||||
|
public ScriptEngine get() {
|
||||||
|
return new RootAutomatorEngine(mContext);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerActivityLifecycleCallbacks() {
|
||||||
|
getApplication().registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||||
|
ScreenMetrics.initIfNeeded(activity);
|
||||||
|
mAppUtils.setCurrentActivity(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityPaused(Activity activity) {
|
||||||
|
mAppUtils.setCurrentActivity(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResumed(Activity activity) {
|
||||||
|
mAppUtils.setCurrentActivity(activity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void addAccessibilityServiceDelegates() {
|
||||||
|
AccessibilityService.addDelegate(100, mAccessibilityInfoProvider);
|
||||||
|
AccessibilityService.addDelegate(200, mNotificationObserver);
|
||||||
|
AccessibilityService.addDelegate(300, mAccessibilityActionRecorder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccessibilityActionRecorder getAccessibilityActionRecorder() {
|
||||||
|
return mAccessibilityActionRecorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppUtils getAppUtils() {
|
||||||
|
return mAppUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UiHandler getUiHandler() {
|
||||||
|
return mUiHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LayoutInspector getLayoutInspector() {
|
||||||
|
return mLayoutInspector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Console getGlobalConsole() {
|
||||||
|
return mGlobalConsole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptEngineService getScriptEngineService() {
|
||||||
|
return mScriptEngineService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccessibilityInfoProvider getInfoProvider() {
|
||||||
|
return mAccessibilityInfoProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class AccessibilityBridgeImpl extends AccessibilityBridge {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ensureServiceEnabled() {
|
||||||
|
AutoJs.this.ensureAccessibilityServiceEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public AccessibilityService getService() {
|
||||||
|
return AccessibilityService.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessibilityInfoProvider getInfoProvider() {
|
||||||
|
return mAccessibilityInfoProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessibilityNotificationObserver getNotificationObserver() {
|
||||||
|
return mNotificationObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester {
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
@Override
|
||||||
|
public void request() {
|
||||||
|
Activity activity = mAppUtils.getCurrentActivity();
|
||||||
|
if (activity instanceof OnActivityResultDelegate.DelegateHost) {
|
||||||
|
ScreenCaptureRequester requester = new ActivityScreenCaptureRequester(
|
||||||
|
((OnActivityResultDelegate.DelegateHost) activity).getOnActivityResultDelegateMediator(), activity);
|
||||||
|
requester.setOnActivityResultCallback(mCallback);
|
||||||
|
requester.request();
|
||||||
|
} else {
|
||||||
|
ScreenCaptureRequestActivity.request(mContext, mCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ package com.stardust.autojs.engine;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.stardust.autojs.BuildConfig;
|
import com.stardust.autojs.BuildConfig;
|
||||||
import com.stardust.autojs.core.accessibility.UiCollection;
|
|
||||||
import com.stardust.autojs.rhino.AndroidContextFactory;
|
import com.stardust.autojs.rhino.AndroidContextFactory;
|
||||||
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
||||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||||
@@ -17,21 +16,14 @@ import org.mozilla.javascript.Callable;
|
|||||||
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Context;
|
||||||
import org.mozilla.javascript.ContextFactory;
|
import org.mozilla.javascript.ContextFactory;
|
||||||
import org.mozilla.javascript.ImporterTopLevel;
|
import org.mozilla.javascript.ImporterTopLevel;
|
||||||
import org.mozilla.javascript.NativeArray;
|
|
||||||
import org.mozilla.javascript.ScriptRuntime;
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
import org.mozilla.javascript.Scriptable;
|
||||||
import org.mozilla.javascript.ScriptableObject;
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
import org.mozilla.javascript.TopLevel;
|
|
||||||
import org.mozilla.javascript.WrapFactory;
|
|
||||||
import org.mozilla.javascript.commonjs.module.RequireBuilder;
|
import org.mozilla.javascript.commonjs.module.RequireBuilder;
|
||||||
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider;
|
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider;
|
||||||
import org.mozilla.javascript.tools.debugger.Dim;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,7 +36,7 @@ import java.util.Locale;
|
|||||||
public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||||
|
|
||||||
private static final String LOG_TAG = "RhinoJavaScriptEngine";
|
private static final String LOG_TAG = "RhinoJavaScriptEngine";
|
||||||
private static ThreadLocal<Thread.UncaughtExceptionHandler> mExceptionHandlerThreadLocal = new ThreadLocal<>();
|
private static ThreadLocal<Thread.UncaughtExceptionHandler> sExceptionHandlerThreadLocal = new ThreadLocal<>();
|
||||||
|
|
||||||
private static int contextCount = 0;
|
private static int contextCount = 0;
|
||||||
private static StringScriptSource sInitScript;
|
private static StringScriptSource sInitScript;
|
||||||
@@ -165,8 +157,8 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setUncaghtExceptionHandler(Thread.UncaughtExceptionHandler handler) {
|
public static void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) {
|
||||||
mExceptionHandlerThreadLocal.set(handler);
|
sExceptionHandlerThreadLocal.set(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
|
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
|
||||||
@@ -205,7 +197,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
|
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
|
||||||
Thread.UncaughtExceptionHandler exceptionHandler = mExceptionHandlerThreadLocal.get();
|
Thread.UncaughtExceptionHandler exceptionHandler = sExceptionHandlerThreadLocal.get();
|
||||||
if (exceptionHandler == null)
|
if (exceptionHandler == null)
|
||||||
return super.doTopCall(callable, cx, scope, thisObj, args);
|
return super.doTopCall(callable, cx, scope, thisObj, args);
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class LoopedBasedJavaScriptExecution extends RunnableScriptExecution {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
javaScriptEngine.getRuntime().loopers.setLooperQuitHandler(null);
|
javaScriptEngine.getRuntime().loopers.setLooperQuitHandler(null);
|
||||||
getListener().onSuccess(LoopedBasedJavaScriptExecution.this, null);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
|
|||||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||||
import com.stardust.autojs.engine.ScriptEngine;
|
import com.stardust.autojs.engine.ScriptEngine;
|
||||||
import com.stardust.autojs.engine.ScriptEngineManager;
|
import com.stardust.autojs.engine.ScriptEngineManager;
|
||||||
import com.stardust.autojs.script.JavaScriptSource;
|
|
||||||
import com.stardust.autojs.script.ScriptSource;
|
import com.stardust.autojs.script.ScriptSource;
|
||||||
import com.stardust.lang.ThreadCompat;
|
|
||||||
import com.stardust.util.IntentExtras;
|
import com.stardust.util.IntentExtras;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +49,7 @@ public class ScriptExecuteActivity extends AppCompatActivity implements Thread.U
|
|||||||
mScriptSource = mScriptExecution.getSource();
|
mScriptSource = mScriptExecution.getSource();
|
||||||
mScriptEngine = mScriptExecution.getEngine();
|
mScriptEngine = mScriptExecution.getEngine();
|
||||||
mExecutionListener = mScriptExecution.getListener();
|
mExecutionListener = mScriptExecution.getListener();
|
||||||
RhinoJavaScriptEngine.setUncaghtExceptionHandler(this);
|
RhinoJavaScriptEngine.setUncaughtExceptionHandler(this);
|
||||||
runScript();
|
runScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ public class ScriptRuntime {
|
|||||||
if (loopers != null)
|
if (loopers != null)
|
||||||
throw new IllegalStateException("already initialized");
|
throw new IllegalStateException("already initialized");
|
||||||
timers = new Timers(bridges);
|
timers = new Timers(bridges);
|
||||||
loopers = new Loopers(timers);
|
loopers = new Loopers(this);
|
||||||
events = new Events(mUiHandler.getContext(), accessibilityBridge, bridges, loopers);
|
events = new Events(mUiHandler.getContext(), accessibilityBridge, bridges, loopers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.stardust.autojs.runtime.api;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.MessageQueue;
|
import android.os.MessageQueue;
|
||||||
|
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||||
import com.stardust.lang.ThreadCompat;
|
import com.stardust.lang.ThreadCompat;
|
||||||
|
|
||||||
@@ -22,10 +23,12 @@ public class Loopers {
|
|||||||
private volatile Looper mServantLooper;
|
private volatile Looper mServantLooper;
|
||||||
private static volatile ConcurrentHashMap<Thread, Looper> sLoopers = new ConcurrentHashMap<>();
|
private static volatile ConcurrentHashMap<Thread, Looper> sLoopers = new ConcurrentHashMap<>();
|
||||||
private Timers mTimers;
|
private Timers mTimers;
|
||||||
|
private ScriptRuntime mScriptRuntime;
|
||||||
private LooperQuitHandler mLooperQuitHandler;
|
private LooperQuitHandler mLooperQuitHandler;
|
||||||
|
|
||||||
public Loopers(Timers timers) {
|
public Loopers(ScriptRuntime runtime) {
|
||||||
mTimers = timers;
|
mTimers = runtime.timers;
|
||||||
|
mScriptRuntime = runtime;
|
||||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||||
waitWhenIdle = true;
|
waitWhenIdle = true;
|
||||||
}
|
}
|
||||||
@@ -35,6 +38,7 @@ public class Loopers {
|
|||||||
Looper l = Looper.myLooper();
|
Looper l = Looper.myLooper();
|
||||||
if (l != null && shouldQuitLooper()) {
|
if (l != null && shouldQuitLooper()) {
|
||||||
if (mLooperQuitHandler != null && mLooperQuitHandler.shouldQuit()) {
|
if (mLooperQuitHandler != null && mLooperQuitHandler.shouldQuit()) {
|
||||||
|
mScriptRuntime.events.emit("exit");
|
||||||
l.quit();
|
l.quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ public class DeveloperUtils {
|
|||||||
return PACKAGE_NAME.equals(runningPackage);
|
return PACKAGE_NAME.equals(runningPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSignature(Context context) {
|
@Nullable
|
||||||
|
public static String getSignature(Context context, String packageName) {
|
||||||
try {
|
try {
|
||||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
|
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||||
Signature[] signatures = packageInfo.signatures;
|
Signature[] signatures = packageInfo.signatures;
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (Signature signature : signatures) {
|
for (Signature signature : signatures) {
|
||||||
@@ -47,7 +48,12 @@ public class DeveloperUtils {
|
|||||||
* 为了开源社区的发展,请善用源码:-)
|
* 为了开源社区的发展,请善用源码:-)
|
||||||
*/
|
*/
|
||||||
public static boolean checkSignature(Context context) {
|
public static boolean checkSignature(Context context) {
|
||||||
return SIGNATURE.equals(getSignature(context));
|
return SIGNATURE.equals(getSignature(context, context.getPackageName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean checkSignature(Context context, String packageName) {
|
||||||
|
return SIGNATURE.equals(getSignature(context, packageName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.os.Bundle;
|
|||||||
|
|
||||||
import com.stardust.auojs.inrt.rt.AutoJs;
|
import com.stardust.auojs.inrt.rt.AutoJs;
|
||||||
import com.stardust.autojs.core.console.ConsoleView;
|
import com.stardust.autojs.core.console.ConsoleView;
|
||||||
|
import com.stardust.autojs.core.console.StardustConsole;
|
||||||
import com.stardust.autojs.script.StringScriptSource;
|
import com.stardust.autojs.script.StringScriptSource;
|
||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private void setupView() {
|
private void setupView() {
|
||||||
ConsoleView consoleView = new ConsoleView(this);
|
ConsoleView consoleView = new ConsoleView(this);
|
||||||
consoleView.setConsole(AutoJs.getInstance().getGlobalConsole());
|
consoleView.setConsole((StardustConsole) AutoJs.getInstance().getGlobalConsole());
|
||||||
setContentView(consoleView);
|
setContentView(consoleView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,9 @@ public class AccessibilityServiceTool {
|
|||||||
public static boolean enableAccessibilityServiceByRootAndWaitFor(Context context, long timeOut) {
|
public static boolean enableAccessibilityServiceByRootAndWaitFor(Context context, long timeOut) {
|
||||||
if (enableAccessibilityServiceByRoot(context, com.stardust.view.accessibility.AccessibilityService.class)) {
|
if (enableAccessibilityServiceByRoot(context, com.stardust.view.accessibility.AccessibilityService.class)) {
|
||||||
com.stardust.view.accessibility.AccessibilityService.waitForEnabled(timeOut);
|
com.stardust.view.accessibility.AccessibilityService.waitForEnabled(timeOut);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void goToAccessibilitySetting() {
|
public static void goToAccessibilitySetting() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.stardust.auojs.inrt.rt;
|
package com.stardust.auojs.inrt.rt;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -40,15 +41,17 @@ import com.stardust.view.accessibility.AccessibilityService;
|
|||||||
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
||||||
import com.stardust.view.accessibility.NotificationListener;
|
import com.stardust.view.accessibility.NotificationListener;
|
||||||
|
|
||||||
|
import org.opencv.android.BaseLoaderCallback;
|
||||||
|
import org.opencv.android.OpenCVLoader;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/4/2.
|
* Created by Stardust on 2017/4/2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AutoJs {
|
public class AutoJs extends com.stardust.autojs.AutoJs {
|
||||||
|
|
||||||
private static AutoJs instance;
|
private static AutoJs instance;
|
||||||
private Class<? extends android.accessibilityservice.AccessibilityService> sAccessibilityServiceClass = AccessibilityService.class;
|
|
||||||
|
|
||||||
public static AutoJs getInstance() {
|
public static AutoJs getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
@@ -58,166 +61,31 @@ public class AutoJs {
|
|||||||
instance = new AutoJs(context);
|
instance = new AutoJs(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
private AutoJs(Context context) {
|
||||||
private final AccessibilityNotificationObserver mNotificationObserver;
|
super(context);
|
||||||
private ScriptEngineManager mScriptEngineManager;
|
|
||||||
private final Context mContext;
|
|
||||||
private final UiHandler mUiHandler;
|
|
||||||
private final AppUtils mAppUtils;
|
|
||||||
private final AccessibilityInfoProvider mAccessibilityInfoProvider;
|
|
||||||
private final ScreenCaptureRequester mScreenCaptureRequester = new ScreenCaptureRequesterImpl();
|
|
||||||
private final ScriptEngineService mScriptEngineService;
|
|
||||||
private final StardustConsole mGlobalConsole;
|
|
||||||
|
|
||||||
|
|
||||||
private AutoJs(final Context context) {
|
|
||||||
mContext = context;
|
|
||||||
mUiHandler = new UiHandler(context);
|
|
||||||
mAppUtils = new AppUtils(context);
|
|
||||||
mGlobalConsole = new GlobalStardustConsole(mUiHandler);
|
|
||||||
mNotificationObserver = new AccessibilityNotificationObserver(context);
|
|
||||||
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
|
||||||
mScriptEngineService = buildScriptEngineService();
|
|
||||||
addAccessibilityServiceDelegates();
|
|
||||||
registerActivityLifecycleCallbacks();
|
|
||||||
InputEventObserver.initGlobal(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StardustConsole getGlobalConsole() {
|
|
||||||
return mGlobalConsole;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScriptEngineService buildScriptEngineService() {
|
|
||||||
initScriptEngineManager();
|
|
||||||
return new ScriptEngineServiceBuilder()
|
|
||||||
.uiHandler(mUiHandler)
|
|
||||||
.globalConsole(mGlobalConsole)
|
|
||||||
.engineManger(mScriptEngineManager)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initScriptEngineManager() {
|
|
||||||
mScriptEngineManager = new ScriptEngineManager(mContext);
|
|
||||||
mScriptEngineManager.registerEngine(JavaScriptSource.ENGINE, new Supplier<ScriptEngine>() {
|
|
||||||
@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)
|
|
||||||
.setEngineService(mScriptEngineService)
|
|
||||||
.setShellSupplier(new Supplier<AbstractShell>() {
|
|
||||||
@Override
|
|
||||||
public AbstractShell get() {
|
|
||||||
return new Shell(mContext, true);
|
|
||||||
}
|
|
||||||
}).build());
|
|
||||||
return engine;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, new Supplier<ScriptEngine>() {
|
|
||||||
@Override
|
|
||||||
public ScriptEngine get() {
|
|
||||||
return new RootAutomatorEngine(mContext);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerActivityLifecycleCallbacks() {
|
|
||||||
App.getApp().registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
|
||||||
ScreenMetrics.initIfNeeded(activity);
|
|
||||||
mAppUtils.setCurrentActivity(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityPaused(Activity activity) {
|
|
||||||
mAppUtils.setCurrentActivity(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResumed(Activity activity) {
|
|
||||||
mAppUtils.setCurrentActivity(activity);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addAccessibilityServiceDelegates() {
|
|
||||||
AccessibilityService.addDelegate(100, mAccessibilityInfoProvider);
|
|
||||||
AccessibilityService.addDelegate(200, mNotificationObserver);
|
|
||||||
AccessibilityService.addDelegate(300, mAccessibilityActionRecorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptEngineService getScriptEngineService() {
|
|
||||||
return mScriptEngineService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void ensureAccessibilityServiceEnabled() {
|
public void ensureAccessibilityServiceEnabled() {
|
||||||
if (AccessibilityService.getInstance() == null) {
|
if (AccessibilityService.getInstance() != null) {
|
||||||
String errorMessage = getErrorMessage();
|
return;
|
||||||
|
}
|
||||||
|
String errorMessage = null;
|
||||||
|
if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(getApplication(), AccessibilityService.class)) {
|
||||||
|
errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
|
||||||
|
} else {
|
||||||
|
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(getApplication(), 2000)) {
|
||||||
|
errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errorMessage != null) {
|
||||||
AccessibilityServiceTool.goToAccessibilitySetting();
|
AccessibilityServiceTool.goToAccessibilitySetting();
|
||||||
throw new ScriptException(errorMessage);
|
throw new ScriptException(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getErrorMessage() {
|
@Override
|
||||||
if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), sAccessibilityServiceClass)) {
|
protected Application getApplication() {
|
||||||
return App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
|
return App.getApp();
|
||||||
} else {
|
|
||||||
if (true) {
|
|
||||||
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(App.getApp(), 2000)) {
|
|
||||||
return App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return App.getApp().getString(R.string.text_no_accessibility_permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class AccessibilityBridgeImpl extends AccessibilityBridge {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ensureServiceEnabled() {
|
|
||||||
AutoJs.this.ensureAccessibilityServiceEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public AccessibilityService getService() {
|
|
||||||
return AccessibilityService.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessibilityInfoProvider getInfoProvider() {
|
|
||||||
return mAccessibilityInfoProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessibilityNotificationObserver getNotificationObserver() {
|
|
||||||
return mNotificationObserver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester {
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
|
||||||
public void request() {
|
|
||||||
Activity activity = mAppUtils.getCurrentActivity();
|
|
||||||
if (activity instanceof OnActivityResultDelegate.DelegateHost) {
|
|
||||||
ScreenCaptureRequester requester = new ActivityScreenCaptureRequester(
|
|
||||||
((OnActivityResultDelegate.DelegateHost) activity).getOnActivityResultDelegateMediator(), activity);
|
|
||||||
requester.setOnActivityResultCallback(mCallback);
|
|
||||||
requester.request();
|
|
||||||
} else {
|
|
||||||
ScreenCaptureRequestActivity.request(mContext, mCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user