From 68845c9a211d0b097e130f9ff63832fbb320307f Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Fri, 5 May 2017 16:54:25 +0800 Subject: [PATCH] Add statics: --- app/build.gradle | 19 ++- .../statics/SQLiteStaticsStorageTest.java | 97 ++++++++++++ .../java/com/stardust/scriptdroid/App.java | 6 +- .../autojs/ScriptExecutionGlobalListener.java | 3 +- .../stardust/scriptdroid/autojs/Shell.java | 124 ++++++++++++---- .../menu/content/RecordNavigatorContent.java | 8 +- .../inputevent/InputEventConverter.java | 13 +- .../record/inputevent/InputEventRecorder.java | 99 +++---------- .../record/inputevent/TouchRecorder.java | 14 +- .../statics/SQLiteStaticsStorage.java | 140 ++++++++++++++++++ .../scriptdroid/statics/ScriptStatics.java | 49 ++++++ .../statics/ScriptStaticsRecord.java | 28 ++++ .../statics/ScriptStaticsStorage.java | 22 +++ 13 files changed, 488 insertions(+), 134 deletions(-) create mode 100644 app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorage.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/statics/ScriptStatics.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java create mode 100644 app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsStorage.java diff --git a/app/build.gradle b/app/build.gradle index ca3e60eb..eba19a76 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,13 +3,13 @@ def AAVersion = '4.2.0' android { compileSdkVersion 25 - buildToolsVersion "25.0.1" + buildToolsVersion "25.0.2" defaultConfig { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 119 - versionName "2.0.8 Beta" + versionCode 120 + versionName "2.0.9 Beta" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } @@ -49,6 +49,9 @@ android { pickFirst 'org/mozilla/javascript/*.java.orig' pickFirst 'org/mozilla/javascript/tools/resources/*.properties' } + configurations.all { + resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1' + } } repositories { @@ -58,13 +61,16 @@ repositories { } 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' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' - annotationProcessor "org.androidannotations:androidannotations:$AAVersion" - compile "org.androidannotations:androidannotations-api:$AAVersion" - compile 'com.android.support:appcompat-v7:25.1.0' + annotationProcessor 'com.pushtorefresh.storio:sqlite-annotations-processor:1.12.3' + compile 'com.pushtorefresh.storio:sqlite-annotations:1.12.3' + compile 'com.android.support:appcompat-v7:25.3.0' compile 'com.android.support:design:25.1.0' compile 'com.github.hyb1996:MutableTheme:0.2.2' 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.github.hyb1996:EnhancedFloaty:0.15' 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(name: 'libtermexec-release', ext: 'aar') compile(name: 'emulatorview-release', ext: 'aar') diff --git a/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java b/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java new file mode 100644 index 00000000..0c9a9199 --- /dev/null +++ b/app/src/androidTest/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorageTest.java @@ -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() + .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() + .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() + .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() + .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); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index a4b52601..0a9c4650 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -13,6 +13,7 @@ import com.stardust.app.SimpleActivityLifecycleCallbacks; import com.stardust.app.VolumeChangeObserver; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.service.AccessibilityWatchDogService; +import com.stardust.scriptdroid.statics.ScriptStatics; import com.stardust.scriptdroid.tool.CrashHandler; import com.stardust.scriptdroid.tool.JsBeautifierFactory; import com.stardust.scriptdroid.ui.error.ErrorReportActivity; @@ -49,9 +50,7 @@ public class App extends MultiDexApplication { } private void setUpStaticsTool() { - new FlurryAgent.Builder() - .withLogEnabled(true) - .build(this, "D42MH48ZN4PJC5TKNYZD"); + ScriptStatics.init(this); } @@ -91,7 +90,6 @@ public class App extends MultiDexApplication { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { super.onActivityCreated(activity, savedInstanceState); - FlurryAgent.logEvent(activity.getClass().getSimpleName()); } @Override diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java index b8bd5add..842dce30 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/ScriptExecutionGlobalListener.java @@ -5,6 +5,7 @@ import com.stardust.autojs.execution.ScriptExecution; import com.stardust.autojs.execution.ScriptExecutionListener; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.statics.ScriptStatics; /** * Created by Stardust on 2017/5/3. @@ -16,7 +17,7 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener { @Override public void onStart(ScriptExecution execution) { execution.getEngine().setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis()); - FlurryAgent.logEvent("EXEC:" + execution.getSource().toString()); + ScriptStatics.recordScript(execution.getSource()); } @Override diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java b/app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java index 077d0e66..42d5ae65 100644 --- a/app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java +++ b/app/src/main/java/com/stardust/scriptdroid/autojs/Shell.java @@ -7,10 +7,16 @@ import android.util.Log; import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.autojs.runtime.api.AbstractShell; +import com.stardust.lang.ThreadCompat; import com.stardust.pio.UncheckedIOException; import com.stardust.scriptdroid.App; +import java.io.BufferedReader; 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.emulatorview.TermSession; @@ -22,19 +28,23 @@ import jackpal.androidterm.util.TermSettings; public class Shell extends AbstractShell implements AutoCloseable { - public interface OutputListener { - void onNewOutput(String str); + public interface Callback { + void onNewLine(String str); + + void onInitialized(); + + void onInterrupted(InterruptedException e); } private static final String TAG = "Shell"; private TermSession mTermSession; - private RuntimeException mInitException; private final Object mInitLock = new Object(); private final Object mExitLock = new Object(); - private boolean mInitialized = false; - private boolean mWaitingExit = false; - private OutputListener mOutputListener; + private volatile RuntimeException mInitException; + private volatile boolean mInitialized = false; + private volatile boolean mWaitingExit = false; + private Callback mCallback; public Shell() { super(); @@ -69,8 +79,12 @@ public class Shell extends AbstractShell implements AutoCloseable { mTermSession.write(command + "\n"); } - public void setOutputListener(OutputListener outputListener) { - mOutputListener = outputListener; + public void setCallback(Callback callback) { + mCallback = callback; + } + + public boolean isInitialized() { + return mInitialized; } private void ensureInitialized() { @@ -97,12 +111,20 @@ public class Shell extends AbstractShell implements AutoCloseable { try { mInitLock.wait(); } catch (InterruptedException e) { - exit(); - throw new ScriptInterruptedException(); + onInterrupted(e); } } } + private void onInterrupted(InterruptedException e) { + if (mCallback == null) { + exit(); + throw new ScriptInterruptedException(); + } else { + mCallback.onInterrupted(e); + } + } + @Override public void exit() { mTermSession.finish(); @@ -124,8 +146,7 @@ public class Shell extends AbstractShell implements AutoCloseable { try { mExitLock.wait(); } catch (InterruptedException e) { - exit(); - throw new ScriptInterruptedException(); + onInterrupted(e); } } } @@ -137,31 +158,65 @@ public class Shell extends AbstractShell implements AutoCloseable { private class MyShellTermSession extends ShellTermSession { + 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(); } - @Override - protected void processInput(byte[] data, int offset, int count) { - String output = new String(data, offset, count); - Log.d(TAG, output); - if(mOutputListener != null){ - mOutputListener.onNewOutput(output); - } - if (mInitialized && !mWaitingExit) { - return; - } - String[] lines = new String(data, offset, count).split("\n"); - for (String line : lines) { - if (!mInitialized && line.endsWith(" # ")) { + private void startReadingThread() { + mReadingThread = new ThreadCompat(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 (mInitialized) { + if (mCallback != null) { + mCallback.onNewLine(line); + } + } else { + if (isRoot() && line.endsWith(" $ su")) { notifyInitialized(); return; } - if (mWaitingExit && line.endsWith(" $ ")) { - notifyExit(); + if (!isRoot() && line.endsWith(" $ ")) { + notifyInitialized(); 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() { @@ -176,6 +231,9 @@ public class Shell extends AbstractShell implements AutoCloseable { synchronized (mInitLock) { mInitLock.notifyAll(); } + if (mCallback != null) { + mCallback.onInitialized(); + } } @Override @@ -186,6 +244,18 @@ public class Shell extends AbstractShell implements AutoCloseable { mExitLock.notify(); } } + + @Override + public void finish() { + super.finish(); + mReadingThread.interrupt(); + try { + mBufferedReader.close(); + mOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/content/RecordNavigatorContent.java index 7f49ba22..d7405f3c 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/content/RecordNavigatorContent.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/menu/content/RecordNavigatorContent.java @@ -66,7 +66,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat if (Pref.isRecordVolumeControlEnable()) { if (mRecorder == null) { startRecord(); - } else if (mRecorder.getState() == Recorder.STATE_RECORDING) { + } else if (alreadyStartedRecord()) { stopRecord(); } } @@ -211,7 +211,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat @Override public void onKeyDown(String keyName) { if (keyName.equals(Pref.getStopRecordTrigger())) { - if (mRecorder != null && mRecorder.getState() == Recorder.STATE_RECORDING && mRecorder.getState() == Recorder.STATE_PAUSED) + if (alreadyStartedRecord()) stopRecord(); } else if (keyName.equals(Pref.getStartRecordTrigger())) { 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 public void onKeyUp(String keyName) { diff --git a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventConverter.java b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventConverter.java index d7ea85cc..9019bf2d 100644 --- a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventConverter.java +++ b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventConverter.java @@ -9,6 +9,7 @@ import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.record.Recorder; +import com.stardust.util.MapEntries; import org.greenrobot.eventbus.EventBus; @@ -72,9 +73,9 @@ public abstract class InputEventConverter { private int mState = Recorder.STATE_NOT_START; public void convertEventIfFormatCorrect(String eventStr) { - if(!mConverting) + if (!mConverting) return; - if(TextUtils.isEmpty(eventStr) || !eventStr.startsWith("[")) + if (TextUtils.isEmpty(eventStr) || !eventStr.startsWith("[")) return; Event event = parseEventOrNull(eventStr); if (event != null) { @@ -94,7 +95,7 @@ public abstract class InputEventConverter { mState = Recorder.STATE_RECORDING; } - public void resume(){ + public void resume() { mConverting = true; mState = Recorder.STATE_RECORDING; } @@ -118,10 +119,12 @@ public abstract class InputEventConverter { return Event.parseEvent(eventStr); } catch (EventFormatException e) { e.printStackTrace(); - if(mFirstEventFormatError){ + if (mFirstEventFormatError) { Toast.makeText(App.getApp(), R.string.text_record_format_error, Toast.LENGTH_SHORT).show(); mFirstEventFormatError = false; - FlurryAgent.logEvent("EventFormatException:" + e.getMessage()); + FlurryAgent.logEvent("EventFormatException", new MapEntries() + .entry("message", e.getMessage()) + .map()); } return null; } diff --git a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java index 230000b6..62e9c922 100644 --- a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java +++ b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/InputEventRecorder.java @@ -5,6 +5,7 @@ import android.util.Log; import com.stardust.pio.UncheckedIOException; import com.stardust.scriptdroid.App; +import com.stardust.scriptdroid.autojs.Shell; import com.stardust.scriptdroid.record.Recorder; import java.io.BufferedReader; @@ -22,27 +23,39 @@ import jackpal.androidterm.util.TermSettings; * Created by Stardust on 2017/3/6. */ -public class InputEventRecorder extends Recorder.AbstractRecorder { +public class InputEventRecorder extends Recorder.AbstractRecorder { private static final String TAG = "InputEventRecorder"; - private TermSession mTermSession; private String mGetEventCommand; + private Shell mShell; protected InputEventConverter mInputEventConverter; + protected InputEventRecorder(InputEventConverter inputEventConverter) { mGetEventCommand = inputEventConverter.getGetEventCommand(); mInputEventConverter = inputEventConverter; } public void listen() { - TermSettings settings = new TermSettings(App.getApp().getResources(), PreferenceManager.getDefaultSharedPreferences(App.getApp())); - try { - mTermSession = new MyShellTermSession(settings, "su"); - mTermSession.initializeEmulator(80, 40); - } catch (IOException e) { - throw new RuntimeException(e); - } + mShell = new Shell(true); + mShell.setCallback(new Shell.Callback() { + @Override + public void onNewLine(String str) { + if (mShell.isInitialized()) { + convertEvent(str); + } + } + @Override + public void onInitialized() { + mShell.exec(mGetEventCommand); + } + + @Override + public void onInterrupted(InterruptedException e) { + stop(); + } + }); } @Override @@ -62,7 +75,7 @@ public class InputEventRecorder extends Recorder.AbstractRecorder { @Override protected void stopImpl() { - mTermSession.finish(); + mShell.exit(); mInputEventConverter.stop(); } @@ -75,70 +88,4 @@ public class InputEventRecorder extends Recorder.AbstractRecorder { 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(); - } - } - } } diff --git a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/TouchRecorder.java b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/TouchRecorder.java index 3ef34bb5..27d1f427 100644 --- a/app/src/main/java/com/stardust/scriptdroid/record/inputevent/TouchRecorder.java +++ b/app/src/main/java/com/stardust/scriptdroid/record/inputevent/TouchRecorder.java @@ -1,12 +1,10 @@ package com.stardust.scriptdroid.record.inputevent; -import com.stardust.scriptdroid.Pref; - /** * Created by Stardust on 2017/3/16. */ -public class TouchRecorder extends InputEventRecorder implements KeyObserver.KeyListener { +public class TouchRecorder extends InputEventRecorder { public TouchRecorder() { super(new InputEventToSendEventJsConverter()); @@ -19,14 +17,4 @@ public class TouchRecorder extends InputEventRecorder implements KeyObserver.Key super.stop(); } - @Override - public void onKeyDown(String keyName) { - - } - - @Override - public void onKeyUp(String keyName) { - - } - } diff --git a/app/src/main/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorage.java b/app/src/main/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorage.java new file mode 100644 index 00000000..414d56d6 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/statics/SQLiteStaticsStorage.java @@ -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 getAll() { + List records = mStorIOSQLite.get() + .listOfObjects(ScriptStaticsRecord.class) + .withQuery(Query.builder() + .table(TABLE_NAME) + .orderBy("times") + .build()) + .prepare() + .executeAsBlocking(); + return toMap(records); + } + + private Map toMap(List records) { + Map map = new HashMap<>(); + for (ScriptStaticsRecord record : records) { + map.put(record.name, String.valueOf(record.times)); + } + return map; + } + + @Override + public Map getMax(int size) { + List 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) { + + } + } + + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStatics.java b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStatics.java new file mode 100644 index 00000000..59e78189 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStatics.java @@ -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(); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java new file mode 100644 index 00000000..1e682c10 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsRecord.java @@ -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() { + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsStorage.java b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsStorage.java new file mode 100644 index 00000000..99b2d82b --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/statics/ScriptStaticsStorage.java @@ -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 getAll(); + + Map getMax(int size); + + void clear(); + + void close(); +}