Clean up SensorManager code.

check for sensor channel when the sensor state is NONE.
This commit is contained in:
Jimmy Shih
2012-05-26 13:33:23 -07:00
parent d4b985cf5b
commit d4db27b092
5 changed files with 79 additions and 82 deletions
@@ -724,7 +724,7 @@ public class TrackRecordingService extends Service {
boolean hasSensorData = sensorManager != null boolean hasSensorData = sensorManager != null
&& sensorManager.isEnabled() && sensorManager.isEnabled()
&& sensorManager.getSensorDataSet() != null && sensorManager.getSensorDataSet() != null
&& sensorManager.isDataValid(); && sensorManager.isSensorDataSetValid();
// If the user has been stationary for two recording just record the first // If the user has been stationary for two recording just record the first
// two and ignore the rest. This code will only have an effect if the // two and ignore the rest. This code will only have an effect if the
@@ -823,7 +823,7 @@ public class TrackRecordingService extends Service {
Location locationToInsert = location; Location locationToInsert = location;
if (sensorManager != null && sensorManager.isEnabled()) { if (sensorManager != null && sensorManager.isEnabled()) {
SensorDataSet sd = sensorManager.getSensorDataSet(); SensorDataSet sd = sensorManager.getSensorDataSet();
if (sd != null && sensorManager.isDataValid()) { if (sd != null && sensorManager.isSensorDataSetValid()) {
locationToInsert = new MyTracksLocation(location, sd); locationToInsert = new MyTracksLocation(location, sd);
} }
} }
@@ -19,6 +19,8 @@ import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.content.Sensor.SensorState;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
@@ -118,11 +120,13 @@ public class BluetoothSensorManager extends SensorManager {
return adapters.get(0); return adapters.get(0);
} }
@Override
public boolean isEnabled() { public boolean isEnabled() {
return bluetoothAdapter != null && bluetoothAdapter.isEnabled(); return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
} }
public void setupChannel() { @Override
protected void setUpChannel() {
if (!isEnabled() || connectionManager == null) { if (!isEnabled() || connectionManager == null) {
Log.w(Constants.TAG, "Disabled manager onStartTrack"); Log.w(Constants.TAG, "Disabled manager onStartTrack");
return; return;
@@ -158,21 +162,22 @@ public class BluetoothSensorManager extends SensorManager {
} }
} }
public void onDestroy() { @Override
protected void tearDownChannel() {
// Stop the Bluetooth sensor services // Stop the Bluetooth sensor services
if (connectionManager != null) { if (connectionManager != null) {
connectionManager.stop(); connectionManager.stop();
} }
} }
public Sensor.SensorDataSet getSensorDataSet() { @Override
public SensorDataSet getSensorDataSet() {
return sensorDataSet; return sensorDataSet;
} }
public Sensor.SensorState getSensorState() { @Override
return (connectionManager == null) public SensorState getSensorState() {
? Sensor.SensorState.NONE return connectionManager == null ? Sensor.SensorState.NONE : connectionManager.getState();
: connectionManager.getState();
} }
// The Handler that gets information back from the BluetoothSensorService // The Handler that gets information back from the BluetoothSensorService
@@ -13,126 +13,118 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.google.android.apps.mytracks.services.sensors; package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.content.Sensor.SensorState;
import android.util.Log;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import android.util.Log;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.Sensor;
/** /**
* Manage the connection to a sensor. * Manage the connection to a sensor.
* *
* @author Sandor Dornbush * @author Sandor Dornbush
*/ */
public abstract class SensorManager { public abstract class SensorManager {
/** private static final String TAG = SensorManager.class.getSimpleName();
* The maximum age where the data is considered valid. private static final long MAX_SENSOR_DATE_SET_AGE = 5000;
*/ private static final long MAX_SENSOR_STATE_AGE = 30000;
public static final long MAX_AGE = 5000; private static final int RETRY_PERIOD = 30000;
private SensorState sensorState = SensorState.NONE;
private long sensorStateTimestamp = System.currentTimeMillis();
/** /**
* Time to wait after a time out to retry. * A time task to check sensor connection.
*/ */
public static final int RETRY_PERIOD = 30000; private TimerTask checkSensorConnectionTimeTask = new TimerTask() {
@Override
private Sensor.SensorState sensorState = Sensor.SensorState.NONE;
private long sensorStateTimestamp = 0;
/**
* A task to run periodically to check to see if connection was lost.
*/
private TimerTask checkSensorManager = new TimerTask() {
@Override
public void run() { public void run() {
Log.i(Constants.TAG,
"SensorManager state: " + getSensorState());
switch (getSensorState()) { switch (getSensorState()) {
case CONNECTING: case CONNECTING:
long age = System.currentTimeMillis() - getSensorStateTimestamp(); if (System.currentTimeMillis() - sensorStateTimestamp > MAX_SENSOR_STATE_AGE) {
if (age > 2 * RETRY_PERIOD) { Log.i(TAG, "Retry setUpChannel");
Log.i(Constants.TAG, "Retrying connecting SensorManager."); setUpChannel();
setupChannel();
} }
break; break;
case NONE:
case DISCONNECTED: case DISCONNECTED:
Log.i(Constants.TAG, setUpChannel();
"Re-registering disconnected SensoManager."); break;
setupChannel(); default:
break; break;
} }
} }
}; };
/**
* This timer invokes periodically the checkLocationListener timer task.
*/
private final Timer timer = new Timer(); private final Timer timer = new Timer();
/** /**
* Is the sensor that this manages enabled. * Returns true if the sensor is enabled.
* @return true if the sensor is enabled
*/ */
public abstract boolean isEnabled(); public abstract boolean isEnabled();
/** /**
* This is called when my tracks starts recording a new track. * Sets up the sensor channel.
* This is the place to open connections to the sensor.
*/ */
public void onStartTrack() { protected abstract void setUpChannel();
setupChannel();
timer.schedule(checkSensorManager, RETRY_PERIOD, RETRY_PERIOD); /**
* Tears down the sensor channel.
*/
protected abstract void tearDownChannel();
/**
* Gets the sensor data set.
*/
public abstract SensorDataSet getSensorDataSet();
/**
* Starts the sensor.
*/
public void startSensor() {
setUpChannel();
timer.schedule(checkSensorConnectionTimeTask, RETRY_PERIOD, RETRY_PERIOD);
} }
/** /**
* This method is used to set up any necessary connections to underlying * Stops the sensor.
* sensor hardware.
*/ */
protected abstract void setupChannel(); public void stopSensor() {
public void shutdown() {
timer.cancel(); timer.cancel();
onDestroy(); tearDownChannel();
} }
/** /**
* This is called when my tracks stops recording. * Sets the sensor state.
* This is the place to shutdown any open connections. *
* @param sensorState the sensor state
*/ */
public abstract void onDestroy(); public void setSensorState(SensorState sensorState) {
sensorStateTimestamp = System.currentTimeMillis();
/**
* Return the last sensor reading.
* @return The last reading from the sensor.
*/
public abstract Sensor.SensorDataSet getSensorDataSet();
public void setSensorState(Sensor.SensorState sensorState) {
this.sensorState = sensorState; this.sensorState = sensorState;
} }
/** /**
* Return the current sensor state. * Gets the sensor state.
* @return The current sensor state.
*/ */
public Sensor.SensorState getSensorState() { public SensorState getSensorState() {
return sensorState; return sensorState;
} }
public long getSensorStateTimestamp() {
return sensorStateTimestamp;
}
/** /**
* @return True if the data is recent enough to be considered valid. * Returns true if the sensor data set is valid.
*/ */
public boolean isDataValid() { public boolean isSensorDataSetValid() {
return (System.currentTimeMillis() - getSensorDataSet().getCreationTime()) < MAX_AGE; SensorDataSet sensorDataSet = getSensorDataSet();
if (sensorDataSet == null) {
return false;
}
return (System.currentTimeMillis() - sensorDataSet.getCreationTime()) < MAX_SENSOR_DATE_SET_AGE;
} }
} }
@@ -84,7 +84,7 @@ public class SensorManagerFactory {
} }
activeSensorType = sensorType; activeSensorType = sensorType;
refCount = 1; refCount = 1;
activeSensorManager.onStartTrack(); activeSensorManager.startSensor();
return activeSensorManager; return activeSensorManager;
} }
@@ -105,7 +105,7 @@ public class SensorManagerFactory {
private void reset() { private void reset() {
activeSensorType = null; activeSensorType = null;
if (activeSensorManager != null) { if (activeSensorManager != null) {
activeSensorManager.shutdown(); activeSensorManager.stopSensor();
} }
activeSensorManager = null; activeSensorManager = null;
refCount = 0; refCount = 0;
@@ -133,7 +133,7 @@ public abstract class AntSensorManager extends SensorManager {
} }
@Override @Override
public void onDestroy() { protected void tearDownChannel() {
Log.i(TAG, "destroying AntSensorManager"); Log.i(TAG, "destroying AntSensorManager");
cleanAntInterface(); cleanAntInterface();
@@ -161,7 +161,7 @@ public abstract class AntSensorManager extends SensorManager {
* {@link #setupAntSensorChannels}. * {@link #setupAntSensorChannels}.
*/ */
@Override @Override
protected final void setupChannel() { protected void setUpChannel() {
setup(); setup();
} }