diff --git a/.travis.yml b/.travis.yml
index c65a9c3..6d11e4c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,11 +3,11 @@ language: android
jdk: oraclejdk8
before_install:
- - wget http://services.gradle.org/distributions/gradle-2.14.1-bin.zip
- - unzip gradle-2.14.1-bin.zip
- - export GRADLE_HOME=$PWD/gradle-2.14.1
+ - wget http://services.gradle.org/distributions/gradle-3.3-bin.zip
+ - unzip gradle-3.3-bin.zip
+ - export GRADLE_HOME=$PWD/gradle-3.3
- export PATH=$GRADLE_HOME/bin:$PATH
- - ( sleep 5 && while [ 1 ]; do sleep 1; echo y; done ) | android update sdk -a --no-ui --filter tool,platform-tool,build-tools-25.0.0
+ - ( sleep 5 && while [ 1 ]; do sleep 1; echo y; done ) | android update sdk -a --no-ui --filter tool,platform-tool,build-tools-25.0.2
script:
- gradle assembleDebug
diff --git a/build.gradle b/build.gradle
index e6359b3..6475517 100755
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.3'
+ classpath 'com.android.tools.build:gradle:2.3.1'
}
}
@@ -45,21 +45,21 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// testCompile 'junit:junit:4.12'
- compile 'com.android.support:appcompat-v7:25.1.0'
- compile 'com.android.support:recyclerview-v7:25.1.0'
- compile 'com.android.support:cardview-v7:25.1.0'
- compile 'com.google.android.gms:play-services-location:10.0.1'
- compile 'com.google.android.gms:play-services-maps:10.0.1'
- compile 'com.google.android.gms:play-services-nearby:10.0.1'
- compile 'com.google.android.gms:play-services-places:10.0.1'
- compile 'com.google.android.gms:play-services-awareness:10.0.1'
+ compile 'com.android.support:appcompat-v7:25.3.1'
+ compile 'com.android.support:recyclerview-v7:25.3.1'
+ compile 'com.android.support:cardview-v7:25.3.1'
+ compile 'com.google.android.gms:play-services-location:10.2.4'
+ compile 'com.google.android.gms:play-services-maps:10.2.4'
+ compile 'com.google.android.gms:play-services-nearby:10.2.4'
+ compile 'com.google.android.gms:play-services-places:10.2.4'
+ compile 'com.google.android.gms:play-services-awareness:10.2.4'
compile 'com.google.maps.android:android-maps-utils:0.4'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'commons-io:commons-io:2.4'
compile 'commons-codec:commons-codec:1.10'
compile 'org.apache.commons:commons-lang3:3.4'
compile 'com.fasterxml.jackson.core:jackson-core:2.7.3'
- compile 'com.github.philjay:mpandroidchart:v3.0.0'
+ compile 'com.github.philjay:mpandroidchart:v3.0.1'
}
buildTypes {
diff --git a/res/values/databases.xml b/res/values/databases.xml
index a6d7f01..672f1cd 100755
--- a/res/values/databases.xml
+++ b/res/values/databases.xml
@@ -12,4 +12,8 @@
CREATE TABLE history(_id INTEGER PRIMARY KEY AUTOINCREMENT, fetched INTEGER, transmitted INTEGER, observed INTEGER, direction TEXT, length INTEGER, body TEXT, number_name TEXT, number TEXT);
+
+
+ CREATE TABLE history(_id INTEGER PRIMARY KEY AUTOINCREMENT, fetched INTEGER, transmitted INTEGER, observed INTEGER, event_name TEXT, event_details TEXT);
+
\ No newline at end of file
diff --git a/src/com/audacious_software/passive_data_kit/Logger.java b/src/com/audacious_software/passive_data_kit/Logger.java
index b315574..9ea620e 100755
--- a/src/com/audacious_software/passive_data_kit/Logger.java
+++ b/src/com/audacious_software/passive_data_kit/Logger.java
@@ -2,7 +2,10 @@
import android.content.Context;
+import com.audacious_software.passive_data_kit.generators.diagnostics.AppEvent;
+
import java.util.HashMap;
+import java.util.Map;
/**
* Created by cjkarr on 4/3/2016.
@@ -10,8 +13,12 @@
public class Logger {
private Context mContext = null;
- public void log(String event, HashMap details) {
- // TODO
+ public void log(String event, Map details) {
+ if (details == null) {
+ details = new HashMap<>();
+ }
+
+ AppEvent.getInstance(this.mContext).logEvent(event, details);
}
private static class LoggerHolder {
diff --git a/src/com/audacious_software/passive_data_kit/activities/DataStreamActivity.java b/src/com/audacious_software/passive_data_kit/activities/DataStreamActivity.java
index 8815505..3e80bb0 100755
--- a/src/com/audacious_software/passive_data_kit/activities/DataStreamActivity.java
+++ b/src/com/audacious_software/passive_data_kit/activities/DataStreamActivity.java
@@ -58,7 +58,7 @@ protected void onPause() {
}
@Override
- public void onGeneratorUpdated(String identifier, Bundle data) {
+ public void onGeneratorUpdated(String identifier, long timestamp, Bundle data) {
final DataStreamActivity me = this;
this.runOnUiThread(new Runnable() {
diff --git a/src/com/audacious_software/passive_data_kit/generators/Generator.java b/src/com/audacious_software/passive_data_kit/generators/Generator.java
index 4adc72e..66563c0 100755
--- a/src/com/audacious_software/passive_data_kit/generators/Generator.java
+++ b/src/com/audacious_software/passive_data_kit/generators/Generator.java
@@ -3,6 +3,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -120,6 +121,12 @@ public static String formatTimestamp(Context context, double timestamp) {
public abstract List fetchPayloads();
+ public Cursor queryHistory(String[] cols, String where, String[] args, String orderBy) {
+ Cursor c = new MatrixCursor(cols);
+
+ return c;
+ }
+
protected int getDatabaseVersion(SQLiteDatabase db) {
String where = "type = ? AND name = ?";
String[] args = { "table", Generator.TABLE_METADATA };
diff --git a/src/com/audacious_software/passive_data_kit/generators/Generators.java b/src/com/audacious_software/passive_data_kit/generators/Generators.java
index ddac98b..384e0f1 100755
--- a/src/com/audacious_software/passive_data_kit/generators/Generators.java
+++ b/src/com/audacious_software/passive_data_kit/generators/Generators.java
@@ -11,6 +11,7 @@
import com.audacious_software.passive_data_kit.Logger;
import com.audacious_software.passive_data_kit.diagnostics.DiagnosticAction;
+import com.audacious_software.passive_data_kit.generators.diagnostics.AppEvent;
import com.audacious_software.pdk.passivedatakit.R;
import java.lang.reflect.InvocationTargetException;
@@ -37,6 +38,8 @@ public void start() {
{
this.mGenerators.clear();
+ this.mGenerators.add(AppEvent.class.getCanonicalName());
+
for (String className : this.mContext.getResources().getStringArray(R.array.pdk_available_generators))
{
this.mGenerators.add(className);
@@ -238,9 +241,19 @@ public List> activeGenerators() {
return active;
}
- public void notifyGeneratorUpdated(String identifier, Bundle bundle) {
+ public void notifyGeneratorUpdated(String identifier, long timestamp, Bundle bundle) {
for (GeneratorUpdatedListener listener : this.mGeneratorUpdatedListeners) {
- listener.onGeneratorUpdated(identifier, bundle);
+ listener.onGeneratorUpdated(identifier, timestamp, bundle);
+ }
+ }
+
+ public void notifyGeneratorUpdated(String identifier, Bundle bundle) {
+ long timestamp = System.currentTimeMillis();
+
+ synchronized(this.mGeneratorUpdatedListeners) {
+ for (GeneratorUpdatedListener listener : this.mGeneratorUpdatedListeners) {
+ listener.onGeneratorUpdated(identifier, timestamp, bundle);
+ }
}
}
@@ -262,14 +275,18 @@ private void setContext(Context context) {
}
public void addNewGeneratorUpdatedListener(Generators.GeneratorUpdatedListener listener) {
- this.mGeneratorUpdatedListeners.add(listener);
+ synchronized(this.mGeneratorUpdatedListeners) {
+ this.mGeneratorUpdatedListeners.add(listener);
+ }
}
public void removeGeneratorUpdatedListener(Generators.GeneratorUpdatedListener listener) {
- this.mGeneratorUpdatedListeners.remove(listener);
+ synchronized(this.mGeneratorUpdatedListeners) {
+ this.mGeneratorUpdatedListeners.remove(listener);
+ }
}
public interface GeneratorUpdatedListener {
- void onGeneratorUpdated(String identifier, Bundle data);
+ void onGeneratorUpdated(String identifier, long timestamp, Bundle data);
}
}
diff --git a/src/com/audacious_software/passive_data_kit/generators/communication/PhoneCalls.java b/src/com/audacious_software/passive_data_kit/generators/communication/PhoneCalls.java
index f72cbe8..cea19b6 100755
--- a/src/com/audacious_software/passive_data_kit/generators/communication/PhoneCalls.java
+++ b/src/com/audacious_software/passive_data_kit/generators/communication/PhoneCalls.java
@@ -171,130 +171,132 @@ public void run() {
Cursor c = me.mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, where, args, CallLog.Calls.DATE);
- while (c.moveToNext()) {
- ContentValues values = new ContentValues();
- values.put(PhoneCalls.HISTORY_OBSERVED, c.getLong(c.getColumnIndex(CallLog.Calls.DATE)));
- values.put(PhoneCalls.HISTORY_DURATION, c.getLong(c.getColumnIndex(CallLog.Calls.DURATION)));
- values.put(PhoneCalls.HISTORY_NUMBER, c.getLong(c.getColumnIndex(CallLog.Calls.DURATION)));
- values.put(PhoneCalls.HISTORY_IS_NEW, (c.getInt(c.getColumnIndex(CallLog.Calls.NEW)) != 0));
-
- Bundle bundle = new Bundle();
- bundle.putLong(PhoneCalls.CALL_DATE_KEY, c.getLong(c.getColumnIndex(CallLog.Calls.DATE)));
- bundle.putLong(PhoneCalls.CALL_DURATION_KEY, c.getLong(c.getColumnIndex(CallLog.Calls.DURATION)));
- bundle.putString(PhoneCalls.CALL_NUMBER_KEY, c.getString(c.getColumnIndex(CallLog.Calls.NUMBER)));
- bundle.putBoolean(PhoneCalls.CALL_IS_NEW_KEY, (c.getInt(c.getColumnIndex(CallLog.Calls.NEW)) != 0));
-
- int features = 0;
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- features = c.getInt(c.getColumnIndex(CallLog.Calls.FEATURES));
- }
+ if (c != null) {
+ while (c.moveToNext()) {
+ ContentValues values = new ContentValues();
+ values.put(PhoneCalls.HISTORY_OBSERVED, c.getLong(c.getColumnIndex(CallLog.Calls.DATE)));
+ values.put(PhoneCalls.HISTORY_DURATION, c.getLong(c.getColumnIndex(CallLog.Calls.DURATION)));
+ values.put(PhoneCalls.HISTORY_NUMBER, c.getLong(c.getColumnIndex(CallLog.Calls.DURATION)));
+ values.put(PhoneCalls.HISTORY_IS_NEW, (c.getInt(c.getColumnIndex(CallLog.Calls.NEW)) != 0));
+
+ Bundle bundle = new Bundle();
+ bundle.putLong(PhoneCalls.CALL_DATE_KEY, c.getLong(c.getColumnIndex(CallLog.Calls.DATE)));
+ bundle.putLong(PhoneCalls.CALL_DURATION_KEY, c.getLong(c.getColumnIndex(CallLog.Calls.DURATION)));
+ bundle.putString(PhoneCalls.CALL_NUMBER_KEY, c.getString(c.getColumnIndex(CallLog.Calls.NUMBER)));
+ bundle.putBoolean(PhoneCalls.CALL_IS_NEW_KEY, (c.getInt(c.getColumnIndex(CallLog.Calls.NEW)) != 0));
+
+ int features = 0;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ features = c.getInt(c.getColumnIndex(CallLog.Calls.FEATURES));
+ }
- int typeInt = c.getInt(c.getColumnIndex(CallLog.Calls.TYPE));
- String type = PhoneCalls.CALL_TYPE_UNKNOWN;
+ int typeInt = c.getInt(c.getColumnIndex(CallLog.Calls.TYPE));
+ String type = PhoneCalls.CALL_TYPE_UNKNOWN;
+
+ switch (Build.VERSION.SDK_INT) {
+ case 25:
+ if (typeInt == CallLog.Calls.ANSWERED_EXTERNALLY_TYPE) {
+ type = PhoneCalls.CALL_TYPE_ANSWERED_EXTERNALLY;
+ }
+
+ bundle.putBoolean(PhoneCalls.CALL_PULLED_EXTERNALLY_KEY, ((features & CallLog.Calls.FEATURES_PULLED_EXTERNALLY) == CallLog.Calls.FEATURES_PULLED_EXTERNALLY));
+
+ values.put(PhoneCalls.HISTORY_PULLED_EXTERNALLY, ((features & CallLog.Calls.FEATURES_PULLED_EXTERNALLY) == CallLog.Calls.FEATURES_PULLED_EXTERNALLY));
+ case 24:
+ if (typeInt == CallLog.Calls.REJECTED_TYPE) {
+ type = PhoneCalls.CALL_TYPE_REJECTED;
+ } else if (typeInt == CallLog.Calls.BLOCKED_TYPE) {
+ type = PhoneCalls.CALL_TYPE_BLOCKED;
+ }
+
+ bundle.putString(PhoneCalls.CALL_POST_DIAL_DIGITS_KEY, c.getString(c.getColumnIndex(CallLog.Calls.POST_DIAL_DIGITS)));
+ bundle.putString(PhoneCalls.CALL_VIA_NUMBER_KEY, c.getString(c.getColumnIndex(CallLog.Calls.VIA_NUMBER)));
+
+ values.put(PhoneCalls.HISTORY_POST_DIAL_DIGITS, c.getString(c.getColumnIndex(CallLog.Calls.POST_DIAL_DIGITS)));
+ values.put(PhoneCalls.HISTORY_VIA_NUMBER, c.getString(c.getColumnIndex(CallLog.Calls.VIA_NUMBER)));
+ case 21:
+ if (typeInt == CallLog.Calls.VOICEMAIL_TYPE) {
+ type = PhoneCalls.CALL_TYPE_VOICEMAIL;
+ }
+
+ bundle.putString(PhoneCalls.CALL_COUNTRY_ISO_KEY, c.getString(c.getColumnIndex(CallLog.Calls.COUNTRY_ISO)));
+ bundle.putLong(PhoneCalls.CALL_DATA_USAGE_KEY, c.getLong(c.getColumnIndex(CallLog.Calls.DATA_USAGE)));
+ bundle.putString(PhoneCalls.CALL_GEOCODED_LOCATION_KEY, c.getString(c.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)));
+ bundle.putBoolean(PhoneCalls.CALL_VIDEO_KEY, ((features & CallLog.Calls.FEATURES_VIDEO) == CallLog.Calls.FEATURES_VIDEO));
+
+ values.put(PhoneCalls.HISTORY_COUNTRY_ISO, c.getString(c.getColumnIndex(CallLog.Calls.COUNTRY_ISO)));
+ values.put(PhoneCalls.HISTORY_DATA_USAGE, c.getLong(c.getColumnIndex(CallLog.Calls.DATA_USAGE)));
+ values.put(PhoneCalls.HISTORY_GEOCODED_LOCATION, c.getString(c.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)));
+ values.put(PhoneCalls.HISTORY_VIDEO, ((features & CallLog.Calls.FEATURES_VIDEO) == CallLog.Calls.FEATURES_VIDEO));
- switch(Build.VERSION.SDK_INT) {
- case 25:
- if (typeInt == CallLog.Calls.ANSWERED_EXTERNALLY_TYPE) {
- type = PhoneCalls.CALL_TYPE_ANSWERED_EXTERNALLY;
- }
-
- bundle.putBoolean(PhoneCalls.CALL_PULLED_EXTERNALLY_KEY, ((features & CallLog.Calls.FEATURES_PULLED_EXTERNALLY) == CallLog.Calls.FEATURES_PULLED_EXTERNALLY));
+// bundle.putString(PhoneCalls.CALL_TRANSCRIPTION_KEY, c.getString(c.getColumnIndex(CallLog.Calls.TRANSCRIPTION)));
+ case 19:
+ switch (c.getInt(c.getColumnIndex(CallLog.Calls.NUMBER_PRESENTATION))) {
+ case CallLog.Calls.PRESENTATION_ALLOWED:
+ bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_ALLOWED);
+ values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_ALLOWED);
+ break;
+ case CallLog.Calls.PRESENTATION_RESTRICTED:
+ bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_RESTRICTED);
+ values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_RESTRICTED);
+ break;
+ case CallLog.Calls.PRESENTATION_PAYPHONE:
+ bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_PAYPHONE);
+ values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_PAYPHONE);
+ break;
+ case CallLog.Calls.PRESENTATION_UNKNOWN:
+ bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_UNKNOWN);
+ values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_UNKNOWN);
+ break;
+ }
+ case 14:
+ bundle.putBoolean(PhoneCalls.CALL_IS_READ_KEY, (c.getInt(c.getColumnIndex(CallLog.Calls.IS_READ)) != 0));
+ values.put(PhoneCalls.HISTORY_IS_READ, (c.getInt(c.getColumnIndex(CallLog.Calls.IS_READ)) != 0));
+ case 1:
+ if (typeInt == CallLog.Calls.INCOMING_TYPE) {
+ type = PhoneCalls.CALL_TYPE_INCOMING;
+ } else if (typeInt == CallLog.Calls.OUTGOING_TYPE) {
+ type = PhoneCalls.CALL_TYPE_OUTGOING;
+ } else if (typeInt == CallLog.Calls.MISSED_TYPE) {
+ type = PhoneCalls.CALL_TYPE_MISSED;
+ }
+ }
- values.put(PhoneCalls.HISTORY_PULLED_EXTERNALLY, ((features & CallLog.Calls.FEATURES_PULLED_EXTERNALLY) == CallLog.Calls.FEATURES_PULLED_EXTERNALLY));
- case 24:
- if (typeInt == CallLog.Calls.REJECTED_TYPE) {
- type = PhoneCalls.CALL_TYPE_REJECTED;
- } else if (typeInt == CallLog.Calls.BLOCKED_TYPE) {
- type = PhoneCalls.CALL_TYPE_BLOCKED;
- }
+ bundle.putString(PhoneCalls.CALL_TYPE_KEY, type);
+ values.put(PhoneCalls.HISTORY_CALL_TYPE, type);
- bundle.putString(PhoneCalls.CALL_POST_DIAL_DIGITS_KEY, c.getString(c.getColumnIndex(CallLog.Calls.POST_DIAL_DIGITS)));
- bundle.putString(PhoneCalls.CALL_VIA_NUMBER_KEY, c.getString(c.getColumnIndex(CallLog.Calls.VIA_NUMBER)));
+ String[] sensitiveFields = {
+ PhoneCalls.CALL_NUMBER_KEY,
+ PhoneCalls.CALL_POST_DIAL_DIGITS_KEY,
+ PhoneCalls.CALL_VIA_NUMBER_KEY,
+ };
- values.put(PhoneCalls.HISTORY_POST_DIAL_DIGITS, c.getString(c.getColumnIndex(CallLog.Calls.POST_DIAL_DIGITS)));
- values.put(PhoneCalls.HISTORY_VIA_NUMBER, c.getString(c.getColumnIndex(CallLog.Calls.VIA_NUMBER)));
- case 21:
- if (typeInt == CallLog.Calls.VOICEMAIL_TYPE) {
- type = PhoneCalls.CALL_TYPE_VOICEMAIL;
+ for (String field : sensitiveFields) {
+ if (bundle.containsKey(field)) {
+ bundle.putString(field, new String(Hex.encodeHex(DigestUtils.sha256(bundle.getString(field)))));
}
+ }
- bundle.putString(PhoneCalls.CALL_COUNTRY_ISO_KEY, c.getString(c.getColumnIndex(CallLog.Calls.COUNTRY_ISO)));
- bundle.putLong(PhoneCalls.CALL_DATA_USAGE_KEY, c.getLong(c.getColumnIndex(CallLog.Calls.DATA_USAGE)));
- bundle.putString(PhoneCalls.CALL_GEOCODED_LOCATION_KEY, c.getString(c.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)));
- bundle.putBoolean(PhoneCalls.CALL_VIDEO_KEY, ((features & CallLog.Calls.FEATURES_VIDEO) == CallLog.Calls.FEATURES_VIDEO));
-
- values.put(PhoneCalls.HISTORY_COUNTRY_ISO, c.getString(c.getColumnIndex(CallLog.Calls.COUNTRY_ISO)));
- values.put(PhoneCalls.HISTORY_DATA_USAGE, c.getLong(c.getColumnIndex(CallLog.Calls.DATA_USAGE)));
- values.put(PhoneCalls.HISTORY_GEOCODED_LOCATION, c.getString(c.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)));
- values.put(PhoneCalls.HISTORY_VIDEO, ((features & CallLog.Calls.FEATURES_VIDEO) == CallLog.Calls.FEATURES_VIDEO));
+ String[] valueSensitiveFields = {
+ PhoneCalls.HISTORY_NUMBER,
+ PhoneCalls.HISTORY_POST_DIAL_DIGITS,
+ PhoneCalls.HISTORY_VIA_NUMBER,
+ };
-// bundle.putString(PhoneCalls.CALL_TRANSCRIPTION_KEY, c.getString(c.getColumnIndex(CallLog.Calls.TRANSCRIPTION)));
- case 19:
- switch (c.getInt(c.getColumnIndex(CallLog.Calls.NUMBER_PRESENTATION))) {
- case CallLog.Calls.PRESENTATION_ALLOWED:
- bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_ALLOWED);
- values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_ALLOWED);
- break;
- case CallLog.Calls.PRESENTATION_RESTRICTED:
- bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_RESTRICTED);
- values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_RESTRICTED);
- break;
- case CallLog.Calls.PRESENTATION_PAYPHONE:
- bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_PAYPHONE);
- values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_PAYPHONE);
- break;
- case CallLog.Calls.PRESENTATION_UNKNOWN:
- bundle.putString(PhoneCalls.CALL_PRESENTATION_KEY, PhoneCalls.CALL_PRESENTATION_UNKNOWN);
- values.put(PhoneCalls.HISTORY_PRESENTATION, PhoneCalls.CALL_PRESENTATION_UNKNOWN);
- break;
+ for (String field : valueSensitiveFields) {
+ if (values.containsKey(field)) {
+ values.put(field, new String(Hex.encodeHex(DigestUtils.sha256(values.getAsString(field)))));
}
- case 14:
- bundle.putBoolean(PhoneCalls.CALL_IS_READ_KEY, (c.getInt(c.getColumnIndex(CallLog.Calls.IS_READ)) != 0));
- values.put(PhoneCalls.HISTORY_IS_READ, (c.getInt(c.getColumnIndex(CallLog.Calls.IS_READ)) != 0));
- case 1:
- if (typeInt == CallLog.Calls.INCOMING_TYPE) {
- type = PhoneCalls.CALL_TYPE_INCOMING;
- } else if (typeInt == CallLog.Calls.OUTGOING_TYPE) {
- type = PhoneCalls.CALL_TYPE_OUTGOING;
- } else if (typeInt == CallLog.Calls.MISSED_TYPE) {
- type = PhoneCalls.CALL_TYPE_MISSED;
- }
- }
-
- bundle.putString(PhoneCalls.CALL_TYPE_KEY, type);
- values.put(PhoneCalls.HISTORY_CALL_TYPE, type);
-
- String[] sensitiveFields = {
- PhoneCalls.CALL_NUMBER_KEY,
- PhoneCalls.CALL_POST_DIAL_DIGITS_KEY,
- PhoneCalls.CALL_VIA_NUMBER_KEY,
- };
-
- for (String field : sensitiveFields) {
- if (bundle.containsKey(field)) {
- bundle.putString(field, new String(Hex.encodeHex(DigestUtils.sha256(bundle.getString(field)))));
}
- }
- String[] valueSensitiveFields = {
- PhoneCalls.HISTORY_NUMBER,
- PhoneCalls.HISTORY_POST_DIAL_DIGITS,
- PhoneCalls.HISTORY_VIA_NUMBER,
- };
+ me.mDatabase.insert(PhoneCalls.TABLE_HISTORY, null, values);
- for (String field : valueSensitiveFields) {
- if (values.containsKey(field)) {
- values.put(field, new String(Hex.encodeHex(DigestUtils.sha256(values.getAsString(field)))));
- }
+ Generators.getInstance(me.mContext).notifyGeneratorUpdated(PhoneCalls.GENERATOR_IDENTIFIER, bundle);
}
- me.mDatabase.insert(PhoneCalls.TABLE_HISTORY, null, values);
-
- Generators.getInstance(me.mContext).notifyGeneratorUpdated(PhoneCalls.GENERATOR_IDENTIFIER, bundle);
+ c.close();
}
-
- c.close();
}
if (me.mHandler != null) {
diff --git a/src/com/audacious_software/passive_data_kit/generators/device/Location.java b/src/com/audacious_software/passive_data_kit/generators/device/Location.java
index b85f6d2..c008de5 100755
--- a/src/com/audacious_software/passive_data_kit/generators/device/Location.java
+++ b/src/com/audacious_software/passive_data_kit/generators/device/Location.java
@@ -10,6 +10,7 @@
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
@@ -119,15 +120,15 @@ public class Location extends Generator implements GoogleApiClient.ConnectionCal
private static int DATABASE_VERSION = 1;
private static final String TABLE_HISTORY = "history";
- private static final String HISTORY_OBSERVED = "observed";
- private static final String HISTORY_LATITUDE = "latitude";
- private static final String HISTORY_LONGITUDE = "longitude";
- private static final String HISTORY_ALTITUDE = "altitude";
- private static final String HISTORY_BEARING = "bearing";
- private static final String HISTORY_SPEED = "speed";
- private static final String HISTORY_PROVIDER = "provider";
- private static final String HISTORY_LOCATION_TIMESTAMP = "location_timestamp";
- private static final String HISTORY_ACCURACY = "accuracy";
+ public static final String HISTORY_OBSERVED = "observed";
+ public static final String HISTORY_LATITUDE = "latitude";
+ public static final String HISTORY_LONGITUDE = "longitude";
+ public static final String HISTORY_ALTITUDE = "altitude";
+ public static final String HISTORY_BEARING = "bearing";
+ public static final String HISTORY_SPEED = "speed";
+ public static final String HISTORY_PROVIDER = "provider";
+ public static final String HISTORY_LOCATION_TIMESTAMP = "location_timestamp";
+ public static final String HISTORY_ACCURACY = "accuracy";
public static Location getInstance(Context context) {
if (Location.sInstance == null) {
@@ -1007,4 +1008,8 @@ public void setUpdateInterval(long interval) {
this.stopGenerator();
this.startGenerator();
}
+
+ public Cursor queryHistory(String[] cols, String where, String[] args, String orderBy) {
+ return this.mDatabase.query(Location.TABLE_HISTORY, cols, where, args, null, null, orderBy);
+ }
}
diff --git a/src/com/audacious_software/passive_data_kit/generators/device/ScreenState.java b/src/com/audacious_software/passive_data_kit/generators/device/ScreenState.java
index 2107447..d8a7432 100755
--- a/src/com/audacious_software/passive_data_kit/generators/device/ScreenState.java
+++ b/src/com/audacious_software/passive_data_kit/generators/device/ScreenState.java
@@ -37,17 +37,18 @@ public class ScreenState extends Generator{
private static final String ENABLED = "com.audacious_software.passive_data_kit.generators.device.ScreenState.ENABLED";
private static final boolean ENABLED_DEFAULT = true;
- private static final String STATE_DOZE = "doze";
- private static final String STATE_DOZE_SUSPEND = "doze_suspend";
- private static final String STATE_ON = "on";
- private static final String STATE_OFF = "off";
- private static final String STATE_UNKNOWN = "unknown";
+ public static final String STATE_DOZE = "doze";
+ public static final String STATE_DOZE_SUSPEND = "doze_suspend";
+ public static final String STATE_ON = "on";
+ public static final String STATE_OFF = "off";
+ public static final String STATE_UNKNOWN = "unknown";
private static final String DATABASE_PATH = "pdk-screen-state.sqlite";
private static final int DATABASE_VERSION = 2;
- private static final String HISTORY_OBSERVED = "observed";
- private static final String HISTORY_STATE = "state";
- private static final String TABLE_HISTORY = "history";
+
+ public static final String HISTORY_OBSERVED = "observed";
+ public static final String HISTORY_STATE = "state";
+ public static final String TABLE_HISTORY = "history";
private static ScreenState sInstance = null;
@@ -439,4 +440,8 @@ public static long latestPointGenerated(Context context) {
return timestamp;
}
+
+ public Cursor queryHistory(String[] cols, String where, String[] args, String orderBy) {
+ return this.mDatabase.query(ScreenState.TABLE_HISTORY, cols, where, args, null, null, orderBy);
+ }
}
diff --git a/src/com/audacious_software/passive_data_kit/generators/diagnostics/AppEvent.java b/src/com/audacious_software/passive_data_kit/generators/diagnostics/AppEvent.java
new file mode 100755
index 0000000..e92d291
--- /dev/null
+++ b/src/com/audacious_software/passive_data_kit/generators/diagnostics/AppEvent.java
@@ -0,0 +1,439 @@
+package com.audacious_software.passive_data_kit.generators.diagnostics;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.audacious_software.passive_data_kit.PassiveDataKit;
+import com.audacious_software.passive_data_kit.activities.generators.DataPointViewHolder;
+import com.audacious_software.passive_data_kit.diagnostics.DiagnosticAction;
+import com.audacious_software.passive_data_kit.generators.Generator;
+import com.audacious_software.passive_data_kit.generators.Generators;
+import com.audacious_software.pdk.passivedatakit.R;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AppEvent extends Generator{
+ private static final String GENERATOR_IDENTIFIER = "pdk-app-event";
+
+ private static final String ENABLED = "com.audacious_software.passive_data_kit.generators.diagnostics.AppEvent.ENABLED";
+ private static final boolean ENABLED_DEFAULT = true;
+
+ private static final String DATABASE_PATH = "pdk-app-event.sqlite";
+ private static final int DATABASE_VERSION = 1;
+
+ public static final String HISTORY_OBSERVED = "observed";
+ public static final String HISTORY_EVENT_NAME = "event_name";
+ public static final String HISTORY_EVENT_DETAILS = "event_details";
+ public static final String TABLE_HISTORY = "history";
+
+ private static AppEvent sInstance = null;
+
+ private SQLiteDatabase mDatabase = null;
+
+ public static AppEvent getInstance(Context context) {
+ if (AppEvent.sInstance == null) {
+ AppEvent.sInstance = new AppEvent(context.getApplicationContext());
+ }
+
+ return AppEvent.sInstance;
+ }
+
+ public AppEvent(Context context) {
+ super(context);
+ }
+
+ public static void start(final Context context) {
+ AppEvent.getInstance(context).startGenerator();
+ }
+
+ private void startGenerator() {
+ final AppEvent me = this;
+
+ Generators.getInstance(this.mContext).registerCustomViewClass(AppEvent.GENERATOR_IDENTIFIER, AppEvent.class);
+
+ File path = PassiveDataKit.getGeneratorsStorage(this.mContext);
+
+ path = new File(path, AppEvent.DATABASE_PATH);
+
+ this.mDatabase = SQLiteDatabase.openOrCreateDatabase(path, null);
+
+ int version = this.getDatabaseVersion(this.mDatabase);
+
+ switch (version) {
+ case 0:
+ this.mDatabase.execSQL(this.mContext.getString(R.string.pdk_generator_app_events_create_history_table));
+ }
+
+ this.setDatabaseVersion(this.mDatabase, AppEvent.DATABASE_VERSION);
+ }
+
+ public static boolean isEnabled(Context context) {
+ SharedPreferences prefs = Generators.getInstance(context).getSharedPreferences(context);
+
+ return prefs.getBoolean(AppEvent.ENABLED, AppEvent.ENABLED_DEFAULT);
+ }
+
+ public static boolean isRunning(Context context) {
+ return (AppEvent.sInstance != null);
+ }
+
+ public static ArrayList diagnostics(Context context) {
+ return new ArrayList<>();
+ }
+
+ public static void bindViewHolder(DataPointViewHolder holder) {
+/* final Context context = holder.itemView.getContext();
+
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+
+ long zeroStart = cal.getTimeInMillis();
+ cal.add(Calendar.DATE, -1);
+
+ LinearLayout zeroTimeline = (LinearLayout) holder.itemView.findViewById(R.id.day_zero_value);
+
+ AppEvents.populateTimeline(context, zeroTimeline, zeroStart);
+
+ long oneStart = cal.getTimeInMillis();
+ cal.add(Calendar.DATE, -1);
+
+ LinearLayout oneTimeline = (LinearLayout) holder.itemView.findViewById(R.id.day_one_value);
+
+ AppEvents.populateTimeline(context, oneTimeline, oneStart);
+
+ long twoStart = cal.getTimeInMillis();
+
+ LinearLayout twoTimeline = (LinearLayout) holder.itemView.findViewById(R.id.day_two_value);
+
+ AppEvents.populateTimeline(context, twoTimeline, twoStart);
+
+ AppEvents generator = AppEvents.getInstance(context);
+
+ Cursor c = generator.mDatabase.query(AppEvents.TABLE_HISTORY, null, null, null, null, null, AppEvents.HISTORY_OBSERVED + " DESC");
+
+ View cardContent = holder.itemView.findViewById(R.id.card_content);
+ View cardEmpty = holder.itemView.findViewById(R.id.card_empty);
+ TextView dateLabel = (TextView) holder.itemView.findViewById(R.id.generator_data_point_date);
+
+ if (c.moveToNext()) {
+ cardContent.setVisibility(View.VISIBLE);
+ cardEmpty.setVisibility(View.GONE);
+
+ long timestamp = c.getLong(c.getColumnIndex(AppEvents.HISTORY_OBSERVED)) / 1000;
+
+ dateLabel.setText(Generator.formatTimestamp(context, timestamp));
+
+ cal = Calendar.getInstance();
+ DateFormat format = android.text.format.DateFormat.getDateFormat(context);
+
+ TextView zeroDayLabel = (TextView) holder.itemView.findViewById(R.id.day_zero_label);
+ zeroDayLabel.setText(format.format(cal.getTime()));
+
+ cal.add(Calendar.DATE, -1);
+
+ TextView oneDayLabel = (TextView) holder.itemView.findViewById(R.id.day_one_label);
+ oneDayLabel.setText(format.format(cal.getTime()));
+
+ cal.add(Calendar.DATE, -1);
+
+ TextView twoDayLabel = (TextView) holder.itemView.findViewById(R.id.day_two_label);
+ twoDayLabel.setText(format.format(cal.getTime()));
+ } else {
+ cardContent.setVisibility(View.GONE);
+ cardEmpty.setVisibility(View.VISIBLE);
+
+ dateLabel.setText(R.string.label_never_pdk);
+ }
+
+ c.close();
+ */
+ }
+
+ /*
+ private static void populateTimeline(Context context, LinearLayout timeline, long start) {
+ timeline.removeAllViews();
+
+ AppEvents generator = AppEvents.getInstance(context);
+
+ long end = start + (24 * 60 * 60 * 1000);
+
+ String where = AppEvents.HISTORY_OBSERVED + " >= ? AND " + AppEvents.HISTORY_OBSERVED + " < ?";
+ String[] args = { "" + start, "" + end };
+
+ Cursor c = generator.mDatabase.query(AppEvents.TABLE_HISTORY, null, where, args, null, null, AppEvents.HISTORY_OBSERVED);
+
+ ArrayList activeStates = new ArrayList<>();
+ ArrayList activeTimestamps = new ArrayList<>();
+
+ while (c.moveToNext()) {
+ long timestamp = c.getLong(c.getColumnIndex(AppEvents.HISTORY_OBSERVED));
+
+ activeTimestamps.add(timestamp);
+
+ String state = c.getString(c.getColumnIndex(AppEvents.HISTORY_STATE));
+ activeStates.add(state);
+ }
+
+ c.close();
+
+ String lastState = AppEvents.STATE_UNKNOWN;
+
+ String lastWhere = AppEvents.HISTORY_OBSERVED + " < ?";
+ String[] lastArgs = { "" + start };
+
+ c = generator.mDatabase.query(AppEvents.TABLE_HISTORY, null, lastWhere, lastArgs, null, null, AppEvents.HISTORY_OBSERVED + " DESC");
+
+ if (c.moveToNext()) {
+ lastState = c.getString(c.getColumnIndex(AppEvents.HISTORY_STATE));
+ }
+
+ if (activeStates.size() > 0) {
+ long firstTimestamp = activeTimestamps.get(0);
+ long firstState = activeTimestamps.get(0);
+
+ View startView = new View(context);
+
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
+ if (AppEvents.STATE_UNKNOWN.equals(lastState)) {
+
+ } else if (AppEvents.STATE_ON.equals(lastState)) {
+ startView.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(lastState)) {
+ startView.setBackgroundColor(0xff263238);
+ } else if (AppEvents.STATE_DOZE.equals(lastState)) {
+ startView.setBackgroundColor(0xff1b5e20);
+ } else if (AppEvents.STATE_DOZE_SUSPEND.equals(lastState)) {
+ startView.setBackgroundColor(0xff1b5e20);
+ }
+ } else {
+ if (AppEvents.STATE_UNKNOWN.equals(lastState)) {
+
+ } else if (AppEvents.STATE_ON.equals(lastState)) {
+ startView.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(lastState)) {
+ startView.setBackgroundColor(0xff263238);
+ }
+ }
+
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, firstTimestamp - start);
+ startView.setLayoutParams(params);
+
+ timeline.addView(startView);
+
+ long now = System.currentTimeMillis();
+
+ if (activeStates.size() == 1) {
+ View v = new View(context);
+
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
+ if (AppEvents.STATE_ON.equals(firstState)) {
+ v.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(firstState)) {
+ v.setBackgroundColor(0xff263238);
+ } else if (AppEvents.STATE_DOZE.equals(firstState)) {
+ v.setBackgroundColor(0xff3f51b5);
+ } else if (AppEvents.STATE_DOZE_SUSPEND.equals(firstState)) {
+ v.setBackgroundColor(0xff3f51b5);
+ }
+ } else {
+ if (AppEvents.STATE_ON.equals(firstState)) {
+ v.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(firstState)) {
+ v.setBackgroundColor(0xff263238);
+ }
+ }
+
+ if (end > System.currentTimeMillis()) {
+ params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, now - firstTimestamp);
+ v.setLayoutParams(params);
+ } else {
+ params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, end - firstTimestamp);
+ v.setLayoutParams(params);
+ }
+
+ timeline.addView(v);
+ } else {
+ for (int i = 1; i < activeStates.size(); i++) {
+ long currentTimestamp = activeTimestamps.get(i);
+
+ long priorTimestamp = activeTimestamps.get(i - 1);
+ String priorState = activeStates.get(i - 1);
+
+ View v = new View(context);
+
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
+ if (AppEvents.STATE_ON.equals(priorState)) {
+ v.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(priorState)) {
+ v.setBackgroundColor(0xff263238);
+ } else if (AppEvents.STATE_DOZE.equals(priorState)) {
+ v.setBackgroundColor(0xff3f51b5);
+ } else if (AppEvents.STATE_DOZE_SUSPEND.equals(priorState)) {
+ v.setBackgroundColor(0xff3f51b5);
+ }
+ } else {
+ if (AppEvents.STATE_ON.equals(priorState)) {
+ v.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(priorState)) {
+ v.setBackgroundColor(0xff263238);
+ }
+ }
+
+ params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, currentTimestamp - priorTimestamp);
+ v.setLayoutParams(params);
+
+ timeline.addView(v);
+ }
+
+ long finalTimestamp = activeTimestamps.get(activeTimestamps.size() - 1);
+ String finalState = activeStates.get(activeStates.size() - 1);
+
+ View v = new View(context);
+
+ if (AppEvents.STATE_ON.equals(finalState)) {
+ v.setBackgroundColor(0xff4CAF50);
+ } else if (AppEvents.STATE_OFF.equals(finalState)) {
+ v.setBackgroundColor(0xff263238);
+ } else if (AppEvents.STATE_DOZE.equals(finalState)) {
+ v.setBackgroundColor(0xff3f51b5);
+ } else if (AppEvents.STATE_DOZE_SUSPEND.equals(finalState)) {
+ v.setBackgroundColor(0xff3f51b5);
+ }
+
+ if (end > now) {
+ params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, now - finalTimestamp);
+ v.setLayoutParams(params);
+ } else {
+ params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, end - finalTimestamp);
+ v.setLayoutParams(params);
+ }
+
+ timeline.addView(v);
+ }
+
+ if (end > now) {
+ View v = new View(context);
+
+ params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, end - now);
+ v.setLayoutParams(params);
+
+ timeline.addView(v);
+ }
+ } else {
+
+ }
+ }
+
+*/
+ public static View fetchView(ViewGroup parent)
+ {
+ return LayoutInflater.from(parent.getContext()).inflate(R.layout.card_generator_generic, parent, false);
+ }
+
+ @Override
+ public List fetchPayloads() {
+ return new ArrayList<>();
+ }
+
+ public static long latestPointGenerated(Context context) {
+ long timestamp = 0;
+
+ AppEvent me = AppEvent.getInstance(context);
+
+ Cursor c = me.mDatabase.query(AppEvent.TABLE_HISTORY, null, null, null, null, null, AppEvent.HISTORY_OBSERVED + " DESC");
+
+ if (c.moveToNext()) {
+ timestamp = c.getLong(c.getColumnIndex(AppEvent.HISTORY_OBSERVED));
+ }
+
+ c.close();
+
+ return timestamp;
+ }
+
+ public Cursor queryHistory(String[] cols, String where, String[] args, String orderBy) {
+ return this.mDatabase.query(AppEvent.TABLE_HISTORY, cols, where, args, null, null, orderBy);
+ }
+
+ public boolean logEvent(String eventName, Map eventDetails) {
+ try {
+ long now = System.currentTimeMillis();
+
+ ContentValues values = new ContentValues();
+ values.put(AppEvent.HISTORY_OBSERVED, now);
+ values.put(AppEvent.HISTORY_EVENT_NAME, eventName);
+
+ Bundle detailsBundle = new Bundle();
+ JSONObject detailsJson = new JSONObject();
+
+ for (String key : eventDetails.keySet()) {
+ Object value = eventDetails.get(key);
+
+ if (value instanceof Double) {
+ Double doubleValue = ((Double) value);
+
+ detailsBundle.putDouble(key, doubleValue);
+ detailsJson.put(key, doubleValue.doubleValue());
+ } else if (value instanceof Float) {
+ Float floatValue = ((Float) value);
+
+ detailsBundle.putDouble(key, floatValue.doubleValue());
+ detailsJson.put(key, floatValue.doubleValue());
+ } else if (value instanceof Long) {
+ Long longValue = ((Long) value);
+
+ detailsBundle.putLong(key, longValue.longValue());
+ detailsJson.put(key, longValue.longValue());
+ } else if (value instanceof Integer) {
+ Integer intValue = ((Integer) value);
+
+ detailsBundle.putLong(key, intValue.longValue());
+ detailsJson.put(key, intValue.longValue());
+ } else if (value instanceof String) {
+ detailsBundle.putString(key, value.toString());
+ detailsJson.put(key, value.toString());
+ } else if (value instanceof Boolean) {
+ detailsBundle.putBoolean(key, ((Boolean) value).booleanValue());
+ detailsJson.put(key, ((Boolean) value).booleanValue());
+ } else {
+ detailsBundle.putString(key, "Unknown Class: " + value.getClass().getCanonicalName());
+ detailsJson.put(key, "Unknown Class: " + value.getClass().getCanonicalName());
+ }
+ }
+
+ values.put(AppEvent.HISTORY_EVENT_DETAILS, detailsJson.toString(2));
+
+ this.mDatabase.insert(AppEvent.TABLE_HISTORY, null, values);
+
+ Bundle update = new Bundle();
+ update.putLong(AppEvent.HISTORY_OBSERVED, now);
+ update.putString(AppEvent.HISTORY_EVENT_NAME, values.getAsString(AppEvent.HISTORY_EVENT_NAME));
+ update.putBundle(AppEvent.HISTORY_EVENT_DETAILS, detailsBundle);
+
+ Generators.getInstance(this.mContext).notifyGeneratorUpdated(AppEvent.GENERATOR_IDENTIFIER, update);
+
+ return true;
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+}
diff --git a/src/com/audacious_software/passive_data_kit/transmitters/HttpTransmitter.java b/src/com/audacious_software/passive_data_kit/transmitters/HttpTransmitter.java
index 863d30e..1d9a2cb 100755
--- a/src/com/audacious_software/passive_data_kit/transmitters/HttpTransmitter.java
+++ b/src/com/audacious_software/passive_data_kit/transmitters/HttpTransmitter.java
@@ -424,10 +424,9 @@ public long transmittedSize() {
}
@Override
- public void onGeneratorUpdated(String identifier, Bundle data) {
+ public void onGeneratorUpdated(String identifier, long timestamp, Bundle data) {
if (data.keySet().size() > 1) { // Only transmit non-empty bundles...
- double now = (double) System.currentTimeMillis();
- now = now / 1000; // Convert to seconds...
+ timestamp = timestamp / 1000; // Convert to seconds...
Generators generators = Generators.getInstance(this.mContext);
@@ -438,7 +437,7 @@ public void onGeneratorUpdated(String identifier, Bundle data) {
}
metadata.putString(Generator.IDENTIFIER, identifier);
- metadata.putDouble(Generator.TIMESTAMP, now);
+ metadata.putDouble(Generator.TIMESTAMP, timestamp);
metadata.putString(Generator.GENERATOR, generators.getGeneratorFullName(identifier));
metadata.putString(Generator.SOURCE, generators.getSource());
metadata.putString(Generator.SOURCE, this.mUserId);