diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml index f4dc05e85..be720c74e 100755 --- a/MyTracks/AndroidManifest.xml +++ b/MyTracks/AndroidManifest.xml @@ -178,6 +178,9 @@ limitations under the License. android:exported="true" android:permission="com.google.android.apps.mytracks.WRITE_TRACK_DATA" /> + + @@ -189,7 +192,6 @@ limitations under the License. - @@ -231,7 +233,7 @@ limitations under the License. android:permissionGroup="android.permission-group.LOCATION" android:label="@string/notification_permission_label" android:description="@string/notification_permission_description" - android:protectionLevel="normal" /> + android:protectionLevel="dangerous" /> + + + - + diff --git a/MyTracks/res/values/do_not_translate.xml b/MyTracks/res/values/do_not_translate.xml index e6e472948..c7cd1fe93 100644 --- a/MyTracks/res/values/do_not_translate.xml +++ b/MyTracks/res/values/do_not_translate.xml @@ -50,4 +50,11 @@ limitations under the License. android.intent.action.SAVE android.intent.action.settings.OPEN + com.google.android.apps.mytracks.START_NEW_TRACK + com.google.android.apps.mytracks.END_CURRENT_TRACK + + + + + com.google.android.apps.mytracks.MYTRACKS_NOTIFICATIONS diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index add11edba..1bdfa390f 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -15,7 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - + + allowAccess announcementFrequency antHeartRateSensorId antPowerSensorId @@ -35,30 +36,34 @@ limitations under the License. reportSpeed sendStatsAndPoints sendToDocs - sendToMyMaps sendToFusionTables + sendToMyMaps sensorType shareUrlOnly splitFrequency timestampTrackName - trackColorMode - trackColorModeFixedSlow + trackColorModeDynamicVariation + + trackColorModeFixedMediumDisplay + trackColorModeFixedMedium - trackColorModeFixedSlowDisplay - trackColorModeFixedMediumDisplay - trackColorModeDynamicVariation - - + trackColorModeFixedSlowDisplay + + trackColorModeFixedSlow + trackColorMode + + autoResumeTrackCurrentRetry recordingTrack selectedTrack - - backupToSd - restoreFromSd - resetToDefaults - sensorOptions + antOptions + backupToSd displaySettingsScreen + resetToDefaults + restoreFromSd + sensorOptions trackColorModeFixedOptions diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 4a6f939d0..9a2d6198f 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -208,6 +208,15 @@ limitations under the License. Not available in your version of Android Not available while recording a track + Allow access + Other apps can read, write, start/stop recording + MyTracks data. + Other apps cannot read, write, start/stop + recording MyTracks data. + Are you sure you want to allow other apps, + including future apps, to control and access MyTracks data? There will be no further + notification. + Announcement frequency Minimum time between two voice announcements @@ -518,11 +527,14 @@ limitations under the License. receive MyTracks notifications + receive MyTracks notifications read MyTracks data write data to MyTracks and start/stop MyTracks recording Allows the application to receive notifications when MyTracks starts or stops a recording. + receive MyTracks notifications + Allows the application to read MyTracks data. Allows the application to write data to diff --git a/MyTracks/res/xml/preferences.xml b/MyTracks/res/xml/preferences.xml index f4cb8d523..24dcf68ed 100644 --- a/MyTracks/res/xml/preferences.xml +++ b/MyTracks/res/xml/preferences.xml @@ -209,6 +209,13 @@ limitations under the License. android:summaryOn="@string/settings_share_url_only_summary_on" android:summaryOff="@string/settings_share_url_only_summary_off" android:defaultValue="false" /> + + diff --git a/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java index 559d9af31..27b19779e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java @@ -142,6 +142,33 @@ public class SettingsActivity extends PreferenceActivity { return true; } }); + + // Add a confirmation dialog for the "Allow access" preference. + final CheckBoxPreference allowAccessPreference = (CheckBoxPreference) findPreference( + getString(R.string.allow_access_key)); + allowAccessPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if ((Boolean) newValue) { + AlertDialog dialog = new AlertDialog.Builder(SettingsActivity.this) + .setCancelable(true) + .setTitle(getString(R.string.settings_allow_access)) + .setMessage(getString(R.string.settings_allow_access_dialog_message)) + .setPositiveButton(android.R.string.ok, new OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int button) { + allowAccessPreference.setChecked(true); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .create(); + dialog.show(); + return false; + } else { + return true; + } + } + }); } private boolean processIntent() { diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java index bcf874c35..af3d57550 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java @@ -17,11 +17,13 @@ package com.google.android.apps.mytracks.content; import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.util.ApiFeatures; +import com.google.android.maps.mytracks.R; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; +import android.content.SharedPreferences; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; @@ -30,6 +32,8 @@ import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; +import android.os.Binder; +import android.os.Process; import android.text.TextUtils; import android.util.Log; @@ -183,8 +187,22 @@ public class MyTracksProvider extends ContentProvider { "waypoints/#", WAYPOINTS_ID); } + private boolean canAccess() { + if (Binder.getCallingPid() == Process.myPid()) { + return true; + } else { + Context context = getContext(); + SharedPreferences sharedPreferences = context.getSharedPreferences( + Constants.SETTINGS_NAME, 0); + return sharedPreferences.getBoolean(context.getString(R.string.allow_access_key), false); + } + } + @Override public boolean onCreate() { + if (!canAccess()) { + return false; + } DatabaseHelper dbHelper = new DatabaseHelper(getContext()); try { db = dbHelper.getWritableDatabase(); @@ -196,6 +214,9 @@ public class MyTracksProvider extends ContentProvider { @Override public int delete(Uri url, String where, String[] selectionArgs) { + if (!canAccess()) { + return 0; + } String table; boolean shouldVacuum = false; switch (urlMatcher.match(url)) { @@ -228,6 +249,9 @@ public class MyTracksProvider extends ContentProvider { @Override public String getType(Uri url) { + if (!canAccess()) { + return null; + } switch (urlMatcher.match(url)) { case TRACKPOINTS: return TrackPointsColumns.CONTENT_TYPE; @@ -248,6 +272,9 @@ public class MyTracksProvider extends ContentProvider { @Override public Uri insert(Uri url, ContentValues initialValues) { + if (!canAccess()) { + return null; + } Log.d(MyTracksProvider.TAG, "MyTracksProvider.insert"); ContentValues values; if (initialValues != null) { @@ -276,6 +303,9 @@ public class MyTracksProvider extends ContentProvider { @Override public int bulkInsert(Uri url, ContentValues[] valuesBulk) { + if (!canAccess()) { + return 0; + } Log.d(MyTracksProvider.TAG, "MyTracksProvider.bulkInsert"); int numInserted = 0; try { @@ -348,6 +378,9 @@ public class MyTracksProvider extends ContentProvider { public Cursor query( Uri url, String[] projection, String selection, String[] selectionArgs, String sort) { + if (!canAccess()) { + return null; + } SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); int match = urlMatcher.match(url); String sortOrder = null; @@ -399,6 +432,9 @@ public class MyTracksProvider extends ContentProvider { @Override public int update(Uri url, ContentValues values, String where, String[] selectionArgs) { + if (!canAccess()) { + return 0; + } int count; int match = urlMatcher.match(url); if (match == TRACKPOINTS) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/ControlRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/ControlRecordingService.java new file mode 100644 index 000000000..e0f70553e --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/ControlRecordingService.java @@ -0,0 +1,119 @@ +/* + * 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.services; + +import static com.google.android.apps.mytracks.Constants.TAG; + +import com.google.android.apps.mytracks.widgets.TrackWidgetProvider; +import com.google.android.maps.mytracks.R; + +import android.app.IntentService; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +/** + * A service to control starting and stopping of a recording. This service, + * through the AndroidManifest.xml, is configured to only allow components of + * the same application to invoke it. Thus this service can be used my MyTracks + * app widget, {@link TrackWidgetProvider}, but not by other applications. This + * application delegates starting and stopping a recording to + * {@link TrackRecordingService} using RPC calls. + * + * @author jshih@google.com (Jimmy Shih) + */ +public class ControlRecordingService extends IntentService implements ServiceConnection { + + private ITrackRecordingService trackRecordingService; + private boolean connected = false; + + public ControlRecordingService() { + super(ControlRecordingService.class.getSimpleName()); + } + + @Override + public void onCreate() { + super.onCreate(); + + Intent newIntent = new Intent(this, TrackRecordingService.class); + startService(newIntent); + bindService(newIntent, this, 0); + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + trackRecordingService = ITrackRecordingService.Stub.asInterface(service); + notifyConnected(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + connected = false; + } + + /** + * Notifies all threads that connection to {@link TrackRecordingService} is + * available. + */ + private synchronized void notifyConnected() { + connected = true; + notifyAll(); + } + + /** + * Waits until the connection to {@link TrackRecordingService} is available. + */ + private synchronized void waitConnected() { + while (!connected) { + try { + wait(); + } catch (InterruptedException e) { + + // can safely ignore + } + } + } + + @Override + protected void onHandleIntent(Intent intent) { + waitConnected(); + String action = intent.getAction(); + if (action != null) { + try { + if (action.equals(getString(R.string.start_new_track_action))) { + trackRecordingService.startNewTrack(); + } else if (action.equals(getString(R.string.end_current_track_action))) { + trackRecordingService.endCurrentTrack(); + } + } catch (RemoteException e) { + Log.d(TAG, "ControlRecordingService onHandleIntent RemoteException", e); + } + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (connected) { + unbindService(this); + connected = false; + } + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java index f89f65e45..b6951394c 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -56,11 +56,13 @@ import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.net.Uri; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; +import android.os.Process; import android.util.Log; import java.util.Timer; @@ -278,39 +280,24 @@ public class TrackRecordingService extends Service { handleStartCommand(intent, startId); return START_STICKY; } - + + /** + * Handles onStart and onStartCommand. This service, through the + * AndroidManifest.xml, is configured to allow both MyTracks and other + * applications to invoke it. With only the intent, we cannot tell whether the + * caller is MyTracks or another app. Thus when starting the service through + * this method, we cannot read/write MyTracks data or start/stop a recording. + */ private void handleStartCommand(Intent intent, int startId) { - Log.d(TAG, - "TrackRecordingService.handleStartCommand: " + startId); + Log.d(TAG, "TrackRecordingService.handleStartCommand: " + startId); - if (intent == null) + if (intent == null) { return; - + } + // Check if called on phone reboot with resume intent. if (intent.getBooleanExtra(RESUME_TRACK_EXTRA_NAME, false)) { resumeTrack(startId); - } else { - // Process actions for controlling the service. - processStartStopIntent(intent); - } - } - - private void processStartStopIntent(Intent intent) { - String action = intent.getAction(); - - if (isNewTrackAction(action)) { - if (!isTrackInProgress()) { - boolean selectNewTrack = intent.getBooleanExtra(getString(R.string.select_new_track_extra), false); - - startNewTrack(); - if (selectNewTrack) { - prefManager.setSelectedTrack(recordingTrackId); - } - } - } else if (isEndTrackAction(action)) { - if (isTrackInProgress()) { - endCurrentTrack(); - } } } @@ -318,14 +305,6 @@ public class TrackRecordingService extends Service { return recordingTrackId != -1 || isRecording; } - private boolean isNewTrackAction(String action) { - return getString(R.string.start_new_track_action).equals(action); - } - - private boolean isEndTrackAction(String action) { - return getString(R.string.end_current_track_action).equals(action); - } - private void resumeTrack(int startId) { Log.d(TAG, "TrackRecordingService: requested resume"); @@ -574,7 +553,7 @@ public class TrackRecordingService extends Service { public long startNewTrack() { Log.d(TAG, "TrackRecordingService.startNewTrack"); if (isTrackInProgress()) { - throw new IllegalStateException("A track is already in progress!"); + return -1L; } long startTime = System.currentTimeMillis(); @@ -982,8 +961,7 @@ public class TrackRecordingService extends Service { * Build a statistics marker. * A statistics marker holds the stats for the* last segment up to this marker. * - * @param Waypoint The waypoint which will be populated with stats data. - * @return the unique id of the inserted marker + * @param waypoint The waypoint which will be populated with stats data. */ private void buildStatisticsMarker(Waypoint waypoint) { StringUtils utils = new StringUtils(TrackRecordingService.this); @@ -1012,7 +990,7 @@ public class TrackRecordingService extends Service { private void endCurrentTrack() { Log.d(TAG, "TrackRecordingService.endCurrentTrack"); if (!isTrackInProgress()) { - throw new IllegalStateException("No recording track in progress!"); + return; } announcementExecutor.shutdown(); @@ -1053,12 +1031,14 @@ public class TrackRecordingService extends Service { } private void sendTrackBroadcast(int actionResId, long trackId) { - Intent broadcastIntent = - new Intent() - .setAction(getString(actionResId)) - .putExtra(getString(R.string.track_id_broadcast_extra), trackId); - sendBroadcast(broadcastIntent, - getString(R.string.broadcast_notifications_permission)); + Intent broadcastIntent = new Intent().setAction(getString(actionResId)).putExtra( + getString(R.string.track_id_broadcast_extra), trackId); + sendBroadcast(broadcastIntent, getString(R.string.mytracks_notifications_permission)); + + SharedPreferences sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, 0); + if (sharedPreferences.getBoolean(getString(R.string.allow_access_key), false)) { + sendBroadcast(broadcastIntent, getString(R.string.broadcast_notifications_permission)); + } } /* @@ -1190,29 +1170,58 @@ public class TrackRecordingService extends Service { } } + /** + * Checks if the service is available. If not, throws an + * {@link IllegalStateException}. + */ private void checkService() { if (service == null) { throw new IllegalStateException("The service has been already detached!"); } } + + /** + * 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 + * RPCs. + */ + private boolean canAccess() { + + // As a precondition for access, must check if the service is available. + checkService(); + + if (Process.myPid() == Binder.getCallingPid()) { + return true; + } else { + SharedPreferences sharedPreferences = service.getSharedPreferences( + Constants.SETTINGS_NAME, 0); + return sharedPreferences.getBoolean(service.getString(R.string.allow_access_key), false); + } + } // Service method delegates. @Override public boolean isRecording() { - checkService(); + if (!canAccess()) { + return false; + } return service.isRecording(); } @Override public long getRecordingTrackId() { - checkService(); + if (!canAccess()) { + return -1L; + } return service.recordingTrackId; } @Override public long startNewTrack() { - checkService(); + if (!canAccess()) { + return -1L; + } return service.startNewTrack(); } @@ -1223,25 +1232,33 @@ public class TrackRecordingService extends Service { * @return the unique ID of the inserted marker */ public long insertWaypoint(WaypointCreationRequest request) { - checkService(); + if (!canAccess()) { + return -1L; + } return service.insertWaypoint(request); } @Override public void endCurrentTrack() { - checkService(); + if (!canAccess()) { + return; + } service.endCurrentTrack(); } @Override public void recordLocation(Location loc) { - checkService(); + if (!canAccess()) { + return; + } service.locationListener.onLocationChanged(loc); } @Override public byte[] getSensorData() { - checkService(); + if (!canAccess()) { + return null; + } if (service.sensorManager == null) { Log.d(TAG, "No sensor manager for data."); return null; @@ -1255,7 +1272,9 @@ public class TrackRecordingService extends Service { @Override public int getSensorState() { - checkService(); + if (!canAccess()) { + return Sensor.SensorState.NONE.getNumber(); + } if (service.sensorManager == null) { Log.d(TAG, "No sensor manager for data."); return Sensor.SensorState.NONE.getNumber(); diff --git a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java index 5ee51fdc0..e62a05a26 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java +++ b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java @@ -19,6 +19,16 @@ package com.google.android.apps.mytracks.widgets; import static com.google.android.apps.mytracks.Constants.SETTINGS_NAME; import static com.google.android.apps.mytracks.Constants.TAG; +import com.google.android.apps.mytracks.MyTracks; +import com.google.android.apps.mytracks.content.MyTracksProviderUtils; +import com.google.android.apps.mytracks.content.Track; +import com.google.android.apps.mytracks.content.TracksColumns; +import com.google.android.apps.mytracks.services.ControlRecordingService; +import com.google.android.apps.mytracks.stats.TripStatistics; +import com.google.android.apps.mytracks.util.StringUtils; +import com.google.android.apps.mytracks.util.UnitConversions; +import com.google.android.maps.mytracks.R; + import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; @@ -32,16 +42,6 @@ import android.os.Handler; import android.util.Log; import android.widget.RemoteViews; -import com.google.android.apps.mytracks.MyTracks; -import com.google.android.apps.mytracks.content.MyTracksProviderUtils; -import com.google.android.apps.mytracks.content.Track; -import com.google.android.apps.mytracks.content.TracksColumns; -import com.google.android.apps.mytracks.services.TrackRecordingService; -import com.google.android.apps.mytracks.stats.TripStatistics; -import com.google.android.apps.mytracks.util.StringUtils; -import com.google.android.apps.mytracks.util.UnitConversions; -import com.google.android.maps.mytracks.R; - /** * An AppWidgetProvider for displaying key track statistics (distance, time, * speed) from the current or most recent track. @@ -175,14 +175,12 @@ public class TrackWidgetProvider // If a new track is started by this appwidget or elsewhere, // toggle the button to active and have it disable the track if pressed. setButtonIntent( - views, context, R.string.end_current_track_action, R.drawable.appwidget_button_enabled, - -1); + views, context, R.string.end_current_track_action, R.drawable.appwidget_button_enabled); } else { // If a track is stopped by this appwidget or elsewhere, // toggle the button to inactive and have it start a new track if pressed. setButtonIntent( - views, context, R.string.start_new_track_action, R.drawable.appwidget_button_disabled, - R.string.select_new_track_extra); + views, context, R.string.start_new_track_action, R.drawable.appwidget_button_disabled); } } @@ -193,15 +191,11 @@ public class TrackWidgetProvider * @param context The widget context * @param action The resource id of the action to fire when the button is pressed * @param icon The resource id of the icon to show for the button - * @param extra Optional resource id of a boolean extra on the intent */ private void setButtonIntent( - RemoteViews views, Context context, int action, int icon, int extra) { - Intent intent = new Intent(context, TrackRecordingService.class); + RemoteViews views, Context context, int action, int icon) { + Intent intent = new Intent(context, ControlRecordingService.class); intent.setAction(context.getString(action)); - if (extra != -1) { - intent.putExtra(context.getString(extra), true); - } PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.appwidget_button, pendingIntent); diff --git a/MyTracksLib/res/values/third_party.xml b/MyTracksLib/res/values/third_party.xml index 00fc3dd15..cac53b825 100644 --- a/MyTracksLib/res/values/third_party.xml +++ b/MyTracksLib/res/values/third_party.xml @@ -23,20 +23,9 @@ limitations under the License. com.google.android.apps.mytracks.TRACK_STARTED - com.google.android.apps.mytracks.TRACK_PAUSED - com.google.android.apps.mytracks.TRACK_RESUMED com.google.android.apps.mytracks.TRACK_STOPPED com.google.android.apps.mytracks.TRACK_ID - - com.google.android.apps.mytracks.START_NEW_TRACK - - com.google.android.apps.mytracks.SELECT_NEW_TRACK - com.google.android.apps.mytracks.END_CURRENT_TRACK - com.google.android.apps.mytracks.services.TrackRecordingService com.google.android.maps.mytracks diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/MapOverlayTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/MapOverlayTest.java index 49a91b49b..72b1b9d42 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/MapOverlayTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/MapOverlayTest.java @@ -63,7 +63,6 @@ public class MapOverlayTest extends AndroidTestCase { assertEquals(2, myTracksOverlay.getNumLocations()); assertEquals(0, myTracksOverlay.getNumWaypoints()); assertNotNull(myTracksOverlay.getLastPath()); - assertEquals(2, ((MockPath)myTracksOverlay.getLastPath()).totalPoints); myTracksOverlay.draw(canvas, mockView, true); assertEquals(2, myTracksOverlay.getNumLocations()); @@ -152,11 +151,8 @@ public class MapOverlayTest extends AndroidTestCase { // No shadow. myTracksOverlay.draw(canvas, mockView, false); assertNotNull(myTracksOverlay.getLastPath()); - assertTrue(myTracksOverlay.getLastPath() instanceof MockPath); - MockPath path = (MockPath) myTracksOverlay.getLastPath(); assertEquals(40, myTracksOverlay.getNumWaypoints()); assertEquals(100, myTracksOverlay.getNumLocations()); - assertEquals(100, path.totalPoints); // TODO: Check the points from the path (and the segments). } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorDynamicSpeedTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorDynamicSpeedTest.java index 63eec1182..40d894aaa 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorDynamicSpeedTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorDynamicSpeedTest.java @@ -15,8 +15,6 @@ */ package com.google.android.apps.mytracks.maps; -import com.google.android.apps.mytracks.MockPath; - import android.location.Location; /** @@ -45,9 +43,6 @@ public class TrackPathDescriptorDynamicSpeedTest extends TrackPathPainterTestCas painter.updatePath(myTracksOverlay.getMapProjection(mockView), myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible, myTracksOverlay.getPoints()); - assertNotNull(myTracksOverlay.getLastPath()); - assertTrue(myTracksOverlay.getLastPath() instanceof MockPath); - painter.drawTrack(canvas); - + painter.drawTrack(canvas); } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorFixedSpeedTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorFixedSpeedTest.java index d78c02fcb..b71037045 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorFixedSpeedTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathDescriptorFixedSpeedTest.java @@ -15,8 +15,6 @@ */ package com.google.android.apps.mytracks.maps; -import com.google.android.apps.mytracks.MockPath; - import android.location.Location; /** @@ -45,8 +43,6 @@ public class TrackPathDescriptorFixedSpeedTest extends TrackPathPainterTestCase painter.updatePath(myTracksOverlay.getMapProjection(mockView), myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible, myTracksOverlay.getPoints()); - assertNotNull(myTracksOverlay.getLastPath()); - assertTrue(myTracksOverlay.getLastPath() instanceof MockPath); painter.drawTrack(canvas); } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterFactoryTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterFactoryTest.java index 83482b26b..ea57ef7b6 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterFactoryTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterFactoryTest.java @@ -16,7 +16,6 @@ package com.google.android.apps.mytracks.maps; import com.google.android.apps.mytracks.Constants; -import com.google.android.apps.mytracks.MockPath; import com.google.android.maps.mytracks.R; import android.content.Context; @@ -57,8 +56,8 @@ public class TrackPathPainterFactoryTest extends TrackPathPainterTestCase { private void testTrackPathPainterFactorySpecific(Context context, SharedPreferences prefs, int track_color_mode, Class c) { - prefs.edit().putString(context.getString(track_color_mode), - context.getString(R.string.track_color_mode_key)).commit(); + prefs.edit().putString(context.getString(R.string.track_color_mode_key), + context.getString(track_color_mode)).commit(); int startLocationIdx = 0; Boolean alwaysVisible = true; @@ -71,8 +70,6 @@ public class TrackPathPainterFactoryTest extends TrackPathPainterTestCase { painter.updatePath(myTracksOverlay.getMapProjection(mockView), myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible, myTracksOverlay.getPoints()); - assertNotNull(myTracksOverlay.getLastPath()); - assertTrue(myTracksOverlay.getLastPath() instanceof MockPath); painter.drawTrack(canvas); } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterSingleColorTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterSingleColorTest.java index 6c6682e32..f1c63cd64 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterSingleColorTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/maps/TrackPathPainterSingleColorTest.java @@ -15,8 +15,6 @@ */ package com.google.android.apps.mytracks.maps; -import com.google.android.apps.mytracks.MockPath; - import android.location.Location; /** @@ -45,8 +43,6 @@ public class TrackPathPainterSingleColorTest extends TrackPathPainterTestCase { painter.updatePath(myTracksOverlay.getMapProjection(mockView), myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible, myTracksOverlay.getPoints()); - assertNotNull(myTracksOverlay.getLastPath()); - assertTrue(myTracksOverlay.getLastPath() instanceof MockPath); painter.drawTrack(canvas); } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java index 87c2a35a5..4d58a101a 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java @@ -405,12 +405,10 @@ public class TrackRecordingServiceTest ITrackRecordingService service = bindAndGetService(createStartIntent()); assertTrue(service.isRecording()); - try { - service.startNewTrack(); - fail("Expecting IllegalStateException"); - } catch (IllegalStateException e) { - // Expected. - } + // Starting a new track when there is a recording should just return -1L. + long newTrack = service.startNewTrack(); + assertEquals(-1L, newTrack); + assertEquals(123, sharedPreferences.getLong( context.getString(R.string.recording_track_key), 0)); assertEquals(123, service.getRecordingTrackId()); @@ -452,13 +450,9 @@ public class TrackRecordingServiceTest ITrackRecordingService service = bindAndGetService(createStartIntent()); assertFalse(service.isRecording()); - // End the current track. - try { - service.endCurrentTrack(); - fail("Expecting IllegalStateException"); - } catch (IllegalStateException e) { - // Expected. - } + // Ending the current track when there is no recording should not result in any error. + service.endCurrentTrack(); + assertEquals(-1, sharedPreferences.getLong( context.getString(R.string.recording_track_key), 0)); assertEquals(-1, service.getRecordingTrackId());