sync from main

This commit is contained in:
Jimmy Shih
2012-04-07 09:32:13 -07:00
27 changed files with 730 additions and 763 deletions
-14
View File
@@ -1,22 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="libs/googleloginclient-helper.jar"/>
<classpathentry exported="true" kind="lib" path="libs/google-common.jar"/>
<classpathentry kind="lib" path="libs/libGoogleAnalytics.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/commons-codec-1.3.jar"/>
<classpathentry exported="true" kind="lib" path="libs/google-api-client/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/google-api-client-1.5.0-beta.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/google-http-client-1.5.0-beta.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/google-oauth-client-1.5.0-beta.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/gson-1.6.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/guava-r09.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/jackson-core-asl-1.6.7.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/jsr305-1.3.9.jar"/>
<classpathentry kind="lib" path="libs/android-support-v4.jar"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/> <classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>
+20 -9
View File
@@ -3,10 +3,21 @@ own licenses, which allow their usage for the My Tracks application. Any other
applications that wish to use these files should consult the appropriate applications that wish to use these files should consult the appropriate
licenses or the JAR's authors. licenses or the JAR's authors.
google-api-client/ Android Support Package:
- see http://code.google.com/p/google-api-java-client/. android-support-v4.jar
- contains Google API client library, google-api-client-1.5.0-beta.jar, and its - see http://developer.android.com/sdk/compatibility-library.html
dependencies.
Google APIs Client Library for Java:
commons-codec-1.3.jar
commons-logging-1.1.1.jar
google-api-client-1.5.0-beta.jar
google-http-client-1.5.0-beta.jar
google-oauth-client-1.5.0-beta.jar
gson-1.6.jar
guava-r09.jar
jackson-core-asl-1.6.7.jar
jsr305-1.3.9.jar
- see http://code.google.com/p/google-api-java-client/
- google-api-client-1.5.0-beta.jar depends on protobuf-java-2.2.0.jar, however, - google-api-client-1.5.0-beta.jar depends on protobuf-java-2.2.0.jar, however,
MyTracksLib already includes protobuf-java.2.3.0-lite.jar. Thus using the MyTracksLib already includes protobuf-java.2.3.0-lite.jar. Thus using the
newer version, protobuf-java.2.3.0-lite.jar. newer version, protobuf-java.2.3.0-lite.jar.
@@ -14,9 +25,9 @@ google-api-client/
some of its classes are already included in the android framework, thus not some of its classes are already included in the android framework, thus not
including xpp3-1.1.4c.jar. including xpp3-1.1.4c.jar.
google-common.jar Google Analytics:
googleloginclient-helper.jar
libGoogleAnalytics.jar libGoogleAnalytics.jar
- see http://code.google.com/mobile/analytics/docs/. - see http://code.google.com/apis/analytics/docs/mobile/android.html
Others:
google-common.jar
Binary file not shown.
+67 -28
View File
@@ -1,44 +1,43 @@
-target 6 #
-optimizationpasses 5 # Section 1
# Default eclipse project proguard settings.
#
-dontusemixedcaseclassnames -dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclasses
-dontpreverify
-verbose -verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
# Add the libraries, but ignore warnings about them -dontpreverify
-libraryjars libs
-libraryjars ../MyTracksLib/libs
-dontwarn com.google.android.googleapps.**
-dontwarn com.android.common.**
-dontwarn com.google.android.gsf.**
-dontwarn org.codehaus.**
-dontwarn com.google.appengine.**
-dontwarn org.apache.avalon.framework.logger.**
-dontwarn org.apache.log.**
-dontwarn org.apache.log4j.**
-dontwarn javax.servlet.**
# Make our stack traces useful -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
# Line numbers will be correct, file names will be replaced by "MT" since the # change from 5 to 2. With 5 passes, the CursorLoader in the android.support.v4 will not compile.
# class name is enough to get the file name. # See http://stackoverflow.com/questions/6605971/android-sdk-tools-revision-12-has-problem-with-proguard-error-conversion-to
-renamesourcefileattribute MT -optimizationpasses 2
-keepattributes SourceFile,LineNumberTable -allowaccessmodification
# Keep everything android references from XMLs -keepattributes *Annotation*
-keep public class * extends android.app.Activity -keep public class * extends android.app.Activity
-keep public class * extends android.app.Application -keep public class * extends android.app.Application
-keep public class * extends android.app.Service -keep public class * extends android.app.Service
-keep public class * extends android.app.backup.BackupAgent
-keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider -keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgent
-keep public class * extends android.preference.Preference -keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
-keep public class com.android.vending.licensing.ILicensingService -keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembers class * { # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>; native <methods>;
} }
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembers class * { -keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet);
} }
@@ -47,6 +46,11 @@
public <init>(android.content.Context, android.util.AttributeSet, int); public <init>(android.content.Context, android.util.AttributeSet, int);
} }
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * { -keepclassmembers enum * {
public static **[] values(); public static **[] values();
public static ** valueOf(java.lang.String); public static ** valueOf(java.lang.String);
@@ -56,20 +60,55 @@
public static final android.os.Parcelable$Creator *; public static final android.os.Parcelable$Creator *;
} }
# Needed by google-api-client to keep generic types and @Key annotations accessed via reflection -keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
#
# Section 2
# Google APIs Client Library for Java proguard settings.
#
# Needed by google-api-client to keep generic types and @Key annotations accessed via reflection
-keepclassmembers class * { -keepclassmembers class * {
@com.google.api.client.util.Key <fields>; @com.google.api.client.util.Key <fields>;
} }
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault -keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
# Needed by Guava # Needed by Guava
-dontwarn sun.misc.Unsafe -dontwarn sun.misc.Unsafe
# See https://groups.google.com/forum/#!topic/guava-discuss/YCZzeCiIVoI
-dontwarn com.google.common.collect.MinMaxPriorityQueue
#
# Section 3
# My Tracks specific proguard settings.
#
# Add the libraries, but ignore warnings about them
-libraryjars libs
-libraryjars ../MyTracksLib/libs
-dontwarn com.android.common.**
-dontwarn com.google.android.googleapps.**
-dontwarn com.google.android.gsf.**
-dontwarn javax.servlet.**
-dontwarn org.apache.avalon.framework.logger.**
-dontwarn org.apache.log.**
-dontwarn org.apache.log4j.**
# Make our stack traces useful
# Line numbers will be correct, file names will be replaced by "MT" since the
# class name is enough to get the file name.
-renamesourcefileattribute MT
-keepattributes SourceFile,LineNumberTable
# Keep services needed by ANT+ protocol # Keep services needed by ANT+ protocol
-keep public class com.dsi.ant.IAnt_6 -keep public class com.dsi.ant.IAnt_6
-keep public class com.dsi.ant.IAnt -keep public class com.dsi.ant.IAnt
-keep public class com.dsi.ant.IServiceSettings -keep public class com.dsi.ant.IServiceSettings
+3 -15
View File
@@ -46,27 +46,15 @@ limitations under the License.
android:orientation="horizontal" > android:orientation="horizontal" >
<TextView <TextView
android:id="@+id/track_list_item_time" android:id="@+id/track_list_item_time"
android:layout_height="wrap_content" style="@style/TrackListItemStatsTextView" />
android:layout_width="wrap_content"
android:singleLine="true"
android:textColor="@color/green"
style="@android:style/TextAppearance.DeviceDefault.Small" />
<TextView <TextView
android:id="@+id/track_list_item_distance" android:id="@+id/track_list_item_distance"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_width="wrap_content" style="@style/TrackListItemStatsTextView" />
android:singleLine="true"
android:textColor="@color/green"
style="@android:style/TextAppearance.DeviceDefault.Small" />
<TextView <TextView
android:id="@+id/track_list_item_start" android:id="@+id/track_list_item_start"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_width="wrap_content" style="@style/TrackListItemStatsTextView" />
android:singleLine="true"
android:textColor="@color/green"
style="@android:style/TextAppearance.DeviceDefault.Small" />
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/track_list_item_description" android:id="@+id/track_list_item_description"
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -125,7 +125,15 @@ limitations under the License.
<item name="android:textColor">@color/stat_label_text</item> <item name="android:textColor">@color/stat_label_text</item>
</style> </style>
<!-- Welcome page TextView --> <!-- The TextView showing the stats in the track list item -->
<style name="TrackListItemStatsTextView" parents="@android:style/TextAppearance.DeviceDefault.Small">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">@color/green</item>
</style>
<!-- Welcome page TextView -->
<style name="WelcomeTextView"> <style name="WelcomeTextView">
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">fill_parent</item> <item name="android:layout_width">fill_parent</item>
@@ -262,6 +262,6 @@ public class StatsUtilities {
R.string.stat_average_moving_pace); R.string.stat_average_moving_pace);
setSpeedLabel(R.id.max_speed_label, setSpeedLabel(R.id.max_speed_label,
R.string.stat_max_speed, R.string.stat_max_speed,
R.string.stat_min_pace); R.string.stat_fastest_pace);
} }
} }
@@ -87,14 +87,14 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
private NavControls navControls; private NavControls navControls;
private long trackId; private long trackId;
private MenuItem stopRecording; private MenuItem stopRecordingMenuItem;
private MenuItem insertMarker; private MenuItem insertMarkerMenuItem;
private MenuItem play; private MenuItem playMenuItem;
private MenuItem share; private MenuItem shareMenuItem;
private MenuItem sendGoogle; private MenuItem sendGoogleMenuItem;
private MenuItem save; private MenuItem saveMenuItem;
private MenuItem edit; private MenuItem editMenuItem;
private MenuItem delete; private MenuItem deleteMenuItem;
private final Runnable changeTab = new Runnable() { private final Runnable changeTab = new Runnable() {
public void run() { public void run() {
@@ -110,10 +110,8 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
new OnSharedPreferenceChangeListener() { new OnSharedPreferenceChangeListener() {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key == null) { // Note that key can be null
return; if (getString(R.string.recording_track_key).equals(key)) {
}
if (key.equals(getString(R.string.recording_track_key))) {
updateMenu(); updateMenu();
} }
} }
@@ -210,7 +208,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
R.string.track_detail_delete_confirm_message, new DialogInterface.OnClickListener() { R.string.track_detail_delete_confirm_message, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
MyTracksProviderUtils.Factory.get(TrackDetailActivity.this).deleteTrack(trackId); deleteCurrentTrack();
startTrackListActivity(); startTrackListActivity();
} }
}); });
@@ -241,14 +239,14 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
menu.findItem(R.id.track_detail_share_tcx) menu.findItem(R.id.track_detail_share_tcx)
.setTitle(getString(R.string.menu_share_file, fileTypes[3])); .setTitle(getString(R.string.menu_share_file, fileTypes[3]));
stopRecording = menu.findItem(R.id.track_detail_stop_recording); stopRecordingMenuItem = menu.findItem(R.id.track_detail_stop_recording);
insertMarker = menu.findItem(R.id.track_detail_insert_marker); insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker);
play = menu.findItem(R.id.track_detail_play); playMenuItem = menu.findItem(R.id.track_detail_play);
share = menu.findItem(R.id.track_detail_share); shareMenuItem = menu.findItem(R.id.track_detail_share);
sendGoogle = menu.findItem(R.id.track_detail_send_google); sendGoogleMenuItem = menu.findItem(R.id.track_detail_send_google);
save = menu.findItem(R.id.track_detail_save); saveMenuItem = menu.findItem(R.id.track_detail_save);
edit = menu.findItem(R.id.track_detail_edit); editMenuItem = menu.findItem(R.id.track_detail_edit);
delete = menu.findItem(R.id.track_detail_delete); deleteMenuItem = menu.findItem(R.id.track_detail_delete);
updateMenu(); updateMenu();
return true; return true;
@@ -282,7 +280,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
stopRecording(); stopRecording();
return true; return true;
case R.id.track_detail_insert_marker: case R.id.track_detail_insert_marker:
// TODO: // TODO: Add insert marker when updating WaypointList to ICS
return true; return true;
case R.id.track_detail_play: case R.id.track_detail_play:
if (isEarthInstalled()) { if (isEarthInstalled()) {
@@ -469,37 +467,45 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
} }
/** /**
* s Updates the menu items. * Updates the menu items.
* *
* @param isRecording true if recording * @param isRecording true if recording
*/ */
private void updateMenuItems(boolean isRecording) { private void updateMenuItems(boolean isRecording) {
if (stopRecording != null) { if (stopRecordingMenuItem != null) {
stopRecording.setVisible(isRecording); stopRecordingMenuItem.setVisible(isRecording);
} }
if (insertMarker != null) { if (insertMarkerMenuItem != null) {
insertMarker.setVisible(isRecording); insertMarkerMenuItem.setVisible(isRecording);
} }
if (play != null) { if (playMenuItem != null) {
play.setVisible(!isRecording); playMenuItem.setVisible(!isRecording);
} }
if (share != null) { if (shareMenuItem != null) {
share.setVisible(!isRecording); shareMenuItem.setVisible(!isRecording);
} }
if (sendGoogle != null) { if (sendGoogleMenuItem != null) {
sendGoogle.setVisible(!isRecording); sendGoogleMenuItem.setVisible(!isRecording);
} }
if (save != null) { if (saveMenuItem != null) {
save.setVisible(!isRecording); saveMenuItem.setVisible(!isRecording);
} }
if (edit != null) { if (editMenuItem != null) {
edit.setVisible(!isRecording); editMenuItem.setVisible(!isRecording);
} }
if (delete != null) { if (deleteMenuItem != null) {
delete.setVisible(!isRecording); deleteMenuItem.setVisible(!isRecording);
} }
} }
/**
* Deletes the current track.
*/
private void deleteCurrentTrack() {
long trackId = trackDataHub.getSelectedTrackId();
MyTracksProviderUtils.Factory.get(TrackDetailActivity.this).deleteTrack(trackId);
}
/** /**
* Starts the {@link TrackListActivity}. * Starts the {@link TrackListActivity}.
*/ */
@@ -86,24 +86,25 @@ public class TrackListActivity extends FragmentActivity {
private final Runnable bindChangedCallback = new Runnable() { private final Runnable bindChangedCallback = new Runnable() {
@Override @Override
public void run() { public void run() {
if (startNewRecording) { if (!startNewRecording) {
ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound(); return;
if (service != null) { }
try {
recordingTrackId = service.startNewTrack(); ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
startNewRecording = false; if (service == null) {
Toast.makeText( Log.d(TAG, "service not available to start a new recording");
TrackListActivity.this, R.string.track_list_record_success, Toast.LENGTH_SHORT) return;
.show(); }
Log.d(TAG, "Started a new recording"); try {
} catch (Exception e) { recordingTrackId = service.startNewTrack();
Toast.makeText( startNewRecording = false;
TrackListActivity.this, R.string.track_list_record_error, Toast.LENGTH_LONG).show(); Toast.makeText(
Log.d(TAG, "Unable to start a new recording.", e); TrackListActivity.this, R.string.track_list_record_success, Toast.LENGTH_SHORT).show();
} Log.d(TAG, "Started a new recording");
} else { } catch (Exception e) {
Log.d(TAG, "service not available to start a new recording"); Toast.makeText(TrackListActivity.this, R.string.track_list_record_error, Toast.LENGTH_LONG)
} .show();
Log.e(TAG, "Unable to start a new recording.", e);
} }
} }
}; };
@@ -116,13 +117,11 @@ public class TrackListActivity extends FragmentActivity {
new OnSharedPreferenceChangeListener() { new OnSharedPreferenceChangeListener() {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key == null) { // Note that key can be null
return; if (getString(R.string.metric_units_key).equals(key)) {
}
if (key.equals(getString(R.string.metric_units_key))) {
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true); metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
} }
if (key.equals(getString(R.string.recording_track_key))) { if (getString(R.string.recording_track_key).equals(key)) {
recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L); recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
if (isRecording()) { if (isRecording()) {
trackRecordingServiceConnection.startAndBind(); trackRecordingServiceConnection.startAndBind();
@@ -116,8 +116,8 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
// Average moving pace // Average moving pace
writePace(averageMovingSpeed, builder, R.string.description_average_moving_pace, lineBreak); writePace(averageMovingSpeed, builder, R.string.description_average_moving_pace, lineBreak);
// Min pace // Fastest pace
writePace(maxSpeed, builder, R.string.description_min_pace, lineBreak); writePace(maxSpeed, builder, R.string.description_fastest_pace, lineBreak);
// Max elevation // Max elevation
writeElevation(stats.getMaxElevation(), builder, R.string.description_max_elevation, lineBreak); writeElevation(stats.getMaxElevation(), builder, R.string.description_max_elevation, lineBreak);
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.LocationUtils; import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.common.annotations.VisibleForTesting;
import android.location.Location; import android.location.Location;
import android.util.Log; import android.util.Log;
@@ -109,11 +110,12 @@ public class SendToGoogleUtils {
* @param segment the track segment * @param segment the track segment
* @param splitTracks an array of track segments * @param splitTracks an array of track segments
*/ */
private static void prepareTrackSegment(Track segment, ArrayList<Track> splitTracks) { @VisibleForTesting
static boolean prepareTrackSegment(Track segment, ArrayList<Track> splitTracks) {
// Make sure the segment has at least 2 points // Make sure the segment has at least 2 points
if (segment.getLocations().size() < 2) { if (segment.getLocations().size() < 2) {
Log.d(TAG, "segment has less than 2 points"); Log.d(TAG, "segment has less than 2 points");
return; return false;
} }
// For a new segment, sets it stop time // For a new segment, sets it stop time
@@ -128,5 +130,6 @@ public class SendToGoogleUtils {
LocationUtils.decimate(segment, 2.0); LocationUtils.decimate(segment, 2.0);
splitTracks.add(segment); splitTracks.add(segment);
return true;
} }
} }
-1
View File
@@ -3,7 +3,6 @@
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/> <classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="lib" path="libs/protobuf-java-2.3.0-lite.jar"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>
-2
View File
@@ -9,8 +9,6 @@
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/MyTracks"/> <classpathentry combineaccessrules="false" kind="src" path="/MyTracks"/>
<classpathentry kind="lib" path="libs/AndroidMockGenerator.jar"/>
<classpathentry kind="lib" path="libs/robotium-solo-3.1.jar"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>
Binary file not shown.
@@ -31,9 +31,9 @@ import android.location.Location;
public class TrackStubUtils { public class TrackStubUtils {
static final String LOCATION_PROVIDER = "gps"; static final String LOCATION_PROVIDER = "gps";
static final double INITIAL_LATITUDE = 22; public static final double INITIAL_LATITUDE = 22;
static final double INITIAL_LONGITUDE = 22; public static final double INITIAL_LONGITUDE = 22;
static final double INITIAL_ALTITUDE = 22; public static final double INITIAL_ALTITUDE = 22;
static final float INITIAL_ACCURACY = 5; static final float INITIAL_ACCURACY = 5;
static final float INITIAL_SPEED = 10; static final float INITIAL_SPEED = 10;
static final float INITIAL_BEARING = 3.0f; static final float INITIAL_BEARING = 3.0f;
@@ -0,0 +1,140 @@
/*
* Copyright 2012 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.io.sendtogoogle;
/**
* Tests the {@link SendToGoogleUtils}.
*
* @author Youtao Liu
*/
import com.google.android.apps.mytracks.TrackStubUtils;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Track;
import android.location.Location;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
public class SendToGoogleUtilsTest extends TestCase {
private final static long TRACK_ID = 1L;
private final static String TRACK_CATEGORY = "trackCategory";
private final static String TRACK_NAME = "trackName";
private final static double DIFFERENCE = 0.02;
private final static double INVALID_LATITUDE = 91;
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
* when there is only one location in a segment.
*/
public void testPrepareTrackSegment_onlyOneLocation() {
Track trackStub = TrackStubUtils.createTrack(1);
assertFalse(SendToGoogleUtils.prepareTrackSegment(trackStub, null));
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, ArrayList)} when there
* is no stop time.
*/
public void testPrepareTrackSegment_noStopTime() {
Track trackStub = TrackStubUtils.createTrack(2);
assertEquals(-1L, trackStub.getStatistics().getStopTime());
ArrayList<Track> tracksArray = new ArrayList<Track>();
assertTrue(SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray));
assertEquals(trackStub, tracksArray.get(0));
// The stop time should be the time of last location
assertEquals(trackStub.getLocations().get(1).getTime(), trackStub.getStatistics().getStopTime());
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
* when there is stop time.
*/
public void testPrepareTrackSegment_hasStopTime() {
Track trackStub = TrackStubUtils.createTrack(2);
// Gives a margin to make sure the this time will be not same with the last
// location in the track.
long stopTime = System.currentTimeMillis() + 1000;
trackStub.getStatistics().setStopTime(stopTime);
ArrayList<Track> tracksArray = new ArrayList<Track>();
SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray);
assertEquals(trackStub, tracksArray.get(0));
assertEquals(stopTime, trackStub.getStatistics().getStopTime());
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareLocations(Track, java.util.List)} .
*/
public void testPrepareLocations() {
Track trackStub = TrackStubUtils.createTrack(2);
trackStub.setId(TRACK_ID);
trackStub.setName(TRACK_NAME);
trackStub.setCategory(TRACK_CATEGORY);
List<Location> locationsArray = new ArrayList<Location>();
// Adds 100 location to List.
for (int i = 0; i < 100; i++) {
// Use this variable as a flag to make all points in the track can be kept
// after run the LocationUtils#decimate(Track, double) with
// Ramer–Douglas–Peucker algorithm.
double latitude = TrackStubUtils.INITIAL_LATITUDE;
if (i % 2 == 0) {
latitude -= DIFFERENCE * (i % 10);
}
// Inserts 9 points which have wrong latitude, so would have 10 segments.
if (i % 10 == 0 && i > 0) {
MyTracksLocation location = TrackStubUtils.createMyTracksLocation();
location.setLatitude(INVALID_LATITUDE);
locationsArray.add(location);
} else {
locationsArray.add(TrackStubUtils.createMyTracksLocation(latitude,
TrackStubUtils.INITIAL_LONGITUDE + DIFFERENCE * (i % 10),
TrackStubUtils.INITIAL_ALTITUDE + DIFFERENCE * (i % 10)));
}
}
ArrayList<Track> result = SendToGoogleUtils.prepareLocations(trackStub, locationsArray);
assertEquals(10, result.size());
// Checks all segments.
for (int i = 0; i < 10; i++) {
Track segmentOne = result.get(i);
assertEquals(TRACK_ID, segmentOne.getId());
assertEquals(TRACK_NAME, segmentOne.getName());
assertEquals(TRACK_CATEGORY, segmentOne.getCategory());
}
// Checks all locations in the first segment.
for (int j = 0; j < 9; j++) {
double latitude = TrackStubUtils.INITIAL_LATITUDE;
if (j % 2 == 0) {
latitude -= DIFFERENCE * (j % 10);
}
Location oneLocation = result.get(0).getLocations().get(j);
assertEquals(TrackStubUtils.createMyTracksLocation().getAltitude() + DIFFERENCE * (j % 10),
oneLocation.getAltitude());
assertEquals(latitude, oneLocation.getLatitude());
assertEquals(TrackStubUtils.createMyTracksLocation().getLongitude() + DIFFERENCE * (j % 10),
oneLocation.getLongitude());
}
}
}
@@ -0,0 +1,169 @@
/*
* Copyright 2012 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.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
import com.jayway.android.robotium.solo.Solo;
import android.app.Instrumentation;
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Tests the {@link UploadResultActivity}.
*
* @author Youtao Liu
*/
public class UploadResultActivityTest extends
ActivityInstrumentationTestCase2<UploadResultActivity> {
private Instrumentation instrumentation;
private UploadResultActivity uploadResultActivity;
private Solo solo;
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
solo = new Solo(instrumentation);
}
/**
* This method is necessary for ActivityInstrumentationTestCase2.
*/
public UploadResultActivityTest() {
super(UploadResultActivity.class);
}
/**
* Checks the display of dialog when send to all and all sends are successful.
*/
public void testAllSuccess() {
initialActivity(true, true, true, true, true, true);
HashSet<String> stringHashSet = new HashSet<String>();
ArrayList<View> view = solo.getViews();
for (View oneView : view) {
if (oneView instanceof TextView && oneView.isShown()) {
stringHashSet.add((String) ((TextView) oneView).getText());
}
}
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.generic_success_title)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_fusion_tables)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_success_footer)));
assertFalse(stringHashSet
.contains(uploadResultActivity.getString(R.string.generic_error_title)));
assertFalse(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
}
/**
* Checks the display of dialog when send to all and all sends are failed.
*/
public void testAllFailed() {
// Send all kinds but all failed.
initialActivity(true, true, true, false, false, false);
HashSet<String> stringHashSet = new HashSet<String>();
ArrayList<View> view = solo.getViews();
for (View oneView : view) {
if (oneView instanceof TextView && oneView.isShown()) {
stringHashSet.add((String) ((TextView) oneView).getText());
}
}
assertTrue(stringHashSet.contains((Object) uploadResultActivity
.getString(R.string.generic_error_title)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_fusion_tables)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.generic_success_title)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_success_footer)));
}
/**
* Checks the display of dialog when match following items:
* <ul>
* <li>Only send to Maps and Docs.</li>
* <li>Send to Maps successful.</li>
* <li>Send to Docs failed.</li>
* </ul>
*/
public void testPartialSuccess() {
initialActivity(true, false, true, true, false, false);
HashSet<String> stringHashSet = new HashSet<String>();
ArrayList<View> view = solo.getViews();
for (View oneView : view) {
if (oneView instanceof TextView && oneView.isShown()) {
stringHashSet.add((String) ((TextView) oneView).getText());
}
}
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.generic_error_title)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_fusion_tables)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.generic_success_title)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_success_footer)));
}
/**
* Initial a {@link SendRequest} and then initials a activity to be tested.
*
* @param isSendMaps
* @param isSendFusionTables
* @param isSendDocs
* @param isMapsSuccess
* @param isFusionTablesSuccess
* @param isDocsSuccess
*/
private void initialActivity(boolean isSendMaps, boolean isSendFusionTables, boolean isSendDocs,
boolean isMapsSuccess, boolean isFusionTablesSuccess, boolean isDocsSuccess) {
Intent intent = new Intent();
SendRequest sendRequest = new SendRequest(1L, true, true, true);
sendRequest.setSendMaps(isSendMaps);
sendRequest.setSendFusionTables(isSendFusionTables);
sendRequest.setSendDocs(isSendDocs);
sendRequest.setMapsSuccess(isMapsSuccess);
sendRequest.setFusionTablesSuccess(isFusionTablesSuccess);
sendRequest.setDocsSuccess(isDocsSuccess);
intent.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
setActivityIntent(intent);
uploadResultActivity = this.getActivity();
}
}