Fix and improve root rocording

This commit is contained in:
hyb1996
2017-05-05 00:35:45 +08:00
parent 7473d7c6a5
commit 163f38760e
80 changed files with 1386 additions and 1017 deletions

View File

@@ -0,0 +1,60 @@
package com.stardust.scriptdroid.script;
import android.app.Activity;
import android.os.Build;
import android.text.TextUtils;
import android.widget.Toast;
import java.io.File;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
/**
* Created by Stardust on 2017/4/1.
*/
public class PathChecker {
public static final int CHECK_RESULT_OK = 0;
private Activity mActivity;
public PathChecker(Activity activity) {
mActivity = activity;
}
public static int check(final String path) {
if (TextUtils.isEmpty(path))
return com.stardust.autojs.R.string.text_path_is_empty;
if (!new File(path).exists())
return com.stardust.autojs.R.string.text_file_not_exists;
return CHECK_RESULT_OK;
}
public boolean checkAndToastError(String path) {
int result = checkWithStoragePermission(path);
if (result != CHECK_RESULT_OK) {
Toast.makeText(mActivity, result, Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
private int checkWithStoragePermission(String path) {
if (!hasStorageReadPermission(mActivity)) {
return com.stardust.autojs.R.string.text_no_file_rw_permission;
}
return check(path);
}
private static boolean hasStorageReadPermission(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
activity.checkSelfPermission(READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED;
}
return true;
}
}

View File

@@ -0,0 +1,104 @@
package com.stardust.scriptdroid.script;
import android.os.Environment;
import com.stardust.pio.PFile;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.ArrayList;
/**
* Created by Stardust on 2017/1/23.
*/
public class ScriptFile extends File {
private String mSimplifyPath;
private String mSimplifiedName;
public ScriptFile(String path) {
super(path);
init();
}
private void init() {
mSimplifiedName = PFile.getNameWithoutExtension(getName());
mSimplifyPath = getPath();
if (mSimplifyPath.startsWith(Environment.getExternalStorageDirectory().getPath())) {
mSimplifyPath = mSimplifyPath.substring(Environment.getExternalStorageDirectory().getPath().length());
}
}
public ScriptFile(ScriptFile parent, String child) {
super(parent, child);
init();
}
public boolean renameTo(String newName) {
if (isDirectory())
return renameTo(new File(getParent(), newName));
else
return renameTo(new File(getParent(), newName + getExtension()));
}
private String getExtension() {
return PFile.getExtension(getName());
}
public String getSimplifiedPath() {
return mSimplifyPath;
}
@Override
public ScriptFile getParentFile() {
String p = this.getParent();
if (p == null)
return null;
return new ScriptFile(p);
}
@Override
public ScriptFile[] listFiles() {
return listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return (file.isDirectory() || file.getName().endsWith(".js")) && !file.getName().startsWith(".");
}
});
}
@Override
public ScriptFile[] listFiles(FilenameFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<ScriptFile> files = new ArrayList<>();
for (String s : ss)
if ((filter == null) || filter.accept(this, s))
files.add(new ScriptFile(this, s));
return files.toArray(new ScriptFile[files.size()]);
}
@Override
public ScriptFile[] listFiles(FileFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<ScriptFile> files = new ArrayList<>();
for (String s : ss) {
ScriptFile f = new ScriptFile(this, s);
if ((filter == null) || filter.accept(f))
files.add(f);
}
return files.toArray(new ScriptFile[files.size()]);
}
public String getSimplifiedName() {
return mSimplifiedName;
}
public boolean moveTo(ScriptFile to) {
return renameTo(new File(to, getName()));
}
}

View File

@@ -0,0 +1,42 @@
package com.stardust.scriptdroid.script;
import java.io.File;
/**
* Created by Stardust on 2017/1/23.
*/
public abstract class ScriptFileList {
private static ScriptFileList impl;
public static void setImpl(ScriptFileList list) {
impl = list;
}
public static ScriptFileList getImpl() {
return impl;
}
public abstract void add(ScriptFile scriptFile);
public abstract ScriptFile get(int i);
public abstract void remove(int i);
public abstract void rename(int position, String newName, boolean renameFile);
public abstract int size();
public boolean deleteFromFileSystem(int i) {
if (i < 0 || i >= size())
return false;
File file = get(i);
remove(i);
return file.delete();
}
public abstract boolean containsPath(String path);
}

View File

@@ -0,0 +1,113 @@
package com.stardust.scriptdroid.script;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.SimpleScriptExecutionListener;
import com.stardust.autojs.runtime.ScriptInterruptedException;
import com.stardust.autojs.script.FileScriptSource;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.autojs.script.ScriptSourceWithInit;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.BuildConfig;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.external.CommonUtils;
import com.stardust.scriptdroid.external.shortcut.Shortcut;
import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
import com.stardust.scriptdroid.script.sample.Sample;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.util.AssetsCache;
import java.io.File;
/**
* Created by Stardust on 2017/5/3.
*/
public class Scripts {
public static final String ACTION_ON_EXECUTION_FINISHED = "Don't leave me alone...";
public static final String EXTRA_EXCEPTION_MESSAGE = "Say something...Eating...17.5.3";
private static final ScriptExecutionListener BROADCAST_SENDER_SCRIPT_EXECUTION_LISTENER = new SimpleScriptExecutionListener() {
@Override
public void onSuccess(ScriptExecution execution, Object result) {
App.getApp().sendBroadcast(new Intent(ACTION_ON_EXECUTION_FINISHED));
}
@Override
public void onException(ScriptExecution execution, Exception e) {
if (ScriptInterruptedException.causedByInterrupted(e)) {
App.getApp().sendBroadcast(new Intent(ACTION_ON_EXECUTION_FINISHED));
} else {
App.getApp().sendBroadcast(new Intent(ACTION_ON_EXECUTION_FINISHED)
.putExtra(EXTRA_EXCEPTION_MESSAGE, e.getMessage()));
}
}
};
private static final String INIT_SCRIPT_PATH = "js/autojs_init.js";
private static ScriptSource initScriptSource;
public static void openByOtherApps(String path) {
Uri uri = Uri.parse("file://" + path);
App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
public static void openByOtherApps(File file) {
openByOtherApps(file.getPath());
}
public static void createShortcut(ScriptFile scriptFile) {
new Shortcut(App.getApp()).name(scriptFile.getSimplifiedName())
.targetClass(ShortcutActivity.class)
.icon(R.drawable.ic_node_js_black)
.extras(new Intent().putExtra(CommonUtils.EXTRA_KEY_PATH, scriptFile.getPath()))
.send();
}
public static void edit(ScriptFile file) {
EditActivity.editFile(App.getApp(), file.getSimplifiedName(), file.getPath());
}
public static void edit(String path) {
edit(new ScriptFile(path));
}
public static ScriptExecution run(ScriptFile file) {
return run(new FileScriptSource(file));
}
public static ScriptExecution run(ScriptSource source) {
return AutoJs.getInstance().getScriptEngineService().execute(wrappedWithInitSource(source));
}
private static ScriptSource wrappedWithInitSource(ScriptSource source) {
return new ScriptSourceWithInit(getInitScriptSource(), source);
}
public static ScriptExecution runWithBroadcastSender(ScriptSource scriptSource) {
return AutoJs.getInstance().getScriptEngineService().execute(wrappedWithInitSource(scriptSource), BROADCAST_SENDER_SCRIPT_EXECUTION_LISTENER);
}
public static ScriptExecution run(Context context, Sample file) {
ScriptSource source = new StringScriptSource(file.name, AssetsCache.get(context.getAssets(), file.path));
return AutoJs.getInstance().getScriptEngineService().execute(wrappedWithInitSource(source));
}
private static ScriptSource getInitScriptSource() {
if(initScriptSource == null || BuildConfig.DEBUG){
String initScript = AssetsCache.get(App.getApp().getAssets(), INIT_SCRIPT_PATH);
initScriptSource = new StringScriptSource(initScript);
}
return initScriptSource;
}
}

View File

@@ -0,0 +1,103 @@
package com.stardust.scriptdroid.script;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.App;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/1/23.
*/
public class SharedPrefScriptFileList extends ScriptFileList {
private static final Gson GSON = new Gson();
private static final String SP_KEY_SCRIPT_NAME = "script_name";
private static final String SP_KEY_SCRIPT_PATH = "script_path";
private static ScriptFileList instance = new SharedPrefScriptFileList(App.getApp());
private SharedPreferences mSharedPreferences;
private List<String> mScriptPath;
private List<String> mScriptName;
public static ScriptFileList getInstance() {
return instance;
}
public SharedPrefScriptFileList(Context context) {
mSharedPreferences = context.getSharedPreferences("SharedPrefScriptFileList", Context.MODE_PRIVATE);
readFromSharedPref();
}
private void readFromSharedPref() {
Type type = new TypeToken<List<String>>() {
}.getType();
mScriptName = GSON.fromJson(mSharedPreferences.getString(SP_KEY_SCRIPT_NAME, ""), type);
mScriptPath = GSON.fromJson(mSharedPreferences.getString(SP_KEY_SCRIPT_PATH, ""), type);
if (mScriptName == null || mScriptPath == null || mScriptName.size() != mScriptPath.size()) {
reset();
}
}
private void reset() {
mScriptName = new ArrayList<>();
mScriptPath = new ArrayList<>();
syncWithSharedPref();
}
@Override
public void add(ScriptFile scriptFile) {
mScriptName.add(scriptFile.getSimplifiedName());
mScriptPath.add(scriptFile.getSimplifiedPath());
syncWithSharedPref();
}
@Override
public ScriptFile get(int i) {
return new ScriptFile(mScriptPath.get(i));
}
@Override
public void remove(int i) {
mScriptName.remove(i);
mScriptPath.remove(i);
syncWithSharedPref();
}
@Override
public void rename(int position, String newName, boolean renameFile) {
mScriptName.set(position, newName);
if (renameFile) {
String newPath = PFile.renameWithoutExtension(mScriptPath.get(position), newName);
mScriptPath.set(position, newPath);
}
syncWithSharedPref();
}
@Override
public int size() {
return mScriptPath.size();
}
@Override
public boolean containsPath(String path) {
return mScriptPath.contains(path);
}
protected void syncWithSharedPref() {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(SP_KEY_SCRIPT_NAME, GSON.toJson(mScriptName));
editor.putString(SP_KEY_SCRIPT_PATH, GSON.toJson(mScriptPath));
editor.apply();
}
}

View File

@@ -0,0 +1,157 @@
package com.stardust.scriptdroid.script;
import android.os.Environment;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.util.FileSorter;
import com.stardust.util.LimitedHashMap;
import org.greenrobot.eventbus.EventBus;
import java.util.Map;
/**
* Created by Stardust on 2017/3/31.
*/
public class StorageScriptProvider {
public static class DirectoryChangeEvent {
public ScriptFile directory;
public DirectoryChangeEvent(ScriptFile directory) {
this.directory = directory;
}
}
public static final String DEFAULT_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + App.getApp().getString(R.string.folder_name);
public static final ScriptFile DEFAULT_DIRECTORY = new ScriptFile(DEFAULT_DIRECTORY_PATH);
private static StorageScriptProvider defaultProvider = new StorageScriptProvider();
public static StorageScriptProvider getDefault() {
return defaultProvider;
}
private static StorageScriptProvider externalStorageProvider;
public static StorageScriptProvider getExternalStorageProvider() {
if (externalStorageProvider == null) {
externalStorageProvider = new StorageScriptProvider(Environment.getExternalStorageDirectory().getPath(), 5);
}
return externalStorageProvider;
}
private EventBus mDirectoryEventBus = new EventBus();
private LimitedHashMap<String, ScriptFile[]> mScriptFileCache;
private ScriptFile mInitialDirectory;
private ScriptFile[] mInitialDirectoryScriptFiles;
public StorageScriptProvider(String path, int cacheSize) {
this(new ScriptFile(path), cacheSize);
}
public StorageScriptProvider(ScriptFile initialDirectory, int cacheSize) {
mInitialDirectory = initialDirectory;
mScriptFileCache = new LimitedHashMap<>(cacheSize);
}
public StorageScriptProvider() {
this(DEFAULT_DIRECTORY, 10);
}
public void notifyDirectoryChanged(ScriptFile directory) {
if (directory.equals(mInitialDirectory)) {
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner();
} else {
clearCache(directory);
}
mDirectoryEventBus.post(new DirectoryChangeEvent(directory));
}
public void notifyStoragePermissionGranted() {
mScriptFileCache.clear();
mInitialDirectoryScriptFiles = null;
mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory));
}
@SuppressWarnings("unchecked")
public void refreshAll() {
Map<String, ScriptFile> files = (Map<String, ScriptFile>) mScriptFileCache.clone();
mScriptFileCache.clear();
mInitialDirectoryScriptFiles = null;
mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory));
for (Map.Entry<String, ScriptFile> file : files.entrySet()) {
mDirectoryEventBus.post(new DirectoryChangeEvent(new ScriptFile(file.getKey())));
}
}
public ScriptFile getInitialDirectory() {
return mInitialDirectory;
}
public ScriptFile[] getInitialDirectoryScriptFiles() {
if (mInitialDirectoryScriptFiles == null) {
mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner();
}
return mInitialDirectoryScriptFiles;
}
private ScriptFile[] getInitialDirectoryScriptFilesInner() {
return listAndSortFiles(mInitialDirectory);
}
public ScriptFile[] getDirectoryScriptFiles(ScriptFile directory) {
if (directory.equals(mInitialDirectory)) {
return getInitialDirectoryScriptFiles();
}
ScriptFile[] scriptFiles = getScriptFilesFromCache(directory);
if (scriptFiles == null) {
scriptFiles = getScriptFiles(directory);
}
return scriptFiles;
}
public void clearCacheExceptInitialDirectory() {
mScriptFileCache.clear();
}
private void clearCache(ScriptFile directory) {
mScriptFileCache.remove(directory.getPath());
}
private ScriptFile[] getScriptFiles(ScriptFile directory) {
ScriptFile[] scriptFiles = listAndSortFiles(directory);
mScriptFileCache.put(directory.getPath(), scriptFiles);
return scriptFiles;
}
private ScriptFile[] listAndSortFiles(ScriptFile directory) {
ScriptFile[] scriptFiles = directory.listFiles();
if (scriptFiles == null)
scriptFiles = new ScriptFile[0];
else
FileSorter.sort(scriptFiles);
return scriptFiles;
}
private ScriptFile[] getScriptFilesFromCache(ScriptFile directory) {
return mScriptFileCache.get(directory.getPath());
}
public void registerDirectoryChangeListener(Object subscriber) {
if (!mDirectoryEventBus.isRegistered(subscriber))
mDirectoryEventBus.register(subscriber);
}
public void unregisterDirectoryChangeListener(Object subscriber) {
mDirectoryEventBus.unregister(subscriber);
}
}

View File

@@ -0,0 +1,24 @@
package com.stardust.scriptdroid.script.sample;
import android.content.Context;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.util.AssetsCache;
import java.io.Serializable;
/**
* Created by Stardust on 2017/3/13.
*/
public class Sample implements Serializable {
public String name;
public String path;
public Sample(String name, String path) {
this.name = name;
this.path = path;
}
}

View File

@@ -0,0 +1,53 @@
package com.stardust.scriptdroid.script.sample;
import android.content.Context;
import android.content.res.AssetManager;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.App;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/1/30.
*/
public class SampleFileManager {
private static SampleFileManager instance = new SampleFileManager();
public static SampleFileManager getInstance() {
return instance;
}
private Context getContext() {
return App.getApp();
}
public List<SampleGroup> getSamplesFromAssets(AssetManager assets, String path) {
List<SampleGroup> sampleGroups = new ArrayList<>();
try {
String[] groups = assets.list(path);
for (String groupName : groups) {
sampleGroups.add(getSampleGroupFromAssets(assets, groupName, path + "/" + groupName));
}
return sampleGroups;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private SampleGroup getSampleGroupFromAssets(AssetManager assets, String groupName, String path) {
SampleGroup group = new SampleGroup(groupName);
try {
String[] samples = assets.list(path);
for (String sample : samples) {
group.add(new Sample(PFile.getNameWithoutExtension(sample), path + "/" + sample));
}
return group;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.stardust.scriptdroid.script.sample;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/3/13.
*/
public class SampleGroup {
public String name;
public List<Sample> sampleList;
public SampleGroup(String name) {
this(name, new ArrayList<Sample>());
}
public SampleGroup(String name, List<Sample> samples) {
this.name = name;
sampleList = samples;
}
public void add(Sample sample){
sampleList.add(sample);
}
}