优化 脚本管理器增删文件后的更新
新增 支持插件 优化 多点找色的内存泄漏 修复 文件重命名时的后缀问题 修复 脚本抛出Throwable不能被捕捉的问题
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
"ui";
|
"ui";
|
||||||
|
|
||||||
var ColoredButton = (function() {
|
var ColoredButton = (function() {
|
||||||
//继承至ui.Widget
|
//继承ui.Widget
|
||||||
util.extend(ColoredButton, ui.Widget);
|
util.extend(ColoredButton, ui.Widget);
|
||||||
|
|
||||||
function ColoredButton() {
|
function ColoredButton() {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
onFinish(execution);
|
onFinish(execution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,14 +87,14 @@ public class Explorer {
|
|||||||
if (cachedParent != null) {
|
if (cachedParent != null) {
|
||||||
cachedParent.addChild(item);
|
cachedParent.addChild(item);
|
||||||
}
|
}
|
||||||
mEventBus.post(new ExplorerChangeEvent(parent, CREATE, item));
|
mEventBus.post(new ExplorerChangeEvent(parent, CREATE, item, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void refreshAll() {
|
public void refreshAll() {
|
||||||
if (mExplorerPageLruCache != null)
|
if (mExplorerPageLruCache != null)
|
||||||
mExplorerPageLruCache.evictAll();
|
mExplorerPageLruCache.evictAll();
|
||||||
mEventBus.post(new ExplorerChangeEvent(ALL));
|
mEventBus.post(ExplorerChangeEvent.EVENT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
package org.autojs.autojs.model.explorer;
|
package org.autojs.autojs.model.explorer;
|
||||||
|
|
||||||
|
import com.stardust.util.ObjectHelper;
|
||||||
|
|
||||||
public class ExplorerChangeEvent {
|
public class ExplorerChangeEvent {
|
||||||
|
|
||||||
|
|
||||||
public static final int REMOVE = 0;
|
public static final int REMOVE = 0;
|
||||||
public static final int CREATE = 1;
|
public static final int CREATE = 1;
|
||||||
public static final int CHANGE = 2;
|
public static final int CHANGE = 2;
|
||||||
public static final int ALL = 3;
|
public static final int ALL = 3;
|
||||||
public static final int CHILDREN_CHANGE = 4;
|
public static final int CHILDREN_CHANGE = 4;
|
||||||
|
|
||||||
|
public static final ExplorerChangeEvent EVENT_ALL = new ExplorerChangeEvent(ALL);
|
||||||
|
|
||||||
private final int mAction;
|
private final int mAction;
|
||||||
private final ExplorerItem mItem;
|
private final ExplorerItem mItem;
|
||||||
private final ExplorerItem mNewItem;
|
private final ExplorerItem mNewItem;
|
||||||
@@ -21,10 +26,10 @@ public class ExplorerChangeEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ExplorerChangeEvent(ExplorerPage parent, int action, ExplorerItem item) {
|
public ExplorerChangeEvent(ExplorerPage parent, int action, ExplorerItem item) {
|
||||||
this(parent, action, item, null);
|
this(parent, action, item, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExplorerChangeEvent(int action) {
|
private ExplorerChangeEvent(int action) {
|
||||||
this(null, action, null, null);
|
this(null, action, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,4 +48,30 @@ public class ExplorerChangeEvent {
|
|||||||
public ExplorerPage getPage() {
|
public ExplorerPage getPage() {
|
||||||
return mPage;
|
return mPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ExplorerChangeEvent{" +
|
||||||
|
"mAction=" + nameOfAction(mAction) +
|
||||||
|
", mPage=" + mPage +
|
||||||
|
", mItem=" + mItem +
|
||||||
|
", mNewItem=" + mNewItem +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String nameOfAction(int action) {
|
||||||
|
switch (action) {
|
||||||
|
case ALL:
|
||||||
|
return "ALL";
|
||||||
|
case CHANGE:
|
||||||
|
return "CHANGE";
|
||||||
|
case CREATE:
|
||||||
|
return "CREATE";
|
||||||
|
case REMOVE:
|
||||||
|
return "REMOVE";
|
||||||
|
case CHILDREN_CHANGE:
|
||||||
|
return "CHILDREN_CHANGE";
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("action = " + action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class ExplorerDirPage extends ExplorerFileItem implements ExplorerPage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExplorerFileItem rename(String newName) {
|
public ExplorerFileItem rename(String newName) {
|
||||||
return new ExplorerDirPage(getFile().renameAndReturnNewFile(newName), getParent());
|
return new ExplorerDirPage(getFile().renameTo(newName), getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int indexOf(ExplorerItem child){
|
protected int indexOf(ExplorerItem child){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.autojs.autojs.model.explorer;
|
|||||||
|
|
||||||
import com.stardust.pio.PFile;
|
import com.stardust.pio.PFile;
|
||||||
import com.stardust.util.ObjectHelper;
|
import com.stardust.util.ObjectHelper;
|
||||||
|
import com.stardust.util.Objects;
|
||||||
|
|
||||||
import org.autojs.autojs.model.script.ScriptFile;
|
import org.autojs.autojs.model.script.ScriptFile;
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ public class ExplorerFileItem implements ExplorerItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ExplorerFileItem rename(String newName) {
|
public ExplorerFileItem rename(String newName) {
|
||||||
return new ExplorerFileItem(mFile.renameAndReturnNewFile(newName), getParent());
|
return new ExplorerFileItem(mFile.renameTo(newName), getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -102,4 +103,24 @@ public class ExplorerFileItem implements ExplorerItem {
|
|||||||
String type = getType();
|
String type = getType();
|
||||||
return type.equals("js") || type.equals("auto");
|
return type.equals("js") || type.equals("auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + "{" +
|
||||||
|
"mFile=" + mFile + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
ExplorerFileItem that = (ExplorerFileItem) o;
|
||||||
|
return Objects.equals(mFile, that.mFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(mFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ public class ExplorerProjectPage extends ExplorerDirPage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExplorerFileItem rename(String newName) {
|
public ExplorerFileItem rename(String newName) {
|
||||||
return new ExplorerProjectPage(getFile().renameAndReturnNewFile(newName), getParent(), mProjectConfig);
|
return new ExplorerProjectPage(getFile().renameTo(newName), getParent(), mProjectConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class Scripts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
RhinoException rhinoException = getRhinoException(e);
|
RhinoException rhinoException = getRhinoException(e);
|
||||||
int line = -1, col = 0;
|
int line = -1, col = 0;
|
||||||
if (rhinoException != null) {
|
if (rhinoException != null) {
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package org.autojs.autojs.ui.common;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.afollestad.materialdialogs.DialogAction;
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
|
|
||||||
|
import org.autojs.autojs.R;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class FileNameInputDialog implements MaterialDialog.InputCallback {
|
||||||
|
|
||||||
|
private String mExcluded;
|
||||||
|
private boolean mIsFirstTextChanged = true;
|
||||||
|
private String mExtension;
|
||||||
|
private Context mContext;
|
||||||
|
private File mDir;
|
||||||
|
|
||||||
|
private void validateInput(MaterialDialog dialog, String extension) {
|
||||||
|
EditText editText = dialog.getInputEditText();
|
||||||
|
if (editText == null)
|
||||||
|
return;
|
||||||
|
Editable input = editText.getText();
|
||||||
|
int errorResId = 0;
|
||||||
|
if (input == null || input.length() == 0) {
|
||||||
|
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (new File(mDir, extension == null ? input.toString() : input.toString() + extension).exists()) {
|
||||||
|
errorResId = R.string.text_file_exists;
|
||||||
|
}
|
||||||
|
if (errorResId == 0) {
|
||||||
|
editText.setError(null);
|
||||||
|
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
|
||||||
|
} else {
|
||||||
|
editText.setError(mContext.getString(errorResId));
|
||||||
|
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||||
|
if (mIsFirstTextChanged) {
|
||||||
|
mIsFirstTextChanged = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EditText editText = dialog.getInputEditText();
|
||||||
|
if (editText == null)
|
||||||
|
return;
|
||||||
|
if (input.equals(mExcluded)) {
|
||||||
|
editText.setError(null);
|
||||||
|
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
validateInput(dialog, mExtension);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -269,10 +269,8 @@ public class ScriptOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Observable<ExplorerFileItem> rename(final ExplorerFileItem item) {
|
public Observable<ExplorerFileItem> rename(final ExplorerFileItem item) {
|
||||||
final ScriptFile oldFile = new ScriptFile(item.getPath());
|
|
||||||
String originalName = item.getName();
|
String originalName = item.getName();
|
||||||
return showNameInputDialog(originalName, new InputCallback(oldFile.isDirectory() ? null : PFiles.getExtension(item.getName()),
|
return showNameInputDialog(originalName, new InputCallback(null, originalName))
|
||||||
originalName))
|
|
||||||
.map(newName -> {
|
.map(newName -> {
|
||||||
ExplorerFileItem newItem = item.rename(newName);
|
ExplorerFileItem newItem = item.rename(newName);
|
||||||
if (ObjectHelper.equals(newItem.toScriptFile(), item.toScriptFile())) {
|
if (ObjectHelper.equals(newItem.toScriptFile(), item.toScriptFile())) {
|
||||||
@@ -307,18 +305,23 @@ public class ScriptOperations {
|
|||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
public void deleteWithoutConfirm(final ScriptFile scriptFile) {
|
public void deleteWithoutConfirm(final ScriptFile scriptFile) {
|
||||||
|
boolean isDir = scriptFile.isDirectory();
|
||||||
Observable.fromPublisher((Publisher<Boolean>) s -> s.onNext(PFiles.deleteRecursively(scriptFile)))
|
Observable.fromPublisher((Publisher<Boolean>) s -> s.onNext(PFiles.deleteRecursively(scriptFile)))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(deleted -> {
|
.subscribe(deleted -> {
|
||||||
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
|
showMessage(deleted ? R.string.text_already_delete : R.string.text_delete_failed);
|
||||||
if (deleted)
|
if (deleted)
|
||||||
notifyFileRemoved(mCurrentDirectory, scriptFile);
|
notifyFileRemoved(isDir, scriptFile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyFileRemoved(ScriptFile directory, ScriptFile scriptFile) {
|
private void notifyFileRemoved(boolean isDir, ScriptFile scriptFile) {
|
||||||
mExplorer.notifyItemRemoved(new ExplorerFileItem(scriptFile, mExplorerPage));
|
if (isDir) {
|
||||||
|
mExplorer.notifyItemRemoved(new ExplorerDirPage(scriptFile, mExplorerPage));
|
||||||
|
} else {
|
||||||
|
mExplorer.notifyItemRemoved(new ExplorerFileItem(scriptFile, mExplorerPage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import android.support.v7.widget.GridLayoutManager;
|
|||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@@ -243,9 +244,40 @@ public class ExplorerView extends ThemeColorSwipeRefreshLayout implements SwipeR
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onExplorerChange(ExplorerChangeEvent event) {
|
public void onExplorerChange(ExplorerChangeEvent event) {
|
||||||
if ((event.getAction() == ExplorerChangeEvent.ALL)
|
Log.d(LOG_TAG, "on explorer change: " + event);
|
||||||
|| mCurrentPageState.page.getPath().equals(event.getPage().getPath())) {
|
if ((event.getAction() == ExplorerChangeEvent.ALL)) {
|
||||||
loadItemList();
|
loadItemList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String currentDirPath = mCurrentPageState.page.getPath();
|
||||||
|
String changedDirPath = event.getPage().getPath();
|
||||||
|
ExplorerItem item = event.getItem();
|
||||||
|
String changedItemPath = item == null ? null : item.getPath();
|
||||||
|
if (currentDirPath.equals(changedItemPath) || (currentDirPath.equals(changedDirPath) &&
|
||||||
|
event.getAction() == ExplorerChangeEvent.CHILDREN_CHANGE)) {
|
||||||
|
loadItemList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentDirPath.equals(changedDirPath)) {
|
||||||
|
int i;
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case ExplorerChangeEvent.CHANGE:
|
||||||
|
i = mExplorerItemList.update(item, event.getNewItem());
|
||||||
|
if (i >= 0) {
|
||||||
|
mExplorerAdapter.notifyItemChanged(item, i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExplorerChangeEvent.CREATE:
|
||||||
|
mExplorerItemList.insertAtFront(event.getNewItem());
|
||||||
|
mExplorerAdapter.notifyItemInserted(event.getNewItem(), 0);
|
||||||
|
break;
|
||||||
|
case ExplorerChangeEvent.REMOVE:
|
||||||
|
i = mExplorerItemList.remove(item);
|
||||||
|
if (i >= 0) {
|
||||||
|
mExplorerAdapter.notifyItemRemoved(item, i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,6 +449,25 @@ public class ExplorerView extends ThemeColorSwipeRefreshLayout implements SwipeR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getItemPosition(ExplorerItem item, int i) {
|
||||||
|
if (item instanceof ExplorerPage) {
|
||||||
|
return i + positionOfCategoryDir + 1;
|
||||||
|
}
|
||||||
|
return i + positionOfCategoryFile() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyItemChanged(ExplorerItem item, int i) {
|
||||||
|
notifyItemChanged(getItemPosition(item, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyItemRemoved(ExplorerItem item, int i) {
|
||||||
|
notifyItemRemoved(getItemPosition(item, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyItemInserted(ExplorerItem item, int i) {
|
||||||
|
notifyItemInserted(getItemPosition(item, i));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
onFinish(execution);
|
onFinish(execution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.autojs.autojs.ui.viewmodel;
|
|||||||
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import org.autojs.autojs.model.explorer.ExplorerDirPage;
|
||||||
import org.autojs.autojs.model.explorer.ExplorerItem;
|
import org.autojs.autojs.model.explorer.ExplorerItem;
|
||||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||||
import org.autojs.autojs.model.explorer.ExplorerSorter;
|
import org.autojs.autojs.model.explorer.ExplorerSorter;
|
||||||
@@ -145,6 +146,47 @@ public class ExplorerItemList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void insertAtFront(ExplorerItem item) {
|
||||||
|
if (item instanceof ExplorerPage) {
|
||||||
|
mItemGroups.add(0, (ExplorerPage) item);
|
||||||
|
} else {
|
||||||
|
mItems.add(0, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int remove(ExplorerItem item) {
|
||||||
|
if (item instanceof ExplorerPage) {
|
||||||
|
return remove(mItemGroups, item);
|
||||||
|
} else {
|
||||||
|
return remove(mItems, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int update(ExplorerItem oldItem, ExplorerItem newItem) {
|
||||||
|
if (oldItem instanceof ExplorerPage) {
|
||||||
|
return update(mItemGroups, (ExplorerPage) oldItem, (ExplorerPage) newItem);
|
||||||
|
} else {
|
||||||
|
return update(mItems, oldItem, newItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> int update(ArrayList<T> list, T oldItem, T newItem) {
|
||||||
|
int i = list.indexOf(oldItem);
|
||||||
|
if (i >= 0) {
|
||||||
|
list.set(i, newItem);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> int remove(ArrayList<?> list, T o) {
|
||||||
|
int i = list.indexOf(o);
|
||||||
|
if (i >= 0) {
|
||||||
|
list.remove(i);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
public ExplorerPage getItemGroup(int i) {
|
public ExplorerPage getItemGroup(int i) {
|
||||||
return mItemGroups.get(i);
|
return mItemGroups.get(i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ runtime.init();
|
|||||||
(function(scope){
|
(function(scope){
|
||||||
var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui',
|
var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui',
|
||||||
"images", "timers", "threads", "events", "engines", "RootAutomator", "http", "storages", "floaty",
|
"images", "timers", "threads", "events", "engines", "RootAutomator", "http", "storages", "floaty",
|
||||||
"sensors", "media"];
|
"sensors", "media", "plugins"];
|
||||||
var len = modules.length;
|
var len = modules.length;
|
||||||
for(var i = 0; i < len; i++) {
|
for(var i = 0; i < len; i++) {
|
||||||
var m = modules[i];
|
var m = modules[i];
|
||||||
|
|||||||
12
autojs/src/main/assets/modules/__plugins__.js
Normal file
12
autojs/src/main/assets/modules/__plugins__.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module.exports = function (runtime, scope) {
|
||||||
|
function plugins(){
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.load = function(packageName){
|
||||||
|
var plugin = runtime.plugins.load(packageName);
|
||||||
|
var index = require(plugin.mainScriptPath);
|
||||||
|
return index(plugin.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugins;
|
||||||
|
}
|
||||||
@@ -84,9 +84,12 @@ public abstract class AutoJs {
|
|||||||
protected void init() {
|
protected void init() {
|
||||||
addAccessibilityServiceDelegates();
|
addAccessibilityServiceDelegates();
|
||||||
registerActivityLifecycleCallbacks();
|
registerActivityLifecycleCallbacks();
|
||||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
|
try {
|
||||||
|
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
|
||||||
});
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ensureAccessibilityServiceEnabled();
|
public abstract void ensureAccessibilityServiceEnabled();
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class ScriptEngineService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
onFinish(execution);
|
onFinish(execution);
|
||||||
String message = null;
|
String message = null;
|
||||||
@@ -80,7 +80,7 @@ public class ScriptEngineService {
|
|||||||
}
|
}
|
||||||
if (execution.getEngine() instanceof JavaScriptEngine) {
|
if (execution.getEngine() instanceof JavaScriptEngine) {
|
||||||
JavaScriptEngine engine = (JavaScriptEngine) execution.getEngine();
|
JavaScriptEngine engine = (JavaScriptEngine) execution.getEngine();
|
||||||
Exception uncaughtException = engine.getUncaughtException();
|
Throwable uncaughtException = engine.getUncaughtException();
|
||||||
if (uncaughtException != null) {
|
if (uncaughtException != null) {
|
||||||
engine.getRuntime().console.error(uncaughtException);
|
engine.getRuntime().console.error(uncaughtException);
|
||||||
message = uncaughtException.getMessage();
|
message = uncaughtException.getMessage();
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public class ColorFinder {
|
|||||||
return new Point[0];
|
return new Point[0];
|
||||||
}
|
}
|
||||||
Point[] points = matOfPoint.toArray();
|
Point[] points = matOfPoint.toArray();
|
||||||
|
OpenCVHelper.release(matOfPoint);
|
||||||
if (rect != null) {
|
if (rect != null) {
|
||||||
for (int i = 0; i < points.length; i++) {
|
for (int i = 0; i < points.length; i++) {
|
||||||
points[i].x = mScreenMetrics.scaleX((int) (points[i].x + rect.x));
|
points[i].x = mScreenMetrics.scaleX((int) (points[i].x + rect.x));
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public class OpenCVHelper {
|
|||||||
callback.onInitFinish();
|
callback.onInitFinish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, activity.getApplicationContext(), new LoaderCallback(activity) {
|
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, activity.getApplicationContext(), new LoaderCallback(activity) {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.stardust.autojs.core.plugin;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
|
import com.stardust.autojs.rhino.TopLevelScope;
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class Plugin {
|
||||||
|
|
||||||
|
public static class PluginLoadException extends RuntimeException {
|
||||||
|
public PluginLoadException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginLoadException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String KEY_REGISTRY = "org.autojs.plugin.sdk.registry";
|
||||||
|
|
||||||
|
public static Plugin load(Context context, Context packageContext, ScriptRuntime runtime, TopLevelScope scope) {
|
||||||
|
try {
|
||||||
|
ApplicationInfo applicationInfo = packageContext.getPackageManager().getApplicationInfo(packageContext.getPackageName(), PackageManager.GET_META_DATA);
|
||||||
|
String registryClass = applicationInfo.metaData.getString(KEY_REGISTRY);
|
||||||
|
if (registryClass == null) {
|
||||||
|
throw new PluginLoadException("no registry in metadata");
|
||||||
|
}
|
||||||
|
Class<?> pluginClass = Class.forName(registryClass, true, packageContext.getClassLoader());
|
||||||
|
Method loadDefault = pluginClass.getMethod("loadDefault", Context.class, Context.class, Object.class, Object.class);
|
||||||
|
return Plugin.create(loadDefault.invoke(null, context, packageContext, runtime, scope));
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new PluginLoadException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Plugin create(Object pluginInstance) {
|
||||||
|
if (pluginInstance == null)
|
||||||
|
return null;
|
||||||
|
return new Plugin(pluginInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Object mPluginInstance;
|
||||||
|
private Method mGetVersion;
|
||||||
|
private Method mGetScriptDir;
|
||||||
|
private String mMainScriptPath;
|
||||||
|
|
||||||
|
public Plugin(Object pluginInstance) {
|
||||||
|
mPluginInstance = pluginInstance;
|
||||||
|
findMethods(pluginInstance.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void findMethods(Class pluginClass) {
|
||||||
|
try {
|
||||||
|
mGetVersion = pluginClass.getMethod("getVersion");
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mGetScriptDir = pluginClass.getMethod("getAssetsScriptDir");
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object unwrap() {
|
||||||
|
return mPluginInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMainScriptPath() {
|
||||||
|
return mMainScriptPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainScriptPath(String mainScriptPath) {
|
||||||
|
mMainScriptPath = mainScriptPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssetsScriptDir() {
|
||||||
|
try {
|
||||||
|
return (String) mGetScriptDir.invoke(mPluginInstance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import com.stardust.autojs.core.ui.ViewExtras;
|
|||||||
import com.stardust.autojs.rhino.NativeArrayLikeJavaObject;
|
import com.stardust.autojs.rhino.NativeArrayLikeJavaObject;
|
||||||
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
||||||
import com.stardust.autojs.rhino.TopLevelScope;
|
import com.stardust.autojs.rhino.TopLevelScope;
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
import com.stardust.autojs.script.JavaScriptSource;
|
import com.stardust.autojs.script.JavaScriptSource;
|
||||||
import com.stardust.autojs.script.StringScriptSource;
|
import com.stardust.autojs.script.StringScriptSource;
|
||||||
import com.stardust.automator.UiObject;
|
import com.stardust.automator.UiObject;
|
||||||
@@ -60,6 +61,12 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
ScriptableObject.putProperty(mScriptable, name, Context.javaToJS(value, mScriptable));
|
ScriptableObject.putProperty(mScriptable, name, Context.javaToJS(value, mScriptable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRuntime(ScriptRuntime runtime) {
|
||||||
|
super.setRuntime(runtime);
|
||||||
|
runtime.setTopLevelScope(mScriptable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object doExecution(JavaScriptSource source) {
|
public Object doExecution(JavaScriptSource source) {
|
||||||
Reader reader = source.getNonNullScriptReader();
|
Reader reader = source.getNonNullScriptReader();
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ public interface ScriptEngine<S extends ScriptSource> {
|
|||||||
|
|
||||||
String cwd();
|
String cwd();
|
||||||
|
|
||||||
void uncaughtException(Exception throwable);
|
void uncaughtException(Throwable throwable);
|
||||||
|
|
||||||
Exception getUncaughtException();
|
Throwable getUncaughtException();
|
||||||
|
|
||||||
void setId(int id);
|
void setId(int id);
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ public interface ScriptEngine<S extends ScriptSource> {
|
|||||||
private Map<String, Object> mTags = new HashMap<>();
|
private Map<String, Object> mTags = new HashMap<>();
|
||||||
private OnDestroyListener mOnDestroyListener;
|
private OnDestroyListener mOnDestroyListener;
|
||||||
private boolean mDestroyed = false;
|
private boolean mDestroyed = false;
|
||||||
private Exception mUncaughtException;
|
private Throwable mUncaughtException;
|
||||||
private volatile AtomicInteger mId = new AtomicInteger(ScriptExecution.NO_ID);
|
private volatile AtomicInteger mId = new AtomicInteger(ScriptExecution.NO_ID);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -114,13 +114,13 @@ public interface ScriptEngine<S extends ScriptSource> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uncaughtException(Exception throwable) {
|
public void uncaughtException(Throwable throwable) {
|
||||||
mUncaughtException = throwable;
|
mUncaughtException = throwable;
|
||||||
forceStop();
|
forceStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Exception getUncaughtException() {
|
public Throwable getUncaughtException() {
|
||||||
return mUncaughtException;
|
return mUncaughtException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,12 +59,12 @@ public class ScriptEngineProxy<S extends ScriptSource> implements ScriptEngine<S
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uncaughtException(Exception throwable) {
|
public void uncaughtException(Throwable throwable) {
|
||||||
mScriptEngine.uncaughtException(throwable);
|
mScriptEngine.uncaughtException(throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Exception getUncaughtException() {
|
public Throwable getUncaughtException() {
|
||||||
return mScriptEngine.getUncaughtException();
|
return mScriptEngine.getUncaughtException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
|||||||
try {
|
try {
|
||||||
prepare(engine);
|
prepare(engine);
|
||||||
Object r = doExecution(engine);
|
Object r = doExecution(engine);
|
||||||
Exception uncaughtException = engine.getUncaughtException();
|
Throwable uncaughtException = engine.getUncaughtException();
|
||||||
if (uncaughtException != null) {
|
if (uncaughtException != null) {
|
||||||
onException(engine, uncaughtException);
|
onException(engine, uncaughtException);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
getListener().onSuccess(this, r);
|
getListener().onSuccess(this, r);
|
||||||
return r;
|
return r;
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
onException(engine, e);
|
onException(engine, e);
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -56,7 +56,7 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onException(ScriptEngine engine, Exception e) {
|
protected void onException(ScriptEngine engine, Throwable e) {
|
||||||
Log.w(TAG, "onException: engine = " + engine, e);
|
Log.w(TAG, "onException: engine = " + engine, e);
|
||||||
getListener().onException(this, e);
|
getListener().onException(this, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onException(Exception e) {
|
private void onException(Throwable e) {
|
||||||
mExecutionListener.onException(mScriptExecution, e);
|
mExecutionListener.onException(mScriptExecution, e);
|
||||||
super.finish();
|
super.finish();
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
super.finish();
|
super.finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Exception exception = mScriptEngine.getUncaughtException();
|
Throwable exception = mScriptEngine.getUncaughtException();
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
onException(exception);
|
onException(exception);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ public interface ScriptExecutionListener extends Serializable {
|
|||||||
|
|
||||||
void onSuccess(ScriptExecution execution, Object result);
|
void onSuccess(ScriptExecution execution, Object result);
|
||||||
|
|
||||||
void onException(ScriptExecution execution, Exception e);
|
void onException(ScriptExecution execution, Throwable e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class ScriptExecutionObserver implements ScriptExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
for (ScriptExecutionListener listener : mScriptExecutionListeners) {
|
for (ScriptExecutionListener listener : mScriptExecutionListeners) {
|
||||||
listener.onException(execution, e);
|
listener.onException(execution, e);
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ public class ScriptExecutionObserver implements ScriptExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
mScriptExecutionListener.onException(execution, e);
|
mScriptExecutionListener.onException(execution, e);
|
||||||
mScriptExecutionObserver.onException(execution, e);
|
mScriptExecutionObserver.onException(execution, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class SimpleScriptExecutionListener implements ScriptExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.stardust.autojs.core.image.Colors;
|
|||||||
import com.stardust.autojs.core.permission.PermissionRequestProxyActivity;
|
import com.stardust.autojs.core.permission.PermissionRequestProxyActivity;
|
||||||
import com.stardust.autojs.core.permission.Permissions;
|
import com.stardust.autojs.core.permission.Permissions;
|
||||||
import com.stardust.autojs.rhino.AndroidClassLoader;
|
import com.stardust.autojs.rhino.AndroidClassLoader;
|
||||||
|
import com.stardust.autojs.rhino.TopLevelScope;
|
||||||
import com.stardust.autojs.runtime.api.AbstractShell;
|
import com.stardust.autojs.runtime.api.AbstractShell;
|
||||||
import com.stardust.autojs.runtime.api.AppUtils;
|
import com.stardust.autojs.runtime.api.AppUtils;
|
||||||
import com.stardust.autojs.runtime.api.Console;
|
import com.stardust.autojs.runtime.api.Console;
|
||||||
@@ -26,6 +27,7 @@ import com.stardust.autojs.runtime.api.Files;
|
|||||||
import com.stardust.autojs.runtime.api.Floaty;
|
import com.stardust.autojs.runtime.api.Floaty;
|
||||||
import com.stardust.autojs.core.looper.Loopers;
|
import com.stardust.autojs.core.looper.Loopers;
|
||||||
import com.stardust.autojs.runtime.api.Media;
|
import com.stardust.autojs.runtime.api.Media;
|
||||||
|
import com.stardust.autojs.runtime.api.Plugins;
|
||||||
import com.stardust.autojs.runtime.api.Sensors;
|
import com.stardust.autojs.runtime.api.Sensors;
|
||||||
import com.stardust.autojs.runtime.api.Threads;
|
import com.stardust.autojs.runtime.api.Threads;
|
||||||
import com.stardust.autojs.runtime.api.Timers;
|
import com.stardust.autojs.runtime.api.Timers;
|
||||||
@@ -193,6 +195,9 @@ public class ScriptRuntime {
|
|||||||
@ScriptVariable
|
@ScriptVariable
|
||||||
public final Media media;
|
public final Media media;
|
||||||
|
|
||||||
|
@ScriptVariable
|
||||||
|
public final Plugins plugins;
|
||||||
|
|
||||||
private Images images;
|
private Images images;
|
||||||
|
|
||||||
private static WeakReference<Context> applicationContext;
|
private static WeakReference<Context> applicationContext;
|
||||||
@@ -201,6 +206,7 @@ public class ScriptRuntime {
|
|||||||
private Supplier<AbstractShell> mShellSupplier;
|
private Supplier<AbstractShell> mShellSupplier;
|
||||||
private ScreenMetrics mScreenMetrics = new ScreenMetrics();
|
private ScreenMetrics mScreenMetrics = new ScreenMetrics();
|
||||||
private Thread mThread;
|
private Thread mThread;
|
||||||
|
private TopLevelScope mTopLevelScope;
|
||||||
|
|
||||||
|
|
||||||
protected ScriptRuntime(Builder builder) {
|
protected ScriptRuntime(Builder builder) {
|
||||||
@@ -223,6 +229,7 @@ public class ScriptRuntime {
|
|||||||
floaty = new Floaty(uiHandler, ui, this);
|
floaty = new Floaty(uiHandler, ui, this);
|
||||||
files = new Files(this);
|
files = new Files(this);
|
||||||
media = new Media(context, this);
|
media = new Media(context, this);
|
||||||
|
plugins = new Plugins(context, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
@@ -236,6 +243,17 @@ public class ScriptRuntime {
|
|||||||
sensors = new Sensors(uiHandler.getContext(), this);
|
sensors = new Sensors(uiHandler.getContext(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TopLevelScope getTopLevelScope() {
|
||||||
|
return mTopLevelScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopLevelScope(TopLevelScope topLevelScope) {
|
||||||
|
if (mTopLevelScope != null) {
|
||||||
|
throw new IllegalStateException("top level has already exists");
|
||||||
|
}
|
||||||
|
mTopLevelScope = topLevelScope;
|
||||||
|
}
|
||||||
|
|
||||||
public static void setApplicationContext(Context context) {
|
public static void setApplicationContext(Context context) {
|
||||||
applicationContext = new WeakReference<>(context);
|
applicationContext = new WeakReference<>(context);
|
||||||
}
|
}
|
||||||
@@ -358,7 +376,7 @@ public class ScriptRuntime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit(Exception e) {
|
public void exit(Throwable e) {
|
||||||
engines.myEngine().uncaughtException(e);
|
engines.myEngine().uncaughtException(e);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
@@ -389,7 +407,7 @@ public class ScriptRuntime {
|
|||||||
ignoresException(floaty::closeAll);
|
ignoresException(floaty::closeAll);
|
||||||
try {
|
try {
|
||||||
events.emit("exit");
|
events.emit("exit");
|
||||||
} catch (Exception ignored) {
|
} catch (Throwable ignored) {
|
||||||
console.error("exception on exit: ", ignored);
|
console.error("exception on exit: ", ignored);
|
||||||
}
|
}
|
||||||
ignoresException(threads::shutDownAll);
|
ignoresException(threads::shutDownAll);
|
||||||
@@ -412,7 +430,7 @@ public class ScriptRuntime {
|
|||||||
private void ignoresException(Runnable r) {
|
private void ignoresException(Runnable r) {
|
||||||
try {
|
try {
|
||||||
r.run();
|
r.run();
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.stardust.autojs.runtime.api;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.stardust.autojs.core.plugin.Plugin;
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
|
import com.stardust.pio.PFiles;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class Plugins {
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final ScriptRuntime mRuntime;
|
||||||
|
private File mPluginCacheDir;
|
||||||
|
|
||||||
|
public Plugins(Context context, ScriptRuntime runtime) {
|
||||||
|
mContext = context;
|
||||||
|
mRuntime = runtime;
|
||||||
|
mPluginCacheDir = new File(mContext.getCacheDir(), "plugin-scripts/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin load(String packageName) {
|
||||||
|
try {
|
||||||
|
Context packageContext = mContext.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
|
||||||
|
Plugin plugin = Plugin.load(mContext, packageContext, mRuntime, mRuntime.getTopLevelScope());
|
||||||
|
if (plugin == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
File scriptCacheDir = getScriptCacheDir(packageName);
|
||||||
|
PFiles.copyAssetDir(packageContext.getAssets(), plugin.getAssetsScriptDir(), scriptCacheDir.getPath(), null);
|
||||||
|
plugin.setMainScriptPath(new File(scriptCacheDir, "index.js").getPath());
|
||||||
|
return plugin;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Plugin.PluginLoadException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getScriptCacheDir(String packageName) {
|
||||||
|
File dir = new File(mPluginCacheDir, packageName + "/");
|
||||||
|
dir.mkdirs();
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
PFiles.deleteRecursively(mPluginCacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -50,7 +50,7 @@ public class VMBridge_custom extends VMBridge_jdk15 {
|
|||||||
try {
|
try {
|
||||||
Object result = adapterWrapper.invoke(cf, target, topScope, proxy, method, args);
|
Object result = adapterWrapper.invoke(cf, target, topScope, proxy, method, args);
|
||||||
return castReturnValue(method, result);
|
return castReturnValue(method, result);
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
// notify the script thread to exit
|
// notify the script thread to exit
|
||||||
com.stardust.autojs.runtime.ScriptRuntime runtime = engine.getRuntime();
|
com.stardust.autojs.runtime.ScriptRuntime runtime = engine.getRuntime();
|
||||||
|
|||||||
@@ -50,15 +50,19 @@ public class PFile extends File {
|
|||||||
mSimplifyPath = PFiles.getSimplifiedPath(getPath());
|
mSimplifyPath = PFiles.getSimplifiedPath(getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean renameTo(String newName) {
|
|
||||||
if (isDirectory())
|
@NonNull
|
||||||
return renameTo(new File(getParent(), newName));
|
public PFile renameTo(String newName) {
|
||||||
else
|
PFile newFile = new PFile(getParent(), newName);
|
||||||
return renameTo(new File(getParent(), newName + "." + getExtension()));
|
if (renameTo(newFile)) {
|
||||||
|
return newFile;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@NonNull
|
||||||
public PFile renameAndReturnNewFile(String newName) {
|
public PFile renameWithoutExt(String newName) {
|
||||||
PFile newFile = isDirectory() ? new PFile(getParent(), newName) :
|
PFile newFile = isDirectory() ? new PFile(getParent(), newName) :
|
||||||
new PFile(getParent(), newName + "." + getExtension());
|
new PFile(getParent(), newName + "." + getExtension());
|
||||||
if (renameTo(newFile)) {
|
if (renameTo(newFile)) {
|
||||||
|
|||||||
@@ -296,9 +296,8 @@ public class PFiles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void copyAssetDir(Context context, String assetsDir, String toDir, String[] list) throws IOException {
|
public static void copyAssetDir(AssetManager manager, String assetsDir, String toDir, String[] list) throws IOException {
|
||||||
new File(toDir).mkdirs();
|
new File(toDir).mkdirs();
|
||||||
AssetManager manager = context.getAssets();
|
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
list = manager.list(assetsDir);
|
list = manager.list(assetsDir);
|
||||||
}
|
}
|
||||||
@@ -323,7 +322,7 @@ public class PFiles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
copyAssetDir(context, fullAssetsPath, join(toDir, file), children);
|
copyAssetDir(manager, fullAssetsPath, join(toDir, file), children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ public class ObjectHelper {
|
|||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,17 @@ public class Objects {
|
|||||||
public static boolean equals(Object a, Object b) {
|
public static boolean equals(Object a, Object b) {
|
||||||
return (a == b) || (a != null && a.equals(b));
|
return (a == b) || (a != null && a.equals(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code of a non-{@code null} argument and 0 for
|
||||||
|
* a {@code null} argument.
|
||||||
|
*
|
||||||
|
* @param o an object
|
||||||
|
* @return the hash code of a non-{@code null} argument and 0 for
|
||||||
|
* a {@code null} argument
|
||||||
|
* @see Object#hashCode
|
||||||
|
*/
|
||||||
|
public static int hashCode(Object o) {
|
||||||
|
return o != null ? o.hashCode() : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(ScriptExecution execution, Exception e) {
|
public void onException(ScriptExecution execution, Throwable e) {
|
||||||
onFinish(execution);
|
onFinish(execution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class AssetsProjectLauncher {
|
|||||||
}
|
}
|
||||||
PFiles.deleteRecursively(new File(mProjectDir));
|
PFiles.deleteRecursively(new File(mProjectDir));
|
||||||
try {
|
try {
|
||||||
PFiles.copyAssetDir(mActivity, mAssetsProjectDir, mProjectDir, null);
|
PFiles.copyAssetDir(mActivity.getAssets(), mAssetsProjectDir, mProjectDir, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UncheckedIOException(e);
|
throw new UncheckedIOException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user