diff --git a/MyTracks/.classpath b/MyTracks/.classpath index 3d5ddb422..ecdfd68ee 100644 --- a/MyTracks/.classpath +++ b/MyTracks/.classpath @@ -6,7 +6,7 @@ - + diff --git a/MyTracks/res/layout/about.xml b/MyTracks/res/layout/about.xml index 753d860e8..0870154b7 100644 --- a/MyTracks/res/layout/about.xml +++ b/MyTracks/res/layout/about.xml @@ -41,8 +41,7 @@ limitations under the License. - + - + - + - + + + + + + + + diff --git a/MyTracks/res/values/do_not_translate.xml b/MyTracks/res/values/do_not_translate.xml index 32095d881..861738bf7 100644 --- a/MyTracks/res/values/do_not_translate.xml +++ b/MyTracks/res/values/do_not_translate.xml @@ -21,6 +21,7 @@ limitations under the License. mytracks@googlegroups.com mytracks.appspot.com + m.google.com/privacy Copyright 2009 Google Inc. Bartlomiej Niechwiej Dylan Casey diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 487afee53..a838c30c1 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -104,6 +104,7 @@ limitations under the License. Error Success Waypoint + License (Start) @@ -378,8 +379,8 @@ limitations under the License. Help Team: Version: - Support Support: + Privacy: Send to... diff --git a/MyTracks/src/com/google/android/apps/mytracks/Eula.java b/MyTracks/src/com/google/android/apps/mytracks/Eula.java index 4471d93fc..aed5a40a0 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/Eula.java +++ b/MyTracks/src/com/google/android/apps/mytracks/Eula.java @@ -21,38 +21,37 @@ import com.google.android.maps.mytracks.R; import android.app.Activity; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; /** - * Displays an EULA ("End User License Agreement") that the user has to accept - * before using the application. Your application should call - * {@link Eula#showEula(android.app.Activity)} in the onCreate() method of the - * first activity. If the user accepts the EULA, it will never be shown again. - * If the user refuses, {@link android.app.Activity#finish()} is invoked on your - * activity. + * This class handles display of EULAs ("End User License Agreements") to the + * user. */ class Eula { private static final String PREFERENCE_EULA_ACCEPTED = "eula.accepted"; private static final String PREFERENCES_EULA = "eula"; + private Eula() {} + /** * Displays the EULA if necessary. This method should be called from the - * onCreate() method of your main Activity. + * onCreate() method of your main Activity. If the user accepts, the EULA + * will never be displayed again. If the user refuses, the activity will + * finish (exit). * * @param activity The Activity to finish if the user rejects the EULA */ - static void showEula(final Activity activity) { + static void showEulaRequireAcceptance(final Activity activity) { final SharedPreferences preferences = activity.getSharedPreferences(PREFERENCES_EULA, Activity.MODE_PRIVATE); if (preferences.getBoolean(PREFERENCE_EULA_ACCEPTED, false)) { return; } - final AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(R.string.eula_title); - builder.setCancelable(true); + final AlertDialog.Builder builder = initDialog(activity); builder.setPositiveButton(R.string.accept, new DialogInterface.OnClickListener() { @Override @@ -73,10 +72,28 @@ class Eula { refuse(activity); } }); - builder.setMessage(ResourceUtils.readFile(activity, R.raw.eula)); builder.show(); } + /** + * Display the EULA to the user in an informational context. They won't be + * given the choice of accepting or declining the EULA -- we're simply + * displaying it for them to read. + */ + static void showEula(Context context) { + AlertDialog.Builder builder = initDialog(context); + builder.setPositiveButton(R.string.ok, null); + builder.show(); + } + + private static AlertDialog.Builder initDialog(Context context) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setCancelable(true); + builder.setTitle(R.string.eula_title); + builder.setMessage(ResourceUtils.readFile(context, R.raw.eula)); + return builder; + } + private static void accept(Activity activity, SharedPreferences preferences) { ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges( preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true)); @@ -87,7 +104,4 @@ class Eula { private static void refuse(Activity activity) { activity.finish(); } - - private Eula() { - } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java index c4ed31c11..6cd26c3b5 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java @@ -315,7 +315,7 @@ public class MyTracks extends TabActivity implements OnTouchListener, } // This will show the eula until the user accepts or quits the app. - Eula.showEula(this); + Eula.showEulaRequireAcceptance(this); // Check if we got invoked via the VIEW intent: Intent intent = getIntent(); diff --git a/MyTracks/src/com/google/android/apps/mytracks/WelcomeActivity.java b/MyTracks/src/com/google/android/apps/mytracks/WelcomeActivity.java index 42edd66f6..cfbab6d73 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/WelcomeActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/WelcomeActivity.java @@ -19,6 +19,7 @@ import com.google.android.maps.mytracks.R; import android.app.Activity; import android.app.AlertDialog; +import android.content.DialogInterface; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -74,6 +75,12 @@ public class WelcomeActivity extends Activity { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setView(view); builder.setPositiveButton(R.string.ok, null); + builder.setNeutralButton(R.string.license, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Eula.showEula(WelcomeActivity.this); + } + }); builder.setIcon(R.drawable.arrow_icon); AlertDialog dialog = builder.create(); dialog.show(); 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 e35e5950b..576504d8a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -598,6 +598,8 @@ public class TrackRecordingService extends Service implements LocationListener { Log.d(MyTracksConstants.TAG, String.format( "Not recording. Distance to last recorded point (%f m) is less than" + " %d m.", distanceToLastRecorded, minRecordingDistance)); + // Return here so that the location is NOT recorded as the last location. + return; } } catch (Error e) { // Probably important enough to rethrow. diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/TrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/TrackWriterTest.java index 12542199b..73721214e 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/TrackWriterTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/TrackWriterTest.java @@ -2,31 +2,27 @@ package com.google.android.apps.mytracks.io; -import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.isA; -import static org.easymock.EasyMock.leq; -import static org.easymock.EasyMock.same; -import com.google.android.apps.mytracks.MyTracksConstants; +import com.google.android.apps.mytracks.content.MyTracksProvider; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; -import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; +import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory; +import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext; import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory; import android.content.Context; -import android.database.MatrixCursor; import android.location.Location; -import android.provider.BaseColumns; import android.test.AndroidTestCase; +import android.test.RenamingDelegatingContext; +import android.test.mock.MockContentResolver; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.OutputStream; import org.easymock.EasyMock; -import org.easymock.IAnswer; import org.easymock.IArgumentMatcher; import org.easymock.IMocksControl; @@ -138,12 +134,19 @@ public class TrackWriterTest extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); + MockContentResolver mockContentResolver = new MockContentResolver(); + RenamingDelegatingContext targetContext = new RenamingDelegatingContext( + getContext(), getContext(), "test."); + Context context = new MockContext(mockContentResolver, targetContext); + MyTracksProvider provider = new MyTracksProvider(); + provider.attachInfo(context, null); + mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider); + setContext(context); + providerUtils = MyTracksProviderUtils.Factory.get(context); + oldProviderUtilsFactory = TestingProviderUtilsFactory.installWithInstance(providerUtils); + mocksControl = EasyMock.createStrictControl(); formatWriter = mocksControl.createMock(TrackFormatWriter.class); - providerUtils = mocksControl.createMock(MyTracksProviderUtils.class); - oldProviderUtilsFactory = - TestingProviderUtilsFactory.installWithInstance(providerUtils); - expect(formatWriter.getExtension()).andStubReturn(EXTENSION); track = new Track(); @@ -225,13 +228,6 @@ public class TrackWriterTest extends AndroidTestCase { public void testWriteDocument_emptyTrack() { writer = new TrackWriter(getContext(), providerUtils, track, formatWriter); - // Don't let it write any waypoints - expect(providerUtils.getWaypointsCursor( - TRACK_ID, 0, MyTracksConstants.MAX_LOADED_WAYPOINTS_POINTS)) - .andStubReturn(null); - expect(providerUtils.getLocationsCursor( - eq(TRACK_ID), leq(0L), leq(0), eq(false))).andStubReturn(null); - // Set expected mock behavior formatWriter.writeHeader(); formatWriter.writeFooter(); @@ -253,7 +249,7 @@ public class TrackWriterTest extends AndroidTestCase { new Location("fake2"), new Location("fake3"), new Location("fake4"), - new Location("fake5"), + new Location("fake5") }; Waypoint[] wps = { new Waypoint(), new Waypoint(), new Waypoint() }; @@ -262,37 +258,14 @@ public class TrackWriterTest extends AndroidTestCase { // Make location 3 invalid locs[2].setLatitude(100); - - // Set up cursors - // We use fake columns since the cursor is only read by the provider utils - final MatrixCursor locCursor = - new MatrixCursor(new String[] { BaseColumns._ID }, 6); - for (int i = 1; i <= 6; i++) { - locCursor.newRow().add(i); + + assertEquals(locs.length, providerUtils.bulkInsertTrackPoints(locs, locs.length, TRACK_ID)); + for (int i = 0; i < wps.length; ++i) { + Waypoint wpt = wps[i]; + wpt.setTrackId(TRACK_ID); + assertNotNull(providerUtils.insertWaypoint(wpt)); + wpt.setId(i + 1); } - expect(providerUtils.getLocationsCursor( - eq(TRACK_ID), leq(0L), leq(0), eq(false))).andStubReturn(locCursor); - providerUtils.fillLocation(same(locCursor), isA(Location.class)); - EasyMock.expectLastCall().andStubAnswer(new IAnswer() { - @Override - public Void answer() throws Throwable { - Location loc = (Location) EasyMock.getCurrentArguments()[1]; - loc.set(locs[locCursor.getPosition()]); - return null; - } - }); - - MatrixCursor wpCursor = - new MatrixCursor(new String[] { BaseColumns._ID }, 3); - wpCursor.newRow().add(1); - wpCursor.newRow().add(2); - wpCursor.newRow().add(3); - expect(providerUtils.getWaypointsCursor( - eq(TRACK_ID), leq(0L), - eq(MyTracksConstants.MAX_LOADED_WAYPOINTS_POINTS))) - .andStubReturn(wpCursor); - expect(providerUtils.createWaypoint(wpCursor)) - .andStubAnswer(stubCursorToArray(wpCursor, wps)); // Begin the track formatWriter.writeHeader(); @@ -317,8 +290,8 @@ public class TrackWriterTest extends AndroidTestCase { formatWriter.writeEndTrack(locEq(locs[5])); // Expect reading/writing of the waypoints (except the first) - formatWriter.writeWaypoint(wps[1]); - formatWriter.writeWaypoint(wps[2]); + formatWriter.writeWaypoint(wptEq(wps[1])); + formatWriter.writeWaypoint(wptEq(wps[2])); formatWriter.writeFooter(); formatWriter.close(); @@ -330,6 +303,26 @@ public class TrackWriterTest extends AndroidTestCase { mocksControl.verify(); } + private static Waypoint wptEq(final Waypoint wpt) { + EasyMock.reportMatcher(new IArgumentMatcher() { + @Override + public boolean matches(Object wptObj2) { + if (wptObj2 == null || wpt == null) return wpt == wptObj2; + Waypoint wpt2 = (Waypoint) wptObj2; + + return wpt.getId() == wpt2.getId(); + } + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("wptEq("); + buffer.append(wpt); + buffer.append(")"); + } + }); + return null; + } + private static Location locEq(final Location loc) { EasyMock.reportMatcher(new IArgumentMatcher() { @Override @@ -359,23 +352,14 @@ public class TrackWriterTest extends AndroidTestCase { }); return null; } - - private IAnswer stubCursorToArray( - final MatrixCursor cursor, final T[] values) { - return new IAnswer() { - @Override - public T answer() throws Throwable { - return values[cursor.getPosition()]; - } - }; - } - + private void fillLocations(Location... locs) { assertTrue(locs.length < 90); for (int i = 0; i < locs.length; i++) { Location location = locs[i]; location.setLatitude(i + 1); location.setLongitude(i + 1); + location.setTime(i + 1000); } } } diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java index 210fefe02..8a9cf4cd3 100644 --- a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java @@ -19,7 +19,6 @@ import static com.google.android.apps.mytracks.signalstrength.SignalStrengthCons import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtilsImpl; -import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.WaypointCreationRequest; import com.google.android.apps.mytracks.services.ITrackRecordingService; import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback; @@ -56,7 +55,6 @@ public class SignalStrengthService extends Service private ITrackRecordingService mytracksService; private long lastSamplingTime; private long samplingPeriod; - private MyTracksProviderUtils utils; @Override public void onCreate() { @@ -67,7 +65,6 @@ public class SignalStrengthService extends Service getString(R.string.mytracks_service_class)); preferences = PreferenceManager.getDefaultSharedPreferences(this); signalListenerFactory = new SignalStrengthListenerFactory(); - utils = new MyTracksProviderUtilsImpl(this.getContentResolver()); } @Override