From a0da23f86ae8434566382e6cb73938eaff21a745 Mon Sep 17 00:00:00 2001 From: Bartlomiej Niechwiej Date: Mon, 15 Nov 2010 23:09:18 -0800 Subject: [PATCH] Various fixes to shared preferences. --- .../android/apps/mytracks/MyTracks.java | 5 + .../mytracks/services/PreferenceManager.java | 15 +-- .../apps/mytracks/services/SplitManager.java | 2 + .../services/StatusAnnouncerTask.java | 4 +- .../services/TrackRecordingService.java | 47 +++++---- .../android/apps/mytracks/MyTracksTest.java | 96 ++++++++++++++++++- 6 files changed, 142 insertions(+), 27 deletions(-) diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java index be2e75360..7ef2f2dae 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java @@ -1343,4 +1343,9 @@ public class MyTracks extends TabActivity implements OnTouchListener, static void clearInstance() { instance = null; } + + // @VisibleForTesting + ITrackRecordingService getTrackRecordingService() { + return trackRecordingService; + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java index 311c17526..5081094d3 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java @@ -42,13 +42,9 @@ public class PreferenceManager { private final String signalSamplingFrequencyKey; private final String splitFrequencyKey; - private final SharedPreferences sharedPreferences; - public PreferenceManager(TrackRecordingService service) { this.service = service; - this.sharedPreferences = - service.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0); - if (sharedPreferences == null) { + if (getSharedPreferences() == null) { Log.w(MyTracksConstants.TAG, "TrackRecordingService: Couldn't get shared preferences."); throw new IllegalStateException("Couldn't get shared preferences"); @@ -85,6 +81,7 @@ public class PreferenceManager { * @param key the key that changed (may be null to update all preferences) */ public void onSharedPreferenceChanged(String key) { + SharedPreferences sharedPreferences = getSharedPreferences(); if (key == null || key.equals(minRecordingDistanceKey)) { service.setMinRecordingDistance( sharedPreferences.getInt( @@ -163,14 +160,18 @@ public class PreferenceManager { } public void setAutoResumeTrackCurrentRetry(int retryAttempts) { - SharedPreferences.Editor editor = sharedPreferences.edit(); + SharedPreferences.Editor editor = getSharedPreferences().edit(); editor.putInt(autoResumeTrackCurrentRetryKey, retryAttempts); editor.commit(); } public void setRecordingTrack(long id) { - Editor editor = sharedPreferences.edit(); + Editor editor = getSharedPreferences().edit(); editor.putLong(recordingTrackKey, id); editor.commit(); } + + private SharedPreferences getSharedPreferences() { + return service.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0); + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/SplitManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/SplitManager.java index 39f4c61ee..79533e202 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/SplitManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/SplitManager.java @@ -125,6 +125,8 @@ public class SplitManager { * @param splitFrequency The frequency in time or distance */ public void setSplitFrequency(int splitFrequency) { + Log.d(MyTracksConstants.TAG, + "setSplitFrequency: splitFrequency = " + splitFrequency); this.splitFrequency = splitFrequency; // TODO: Decouple service from this class once and forever. diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java index 5d2186d05..25571d515 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java @@ -34,7 +34,7 @@ import android.util.Log; import java.util.Locale; /** - * This class will periodically announce the user's trip statitics. + * This class will periodically announce the user's trip statistics. * * @author Sandor Dornbush */ @@ -61,7 +61,7 @@ public class StatusAnnouncerTask implements PeriodicTask { private TextToSpeech tts; /** - * The response recieved from the TTS engine ater initialization. + * The response received from the TTS engine after initialization. */ private boolean ready = 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 788febe5d..fb1a0ad97 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -166,17 +166,17 @@ public class TrackRecordingService extends Service implements LocationListener { /** * Is the service currently recording a track? */ - private boolean isRecording = false; + private boolean isRecording; /** * Last good location the service has received from the location listener */ - private Location lastLocation = null; + private Location lastLocation; /** * Last valid location (i.e. not a marker) that was recorded. */ - private Location lastValidLocation = null; + private Location lastValidLocation; /** * The frequency of status announcements. @@ -617,14 +617,19 @@ public class TrackRecordingService extends Service implements LocationListener { * * @param key the key that changed (may be null to update all preferences) */ - public void onSharedPreferenceChanged(String key) { + public void onSharedPreferenceChanged(final String key) { Log.d(MyTracksConstants.TAG, "TrackRecordingService.onSharedPreferenceChanged"); - prefManager.onSharedPreferenceChanged(key); + handler.post(new Runnable() { + @Override + public void run() { + prefManager.onSharedPreferenceChanged(key); - if (isRecording) { - registerLocationListener(); - } + if (isRecording) { + registerLocationListener(); + } + } + }); } /* @@ -682,15 +687,23 @@ public class TrackRecordingService extends Service implements LocationListener { Log.d(MyTracksConstants.TAG, "TrackRecordingService.setUpAnnouncer: " + announcementExecuter); if (announcementFrequency != -1 && recordingTrackId != -1) { - if (announcementExecuter == null) { - StatusAnnouncerFactory statusAnnouncerFactory = - new StatusAnnouncerFactory(ApiFeatures.getInstance()); - PeriodicTask announcer = statusAnnouncerFactory.create(this); - if (announcer == null) return; - - announcementExecuter = new PeriodicTaskExecuter(announcer, this); - } - announcementExecuter.scheduleTask(announcementFrequency * 60000); + handler.post(new Runnable() { + @Override + public void run() { + if (announcementExecuter == null) { + StatusAnnouncerFactory statusAnnouncerFactory = + new StatusAnnouncerFactory(ApiFeatures.getInstance()); + PeriodicTask announcer = statusAnnouncerFactory.create( + TrackRecordingService.this); + if (announcer == null) { + return; + } + announcementExecuter = new PeriodicTaskExecuter(announcer, + TrackRecordingService.this); + } + announcementExecuter.scheduleTask(announcementFrequency * 60000); + } + }); } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/MyTracksTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/MyTracksTest.java index 5ade845eb..8d5887e40 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/MyTracksTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/MyTracksTest.java @@ -15,13 +15,17 @@ */ package com.google.android.apps.mytracks; +import com.google.android.apps.mytracks.services.ITrackRecordingService; import com.google.android.maps.mytracks.R; +import android.app.Activity; +import android.app.Instrumentation.ActivityMonitor; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.net.Uri; import android.test.ActivityInstrumentationTestCase2; +import android.widget.Button; import java.io.File; import java.util.concurrent.TimeoutException; @@ -47,6 +51,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2{ @Override protected void tearDown() throws Exception { clearSelectedAndRecordingTracks(); + waitForIdle(); super.tearDown(); } @@ -134,6 +139,65 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2{ assertNotNull(getActivity()); assertNotNull(MyTracks.getInstance()); assertNotNull(getActivity().getSharedPreferences()); + + // Check if not recording. + clearSelectedAndRecordingTracks(); + waitForIdle(); + + assertFalse(getActivity().isRecording()); + assertEquals(-1, getActivity().getRecordingTrackId()); + long selectedTrackId = getActivity().getSharedPreferences().getLong( + getActivity().getString(R.string.selected_track_key), -1); + assertEquals(selectedTrackId, getActivity().getSelectedTrackId()); + + // Start a new track. + getActivity().startRecording(); + long recordingTrackId = awaitRecordingStatus(5000, true); + assertTrue(recordingTrackId >= 0); + + // Wait until we are done and make sure that selectedTrack = recordingTrack. + waitForIdle(); + assertEquals(recordingTrackId, getActivity().getSharedPreferences().getLong( + getActivity().getString(R.string.recording_track_key), -1)); + selectedTrackId = getActivity().getSharedPreferences().getLong( + getActivity().getString(R.string.selected_track_key), -1); + assertEquals(recordingTrackId, selectedTrackId); + assertEquals(selectedTrackId, getActivity().getSelectedTrackId()); + + // Watch for MyTracksDetails activity. + ActivityMonitor monitor = getInstrumentation().addMonitor( + MyTracksDetails.class.getName(), null, false); + + // Now, stop the track and make sure that it is still selected, but + // no longer recording. + getActivity().stopRecording(); + + // Check if we got back MyTracksDetails activity. + Activity activity = getInstrumentation().waitForMonitor(monitor); + assertTrue(activity instanceof MyTracksDetails); + + // TODO: Update track name and other properties and test if they were + // properly saved. + + // Simulate a click on Save button. + Button save = (Button) activity.findViewById(R.id.trackdetails_save); + save.performClick(); + + // Check the remaining properties. + recordingTrackId = awaitRecordingStatus(5000, false); + assertEquals(-1, recordingTrackId); + assertEquals(recordingTrackId, getActivity().getRecordingTrackId()); + assertEquals(recordingTrackId, getActivity().getSharedPreferences().getLong( + getActivity().getString(R.string.recording_track_key), -1)); + // Make sure this is the same track as the last recording track ID. + assertEquals(selectedTrackId, getActivity().getSelectedTrackId()); + } + + public void testRecording_changePreferences() throws Exception { + // Make sure we can start MyTracks and the activity doesn't start recording. + assertNotNull(getActivity()); + assertNotNull(MyTracks.getInstance()); + assertNotNull(getActivity().getSharedPreferences()); // Check if not recording. clearSelectedAndRecordingTracks(); @@ -157,10 +221,39 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2{ getActivity().getString(R.string.selected_track_key), -1); assertEquals(recordingTrackId, selectedTrackId); assertEquals(selectedTrackId, getActivity().getSelectedTrackId()); + + // Change shared preferences and observe if the service notices the change. + Editor editor = getActivity().getSharedPreferences().edit(); + editor.putInt(getActivity().getString(R.string.announcement_frequency_key), + 1); + editor.putInt(getActivity().getString(R.string.split_frequency_key), 1); + editor.putInt( + getActivity().getString(R.string.signal_sampling_frequency_key), 1); + editor.commit(); + + // Notify the service about changed preferences. + ITrackRecordingService service = getActivity().getTrackRecordingService(); + assertNotNull(service); + service.sharedPreferenceChanged(null); + + // TODO: Test if the service has updated its preferences. + + // Watch for MyTracksDetails activity. + ActivityMonitor monitor = getInstrumentation().addMonitor( + MyTracksDetails.class.getName(), null, false); // Now, stop the track and make sure that it is still selected, but // no longer recording. getActivity().stopRecording(); + + // Check if we got back MyTracksDetails activity. + Activity activity = getInstrumentation().waitForMonitor(monitor); + assertTrue(activity instanceof MyTracksDetails); + // Simulate a click on Save button. + Button save = (Button) activity.findViewById(R.id.trackdetails_save); + save.performClick(); + + // Check if after stopping the service all properties are up to date. recordingTrackId = awaitRecordingStatus(5000, false); assertEquals(-1, recordingTrackId); assertEquals(recordingTrackId, getActivity().getRecordingTrackId()); @@ -197,10 +290,11 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2{ * Clears {selected,recording}TrackId in the {@link SharedPreferences}. */ private void clearSelectedAndRecordingTracks() { - // TODO: Consider clearing all preferences. Editor editor = getActivity().getSharedPreferences().edit(); editor.putLong(getActivity().getString(R.string.selected_track_key), -1); editor.putLong(getActivity().getString(R.string.recording_track_key), -1); + + editor.clear(); editor.commit(); }