Skip to content

Commit

Permalink
Fixed various crashing bugs related to launching external apps on And…
Browse files Browse the repository at this point in the history
…roid 6.

* Added support for grabbing wake locks in sensor generators.
* Added ability to run Accelerometer in a sampling (as opposed to continuous) mode
  • Loading branch information
audaciouscode committed May 15, 2017
1 parent b0ccf25 commit b092533
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 45 deletions.
1 change: 1 addition & 0 deletions AndroidManifest.xml
Expand Up @@ -6,6 +6,7 @@
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
<application android:allowBackup="true"
Expand Down
3 changes: 3 additions & 0 deletions res/values/diagnostics.xml
Expand Up @@ -22,4 +22,7 @@

<string name="diagnostic_usage_stats_permission_required_title">App Usage Data Permission Required</string>
<string name="diagnostic_usage_stats_permission_required">This app requires access to app usage data from your device\'s settings.</string>

<string name="diagnostic_battery_optimization_exempt_title">Battery Optimization Enabled</string>
<string name="diagnostic_battery_optimization_exempt">This app uses device features that do not function consistently while the app is subject to battery optimizations. Please grant a battery optimization exemption to ensure full and consistent functioning.</string>
</resources>
Expand Up @@ -5,6 +5,7 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.SparseArray;
Expand Down Expand Up @@ -32,6 +33,7 @@ public class Generators {
private HashMap<String, Class<? extends Generator>> mGeneratorMap = new HashMap<>();
private SparseArray<Class<? extends Generator>> mViewTypeMap = new SparseArray<>();
private HashSet<GeneratorUpdatedListener> mGeneratorUpdatedListeners = new HashSet<>();
private HashMap<String, PowerManager.WakeLock> mWakeLocks = new HashMap<>();

public void start() {
if (!this.mStarted)
Expand Down Expand Up @@ -257,6 +259,28 @@ public void notifyGeneratorUpdated(String identifier, Bundle bundle) {
}
}

public void acquireWakeLock(String tag, int lockType) {
this.releaseWakeLock(tag);

PowerManager power = (PowerManager) this.mContext.getSystemService(Context.POWER_SERVICE);

PowerManager.WakeLock lock = power.newWakeLock(lockType, tag);

this.mWakeLocks.put(tag, lock);
}

public void releaseWakeLock(String tag) {
if (this.mWakeLocks.containsKey(tag)) {
PowerManager.WakeLock lock = this.mWakeLocks.get(tag);

if (lock.isHeld()) {
lock.release();
}

this.mWakeLocks.remove(tag);
}
}

private static class GeneratorsHolder {
public static Generators instance = new Generators();
}
Expand Down
Expand Up @@ -180,7 +180,9 @@ public static ArrayList<DiagnosticAction> diagnostics(final Context context) {
actions.add(new DiagnosticAction(context.getString(R.string.diagnostic_usage_stats_permission_required_title), context.getString(R.string.diagnostic_usage_stats_permission_required), new Runnable() {
@Override
public void run() {
context.startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}));
}
Expand Down
Expand Up @@ -3,6 +3,7 @@
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
Expand All @@ -14,8 +15,10 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand Down Expand Up @@ -52,6 +55,15 @@ public class Accelerometer extends SensorGenerator implements SensorEventListene
private static final String ENABLED = "com.audacious_software.passive_data_kit.generators.device.Accelerometer.ENABLED";
private static final boolean ENABLED_DEFAULT = true;

private static final String IGNORE_POWER_MANAGEMENT = "com.audacious_software.passive_data_kit.generators.sensors.Accelerometer.IGNORE_POWER_MANAGEMENT";
private static final boolean IGNORE_POWER_MANAGEMENT_DEFAULT = true;

private static final String REFRESH_INTERVAL = "com.audacious_software.passive_data_kit.generators.sensors.Accelerometer.REFRESH_INTERVAL";
private static final long REFRESH_INTERVAL_DEFAULT = 0;

private static final String REFRESH_DURATION = "com.audacious_software.passive_data_kit.generators.sensors.Accelerometer.REFRESH_DURATION";
private static final long REFRESH_DURATION_DEFAULT = (5 * 60 * 1000);

private static final String DATABASE_PATH = "pdk-sensor-accelerometer.sqlite";
private static final int DATABASE_VERSION = 1;

Expand Down Expand Up @@ -93,6 +105,7 @@ public class Accelerometer extends SensorGenerator implements SensorEventListene
long mBaseTimestamp = 0;

private long mLatestTimestamp = 0;
private Thread mIntervalThread = null;

public static Accelerometer getInstance(Context context) {
if (Accelerometer.sInstance == null) {
Expand All @@ -110,6 +123,39 @@ public static void start(final Context context) {
Accelerometer.getInstance(context).startGenerator();
}

public void setIgnorePowerManagement(boolean ignore) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.mContext);
SharedPreferences.Editor e = prefs.edit();

e.putBoolean(Accelerometer.IGNORE_POWER_MANAGEMENT, ignore);
e.apply();

this.stopGenerator();
this.startGenerator();
}

public void setRefreshInterval(long interval) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.mContext);
SharedPreferences.Editor e = prefs.edit();

e.putLong(Accelerometer.REFRESH_INTERVAL, interval);
e.apply();

this.stopGenerator();
this.startGenerator();
}

public void setRefreshDuration(long duration) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.mContext);
SharedPreferences.Editor e = prefs.edit();

e.putLong(Accelerometer.REFRESH_DURATION, duration);
e.apply();

this.stopGenerator();
this.startGenerator();
}

private void startGenerator() {
final SensorManager sensors = (SensorManager) this.mContext.getSystemService(Context.SENSOR_SERVICE);

Expand Down Expand Up @@ -158,36 +204,95 @@ public void run()
else
sensors.registerListener(me, me.mSensor, SensorManager.SENSOR_DELAY_NORMAL, Accelerometer.sHandler);

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(me.mContext);

final long refreshInterval = prefs.getLong(Accelerometer.REFRESH_INTERVAL, Accelerometer.REFRESH_INTERVAL_DEFAULT);

if (refreshInterval > 0) {
final long refreshDuration = prefs.getLong(Accelerometer.REFRESH_DURATION, Accelerometer.REFRESH_DURATION_DEFAULT);

if (me.mIntervalThread != null) {
me.mIntervalThread.interrupt();
me.mIntervalThread = null;
}

Runnable managerRunnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
Thread.sleep(refreshDuration);

sensors.unregisterListener(me, me.mSensor);

Thread.sleep(refreshInterval - refreshDuration);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
sensors.registerListener(me, me.mSensor, SensorManager.SENSOR_DELAY_NORMAL, 0, Accelerometer.sHandler);
else
sensors.registerListener(me, me.mSensor, SensorManager.SENSOR_DELAY_NORMAL, Accelerometer.sHandler);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};

me.mIntervalThread = new Thread(managerRunnable, "accelerometer-interval");
me.mIntervalThread.start();
}

Looper.loop();
}
};

Thread t = new Thread(r, "accelerometer");
t.start();

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(me.mContext);

if (prefs.getBoolean(Accelerometer.IGNORE_POWER_MANAGEMENT, Accelerometer.IGNORE_POWER_MANAGEMENT_DEFAULT)) {
Generators.getInstance(this.mContext).acquireWakeLock(Accelerometer.IDENTIFIER, PowerManager.PARTIAL_WAKE_LOCK);
} else {
Generators.getInstance(this.mContext).releaseWakeLock(Accelerometer.IDENTIFIER);
}
} else {
if (this.mSensor != null) {
sensors.unregisterListener(this, this.mSensor);
this.stopGenerator();
}
}

if (Accelerometer.sHandler != null) {
Looper loop = Accelerometer.sHandler.getLooper();
loop.quit();
private void stopGenerator() {
final SensorManager sensors = (SensorManager) this.mContext.getSystemService(Context.SENSOR_SERVICE);

Accelerometer.sHandler = null;
}
if (this.mSensor != null) {
if (this.mIntervalThread != null) {
this.mIntervalThread.interrupt();
this.mIntervalThread = null;
}

me.mXValueBuffers = null;
me.mYValueBuffers = null;
me.mZValueBuffers = null;
me.mAccuracyBuffers = null;
me.mRawTimestampBuffers = null;
me.mTimestampBuffers = null;
sensors.unregisterListener(this, this.mSensor);

me.mActiveBuffersIndex = 0;
me.mCurrentBufferIndex = 0;
if (Accelerometer.sHandler != null) {
Looper loop = Accelerometer.sHandler.getLooper();
loop.quit();

this.mSensor = null;
Accelerometer.sHandler = null;
}

this.mXValueBuffers = null;
this.mYValueBuffers = null;
this.mZValueBuffers = null;
this.mAccuracyBuffers = null;
this.mRawTimestampBuffers = null;
this.mTimestampBuffers = null;

this.mActiveBuffersIndex = 0;
this.mCurrentBufferIndex = 0;

this.mSensor = null;
}

Generators.getInstance(this.mContext).releaseWakeLock(Accelerometer.IDENTIFIER);
}

public static boolean isEnabled(Context context) {
Expand All @@ -204,8 +309,30 @@ public static boolean isRunning(Context context) {
return Accelerometer.sInstance.mSensor != null;
}

public static ArrayList<DiagnosticAction> diagnostics(Context context) {
return new ArrayList<>();
public static ArrayList<DiagnosticAction> diagnostics(final Context context) {
ArrayList<DiagnosticAction> actions = new ArrayList<>();

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

if (prefs.getBoolean(Accelerometer.IGNORE_POWER_MANAGEMENT, Accelerometer.IGNORE_POWER_MANAGEMENT_DEFAULT)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PowerManager power = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

if (power.isIgnoringBatteryOptimizations(context.getPackageName()) == false) {
actions.add(new DiagnosticAction(context.getString(R.string.diagnostic_battery_optimization_exempt_title), context.getString(R.string.diagnostic_battery_optimization_exempt), new Runnable() {

@Override
public void run() {
Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}));
}
}
}

return actions;
}

public static void bindViewHolder(final DataPointViewHolder holder) {
Expand Down Expand Up @@ -483,12 +610,9 @@ public String getFormattedValue(float value, AxisBase axis) {

dateLabel.setText(R.string.label_never_pdk);
}

Log.e("PDK", "MAIN DONE: " + (System.currentTimeMillis() - drawStart));
}

public static View fetchView(ViewGroup parent)
{
public static View fetchView(ViewGroup parent) {
return LayoutInflater.from(parent.getContext()).inflate(R.layout.card_generator_sensors_accelerometer, parent, false);
}

Expand Down Expand Up @@ -539,8 +663,6 @@ public void onSensorChanged(SensorEvent sensorEvent) {
}
}

// Log.e("PDK", "ACCEL[" + this.mCurrentBufferIndex + "/" + this.mActiveBuffersIndex + "] = " + sensorEvent.values[0] + " -- " + sensorEvent.values[1] + " -- " + sensorEvent.values[2]);

this.mXValueBuffers[this.mActiveBuffersIndex][this.mCurrentBufferIndex] = sensorEvent.values[0];
this.mYValueBuffers[this.mActiveBuffersIndex][this.mCurrentBufferIndex] = sensorEvent.values[1];
this.mZValueBuffers[this.mActiveBuffersIndex][this.mCurrentBufferIndex] = sensorEvent.values[2];
Expand Down Expand Up @@ -602,7 +724,7 @@ public void run() {
if (now - me.mLastCleanup > me.mCleanupInterval) {
me.mLastCleanup = now;

long start = (now - (2 * 24 * 60 * 60 * 1000)) * 1000 * 1000;
long start = (now - (24 * 60 * 60 * 1000)) * 1000 * 1000;

String where = Accelerometer.HISTORY_OBSERVED + " < ?";
String[] args = { "" + start };
Expand Down

0 comments on commit b092533

Please sign in to comment.