Add statics:

This commit is contained in:
hyb1996
2017-05-05 16:54:25 +08:00
parent 163f38760e
commit 68845c9a21
13 changed files with 488 additions and 134 deletions

View File

@@ -3,13 +3,13 @@ def AAVersion = '4.2.0'
android { android {
compileSdkVersion 25 compileSdkVersion 25
buildToolsVersion "25.0.1" buildToolsVersion "25.0.2"
defaultConfig { defaultConfig {
applicationId "com.stardust.scriptdroid" applicationId "com.stardust.scriptdroid"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 23 targetSdkVersion 23
versionCode 119 versionCode 120
versionName "2.0.8 Beta" versionName "2.0.9 Beta"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
} }
@@ -49,6 +49,9 @@ android {
pickFirst 'org/mozilla/javascript/*.java.orig' pickFirst 'org/mozilla/javascript/*.java.orig'
pickFirst 'org/mozilla/javascript/tools/resources/*.properties' pickFirst 'org/mozilla/javascript/tools/resources/*.properties'
} }
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
}
} }
repositories { repositories {
@@ -58,13 +61,16 @@ repositories {
} }
dependencies { dependencies {
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
annotationProcessor "org.androidannotations:androidannotations:$AAVersion" annotationProcessor 'com.pushtorefresh.storio:sqlite-annotations-processor:1.12.3'
compile "org.androidannotations:androidannotations-api:$AAVersion" compile 'com.pushtorefresh.storio:sqlite-annotations:1.12.3'
compile 'com.android.support:appcompat-v7:25.1.0' compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.android.support:design:25.1.0' compile 'com.android.support:design:25.1.0'
compile 'com.github.hyb1996:MutableTheme:0.2.2' compile 'com.github.hyb1996:MutableTheme:0.2.2'
compile 'com.afollestad.material-dialogs:core:0.9.2.3' compile 'com.afollestad.material-dialogs:core:0.9.2.3'
@@ -85,6 +91,7 @@ dependencies {
compile 'com.android.volley:volley:1.0.0' compile 'com.android.volley:volley:1.0.0'
compile 'com.github.hyb1996:EnhancedFloaty:0.15' compile 'com.github.hyb1996:EnhancedFloaty:0.15'
compile 'com.flurry.android:analytics:7.0.0@aar' compile 'com.flurry.android:analytics:7.0.0@aar'
compile 'com.pushtorefresh.storio:sqlite:1.12.3'
compile 'com.android.support:multidex:1.0.1' compile 'com.android.support:multidex:1.0.1'
compile(name: 'libtermexec-release', ext: 'aar') compile(name: 'libtermexec-release', ext: 'aar')
compile(name: 'emulatorview-release', ext: 'aar') compile(name: 'emulatorview-release', ext: 'aar')

View File

@@ -0,0 +1,97 @@
package com.stardust.scriptdroid.statics;
import android.support.test.InstrumentationRegistry;
import com.stardust.autojs.script.FileScriptSource;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.util.MapEntries;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Created by Stardust on 2017/5/5.
*/
public class SQLiteStaticsStorageTest {
private SQLiteStaticsStorage mStorage;
@Before
public void setUp() throws Exception {
mStorage = new SQLiteStaticsStorage(InstrumentationRegistry.getTargetContext());
}
@Test
public void record() throws Exception {
testOneRecord();
testTwoRecord();
testRepeatedRecord();
}
@Test
public void testOneRecord() {
mStorage.clear();
mStorage.record(new StringScriptSource("Name", "Script"));
assertEquals(mStorage.getAll(), new MapEntries<String, String>()
.entry("Name.js", "1")
.map());
}
@Test
public void testTwoRecord() {
mStorage.clear();
mStorage.record(new StringScriptSource("Name", "Script"));
mStorage.record(new FileScriptSource("/test/test.js"));
assertEquals(mStorage.getAll(), new MapEntries<String, String>()
.entry("Name.js", "1")
.entry("/test/test.js", "1")
.map());
}
@Test
public void testRepeatedRecord() {
mStorage.clear();
mStorage.record(new FileScriptSource("/test/test.js"));
mStorage.record(new StringScriptSource("Name", "Script"));
mStorage.record(new FileScriptSource("/test/test.js"));
mStorage.record(new FileScriptSource("/test/test.js"));
assertEquals(mStorage.getAll(), new MapEntries<String, String>()
.entry("Name.js", "1")
.entry("/test/test.js", "3")
.map());
}
@Test
public void getMax() throws Exception {
mStorage.clear();
put(new FileScriptSource("/test/test.js"), 50);
put(new StringScriptSource("Name4", "Script"), 10);
put(new StringScriptSource("Name5", "Script"), 5);
put(new StringScriptSource("Name6", "Script"), 4);
put(new StringScriptSource("Name7", "Script"), 3);
put(new StringScriptSource("Name8", "Script"), 1);
put(new StringScriptSource("Name9", "Script"), 1);
put(new StringScriptSource("Name3", "Script"), 20);
put(new StringScriptSource("Name1", "Script"), 100);
assertEquals(mStorage.getMax(5), new MapEntries<String, String>()
.entry("Name1.js", "100")
.entry("/test/test.js", "50")
.entry("Name3.js", "20")
.entry("Name4.js", "10")
.entry("Name5.js", "5")
.map());
}
private void put(ScriptSource source, int times) {
for (int i = 0; i < times; i++) {
mStorage.record(source);
}
}
}

View File

@@ -13,6 +13,7 @@ import com.stardust.app.SimpleActivityLifecycleCallbacks;
import com.stardust.app.VolumeChangeObserver; import com.stardust.app.VolumeChangeObserver;
import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService; import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.statics.ScriptStatics;
import com.stardust.scriptdroid.tool.CrashHandler; import com.stardust.scriptdroid.tool.CrashHandler;
import com.stardust.scriptdroid.tool.JsBeautifierFactory; import com.stardust.scriptdroid.tool.JsBeautifierFactory;
import com.stardust.scriptdroid.ui.error.ErrorReportActivity; import com.stardust.scriptdroid.ui.error.ErrorReportActivity;
@@ -49,9 +50,7 @@ public class App extends MultiDexApplication {
} }
private void setUpStaticsTool() { private void setUpStaticsTool() {
new FlurryAgent.Builder() ScriptStatics.init(this);
.withLogEnabled(true)
.build(this, "D42MH48ZN4PJC5TKNYZD");
} }
@@ -91,7 +90,6 @@ public class App extends MultiDexApplication {
@Override @Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
super.onActivityCreated(activity, savedInstanceState); super.onActivityCreated(activity, savedInstanceState);
FlurryAgent.logEvent(activity.getClass().getSimpleName());
} }
@Override @Override

View File

@@ -5,6 +5,7 @@ import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener; import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.statics.ScriptStatics;
/** /**
* Created by Stardust on 2017/5/3. * Created by Stardust on 2017/5/3.
@@ -16,7 +17,7 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
@Override @Override
public void onStart(ScriptExecution execution) { public void onStart(ScriptExecution execution) {
execution.getEngine().setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis()); execution.getEngine().setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis());
FlurryAgent.logEvent("EXEC:" + execution.getSource().toString()); ScriptStatics.recordScript(execution.getSource());
} }
@Override @Override

View File

@@ -7,10 +7,16 @@ import android.util.Log;
import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.autojs.runtime.ScriptInterruptedException;
import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.lang.ThreadCompat;
import com.stardust.pio.UncheckedIOException; import com.stardust.pio.UncheckedIOException;
import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.App;
import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import jackpal.androidterm.ShellTermSession; import jackpal.androidterm.ShellTermSession;
import jackpal.androidterm.emulatorview.TermSession; import jackpal.androidterm.emulatorview.TermSession;
@@ -22,19 +28,23 @@ import jackpal.androidterm.util.TermSettings;
public class Shell extends AbstractShell implements AutoCloseable { public class Shell extends AbstractShell implements AutoCloseable {
public interface OutputListener { public interface Callback {
void onNewOutput(String str); void onNewLine(String str);
void onInitialized();
void onInterrupted(InterruptedException e);
} }
private static final String TAG = "Shell"; private static final String TAG = "Shell";
private TermSession mTermSession; private TermSession mTermSession;
private RuntimeException mInitException;
private final Object mInitLock = new Object(); private final Object mInitLock = new Object();
private final Object mExitLock = new Object(); private final Object mExitLock = new Object();
private boolean mInitialized = false; private volatile RuntimeException mInitException;
private boolean mWaitingExit = false; private volatile boolean mInitialized = false;
private OutputListener mOutputListener; private volatile boolean mWaitingExit = false;
private Callback mCallback;
public Shell() { public Shell() {
super(); super();
@@ -69,8 +79,12 @@ public class Shell extends AbstractShell implements AutoCloseable {
mTermSession.write(command + "\n"); mTermSession.write(command + "\n");
} }
public void setOutputListener(OutputListener outputListener) { public void setCallback(Callback callback) {
mOutputListener = outputListener; mCallback = callback;
}
public boolean isInitialized() {
return mInitialized;
} }
private void ensureInitialized() { private void ensureInitialized() {
@@ -97,9 +111,17 @@ public class Shell extends AbstractShell implements AutoCloseable {
try { try {
mInitLock.wait(); mInitLock.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
onInterrupted(e);
}
}
}
private void onInterrupted(InterruptedException e) {
if (mCallback == null) {
exit(); exit();
throw new ScriptInterruptedException(); throw new ScriptInterruptedException();
} } else {
mCallback.onInterrupted(e);
} }
} }
@@ -124,8 +146,7 @@ public class Shell extends AbstractShell implements AutoCloseable {
try { try {
mExitLock.wait(); mExitLock.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
exit(); onInterrupted(e);
throw new ScriptInterruptedException();
} }
} }
} }
@@ -137,31 +158,65 @@ public class Shell extends AbstractShell implements AutoCloseable {
private class MyShellTermSession extends ShellTermSession { private class MyShellTermSession extends ShellTermSession {
private BufferedReader mBufferedReader;
private OutputStream mOutputStream;
private Thread mReadingThread;
public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException { public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException {
super(settings, initialCommand); super(settings, initialCommand);
PipedInputStream pipedInputStream = new PipedInputStream(8192);
mBufferedReader = new BufferedReader(new InputStreamReader(pipedInputStream));
mOutputStream = new PipedOutputStream(pipedInputStream);
startReadingThread();
} }
private void startReadingThread() {
mReadingThread = new ThreadCompat(new Runnable() {
@Override @Override
protected void processInput(byte[] data, int offset, int count) { public void run() {
String output = new String(data, offset, count); String line;
Log.d(TAG, output); try {
if(mOutputListener != null){ while (!Thread.currentThread().isInterrupted()
mOutputListener.onNewOutput(output); && (line = mBufferedReader.readLine()) != null) {
onNewLine(line);
} }
if (mInitialized && !mWaitingExit) { } catch (IOException e) {
return; e.printStackTrace();
} }
String[] lines = new String(data, offset, count).split("\n"); }
for (String line : lines) { });
if (!mInitialized && line.endsWith(" # ")) { mReadingThread.start();
}
private void onNewLine(String line) {
Log.d(TAG, line);
if (mInitialized) {
if (mCallback != null) {
mCallback.onNewLine(line);
}
} else {
if (isRoot() && line.endsWith(" $ su")) {
notifyInitialized(); notifyInitialized();
return; return;
} }
if (mWaitingExit && line.endsWith(" $ ")) { if (!isRoot() && line.endsWith(" $ ")) {
notifyExit(); notifyInitialized();
return; return;
} }
} }
if (mWaitingExit && line.endsWith(" exit")) {
notifyExit();
}
}
@Override
protected void processInput(byte[] data, int offset, int count) {
try {
mOutputStream.write(data, offset, count);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} }
private void notifyExit() { private void notifyExit() {
@@ -176,6 +231,9 @@ public class Shell extends AbstractShell implements AutoCloseable {
synchronized (mInitLock) { synchronized (mInitLock) {
mInitLock.notifyAll(); mInitLock.notifyAll();
} }
if (mCallback != null) {
mCallback.onInitialized();
}
} }
@Override @Override
@@ -186,6 +244,18 @@ public class Shell extends AbstractShell implements AutoCloseable {
mExitLock.notify(); mExitLock.notify();
} }
} }
@Override
public void finish() {
super.finish();
mReadingThread.interrupt();
try {
mBufferedReader.close();
mOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
} }

View File

@@ -66,7 +66,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
if (Pref.isRecordVolumeControlEnable()) { if (Pref.isRecordVolumeControlEnable()) {
if (mRecorder == null) { if (mRecorder == null) {
startRecord(); startRecord();
} else if (mRecorder.getState() == Recorder.STATE_RECORDING) { } else if (alreadyStartedRecord()) {
stopRecord(); stopRecord();
} }
} }
@@ -211,7 +211,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
@Override @Override
public void onKeyDown(String keyName) { public void onKeyDown(String keyName) {
if (keyName.equals(Pref.getStopRecordTrigger())) { if (keyName.equals(Pref.getStopRecordTrigger())) {
if (mRecorder != null && mRecorder.getState() == Recorder.STATE_RECORDING && mRecorder.getState() == Recorder.STATE_PAUSED) if (alreadyStartedRecord())
stopRecord(); stopRecord();
} else if (keyName.equals(Pref.getStartRecordTrigger())) { } else if (keyName.equals(Pref.getStartRecordTrigger())) {
if (mRecorder == null) if (mRecorder == null)
@@ -219,6 +219,10 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
} }
} }
private boolean alreadyStartedRecord() {
return mRecorder != null && mRecorder.getState() == Recorder.STATE_RECORDING && mRecorder.getState() == Recorder.STATE_PAUSED;
}
@Override @Override
public void onKeyUp(String keyName) { public void onKeyUp(String keyName) {

View File

@@ -9,6 +9,7 @@ import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.record.Recorder; import com.stardust.scriptdroid.record.Recorder;
import com.stardust.util.MapEntries;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
@@ -72,9 +73,9 @@ public abstract class InputEventConverter {
private int mState = Recorder.STATE_NOT_START; private int mState = Recorder.STATE_NOT_START;
public void convertEventIfFormatCorrect(String eventStr) { public void convertEventIfFormatCorrect(String eventStr) {
if(!mConverting) if (!mConverting)
return; return;
if(TextUtils.isEmpty(eventStr) || !eventStr.startsWith("[")) if (TextUtils.isEmpty(eventStr) || !eventStr.startsWith("["))
return; return;
Event event = parseEventOrNull(eventStr); Event event = parseEventOrNull(eventStr);
if (event != null) { if (event != null) {
@@ -94,7 +95,7 @@ public abstract class InputEventConverter {
mState = Recorder.STATE_RECORDING; mState = Recorder.STATE_RECORDING;
} }
public void resume(){ public void resume() {
mConverting = true; mConverting = true;
mState = Recorder.STATE_RECORDING; mState = Recorder.STATE_RECORDING;
} }
@@ -118,10 +119,12 @@ public abstract class InputEventConverter {
return Event.parseEvent(eventStr); return Event.parseEvent(eventStr);
} catch (EventFormatException e) { } catch (EventFormatException e) {
e.printStackTrace(); e.printStackTrace();
if(mFirstEventFormatError){ if (mFirstEventFormatError) {
Toast.makeText(App.getApp(), R.string.text_record_format_error, Toast.LENGTH_SHORT).show(); Toast.makeText(App.getApp(), R.string.text_record_format_error, Toast.LENGTH_SHORT).show();
mFirstEventFormatError = false; mFirstEventFormatError = false;
FlurryAgent.logEvent("EventFormatException:" + e.getMessage()); FlurryAgent.logEvent("EventFormatException", new MapEntries<String, String>()
.entry("message", e.getMessage())
.map());
} }
return null; return null;
} }

View File

@@ -5,6 +5,7 @@ import android.util.Log;
import com.stardust.pio.UncheckedIOException; import com.stardust.pio.UncheckedIOException;
import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.autojs.Shell;
import com.stardust.scriptdroid.record.Recorder; import com.stardust.scriptdroid.record.Recorder;
import java.io.BufferedReader; import java.io.BufferedReader;
@@ -25,24 +26,36 @@ import jackpal.androidterm.util.TermSettings;
public class InputEventRecorder extends Recorder.AbstractRecorder { public class InputEventRecorder extends Recorder.AbstractRecorder {
private static final String TAG = "InputEventRecorder"; private static final String TAG = "InputEventRecorder";
private TermSession mTermSession;
private String mGetEventCommand; private String mGetEventCommand;
private Shell mShell;
protected InputEventConverter mInputEventConverter; protected InputEventConverter mInputEventConverter;
protected InputEventRecorder(InputEventConverter inputEventConverter) { protected InputEventRecorder(InputEventConverter inputEventConverter) {
mGetEventCommand = inputEventConverter.getGetEventCommand(); mGetEventCommand = inputEventConverter.getGetEventCommand();
mInputEventConverter = inputEventConverter; mInputEventConverter = inputEventConverter;
} }
public void listen() { public void listen() {
TermSettings settings = new TermSettings(App.getApp().getResources(), PreferenceManager.getDefaultSharedPreferences(App.getApp())); mShell = new Shell(true);
try { mShell.setCallback(new Shell.Callback() {
mTermSession = new MyShellTermSession(settings, "su"); @Override
mTermSession.initializeEmulator(80, 40); public void onNewLine(String str) {
} catch (IOException e) { if (mShell.isInitialized()) {
throw new RuntimeException(e); convertEvent(str);
}
} }
@Override
public void onInitialized() {
mShell.exec(mGetEventCommand);
}
@Override
public void onInterrupted(InterruptedException e) {
stop();
}
});
} }
@Override @Override
@@ -62,7 +75,7 @@ public class InputEventRecorder extends Recorder.AbstractRecorder {
@Override @Override
protected void stopImpl() { protected void stopImpl() {
mTermSession.finish(); mShell.exit();
mInputEventConverter.stop(); mInputEventConverter.stop();
} }
@@ -75,70 +88,4 @@ public class InputEventRecorder extends Recorder.AbstractRecorder {
mInputEventConverter.convertEventIfFormatCorrect(eventStr); mInputEventConverter.convertEventIfFormatCorrect(eventStr);
} }
private class MyShellTermSession extends ShellTermSession {
private volatile boolean mGettingEvents = false;
private BufferedReader mBufferedReader;
private OutputStream mOutputStream;
private Thread mReadingThread;
public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException {
super(settings, initialCommand);
PipedInputStream pipedInputStream = new PipedInputStream(8192);
mBufferedReader = new BufferedReader(new InputStreamReader(pipedInputStream));
mOutputStream = new PipedOutputStream(pipedInputStream);
startReadingThread();
}
private void startReadingThread() {
mReadingThread = new Thread(new Runnable() {
@Override
public void run() {
String line;
try {
while (!Thread.currentThread().isInterrupted()
&& (line = mBufferedReader.readLine()) != null){
onNewLine(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
mReadingThread.start();
}
private void onNewLine(String line) {
Log.d(TAG, line);
if (!mGettingEvents && line.endsWith(" $ su")) {
mTermSession.write(mGetEventCommand + "\r");
mGettingEvents = true;
} else if (mGettingEvents) {
convertEvent(line);
}
}
@Override
protected void processInput(byte[] data, int offset, int count) {
try {
mOutputStream.write(data, offset, count);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void finish() {
super.finish();
mReadingThread.interrupt();
try {
mBufferedReader.close();
mOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }

View File

@@ -1,12 +1,10 @@
package com.stardust.scriptdroid.record.inputevent; package com.stardust.scriptdroid.record.inputevent;
import com.stardust.scriptdroid.Pref;
/** /**
* Created by Stardust on 2017/3/16. * Created by Stardust on 2017/3/16.
*/ */
public class TouchRecorder extends InputEventRecorder implements KeyObserver.KeyListener { public class TouchRecorder extends InputEventRecorder {
public TouchRecorder() { public TouchRecorder() {
super(new InputEventToSendEventJsConverter()); super(new InputEventToSendEventJsConverter());
@@ -19,14 +17,4 @@ public class TouchRecorder extends InputEventRecorder implements KeyObserver.Key
super.stop(); super.stop();
} }
@Override
public void onKeyDown(String keyName) {
}
@Override
public void onKeyUp(String keyName) {
}
} }

View File

@@ -0,0 +1,140 @@
package com.stardust.scriptdroid.statics;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite;
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery;
import com.pushtorefresh.storio.sqlite.queries.Query;
import com.stardust.autojs.script.ScriptSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Stardust on 2017/5/5.
*/
public class SQLiteStaticsStorage implements ScriptStaticsStorage {
private static final int VERSION = 1;
private static final String DATABASE_NAME = "Ever.db";
static final String TABLE_NAME = "FinalEating";
private StorIOSQLite mStorIOSQLite;
public SQLiteStaticsStorage(Context context) {
mStorIOSQLite = DefaultStorIOSQLite.builder()
.sqliteOpenHelper(new SQLiteOpenHelper(context))
.addTypeMapping(ScriptStaticsRecord.class, new ScriptStaticsRecordSQLiteTypeMapping())
.build();
}
@Override
public void record(ScriptSource source) {
int times = getTimes(source) + 1;
mStorIOSQLite.put()
.object(new ScriptStaticsRecord(source.toString(), times))
.prepare()
.executeAsBlocking();
}
public int getTimes(ScriptSource source) {
ScriptStaticsRecord record = mStorIOSQLite.get()
.object(ScriptStaticsRecord.class)
.withQuery(Query.builder()
.table(TABLE_NAME)
.where("name = ?")
.whereArgs(source.toString())
.build())
.prepare()
.executeAsBlocking();
if (record != null) {
return record.times;
} else {
return 0;
}
}
@Override
public Map<String, String> getAll() {
List<ScriptStaticsRecord> records = mStorIOSQLite.get()
.listOfObjects(ScriptStaticsRecord.class)
.withQuery(Query.builder()
.table(TABLE_NAME)
.orderBy("times")
.build())
.prepare()
.executeAsBlocking();
return toMap(records);
}
private Map<String, String> toMap(List<ScriptStaticsRecord> records) {
Map<String, String> map = new HashMap<>();
for (ScriptStaticsRecord record : records) {
map.put(record.name, String.valueOf(record.times));
}
return map;
}
@Override
public Map<String, String> getMax(int size) {
List<ScriptStaticsRecord> records = mStorIOSQLite.get()
.listOfObjects(ScriptStaticsRecord.class)
.withQuery(Query.builder()
.table(TABLE_NAME)
.orderBy("times DESC")
.limit(size)
.build())
.prepare()
.executeAsBlocking();
return toMap(records);
}
@Override
public void clear() {
mStorIOSQLite.delete()
.byQuery(DeleteQuery.builder()
.table(TABLE_NAME)
.build())
.prepare()
.executeAsBlocking();
}
@Override
public void close() {
try {
mStorIOSQLite.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static class SQLiteOpenHelper extends android.database.sqlite.SQLiteOpenHelper {
SQLiteOpenHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(\n"
+ "name TEXT NOT NULL PRIMARY KEY, "
+ "times INTEGER"
+ ");");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}

View File

@@ -0,0 +1,49 @@
package com.stardust.scriptdroid.statics;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.format.DateUtils;
import com.flurry.android.FlurryAgent;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.scriptdroid.BuildConfig;
/**
* Created by Stardust on 2017/5/5.
*/
public class ScriptStatics {
private static final String KEY_MILLIS = "Sorry, I should have left";
private static ScriptStaticsStorage storage;
private static SharedPreferences preferences;
public static void init(Context context) {
storage = new SQLiteStaticsStorage(context);
new FlurryAgent.Builder()
.withLogEnabled(BuildConfig.DEBUG)
.build(context, "D42MH48ZN4PJC5TKNYZD");
preferences = PreferenceManager.getDefaultSharedPreferences(context);
}
public static void recordScript(ScriptSource source) {
storage.record(source);
sendStaticsIfNeeded();
}
private static void sendStaticsIfNeeded() {
long millis = preferences.getLong(KEY_MILLIS, 0);
if (!DateUtils.isToday(millis)) {
preferences.edit().putLong(KEY_MILLIS, System.currentTimeMillis()).apply();
FlurryAgent.logEvent("ScriptStatics", storage.getMax(10));
}
}
@Override
protected void finalize() throws Throwable {
super.finalize();
storage.close();
}
}

View File

@@ -0,0 +1,28 @@
package com.stardust.scriptdroid.statics;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteCreator;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
/**
* Created by Stardust on 2017/5/5.
*/
@StorIOSQLiteType(table = SQLiteStaticsStorage.TABLE_NAME)
public class ScriptStaticsRecord {
@StorIOSQLiteColumn(name = "name", key = true)
public String name;
@StorIOSQLiteColumn(name = "times")
public int times;
public ScriptStaticsRecord(String name, int times) {
this.name = name;
this.times = times;
}
public ScriptStaticsRecord() {
}
}

View File

@@ -0,0 +1,22 @@
package com.stardust.scriptdroid.statics;
import com.stardust.autojs.script.ScriptSource;
import java.util.Map;
/**
* Created by Stardust on 2017/5/5.
*/
public interface ScriptStaticsStorage {
void record(ScriptSource source);
Map<String, String> getAll();
Map<String, String> getMax(int size);
void clear();
void close();
}