forked from upstream-mirrors/OpenTracks
Properly handling invalid track/point/waypoint IDs.
This makes the provider utils implementation return null for those cases, and fixes all callers which didn't check for that.
This commit is contained in:
@@ -144,6 +144,7 @@ public class ChartActivity extends Activity implements TrackDataListener {
|
|||||||
|
|
||||||
dataHub.registerTrackDataListener(this, EnumSet.of(
|
dataHub.registerTrackDataListener(this, EnumSet.of(
|
||||||
ListenerDataType.SELECTED_TRACK_CHANGED,
|
ListenerDataType.SELECTED_TRACK_CHANGED,
|
||||||
|
ListenerDataType.TRACK_UPDATES,
|
||||||
ListenerDataType.POINT_UPDATES,
|
ListenerDataType.POINT_UPDATES,
|
||||||
ListenerDataType.SAMPLED_OUT_POINT_UPDATES,
|
ListenerDataType.SAMPLED_OUT_POINT_UPDATES,
|
||||||
ListenerDataType.WAYPOINT_UPDATES,
|
ListenerDataType.WAYPOINT_UPDATES,
|
||||||
|
|||||||
@@ -189,6 +189,11 @@ public class ExportAllTracks {
|
|||||||
Log.i(Constants.TAG, "ExportAllTracks: exporting: " + id);
|
Log.i(Constants.TAG, "ExportAllTracks: exporting: " + id);
|
||||||
TrackWriter writer =
|
TrackWriter writer =
|
||||||
TrackWriterFactory.newWriter(activity, providerUtils, id, format);
|
TrackWriterFactory.newWriter(activity, providerUtils, id, format);
|
||||||
|
if (writer == null) {
|
||||||
|
showToast(R.string.error_track_does_not_exist, Toast.LENGTH_LONG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
writer.writeTrack();
|
writer.writeTrack();
|
||||||
|
|
||||||
if (!writer.wasSuccess()) {
|
if (!writer.wasSuccess()) {
|
||||||
|
|||||||
@@ -963,8 +963,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
|||||||
// Update the map id for this track:
|
// Update the map id for this track:
|
||||||
try {
|
try {
|
||||||
Track track = providerUtils.getTrack(trackId);
|
Track track = providerUtils.getTrack(trackId);
|
||||||
track.setMapId(mapId);
|
if (track != null) {
|
||||||
providerUtils.updateTrack(track);
|
track.setMapId(mapId);
|
||||||
|
providerUtils.updateTrack(track);
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Updating map id failed.");
|
||||||
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
// If that fails whatever reasons we'll just log an error, but
|
// If that fails whatever reasons we'll just log an error, but
|
||||||
// continue.
|
// continue.
|
||||||
@@ -1017,8 +1021,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
|||||||
// Update the table id for this track:
|
// Update the table id for this track:
|
||||||
try {
|
try {
|
||||||
Track track = providerUtils.getTrack(trackId);
|
Track track = providerUtils.getTrack(trackId);
|
||||||
track.setTableId(tableId);
|
if (track != null) {
|
||||||
providerUtils.updateTrack(track);
|
track.setTableId(tableId);
|
||||||
|
providerUtils.updateTrack(track);
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Updating table id failed.");
|
||||||
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
// If that fails whatever reasons we'll just log an error, but
|
// If that fails whatever reasons we'll just log an error, but
|
||||||
// continue.
|
// continue.
|
||||||
@@ -1228,6 +1236,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
|||||||
*/
|
*/
|
||||||
public void saveTrack(long trackId, TrackFileFormat format) {
|
public void saveTrack(long trackId, TrackFileFormat format) {
|
||||||
TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
|
TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
|
||||||
|
if (writer == null) {
|
||||||
|
dialogManager.showMessageDialog(R.string.error_track_does_not_exist, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteProgressController controller = new WriteProgressController(this, writer);
|
WriteProgressController controller = new WriteProgressController(this, writer);
|
||||||
controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
|
controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -1247,6 +1260,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
|||||||
*/
|
*/
|
||||||
public void sendTrack(long trackId, final TrackFileFormat format) {
|
public void sendTrack(long trackId, final TrackFileFormat format) {
|
||||||
TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
|
TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
|
||||||
|
if (writer == null) {
|
||||||
|
dialogManager.showMessageDialog(R.string.error_track_does_not_exist, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FileUtils fileUtils = new FileUtils();
|
FileUtils fileUtils = new FileUtils();
|
||||||
String extension = format.getExtension();
|
String extension = format.getExtension();
|
||||||
|
|||||||
@@ -73,15 +73,18 @@ public class WaypointsList extends ListActivity
|
|||||||
contextPosition = info.position;
|
contextPosition = info.position;
|
||||||
waypointId = WaypointsList.this.listView.getAdapter()
|
waypointId = WaypointsList.this.listView.getAdapter()
|
||||||
.getItemId(contextPosition);
|
.getItemId(contextPosition);
|
||||||
int type = providerUtils.getWaypoint(info.id).getType();
|
Waypoint waypoint = providerUtils.getWaypoint(info.id);
|
||||||
menu.add(0, Constants.MENU_SHOW, 0,
|
if (waypoint != null) {
|
||||||
R.string.waypointslist_show_waypoint);
|
int type = waypoint.getType();
|
||||||
menu.add(0, Constants.MENU_EDIT, 0,
|
menu.add(0, Constants.MENU_SHOW, 0,
|
||||||
R.string.waypointslist_edit_waypoint);
|
R.string.waypointslist_show_waypoint);
|
||||||
menu.add(0, Constants.MENU_DELETE, 0,
|
menu.add(0, Constants.MENU_EDIT, 0,
|
||||||
R.string.waypointslist_delete_waypoint).setEnabled(
|
R.string.waypointslist_edit_waypoint);
|
||||||
recordingTrackId < 0 || type == Waypoint.TYPE_WAYPOINT ||
|
menu.add(0, Constants.MENU_DELETE, 0,
|
||||||
info.id != providerUtils.getLastWaypointId(recordingTrackId));
|
R.string.waypointslist_delete_waypoint).setEnabled(
|
||||||
|
recordingTrackId < 0 || type == Waypoint.TYPE_WAYPOINT ||
|
||||||
|
info.id != providerUtils.getLastWaypointId(recordingTrackId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ package com.google.android.apps.mytracks.content;
|
|||||||
|
|
||||||
import static com.google.android.apps.mytracks.Constants.DEFAULT_MIN_REQUIRED_ACCURACY;
|
import static com.google.android.apps.mytracks.Constants.DEFAULT_MIN_REQUIRED_ACCURACY;
|
||||||
import static com.google.android.apps.mytracks.Constants.MAX_DISPLAYED_WAYPOINTS_POINTS;
|
import static com.google.android.apps.mytracks.Constants.MAX_DISPLAYED_WAYPOINTS_POINTS;
|
||||||
import static com.google.android.apps.mytracks.Constants.TARGET_DISPLAYED_TRACK_POINTS;
|
|
||||||
import static com.google.android.apps.mytracks.Constants.MAX_LOCATION_AGE_MS;
|
import static com.google.android.apps.mytracks.Constants.MAX_LOCATION_AGE_MS;
|
||||||
import static com.google.android.apps.mytracks.Constants.MAX_NETWORK_AGE_MS;
|
import static com.google.android.apps.mytracks.Constants.MAX_NETWORK_AGE_MS;
|
||||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||||
|
import static com.google.android.apps.mytracks.Constants.TARGET_DISPLAYED_TRACK_POINTS;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.content.DataSourceManager.DataSourceListener;
|
import com.google.android.apps.mytracks.content.DataSourceManager.DataSourceListener;
|
||||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.DoubleBufferedLocationFactory;
|
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.DoubleBufferedLocationFactory;
|
||||||
@@ -40,7 +40,6 @@ import android.location.LocationManager;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -791,10 +790,6 @@ public class TrackDataHub {
|
|||||||
public void run() {
|
public void run() {
|
||||||
for (TrackDataListener listener : listeners) {
|
for (TrackDataListener listener : listeners) {
|
||||||
listener.onSelectedTrackChanged(track, isRecordingSelected());
|
listener.onSelectedTrackChanged(track, isRecordingSelected());
|
||||||
|
|
||||||
if (track != null) {
|
|
||||||
listener.onTrackUpdated(track);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -179,6 +179,11 @@ public class SendToFusionTables implements Runnable {
|
|||||||
|
|
||||||
// Get the track meta-data
|
// Get the track meta-data
|
||||||
Track track = providerUtils.getTrack(trackId);
|
Track track = providerUtils.getTrack(trackId);
|
||||||
|
if (track == null) {
|
||||||
|
Log.w(Constants.TAG, "Cannot get track.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String originalDescription = track.getDescription();
|
String originalDescription = track.getDescription();
|
||||||
|
|
||||||
// Create a new table:
|
// Create a new table:
|
||||||
@@ -207,7 +212,6 @@ public class SendToFusionTables implements Runnable {
|
|||||||
Log.d(Constants.TAG, "SendToFusionTables: Done: " + success);
|
Log.d(Constants.TAG, "SendToFusionTables: Done: " + success);
|
||||||
progressIndicator.setProgressValue(PROGRESS_COMPLETE);
|
progressIndicator.setProgressValue(PROGRESS_COMPLETE);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
final boolean finalSuccess = success;
|
final boolean finalSuccess = success;
|
||||||
final int finalStatusMessageId = statusMessageId;
|
final int finalStatusMessageId = statusMessageId;
|
||||||
context.runOnUiThread(new Runnable() {
|
context.runOnUiThread(new Runnable() {
|
||||||
@@ -304,7 +308,7 @@ public class SendToFusionTables implements Runnable {
|
|||||||
|
|
||||||
Cursor locationsCursor = providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
Cursor locationsCursor = providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
||||||
try {
|
try {
|
||||||
if (!locationsCursor.moveToFirst()) {
|
if (locationsCursor == null || !locationsCursor.moveToFirst()) {
|
||||||
Log.w(Constants.TAG, "Unable to get any points to upload");
|
Log.w(Constants.TAG, "Unable to get any points to upload");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -391,7 +395,9 @@ public class SendToFusionTables implements Runnable {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
locationsCursor.close();
|
if (locationsCursor != null) {
|
||||||
|
locationsCursor.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ public class SendToMyMaps implements Runnable {
|
|||||||
|
|
||||||
// Get the track meta-data
|
// Get the track meta-data
|
||||||
Track track = providerUtils.getTrack(trackId);
|
Track track = providerUtils.getTrack(trackId);
|
||||||
|
if (track == null) {
|
||||||
|
Log.w(Constants.TAG, "Cannot get track.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String originalDescription = track.getDescription();
|
String originalDescription = track.getDescription();
|
||||||
track.setDescription("<p>" + track.getDescription() + "</p><p>"
|
track.setDescription("<p>" + track.getDescription() + "</p><p>"
|
||||||
+ stringUtils.generateTrackDescription(track, null, null) + "</p>");
|
+ stringUtils.generateTrackDescription(track, null, null) + "</p>");
|
||||||
@@ -206,7 +211,7 @@ public class SendToMyMaps implements Runnable {
|
|||||||
Cursor locationsCursor =
|
Cursor locationsCursor =
|
||||||
providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
||||||
try {
|
try {
|
||||||
if (!locationsCursor.moveToFirst()) {
|
if (locationsCursor == null || !locationsCursor.moveToFirst()) {
|
||||||
Log.w(TAG, "Unable to get any points to upload");
|
Log.w(TAG, "Unable to get any points to upload");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -297,7 +302,9 @@ public class SendToMyMaps implements Runnable {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
locationsCursor.close();
|
if (locationsCursor != null) {
|
||||||
|
locationsCursor.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package com.google.android.apps.mytracks.io.file;
|
package com.google.android.apps.mytracks.io.file;
|
||||||
|
|
||||||
|
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||||
import com.google.android.apps.mytracks.content.Track;
|
import com.google.android.apps.mytracks.content.Track;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory to produce track writers for any format.
|
* A factory to produce track writers for any format.
|
||||||
@@ -90,6 +93,11 @@ public class TrackWriterFactory {
|
|||||||
MyTracksProviderUtils providerUtils,
|
MyTracksProviderUtils providerUtils,
|
||||||
long trackId, TrackFileFormat format) {
|
long trackId, TrackFileFormat format) {
|
||||||
Track track = providerUtils.getTrack(trackId);
|
Track track = providerUtils.getTrack(trackId);
|
||||||
|
if (track == null) {
|
||||||
|
Log.w(TAG, "Trying to create a writer for an invalid track, id=" + trackId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return newWriter(context, providerUtils, track, format);
|
return newWriter(context, providerUtils, track, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+40
@@ -660,6 +660,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Waypoint getFirstWaypoint(long trackId) {
|
public Waypoint getFirstWaypoint(long trackId) {
|
||||||
|
if (trackId <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Cursor cursor = contentResolver.query(
|
Cursor cursor = contentResolver.query(
|
||||||
WaypointsColumns.CONTENT_URI,
|
WaypointsColumns.CONTENT_URI,
|
||||||
null /*projection*/,
|
null /*projection*/,
|
||||||
@@ -682,6 +686,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Waypoint getWaypoint(long waypointId) {
|
public Waypoint getWaypoint(long waypointId) {
|
||||||
|
if (waypointId < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Cursor cursor = contentResolver.query(
|
Cursor cursor = contentResolver.query(
|
||||||
WaypointsColumns.CONTENT_URI,
|
WaypointsColumns.CONTENT_URI,
|
||||||
null /*projection*/,
|
null /*projection*/,
|
||||||
@@ -704,6 +712,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastLocationId(long trackId) {
|
public long getLastLocationId(long trackId) {
|
||||||
|
if (trackId < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
final String[] projection = {"_id"};
|
final String[] projection = {"_id"};
|
||||||
Cursor cursor = contentResolver.query(
|
Cursor cursor = contentResolver.query(
|
||||||
TrackPointsColumns.CONTENT_URI,
|
TrackPointsColumns.CONTENT_URI,
|
||||||
@@ -728,6 +740,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getFirstWaypointId(long trackId) {
|
public long getFirstWaypointId(long trackId) {
|
||||||
|
if (trackId < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
final String[] projection = {"_id"};
|
final String[] projection = {"_id"};
|
||||||
Cursor cursor = contentResolver.query(
|
Cursor cursor = contentResolver.query(
|
||||||
WaypointsColumns.CONTENT_URI,
|
WaypointsColumns.CONTENT_URI,
|
||||||
@@ -752,6 +768,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastWaypointId(long trackId) {
|
public long getLastWaypointId(long trackId) {
|
||||||
|
if (trackId < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
final String[] projection = {"_id"};
|
final String[] projection = {"_id"};
|
||||||
Cursor cursor = contentResolver.query(
|
Cursor cursor = contentResolver.query(
|
||||||
WaypointsColumns.CONTENT_URI,
|
WaypointsColumns.CONTENT_URI,
|
||||||
@@ -815,6 +835,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getLocation(long id) {
|
public Location getLocation(long id) {
|
||||||
|
if (id < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String selection = TrackPointsColumns._ID + "=" + id;
|
String selection = TrackPointsColumns._ID + "=" + id;
|
||||||
return findLocationBy(selection);
|
return findLocationBy(selection);
|
||||||
}
|
}
|
||||||
@@ -822,6 +846,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
@Override
|
@Override
|
||||||
public Cursor getLocationsCursor(long trackId, long minTrackPointId,
|
public Cursor getLocationsCursor(long trackId, long minTrackPointId,
|
||||||
int maxLocations, boolean descending) {
|
int maxLocations, boolean descending) {
|
||||||
|
if (trackId < 0 || maxLocations < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String selection;
|
String selection;
|
||||||
if (minTrackPointId >= 0) {
|
if (minTrackPointId >= 0) {
|
||||||
selection = String.format("%s=%d AND %s%s%d",
|
selection = String.format("%s=%d AND %s%s%d",
|
||||||
@@ -842,6 +870,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
@Override
|
@Override
|
||||||
public Cursor getWaypointsCursor(long trackId, long minWaypointId,
|
public Cursor getWaypointsCursor(long trackId, long minWaypointId,
|
||||||
int maxWaypoints) {
|
int maxWaypoints) {
|
||||||
|
if (trackId < 0 || maxWaypoints < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String selection;
|
String selection;
|
||||||
if (minWaypointId > 0) {
|
if (minWaypointId > 0) {
|
||||||
selection = String.format("%s=%d AND %s>=%d",
|
selection = String.format("%s=%d AND %s>=%d",
|
||||||
@@ -863,6 +895,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Track getTrack(long id) {
|
public Track getTrack(long id) {
|
||||||
|
if (id < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String select = TracksColumns._ID + "=" + id;
|
String select = TracksColumns._ID + "=" + id;
|
||||||
return findTrackBy(select);
|
return findTrackBy(select);
|
||||||
}
|
}
|
||||||
@@ -929,6 +965,10 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trackExists(long id) {
|
public boolean trackExists(long id) {
|
||||||
|
if (id < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
try {
|
try {
|
||||||
final String[] projection = { TracksColumns._ID };
|
final String[] projection = { TracksColumns._ID };
|
||||||
|
|||||||
Reference in New Issue
Block a user