forked from upstream-mirrors/OpenTracks
merge heads
This commit is contained in:
@@ -73,18 +73,18 @@ public class SensorStateActivity extends Activity {
|
|||||||
runOnUiThread(stateUpdater);
|
runOnUiThread(stateUpdater);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A temporary sensor manager, when none is available.
|
* A temporary sensor manager, when none is available.
|
||||||
*/
|
*/
|
||||||
private SensorManager tempSensorManager = null;
|
private SensorManager tempSensorManager = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A state flag set to true when the activity is active/visible,
|
* A state flag set to true when the activity is active/visible,
|
||||||
* i.e. after resume, and before pause
|
* i.e. after resume, and before pause
|
||||||
*
|
*
|
||||||
* Used to avoid updating after the pause event, because sometimes an update
|
* Used to avoid updating after the pause event, because sometimes an update
|
||||||
* event occurs even after the timer is cancelled. In this case,
|
* event occurs even after the timer is cancelled. In this case,
|
||||||
* it could cause the {@link #tempSensorManager} to be recreated, after it
|
* it could cause the {@link #tempSensorManager} to be recreated, after it
|
||||||
* is destroyed at the pause event.
|
* is destroyed at the pause event.
|
||||||
@@ -111,7 +111,7 @@ public class SensorStateActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
isVisible = true;
|
isVisible = true;
|
||||||
|
|
||||||
serviceConnection.bindIfRunning();
|
serviceConnection.bindIfRunning();
|
||||||
@@ -123,7 +123,7 @@ public class SensorStateActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
isVisible = false;
|
isVisible = false;
|
||||||
|
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
timer.purge();
|
timer.purge();
|
||||||
timer = null;
|
timer = null;
|
||||||
@@ -139,9 +139,9 @@ public class SensorStateActivity extends Activity {
|
|||||||
|
|
||||||
private void updateState() {
|
private void updateState() {
|
||||||
Log.d(TAG, "Updating SensorStateActivity");
|
Log.d(TAG, "Updating SensorStateActivity");
|
||||||
|
|
||||||
ITrackRecordingService service = serviceConnection.getServiceIfBound();
|
ITrackRecordingService service = serviceConnection.getServiceIfBound();
|
||||||
|
|
||||||
// Check if service is available, and recording.
|
// Check if service is available, and recording.
|
||||||
boolean isRecording = false;
|
boolean isRecording = false;
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
@@ -151,7 +151,7 @@ public class SensorStateActivity extends Activity {
|
|||||||
Log.e(TAG, "Unable to determine if service is recording.", e);
|
Log.e(TAG, "Unable to determine if service is recording.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If either service isn't available, or not recording.
|
// If either service isn't available, or not recording.
|
||||||
if (!isRecording) {
|
if (!isRecording) {
|
||||||
updateFromTempSensorManager();
|
updateFromTempSensorManager();
|
||||||
@@ -159,19 +159,17 @@ public class SensorStateActivity extends Activity {
|
|||||||
updateFromSysSensorManager();
|
updateFromSysSensorManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFromTempSensorManager() {
|
private void updateFromTempSensorManager() {
|
||||||
// Use variables to hold the sensor state and data set.
|
// Use variables to hold the sensor state and data set.
|
||||||
Sensor.SensorState currentState = null;
|
Sensor.SensorState currentState = null;
|
||||||
Sensor.SensorDataSet currentDataSet = null;
|
Sensor.SensorDataSet currentDataSet = null;
|
||||||
|
|
||||||
// If no temp sensor manager is present, create one, and start it.
|
// If no temp sensor manager is present, create one, and start it.
|
||||||
if (tempSensorManager == null) {
|
if (tempSensorManager == null) {
|
||||||
tempSensorManager = SensorManagerFactory.getSensorManager(this);
|
tempSensorManager = SensorManagerFactory.getInstance().getSensorManager(this);
|
||||||
if (tempSensorManager != null)
|
|
||||||
tempSensorManager.onStartTrack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a temp sensor manager is available, use states from temp sensor
|
// If a temp sensor manager is available, use states from temp sensor
|
||||||
// manager.
|
// manager.
|
||||||
if (tempSensorManager != null) {
|
if (tempSensorManager != null) {
|
||||||
@@ -182,15 +180,15 @@ public class SensorStateActivity extends Activity {
|
|||||||
// Update the sensor state, and sensor data, using the variables.
|
// Update the sensor state, and sensor data, using the variables.
|
||||||
updateSensorStateAndData(currentState, currentDataSet);
|
updateSensorStateAndData(currentState, currentDataSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFromSysSensorManager() {
|
private void updateFromSysSensorManager() {
|
||||||
// Use variables to hold the sensor state and data set.
|
// Use variables to hold the sensor state and data set.
|
||||||
Sensor.SensorState currentState = null;
|
Sensor.SensorState currentState = null;
|
||||||
Sensor.SensorDataSet currentDataSet = null;
|
Sensor.SensorDataSet currentDataSet = null;
|
||||||
|
|
||||||
ITrackRecordingService service = serviceConnection.getServiceIfBound();
|
ITrackRecordingService service = serviceConnection.getServiceIfBound();
|
||||||
|
|
||||||
// If a temp sensor manager is present, shut it down,
|
// If a temp sensor manager is present, shut it down,
|
||||||
// probably recording just started.
|
// probably recording just started.
|
||||||
stopTempSensorManager();
|
stopTempSensorManager();
|
||||||
|
|
||||||
@@ -208,7 +206,7 @@ public class SensorStateActivity extends Activity {
|
|||||||
} catch (InvalidProtocolBufferException e) {
|
} catch (InvalidProtocolBufferException e) {
|
||||||
Log.e(TAG, "Could not read sensor data.", e);
|
Log.e(TAG, "Could not read sensor data.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
currentState = Sensor.SensorState.valueOf(service.getSensorState());
|
currentState = Sensor.SensorState.valueOf(service.getSensorState());
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -220,17 +218,17 @@ public class SensorStateActivity extends Activity {
|
|||||||
// Update the sensor state, and sensor data, using the variables.
|
// Update the sensor state, and sensor data, using the variables.
|
||||||
updateSensorStateAndData(currentState, currentDataSet);
|
updateSensorStateAndData(currentState, currentDataSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the temporary sensor manager, if one exists.
|
* Stops the temporary sensor manager, if one exists.
|
||||||
*/
|
*/
|
||||||
private void stopTempSensorManager() {
|
private void stopTempSensorManager() {
|
||||||
if (tempSensorManager != null) {
|
if (tempSensorManager != null) {
|
||||||
tempSensorManager.shutdown();
|
SensorManagerFactory.getInstance().releaseSensorManager(tempSensorManager);
|
||||||
tempSensorManager = null;
|
tempSensorManager = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSensorStateAndData(Sensor.SensorState state, Sensor.SensorDataSet dataSet) {
|
private void updateSensorStateAndData(Sensor.SensorState state, Sensor.SensorDataSet dataSet) {
|
||||||
updateSensorState(state == null ? Sensor.SensorState.NONE : state);
|
updateSensorState(state == null ? Sensor.SensorState.NONE : state);
|
||||||
updateSensorData(dataSet);
|
updateSensorData(dataSet);
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ public class TrackRecordingService extends Service {
|
|||||||
handleStartCommand(intent, startId);
|
handleStartCommand(intent, startId);
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleStartCommand(Intent intent, int startId) {
|
private void handleStartCommand(Intent intent, int startId) {
|
||||||
Log.d(TAG, "TrackRecordingService.handleStartCommand: " + startId);
|
Log.d(TAG, "TrackRecordingService.handleStartCommand: " + startId);
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ public class TrackRecordingService extends Service {
|
|||||||
private boolean isTrackInProgress() {
|
private boolean isTrackInProgress() {
|
||||||
return recordingTrackId != -1 || isRecording;
|
return recordingTrackId != -1 || isRecording;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resumeTrack(int startId) {
|
private void resumeTrack(int startId) {
|
||||||
Log.d(TAG, "TrackRecordingService: requested resume");
|
Log.d(TAG, "TrackRecordingService: requested resume");
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ public class TrackRecordingService extends Service {
|
|||||||
unregisterLocationListener();
|
unregisterLocationListener();
|
||||||
shutdownTaskExecutors();
|
shutdownTaskExecutors();
|
||||||
if (sensorManager != null) {
|
if (sensorManager != null) {
|
||||||
sensorManager.shutdown();
|
SensorManagerFactory.getInstance().releaseSensorManager(sensorManager);
|
||||||
sensorManager = null;
|
sensorManager = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,12 +499,12 @@ public class TrackRecordingService extends Service {
|
|||||||
protected void startForegroundService(Notification notification) {
|
protected void startForegroundService(Notification notification) {
|
||||||
startForeground(1, notification);
|
startForeground(1, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected void stopForegroundService() {
|
protected void stopForegroundService() {
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpTaskExecutors() {
|
private void setUpTaskExecutors() {
|
||||||
announcementExecutor = new PeriodicTaskExecutor(this, new StatusAnnouncerFactory());
|
announcementExecutor = new PeriodicTaskExecutor(this, new StatusAnnouncerFactory());
|
||||||
splitExecutor = new PeriodicTaskExecutor(this, new SplitTask.Factory());
|
splitExecutor = new PeriodicTaskExecutor(this, new SplitTask.Factory());
|
||||||
@@ -559,7 +559,7 @@ public class TrackRecordingService extends Service {
|
|||||||
Log.d(TAG,
|
Log.d(TAG,
|
||||||
"Location listener now unregistered w/ TrackRecordingService.");
|
"Location listener now unregistered w/ TrackRecordingService.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDefaultActivityType(Context context) {
|
private String getDefaultActivityType(Context context) {
|
||||||
SharedPreferences prefs = context.getSharedPreferences(
|
SharedPreferences prefs = context.getSharedPreferences(
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
@@ -601,10 +601,7 @@ public class TrackRecordingService extends Service {
|
|||||||
length = 0;
|
length = 0;
|
||||||
showNotification();
|
showNotification();
|
||||||
registerLocationListener();
|
registerLocationListener();
|
||||||
sensorManager = SensorManagerFactory.getSensorManager(this);
|
sensorManager = SensorManagerFactory.getInstance().getSensorManager(this);
|
||||||
if (sensorManager != null) {
|
|
||||||
sensorManager.onStartTrack();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the number of auto-resume retries.
|
// Reset the number of auto-resume retries.
|
||||||
setAutoResumeTrackRetries(0);
|
setAutoResumeTrackRetries(0);
|
||||||
@@ -1038,7 +1035,7 @@ public class TrackRecordingService extends Service {
|
|||||||
prefManager.setRecordingTrack(recordingTrackId = -1);
|
prefManager.setRecordingTrack(recordingTrackId = -1);
|
||||||
|
|
||||||
if (sensorManager != null) {
|
if (sensorManager != null) {
|
||||||
sensorManager.shutdown();
|
SensorManagerFactory.getInstance().releaseSensorManager(sensorManager);
|
||||||
sensorManager = null;
|
sensorManager = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1056,7 +1053,7 @@ public class TrackRecordingService extends Service {
|
|||||||
.setAction(getString(actionResId))
|
.setAction(getString(actionResId))
|
||||||
.putExtra(getString(R.string.track_id_broadcast_extra), trackId);
|
.putExtra(getString(R.string.track_id_broadcast_extra), trackId);
|
||||||
sendBroadcast(broadcastIntent, getString(R.string.permission_notification_value));
|
sendBroadcast(broadcastIntent, getString(R.string.permission_notification_value));
|
||||||
|
|
||||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
SharedPreferences sharedPreferences = getSharedPreferences(
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
if (sharedPreferences.getBoolean(getString(R.string.allow_access_key), false)) {
|
if (sharedPreferences.getBoolean(getString(R.string.allow_access_key), false)) {
|
||||||
@@ -1202,17 +1199,17 @@ public class TrackRecordingService extends Service {
|
|||||||
throw new IllegalStateException("The service has been already detached!");
|
throw new IllegalStateException("The service has been already detached!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the RPC caller is from the same application or if the
|
* Returns true if the RPC caller is from the same application or if the
|
||||||
* "Allow access" setting indicates that another app can invoke this service's
|
* "Allow access" setting indicates that another app can invoke this service's
|
||||||
* RPCs.
|
* RPCs.
|
||||||
*/
|
*/
|
||||||
private boolean canAccess() {
|
private boolean canAccess() {
|
||||||
|
|
||||||
// As a precondition for access, must check if the service is available.
|
// As a precondition for access, must check if the service is available.
|
||||||
checkService();
|
checkService();
|
||||||
|
|
||||||
if (Process.myPid() == Binder.getCallingPid()) {
|
if (Process.myPid() == Binder.getCallingPid()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -1297,7 +1294,7 @@ public class TrackRecordingService extends Service {
|
|||||||
public int getSensorState() {
|
public int getSensorState() {
|
||||||
if (!canAccess()) {
|
if (!canAccess()) {
|
||||||
return Sensor.SensorState.NONE.getNumber();
|
return Sensor.SensorState.NONE.getNumber();
|
||||||
}
|
}
|
||||||
if (service.sensorManager == null) {
|
if (service.sensorManager == null) {
|
||||||
Log.d(TAG, "No sensor manager for data.");
|
Log.d(TAG, "No sensor manager for data.");
|
||||||
return Sensor.SensorState.NONE.getNumber();
|
return Sensor.SensorState.NONE.getNumber();
|
||||||
|
|||||||
+56
-7
@@ -31,15 +31,28 @@ import android.util.Log;
|
|||||||
*/
|
*/
|
||||||
public class SensorManagerFactory {
|
public class SensorManagerFactory {
|
||||||
|
|
||||||
|
private String activeSensorType;
|
||||||
|
private SensorManager activeSensorManager;
|
||||||
|
private int refCount;
|
||||||
|
|
||||||
|
private static SensorManagerFactory instance = new SensorManagerFactory();
|
||||||
|
|
||||||
private SensorManagerFactory() {
|
private SensorManagerFactory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a new sensor manager.
|
* Get the factory instance.
|
||||||
|
*/
|
||||||
|
public static SensorManagerFactory getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get and start a new sensor manager.
|
||||||
* @param context Context to fetch system preferences.
|
* @param context Context to fetch system preferences.
|
||||||
* @return The sensor manager that corresponds to the sensor type setting.
|
* @return The sensor manager that corresponds to the sensor type setting.
|
||||||
*/
|
*/
|
||||||
public static SensorManager getSensorManager(Context context) {
|
public SensorManager getSensorManager(Context context) {
|
||||||
SharedPreferences prefs = context.getSharedPreferences(
|
SharedPreferences prefs = context.getSharedPreferences(
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
if (prefs == null) {
|
if (prefs == null) {
|
||||||
@@ -52,18 +65,54 @@ public class SensorManagerFactory {
|
|||||||
Log.i(Constants.TAG, "Creating sensor of type: " + sensor);
|
Log.i(Constants.TAG, "Creating sensor of type: " + sensor);
|
||||||
|
|
||||||
if (sensor == null) {
|
if (sensor == null) {
|
||||||
|
reset();
|
||||||
return null;
|
return null;
|
||||||
} else if (sensor.equals(context.getString(R.string.sensor_type_value_ant))) {
|
}
|
||||||
return new AntDirectSensorManager(context);
|
if (sensor.equals(activeSensorType)) {
|
||||||
|
Log.i(Constants.TAG, "Returning existing sensor manager.");
|
||||||
|
refCount++;
|
||||||
|
return activeSensorManager;
|
||||||
|
}
|
||||||
|
reset();
|
||||||
|
|
||||||
|
if (sensor.equals(context.getString(R.string.sensor_type_value_ant))) {
|
||||||
|
activeSensorManager = new AntDirectSensorManager(context);
|
||||||
} else if (sensor.equals(context.getString(R.string.sensor_type_value_srm_ant_bridge))) {
|
} else if (sensor.equals(context.getString(R.string.sensor_type_value_srm_ant_bridge))) {
|
||||||
return new AntSrmBridgeSensorManager(context);
|
activeSensorManager = new AntSrmBridgeSensorManager(context);
|
||||||
} else if (sensor.equals(context.getString(R.string.sensor_type_value_zephyr))) {
|
} else if (sensor.equals(context.getString(R.string.sensor_type_value_zephyr))) {
|
||||||
return new ZephyrSensorManager(context);
|
activeSensorManager = new ZephyrSensorManager(context);
|
||||||
} else if (sensor.equals(context.getString(R.string.sensor_type_value_polar))) {
|
} else if (sensor.equals(context.getString(R.string.sensor_type_value_polar))) {
|
||||||
return new PolarSensorManager(context);
|
activeSensorManager = new PolarSensorManager(context);
|
||||||
} else {
|
} else {
|
||||||
Log.w(Constants.TAG, "Unable to find sensor type: " + sensor);
|
Log.w(Constants.TAG, "Unable to find sensor type: " + sensor);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
activeSensorType = sensor;
|
||||||
|
refCount = 1;
|
||||||
|
activeSensorManager.onStartTrack();
|
||||||
|
return activeSensorManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish using a sensor manager.
|
||||||
|
*/
|
||||||
|
public void releaseSensorManager(SensorManager sensorManager) {
|
||||||
|
Log.i(Constants.TAG, "releaseSensorManager: " + activeSensorType + " " + refCount);
|
||||||
|
if (sensorManager != activeSensorManager) {
|
||||||
|
Log.e(Constants.TAG, "invalid parameter to releaseSensorManager");
|
||||||
|
}
|
||||||
|
if (--refCount > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reset() {
|
||||||
|
activeSensorType = null;
|
||||||
|
if (activeSensorManager != null) {
|
||||||
|
activeSensorManager.shutdown();
|
||||||
|
}
|
||||||
|
activeSensorManager = null;
|
||||||
|
refCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -17,23 +17,23 @@ public class SensorManagerFactoryTest extends AndroidTestCase {
|
|||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
sharedPreferences = getContext().getSharedPreferences(
|
sharedPreferences = getContext().getSharedPreferences(
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
// Let's use default values.
|
// Let's use default values.
|
||||||
sharedPreferences.edit().clear().apply();
|
sharedPreferences.edit().clear().apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testDefaultSettings() throws Exception {
|
public void testDefaultSettings() throws Exception {
|
||||||
assertNull(SensorManagerFactory.getSensorManager(getContext()));
|
assertNull(SensorManagerFactory.getInstance().getSensorManager(getContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testCreateZephyr() throws Exception {
|
public void testCreateZephyr() throws Exception {
|
||||||
assertClassForName(ZephyrSensorManager.class, R.string.sensor_type_value_zephyr);
|
assertClassForName(ZephyrSensorManager.class, R.string.sensor_type_value_zephyr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testCreateAnt() throws Exception {
|
public void testCreateAnt() throws Exception {
|
||||||
assertClassForName(AntDirectSensorManager.class, R.string.sensor_type_value_ant);
|
assertClassForName(AntDirectSensorManager.class, R.string.sensor_type_value_ant);
|
||||||
@@ -49,8 +49,9 @@ public class SensorManagerFactoryTest extends AndroidTestCase {
|
|||||||
.putString(getContext().getString(R.string.sensor_type_key),
|
.putString(getContext().getString(R.string.sensor_type_key),
|
||||||
getContext().getString(i))
|
getContext().getString(i))
|
||||||
.apply();
|
.apply();
|
||||||
SensorManager sm = SensorManagerFactory.getSensorManager(getContext());
|
SensorManager sm = SensorManagerFactory.getInstance().getSensorManager(getContext());
|
||||||
assertNotNull(sm);
|
assertNotNull(sm);
|
||||||
assertTrue(c.isInstance(sm));
|
assertTrue(c.isInstance(sm));
|
||||||
|
SensorManagerFactory.getInstance().releaseSensorManager(sm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user