Merge heads

This commit is contained in:
youtaol
2012-07-26 11:00:04 +08:00
14 changed files with 1354 additions and 1815 deletions
@@ -15,7 +15,6 @@
*/ */
package com.google.android.apps.mytracks; package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.services.RemoveTempFilesService; import com.google.android.apps.mytracks.services.RemoveTempFilesService;
import com.google.android.apps.mytracks.util.AnalyticsUtils; import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.ApiAdapterFactory;
@@ -26,13 +25,11 @@ import android.content.Intent;
/** /**
* MyTracksApplication for keeping global state. * MyTracksApplication for keeping global state.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
public class MyTracksApplication extends Application { public class MyTracksApplication extends Application {
private TrackDataHub trackDataHub;
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@@ -43,16 +40,4 @@ public class MyTracksApplication extends Application {
Intent intent = new Intent(this, RemoveTempFilesService.class); Intent intent = new Intent(this, RemoveTempFilesService.class);
startService(intent); startService(intent);
} }
/**
* Gets the application's TrackDataHub.
*
* Note: use synchronized to make sure only one instance is created per application.
*/
public synchronized TrackDataHub getTrackDataHub() {
if (trackDataHub == null) {
trackDataHub = TrackDataHub.newInstance(getApplicationContext());
}
return trackDataHub;
}
} }
@@ -137,8 +137,7 @@ public class TrackDetailActivity extends AbstractMyTracksActivity implements Del
getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE) getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); .registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null); trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
trackDataHub = ((MyTracksApplication) getApplication()).getTrackDataHub(); trackDataHub = TrackDataHub.newInstance(this);
trackDataHub.loadTrack(trackId);
mapViewContainer = getLayoutInflater().inflate(R.layout.map, null); mapViewContainer = getLayoutInflater().inflate(R.layout.map, null);
ApiAdapterFactory.getApiAdapter().disableHardwareAccelerated(mapViewContainer); ApiAdapterFactory.getApiAdapter().disableHardwareAccelerated(mapViewContainer);
@@ -167,7 +166,6 @@ public class TrackDetailActivity extends AbstractMyTracksActivity implements Del
public void onNewIntent(Intent intent) { public void onNewIntent(Intent intent) {
setIntent(intent); setIntent(intent);
handleIntent(intent); handleIntent(intent);
trackDataHub.loadTrack(trackId);
showMarker(); showMarker();
} }
@@ -180,6 +178,7 @@ public class TrackDetailActivity extends AbstractMyTracksActivity implements Del
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
trackDataHub.loadTrack(trackId);
TrackRecordingServiceConnectionUtils.resume(this, trackRecordingServiceConnection); TrackRecordingServiceConnectionUtils.resume(this, trackRecordingServiceConnection);
setTitle(trackId == PreferencesUtils.getLong(this, R.string.recording_track_id_key)); setTitle(trackId == PreferencesUtils.getLong(this, R.string.recording_track_id_key));
} }
@@ -350,12 +349,19 @@ public class TrackDetailActivity extends AbstractMyTracksActivity implements Del
} }
/** /**
* @return the mapViewContainer * Gets the map view container.
*/ */
public View getMapViewContainer() { public View getMapViewContainer() {
return mapViewContainer; return mapViewContainer;
} }
/**
* Gets the {@link TrackDataHub}.
*/
public TrackDataHub getTrackDataHub() {
return trackDataHub;
}
/** /**
* Handles the data in the intent. * Handles the data in the intent.
*/ */
@@ -149,25 +149,25 @@ public class DataSource {
} }
/** /**
* Registers a compass listener. * Registers a heading listener.
* *
* @param listener the listener * @param listener the listener
*/ */
public void registerCompassListener(SensorEventListener listener) { public void registerHeadingListener(SensorEventListener listener) {
Sensor compass = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); Sensor heading = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
if (compass == null) { if (heading == null) {
Log.d(TAG, "No compass sensor."); Log.d(TAG, "No heading sensor.");
return; return;
} }
sensorManager.registerListener(listener, compass, SensorManager.SENSOR_DELAY_UI); sensorManager.registerListener(listener, heading, SensorManager.SENSOR_DELAY_UI);
} }
/** /**
* Unregisters a compass listener. * Unregisters a heading listener.
* *
* @param listener the listener * @param listener the listener
*/ */
public void unregisterCompassListener(SensorEventListener listener) { public void unregisterHeadingListener(SensorEventListener listener) {
sensorManager.unregisterListener(listener); sensorManager.unregisterListener(listener);
} }
@@ -133,11 +133,11 @@ public class DataSourceManager {
} }
/** /**
* Listener for compass changes. * Listener for heading changes.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
private class CompassListener implements SensorEventListener { private class HeadingListener implements SensorEventListener {
@Override @Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { public void onAccuracyChanged(Sensor sensor, int accuracy) {
@@ -174,7 +174,7 @@ public class DataSourceManager {
private final WaypointsTableObserver waypointsTableObserver; private final WaypointsTableObserver waypointsTableObserver;
private final TrackPointsTableObserver trackPointsTableObserver; private final TrackPointsTableObserver trackPointsTableObserver;
private final CurrentLocationListener currentLocationListener; private final CurrentLocationListener currentLocationListener;
private final CompassListener compassListener; private final HeadingListener headingListener;
private final PreferenceListener preferenceListener; private final PreferenceListener preferenceListener;
public DataSourceManager(DataSource dataSource, DataSourceListener dataSourceListener) { public DataSourceManager(DataSource dataSource, DataSourceListener dataSourceListener) {
@@ -186,7 +186,7 @@ public class DataSourceManager {
waypointsTableObserver = new WaypointsTableObserver(); waypointsTableObserver = new WaypointsTableObserver();
trackPointsTableObserver = new TrackPointsTableObserver(); trackPointsTableObserver = new TrackPointsTableObserver();
currentLocationListener = new CurrentLocationListener(); currentLocationListener = new CurrentLocationListener();
compassListener = new CompassListener(); headingListener = new HeadingListener();
preferenceListener = new PreferenceListener(); preferenceListener = new PreferenceListener();
} }
@@ -202,9 +202,9 @@ public class DataSourceManager {
* Map SAMPLED_OUT_POINT_UPDATES to POINT_UPDATES since they correspond to * Map SAMPLED_OUT_POINT_UPDATES to POINT_UPDATES since they correspond to
* the same internal listener * the same internal listener
*/ */
if (neededListeners.contains(TrackDataType.SAMPLED_OUT_TRACK_POINTS)) { if (neededListeners.contains(TrackDataType.SAMPLED_OUT_TRACK_POINTS_TABLE)) {
neededListeners.remove(TrackDataType.SAMPLED_OUT_TRACK_POINTS); neededListeners.remove(TrackDataType.SAMPLED_OUT_TRACK_POINTS_TABLE);
neededListeners.add(TrackDataType.TRACK_POINTS_TABLE); neededListeners.add(TrackDataType.SAMPLED_IN_TRACK_POINTS_TABLE);
} }
Log.d(TAG, "Updating listeners " + neededListeners); Log.d(TAG, "Updating listeners " + neededListeners);
@@ -248,18 +248,18 @@ public class DataSourceManager {
case WAYPOINTS_TABLE: case WAYPOINTS_TABLE:
dataSource.registerContentObserver(WaypointsColumns.CONTENT_URI, waypointsTableObserver); dataSource.registerContentObserver(WaypointsColumns.CONTENT_URI, waypointsTableObserver);
break; break;
case TRACK_POINTS_TABLE: case SAMPLED_IN_TRACK_POINTS_TABLE:
dataSource.registerContentObserver( dataSource.registerContentObserver(
TrackPointsColumns.CONTENT_URI, trackPointsTableObserver); TrackPointsColumns.CONTENT_URI, trackPointsTableObserver);
break; break;
case SAMPLED_OUT_TRACK_POINTS: case SAMPLED_OUT_TRACK_POINTS_TABLE:
// Do nothing. SAMPLED_OUT_POINT_UPDATES is mapped to POINT_UPDATES. // Do nothing. SAMPLED_OUT_POINT_UPDATES is mapped to POINT_UPDATES.
break; break;
case LOCATION: case LOCATION:
dataSource.registerLocationListener(currentLocationListener); dataSource.registerLocationListener(currentLocationListener);
break; break;
case COMPASS: case HEADING:
dataSource.registerCompassListener(compassListener); dataSource.registerHeadingListener(headingListener);
break; break;
case PREFERENCE: case PREFERENCE:
dataSource.registerOnSharedPreferenceChangeListener(preferenceListener); dataSource.registerOnSharedPreferenceChangeListener(preferenceListener);
@@ -285,17 +285,17 @@ public class DataSourceManager {
case WAYPOINTS_TABLE: case WAYPOINTS_TABLE:
dataSource.unregisterContentObserver(waypointsTableObserver); dataSource.unregisterContentObserver(waypointsTableObserver);
break; break;
case TRACK_POINTS_TABLE: case SAMPLED_IN_TRACK_POINTS_TABLE:
dataSource.unregisterContentObserver(trackPointsTableObserver); dataSource.unregisterContentObserver(trackPointsTableObserver);
break; break;
case SAMPLED_OUT_TRACK_POINTS: case SAMPLED_OUT_TRACK_POINTS_TABLE:
// Do nothing. SAMPLED_OUT_POINT_UPDATES is mapped to POINT_UPDATES. // Do nothing. SAMPLED_OUT_POINT_UPDATES is mapped to POINT_UPDATES.
break; break;
case LOCATION: case LOCATION:
dataSource.unregisterLocationListener(currentLocationListener); dataSource.unregisterLocationListener(currentLocationListener);
break; break;
case COMPASS: case HEADING:
dataSource.unregisterCompassListener(compassListener); dataSource.unregisterHeadingListener(headingListener);
break; break;
case PREFERENCE: case PREFERENCE:
dataSource.unregisterOnSharedPreferenceChangeListener(preferenceListener); dataSource.unregisterOnSharedPreferenceChangeListener(preferenceListener);
@@ -1,105 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.content;
import java.util.EnumSet;
/**
* State for a registered {@link TrackDataListener}.
*
* @author Jimmy Shih
*/
public class ListenerState {
private TrackDataListener trackDataListener;
private EnumSet<TrackDataType> trackDataTypes;
private long lastTrackId;
private long lastPointId;
private int lastSamplingFrequency;
private int numberOfLoadedPoints;
public ListenerState(
TrackDataListener trackDataListener, EnumSet<TrackDataType> trackDataTypes) {
this.trackDataListener = trackDataListener;
this.trackDataTypes = trackDataTypes;
}
/**
* Gets the {@link TrackDataListener}.
*/
public TrackDataListener getTrackDataListener() {
return trackDataListener;
}
/**
* Gets the track data types.
*/
public EnumSet<TrackDataType> getTrackDataTypes() {
return trackDataTypes;
}
/**
* Gets the last track id.
*/
public long getLastTrackId() {
return lastTrackId;
}
/**
* Gets the last point id.
*/
public long getLastPointId() {
return lastPointId;
}
/**
* Gets the last sampling frequency.
*/
public int getLastSamplingFrequency() {
return lastSamplingFrequency;
}
/**
* Get the number of loaded points.
*/
public int getNumberOfLoadedPoints() {
return numberOfLoadedPoints;
}
/**
* Sets the listener state.
*
* @param trackId track id
* @param pointId point id
* @param samplingFrequency sampling frequency
* @param loadedPoints number of loaded points
*/
public void setState(long trackId, long pointId, int samplingFrequency, int loadedPoints) {
lastTrackId = trackId;
lastPointId = pointId;
lastSamplingFrequency = samplingFrequency;
numberOfLoadedPoints = loadedPoints;
}
/**
* Resets state.
*/
public void resetState() {
setState(0L, 0L, 0, 0);
}
}
File diff suppressed because it is too large Load Diff
@@ -13,138 +13,131 @@
* 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.content;
import com.google.android.apps.mytracks.content.Track; package com.google.android.apps.mytracks.content;
import com.google.android.apps.mytracks.content.Waypoint;
import android.location.Location; import android.location.Location;
/** /**
* Listener for track data, for both initial and incremental loading. * Listener for track data changes.
* *
* @author Rodrigo Damazio * @author Rodrigo Damazio
*/ */
public interface TrackDataListener { public interface TrackDataListener {
/** States for the GPS location provider. */ /**
public enum ProviderState { * Location state.
DISABLED, *
NO_FIX, * @author Jimmy Shih
BAD_FIX, */
GOOD_FIX; public enum LocationState {
DISABLED, NO_FIX, BAD_FIX, GOOD_FIX;
} }
/** /**
* Called when the location provider changes state. * Called when the location state changes.
*/ */
void onProviderStateChange(ProviderState state); public void onLocationStateChanged(LocationState locationState);
/** /**
* Called when the current location changes. * Called when the location changes. This is meant for location display only,
* This is meant for immediate location display only - track point data is * track point data is reported with other methods like
* delivered by other methods below, such as {@link #onNewTrackPoint}. * {@link #onSampledInTrackPoint(Location)} and
* * {@link #onSampledOutTrackPoint(Location)}.
* @param loc the last known location
*/
void onCurrentLocationChanged(Location loc);
/**
* Called when the current heading changes.
*
* @param heading the current heading, already accounting magnetic declination
*/
void onCurrentHeadingChanged(double heading);
/**
* Called when the currently-selected track changes.
* This will be followed by calls to data methods such as
* {@link #onTrackUpdated}, {@link #clearTrackPoints},
* {@link #onNewTrackPoint(Location)}, etc., even if no track is currently
* selected (in which case you'll only get calls to clear the current data).
* *
* @param track the selected track, or null if no track is selected * @param location the location
* @param isRecording whether we're currently recording the selected track
*/ */
void onSelectedTrackChanged(Track track, boolean isRecording); public void onLocationChanged(Location location);
/** /**
* Called when the track and/or its statistics have been updated. * Called when the heading changes.
* *
* @param track the updated version of the track * @param heading the heading
*/ */
void onTrackUpdated(Track track); public void onHeadingChanged(double heading);
/** /**
* Called to clear any previously-sent track points. * Called when the selected track changes. This will be followed by calls to
* This can be called at any time that we decide the data needs to be * data methods such as {@link #onTrackUpdated(Track)},
* reloaded, such as when it needs to be resampled. * {@link #clearTrackPoints()}, {@link #onSampledInTrackPoint(Location)},
* etc., even if no track is currently selected (in which case you'll only get
* calls to clear the current data).
*
* @param track the selected track or null if no track is selected
* @param isRecording true if the selected track is recording
*/ */
void clearTrackPoints(); public void onSelectedTrackChanged(Track track, boolean isRecording);
/** /**
* Called when a new interesting track point is read. * Called when the track or its statistics has been updated.
* In this case, interesting means that the point has already undergone *
* sampling and invalid point filtering. * @param track the track
*
* @param loc the new track point
*/ */
void onNewTrackPoint(Location loc); public void onTrackUpdated(Track track);
/** /**
* Called when a uninteresting track point is read. * Called to clear previously-sent track points.
* Uninteresting points are all points that get sampled out of the track.
*
* @param loc the new track point
*/ */
void onSampledOutTrackPoint(Location loc); public void clearTrackPoints();
/** /**
* Called when an invalid point (representing a segment split) is read. * Called when a sampled in track point is read.
*
* @param location the location
*/ */
void onSegmentSplit(); public void onSampledInTrackPoint(Location location);
/** /**
* Called when we're done (for the time being) sending new points. * Called when a sampled out track point is read.
* This gets called after every batch of calls to {@link #onNewTrackPoint}, *
* {@link #onSampledOutTrackPoint} and {@link #onSegmentSplit}. * @param location the location
*/ */
void onNewTrackPointsDone(); public void onSampledOutTrackPoint(Location location);
/** /**
* Called to clear any previously-sent waypoints. * Called when an invalid track point representing a segment split is read.
* This can be called at any time that we decide the data needs to be
* reloaded.
*/ */
void clearWaypoints(); public void onSegmentSplit();
/**
* Called when finish sending new track points. This gets called after every
* batch of calls to {@link #onSampledInTrackPoint(Location)},
* {@link #onSampledOutTrackPoint(Location)} and {@link #onSegmentSplit()}.
*/
public void onNewTrackPointsDone();
/**
* Called to clear previously sent waypoints.
*/
public void clearWaypoints();
/** /**
* Called when a new waypoint is read. * Called when a new waypoint is read.
* *
* @param wpt the new waypoint * @param waypoint the waypoint
*/ */
void onNewWaypoint(Waypoint wpt); public void onNewWaypoint(Waypoint waypoint);
/** /**
* Called when we're done (for the time being) sending new waypoints. * Called when finish sending new waypoints. This gets called after every
* This gets called after every batch of calls to {@link #clearWaypoints} and * batch of calls to {@link #clearWaypoints()} and
* {@link #onNewWaypoint}. * {@link #onNewWaypoint(Waypoint)}.
*/ */
void onNewWaypointsDone(); public void onNewWaypointsDone();
/** /**
* Called when the display units are changed by the user. * Called when the metric units preference value is change.
* *
* @param metric true if the units are metric, false if imperial * @param metricUnits true to use metric units, false to use imperial units
* @return true to reload all the data, false otherwise * @return true to reload all the data, false otherwise.
*/ */
boolean onUnitsChanged(boolean metric); public boolean onMetricUnitsChanged(boolean metricUnits);
/** /**
* Called when the speed/pace display unit is changed by the user. * Called when the report speed preference value is changed.
* *
* @param reportSpeed true to report speed, false for pace * @param reportSpeed true to report speed, false to report pace
* @return true to reload all the data, false otherwise * @return true to reload all the data, false otherwise.
*/ */
boolean onReportSpeedChanged(boolean reportSpeed); public boolean onReportSpeedChanged(boolean reportSpeed);
} }
@@ -35,9 +35,9 @@ import java.util.Set;
*/ */
public class TrackDataManager { public class TrackDataManager {
// Map of listener to its state // Map of listener to its track data types
private final Map<TrackDataListener, ListenerState> private final Map<TrackDataListener, EnumSet<TrackDataType>>
listenerToStateMap = new HashMap<TrackDataListener, ListenerState>(); listenerToTypesMap = new HashMap<TrackDataListener, EnumSet<TrackDataType>>();
// Map of track data type to listeners // Map of track data type to listeners
private final Map<TrackDataType, Set<TrackDataListener>> private final Map<TrackDataType, Set<TrackDataListener>>
@@ -55,20 +55,15 @@ public class TrackDataManager {
* @param listener the listener * @param listener the listener
* @param trackDataTypes the track data types the listener is interested * @param trackDataTypes the track data types the listener is interested
*/ */
public ListenerState registerListener( public void registerListener(
TrackDataListener listener, EnumSet<TrackDataType> trackDataTypes) { TrackDataListener listener, EnumSet<TrackDataType> trackDataTypes) {
if (listenerToStateMap.containsKey(listener)) { if (listenerToTypesMap.containsKey(listener)) {
throw new IllegalStateException("Listener is already registered"); throw new IllegalStateException("Listener is already registered");
} }
listenerToTypesMap.put(listener, trackDataTypes);
ListenerState listenerState = new ListenerState(listener, trackDataTypes);
listenerToStateMap.put(listener, listenerState);
for (TrackDataType trackDataType : trackDataTypes) { for (TrackDataType trackDataType : trackDataTypes) {
typeToListenersMap.get(trackDataType).add(listener); typeToListenersMap.get(trackDataType).add(listener);
} }
return listenerState;
} }
/** /**
@@ -77,14 +72,14 @@ public class TrackDataManager {
* @param listener the listener * @param listener the listener
*/ */
public void unregisterListener(TrackDataListener listener) { public void unregisterListener(TrackDataListener listener) {
ListenerState removed = listenerToStateMap.remove(listener); EnumSet<TrackDataType> removedTypes = listenerToTypesMap.remove(listener);
if (removed == null) { if (removedTypes == null) {
Log.w(TAG, "Tried to unregister a listener that is not registered."); Log.w(TAG, "Tried to unregister a listener that is not registered.");
return; return;
} }
// Remove the listener from the typeToListenersMap // Remove the listener from the typeToListenersMap
for (TrackDataType trackDataType : removed.getTrackDataTypes()) { for (TrackDataType trackDataType : removedTypes) {
typeToListenersMap.get(trackDataType).remove(listener); typeToListenersMap.get(trackDataType).remove(listener);
} }
} }
@@ -93,16 +88,16 @@ public class TrackDataManager {
* Gets the number of {@link TrackDataListener}. * Gets the number of {@link TrackDataListener}.
*/ */
public int getNumberOfListeners() { public int getNumberOfListeners() {
return listenerToStateMap.size(); return listenerToTypesMap.size();
} }
/** /**
* Gets the track listener state. * Gets the track data types for a listener.
* *
* @param listener the listener * @param listener the listener
*/ */
public ListenerState getListenerState(TrackDataListener listener) { public EnumSet<TrackDataType> getTrackDataTypes(TrackDataListener listener) {
return listenerToStateMap.get(listener); return listenerToTypesMap.get(listener);
} }
/** /**
@@ -119,9 +114,11 @@ public class TrackDataManager {
*/ */
public EnumSet<TrackDataType> getRegisteredTrackDataTypes() { public EnumSet<TrackDataType> getRegisteredTrackDataTypes() {
EnumSet<TrackDataType> types = EnumSet.noneOf(TrackDataType.class); EnumSet<TrackDataType> types = EnumSet.noneOf(TrackDataType.class);
for (ListenerState registration : this.listenerToStateMap.values()) { for (EnumSet<TrackDataType> value : listenerToTypesMap.values()) {
types.addAll(registration.getTrackDataTypes()); types.addAll(value);
} }
// Always include preference
types.add(TrackDataType.PREFERENCE);
return types; return types;
} }
} }
@@ -22,13 +22,12 @@ package com.google.android.apps.mytracks.content;
* @author Jimmy Shih * @author Jimmy Shih
*/ */
public enum TrackDataType { public enum TrackDataType {
SELECTED_TRACK, // selected track changes SELECTED_TRACK, // selected track changes
TRACKS_TABLE, // tracks table changes TRACKS_TABLE, // tracks table changes
WAYPOINTS_TABLE, // waypoints table changes WAYPOINTS_TABLE, // waypoints table changes
TRACK_POINTS_TABLE, // track points table changes SAMPLED_IN_TRACK_POINTS_TABLE, // sampled-in track points table changes
SAMPLED_OUT_TRACK_POINTS, // sampled-out track points changes SAMPLED_OUT_TRACK_POINTS_TABLE, // sampled-out track points table changes
LOCATION, // location changes LOCATION, // location changes
COMPASS, // compass changes HEADING, // heading changes
PREFERENCE; // preference changes PREFERENCE // preference changes
} }
@@ -18,14 +18,14 @@ package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.ChartView; import com.google.android.apps.mytracks.ChartView;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksApplication; import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.content.TrackDataType;
import com.google.android.apps.mytracks.content.MyTracksLocation; import com.google.android.apps.mytracks.content.MyTracksLocation;
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.SensorDataSet;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TrackDataHub; import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TrackDataListener; import com.google.android.apps.mytracks.content.TrackDataListener;
import com.google.android.apps.mytracks.content.TrackDataType;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.DoubleBuffer; import com.google.android.apps.mytracks.stats.DoubleBuffer;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder; import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
@@ -96,7 +96,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
zoomControls.setIsZoomInEnabled(chartView.canZoomIn()); zoomControls.setIsZoomInEnabled(chartView.canZoomIn());
zoomControls.setIsZoomOutEnabled(chartView.canZoomOut()); zoomControls.setIsZoomOutEnabled(chartView.canZoomOut());
chartView.setShowPointer(isRecording()); chartView.setShowPointer(isSelectedTrackRecording());
chartView.invalidate(); chartView.invalidate();
} }
}; };
@@ -164,17 +164,17 @@ public class ChartFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public void onProviderStateChange(ProviderState state) { public void onLocationStateChanged(LocationState state) {
// We don't care. // We don't care.
} }
@Override @Override
public void onCurrentLocationChanged(Location loc) { public void onLocationChanged(Location loc) {
// We don't care. // We don't care.
} }
@Override @Override
public void onCurrentHeadingChanged(double heading) { public void onHeadingChanged(double heading) {
// We don't care. // We don't care.
} }
@@ -213,7 +213,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public void onNewTrackPoint(Location location) { public void onSampledInTrackPoint(Location location) {
if (LocationUtils.isValidLocation(location)) { if (LocationUtils.isValidLocation(location)) {
double[] data = new double[ChartView.NUM_SERIES + 1]; double[] data = new double[ChartView.NUM_SERIES + 1];
fillDataPoint(location, data); fillDataPoint(location, data);
@@ -259,7 +259,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public boolean onUnitsChanged(boolean metric) { public boolean onMetricUnitsChanged(boolean metric) {
if (metricUnits == metric) { if (metricUnits == metric) {
return false; return false;
} }
@@ -358,13 +358,13 @@ public class ChartFragment extends Fragment implements TrackDataListener {
* accessed by multiple threads. * accessed by multiple threads.
*/ */
private synchronized void resumeTrackDataHub() { private synchronized void resumeTrackDataHub() {
trackDataHub = ((MyTracksApplication) getActivity().getApplication()).getTrackDataHub(); trackDataHub = ((TrackDetailActivity) getActivity()).getTrackDataHub();
trackDataHub.registerTrackDataListener(this, EnumSet.of( trackDataHub.registerTrackDataListener(this, EnumSet.of(
TrackDataType.SELECTED_TRACK, TrackDataType.SELECTED_TRACK,
TrackDataType.TRACKS_TABLE, TrackDataType.TRACKS_TABLE,
TrackDataType.WAYPOINTS_TABLE, TrackDataType.WAYPOINTS_TABLE,
TrackDataType.TRACK_POINTS_TABLE, TrackDataType.SAMPLED_IN_TRACK_POINTS_TABLE,
TrackDataType.SAMPLED_OUT_TRACK_POINTS, TrackDataType.SAMPLED_OUT_TRACK_POINTS_TABLE,
TrackDataType.PREFERENCE)); TrackDataType.PREFERENCE));
} }
@@ -378,11 +378,11 @@ public class ChartFragment extends Fragment implements TrackDataListener {
} }
/** /**
* Returns true if recording. Needs to be synchronized because trackDataHub * Returns true if the selected track is recording. Needs to be synchronized
* can be accessed by multiple threads. * because trackDataHub can be accessed by multiple threads.
*/ */
private synchronized boolean isRecording() { private synchronized boolean isSelectedTrackRecording() {
return trackDataHub != null && trackDataHub.isRecordingSelected(); return trackDataHub != null && trackDataHub.isSelectedTrackRecording();
} }
/** /**
@@ -17,14 +17,13 @@
package com.google.android.apps.mytracks.fragments; package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.MapOverlay; import com.google.android.apps.mytracks.MapOverlay;
import com.google.android.apps.mytracks.MyTracksApplication;
import com.google.android.apps.mytracks.TrackDetailActivity; import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.content.TrackDataType;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TrackDataHub; import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TrackDataListener; import com.google.android.apps.mytracks.content.TrackDataListener;
import com.google.android.apps.mytracks.content.TrackDataType;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.ApiAdapterFactory;
@@ -271,7 +270,7 @@ public class MapFragment extends Fragment
} }
@Override @Override
public void onProviderStateChange(ProviderState state) { public void onLocationStateChanged(LocationState state) {
final int messageId; final int messageId;
final boolean isGpsDisabled; final boolean isGpsDisabled;
switch (state) { switch (state) {
@@ -315,13 +314,13 @@ public class MapFragment extends Fragment
} }
@Override @Override
public void onCurrentLocationChanged(Location location) { public void onLocationChanged(Location location) {
currentLocation = location; currentLocation = location;
updateCurrentLocation(); updateCurrentLocation();
} }
@Override @Override
public void onCurrentHeadingChanged(double heading) { public void onHeadingChanged(double heading) {
if (mapOverlay.setHeading((float) heading)) { if (mapOverlay.setHeading((float) heading)) {
mapView.postInvalidate(); mapView.postInvalidate();
} }
@@ -362,7 +361,7 @@ public class MapFragment extends Fragment
} }
@Override @Override
public void onNewTrackPoint(Location location) { public void onSampledInTrackPoint(Location location) {
if (LocationUtils.isValidLocation(location)) { if (LocationUtils.isValidLocation(location)) {
mapOverlay.addLocation(location); mapOverlay.addLocation(location);
} }
@@ -402,7 +401,7 @@ public class MapFragment extends Fragment
} }
@Override @Override
public boolean onUnitsChanged(boolean metric) { public boolean onMetricUnitsChanged(boolean metric) {
// We don't care. // We don't care.
return false; return false;
} }
@@ -418,13 +417,13 @@ public class MapFragment extends Fragment
* accessed by multiple threads. * accessed by multiple threads.
*/ */
private synchronized void resumeTrackDataHub() { private synchronized void resumeTrackDataHub() {
trackDataHub = ((MyTracksApplication) getActivity().getApplication()).getTrackDataHub(); trackDataHub = ((TrackDetailActivity) getActivity()).getTrackDataHub();
trackDataHub.registerTrackDataListener(this, EnumSet.of( trackDataHub.registerTrackDataListener(this, EnumSet.of(
TrackDataType.SELECTED_TRACK, TrackDataType.SELECTED_TRACK,
TrackDataType.WAYPOINTS_TABLE, TrackDataType.WAYPOINTS_TABLE,
TrackDataType.TRACK_POINTS_TABLE, TrackDataType.SAMPLED_IN_TRACK_POINTS_TABLE,
TrackDataType.LOCATION, TrackDataType.LOCATION,
TrackDataType.COMPASS)); TrackDataType.HEADING));
} }
/** /**
@@ -16,11 +16,11 @@
package com.google.android.apps.mytracks.fragments; package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.MyTracksApplication; import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.content.TrackDataType;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TrackDataHub; import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TrackDataListener; import com.google.android.apps.mytracks.content.TrackDataListener;
import com.google.android.apps.mytracks.content.TrackDataType;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
@@ -61,7 +61,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
// A runnable to update the total time field. // A runnable to update the total time field.
private final Runnable updateTotalTime = new Runnable() { private final Runnable updateTotalTime = new Runnable() {
public void run() { public void run() {
if (isRecording()) { if (isSelectedTrackRecording()) {
StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() - startTime); StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() - startTime);
} }
} }
@@ -117,8 +117,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public void onProviderStateChange(ProviderState state) { public void onLocationStateChanged(LocationState state) {
if (isResumed() && (state == ProviderState.DISABLED || state == ProviderState.NO_FIX)) { if (isResumed() && (state == LocationState.DISABLED || state == LocationState.NO_FIX)) {
getActivity().runOnUiThread(new Runnable() { getActivity().runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -130,8 +130,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public void onCurrentLocationChanged(final Location location) { public void onLocationChanged(final Location location) {
if (isResumed() && isRecording()) { if (isResumed() && isSelectedTrackRecording()) {
getActivity().runOnUiThread(new Runnable() { getActivity().runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -143,7 +143,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public void onCurrentHeadingChanged(double heading) { public void onHeadingChanged(double heading) {
// We don't care. // We don't care.
} }
@@ -175,7 +175,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
lastTripStatistics = track.getTripStatistics(); lastTripStatistics = track.getTripStatistics();
startTime = track.getTripStatistics().getStartTime(); startTime = track.getTripStatistics().getStartTime();
if (!isRecording()) { if (!isSelectedTrackRecording()) {
lastLocation = null; lastLocation = null;
} }
updateUi(); updateUi();
@@ -190,7 +190,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public void onNewTrackPoint(Location loc) { public void onSampledInTrackPoint(Location loc) {
// We don't care. // We don't care.
} }
@@ -225,7 +225,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
} }
@Override @Override
public boolean onUnitsChanged(final boolean metric) { public boolean onMetricUnitsChanged(final boolean metric) {
if (isResumed()) { if (isResumed()) {
getActivity().runOnUiThread(new Runnable() { getActivity().runOnUiThread(new Runnable() {
@Override @Override
@@ -255,7 +255,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
* be accessed by multiple threads. * be accessed by multiple threads.
*/ */
private synchronized void resumeTrackDataHub() { private synchronized void resumeTrackDataHub() {
trackDataHub = ((MyTracksApplication) getActivity().getApplication()).getTrackDataHub(); trackDataHub = ((TrackDetailActivity) getActivity()).getTrackDataHub();
trackDataHub.registerTrackDataListener(this, EnumSet.of( trackDataHub.registerTrackDataListener(this, EnumSet.of(
TrackDataType.SELECTED_TRACK, TrackDataType.SELECTED_TRACK,
TrackDataType.TRACKS_TABLE, TrackDataType.TRACKS_TABLE,
@@ -273,11 +273,11 @@ public class StatsFragment extends Fragment implements TrackDataListener {
} }
/** /**
* Returns true if recording. Needs to be synchronized because trackDataHub * Returns true if the selected track is recording. Needs to be synchronized
* can be accessed by multiple threads. * because trackDataHub can be accessed by multiple threads.
*/ */
private synchronized boolean isRecording() { private synchronized boolean isSelectedTrackRecording() {
return trackDataHub != null && trackDataHub.isRecordingSelected(); return trackDataHub != null && trackDataHub.isSelectedTrackRecording();
} }
/** /**
@@ -824,7 +824,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
throw new IllegalArgumentException("locationFactory is null"); throw new IllegalArgumentException("locationFactory is null");
} }
return new LocationIterator() { return new LocationIterator() {
private long lastTrackPointId = startTrackPointId; private long lastTrackPointId = -1L;
private Cursor cursor = getCursor(startTrackPointId); private Cursor cursor = getCursor(startTrackPointId);
private final CachedTrackPointsIndexes private final CachedTrackPointsIndexes
indexes = cursor != null ? new CachedTrackPointsIndexes(cursor) indexes = cursor != null ? new CachedTrackPointsIndexes(cursor)
@@ -843,7 +843,8 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
* Advances the cursor to the next batch. Returns true if successful. * Advances the cursor to the next batch. Returns true if successful.
*/ */
private boolean advanceCursorToNextBatch() { private boolean advanceCursorToNextBatch() {
long trackPointId = lastTrackPointId + (descending ? -1 : 1); long trackPointId = lastTrackPointId == -1L ? -1L : lastTrackPointId + (descending ? -1
: 1);
Log.d(TAG, "Advancing track point id: " + trackPointId); Log.d(TAG, "Advancing track point id: " + trackPointId);
cursor.close(); cursor.close();
cursor = getCursor(trackPointId); cursor = getCursor(trackPointId);
File diff suppressed because it is too large Load Diff