This commit is contained in:
Dennis Guse
2019-06-23 19:18:01 +02:00
parent de49a947f3
commit a62dee645b
41 changed files with 14 additions and 5885 deletions
@@ -1,65 +0,0 @@
/*
* 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.endtoendtest;
import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.util.Log;
/**
* End-to-end test test runner.
*
* @author Youtao Liu
*/
public class EndToEndTestRunner extends InstrumentationTestRunner {
private static final String TAG = EndToEndTestRunner.class.getSimpleName();
private static final String PORT_KEY = "port";
private static final String RESOURCE_KEY = "resource";
private static final String SENSOR_KEY = "sensor";
private static final String STRESS_KEY = "stress";
private static final String TRUE_VALUE = "true";
@Override
public void onCreate(Bundle bundle) {
// Get the emulator port parameter for GPS signals
String port = bundle.getString(PORT_KEY);
if (port != null) {
try {
EndToEndTestUtils.emulatorPort = Integer.parseInt(port);
} catch (Exception e) {
Log.e(TAG, "Unable to get emulator port parameter, use the default value.", e);
}
}
Log.d(TAG, "Emulator port: " + EndToEndTestUtils.emulatorPort);
RunConfiguration runConfiguration = RunConfiguration.getInstance();
runConfiguration.setRunResourceTest(
TRUE_VALUE.equalsIgnoreCase(bundle.getString(RESOURCE_KEY)));
Log.d(TAG, "Run resource test: " + runConfiguration.getRunResourceTest());
runConfiguration.setRunSensorTest(TRUE_VALUE.equalsIgnoreCase(bundle.getString(SENSOR_KEY)));
Log.d(TAG, "Run sensor test: " + runConfiguration.getRunSensorTest());
runConfiguration.setRunStressTest(TRUE_VALUE.equalsIgnoreCase(bundle.getString(STRESS_KEY)));
Log.d(TAG, "Run stress test: " + runConfiguration.getRunStressTest());
super.onCreate(bundle);
}
}
@@ -1,936 +0,0 @@
package com.google.android.apps.mytracks.endtoendtest;
/*
* 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.
*/
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.maps.mytracks.R;
import com.robotium.solo.Solo;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import junit.framework.Assert;
/**
* Provides utilities to smoke test.
*
* @author Youtao Liu
*/
public class EndToEndTestUtils {
public static final int TINY_WAIT_TIME = 200;
public static final int VERY_SHORT_WAIT_TIME = 500;
public static final int SHORT_WAIT_TIME = 2000;
public static final int NORMAL_WAIT_TIME = 8000;
public static final int LONG_WAIT_TIME = 15000;
public static final int SUPER_LONG_WAIT_TIME = 100000;
// Pause 200ms between each send.
public static final double START_LONGITUDE = 51;
public static final double START_LATITUDE = -1.3f;
public static final double DELTA_LONGITUDE = 0.0005f;
public static final double DELTA_LADITUDE = 0.0005f;
public static final String WAYPOINT_NAME = "testWaypoint";
public static final String WAYPOINT_TYPE = "testWaypoinType";
public static final String WAYPOINT_DESCRIPTION = "testWaypointDesc";
public static final String DEFAULT_ACTIVITY_TYPE = "TestActivity";
public static final String TRACK_NAME_PREFIX = "testTrackName";
private static final String TAG = EndToEndTestUtils.class.getSimpleName();
private static final String TRACK_DESCRIPTION_PREFIX = "testTrackDesc";
private static final int ORIENTATION_PORTRAIT = 1;
private static final int ORIENTATION_LANDSCAPE = 0;
private static final String ANDROID_LOCAL_IP = "10.0.2.2";
private static final String NO_GPS_MESSAGE_PREFIX = "GPS is not available";
private static final String MORE_OPTION_CLASSNAME = "com.android.internal.view.menu.ActionMenuPresenter$OverflowMenuButton";
private static final String MENUITEM_CLASSNAME = "com.android.internal.view.menu.IconMenuItemView";
// Following is some check strings in English and Chinese
private static final HashMap<String, String>
RELATIVE_START_TIME_SUFFIX_MULTILINGUAL = new HashMap<String, String>();
static {
RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.put("en", "mins ago");
RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.put("de", "Minuten");
RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.put("fr", "minute");
RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.put("ar", "دقيقة");
RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.put("zh", "分钟前");
}
public static int emulatorPort = 5554; // usually 5554.
public static String activityType = DEFAULT_ACTIVITY_TYPE;
public static String trackName;
public static String trackDescription;
public static com.robotium.solo.Solo SOLO;
public static Instrumentation instrumentation;
public static TrackListActivity trackListActivity;
/*
* Check whether the UI has an action bar which is related with the version of
* Android OS.
*/
public static boolean hasActionBar = false;
public static boolean isEmulator = true;
public static boolean hasGpsSignal = true;
private static boolean isCheckedFirstLaunch = false;
private static boolean isGooglePlayServicesLatest = true;
private static String language;
private EndToEndTestUtils() {};
/**
* Checks the language, then sets the fields with right string.
*/
private static void checkLanguage() {
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration configuration = trackListActivity.getBaseContext()
.getResources().getConfiguration();
configuration.locale = locale;
language = instrumentation.getContext().getResources().getConfiguration().locale.getLanguage();
}
/**
* Sends Gps data to emulator, and the start value has an offset.
*
* @param number send times
* @param offset is used to compute the start latitude and longitude
* @param pause pause interval between each sending
*/
public static void sendGps(int number, int offset, int pause) {
if (number < 1) {
return;
}
int pauseInterval = TINY_WAIT_TIME;
if (pause != -1) {
pauseInterval = pause;
}
// If it's a real device, does not send simulated GPS signal.
if (!isEmulator) {
return;
}
PrintStream out = null;
Socket socket = null;
try {
socket = new Socket(ANDROID_LOCAL_IP, emulatorPort);
out = new PrintStream(socket.getOutputStream());
double longitude = START_LONGITUDE + offset * DELTA_LONGITUDE;
double latitude = START_LATITUDE + offset * DELTA_LADITUDE;
for (int i = 0; i < number; i++) {
out.println("geo fix " + longitude + " " + latitude);
longitude += DELTA_LONGITUDE;
latitude += DELTA_LADITUDE;
Thread.sleep(pauseInterval);
}
// Wait the GPS signal can be obtained by MyTracks.
Thread.sleep(SHORT_WAIT_TIME);
} catch (UnknownHostException e) {
System.exit(-1);
} catch (IOException e) {
System.exit(-1);
} catch (InterruptedException e) {
System.exit(-1);
} finally {
if (out != null) {
out.close();
}
}
}
/**
* Send Gps data to emulator.
*
* @param number number of signals
* @param offset is used to compute the start latitude and longitude
*/
public static void sendGps(int number, int offset) {
sendGps(number, offset, -1);
}
/**
* Send Gps data to emulator.
*
* @param number number of signals
*/
public static void sendGps(int number) {
sendGps(number, 0, -1);
}
/**
* Sets the status whether the test is run on an emulator or not.
*/
private static void setIsEmulator() {
isEmulator = android.os.Build.MODEL.equals("google_sdk");
}
/**
* Checks whether the Google Play Services need update.
*/
private static boolean isGooglePlayServicesLatest() {
return findTextView("Google Play services") == null;
}
/**
* A setup for debugging end-to-end tests.
*
* @param inst the instrumentation
* @param activity the track list activity
*/
public static void setupForDebug(Instrumentation inst, TrackListActivity activity) {
instrumentation = inst;
trackListActivity = activity;
SOLO = new Solo(instrumentation, trackListActivity);
setIsEmulator();
hasActionBar = setHasActionBar();
checkLanguage();
}
/**
* A setup for all end-to-end tests.
*
* @param inst the instrumentation
* @param activity the track list activity
*/
public static void setupForAllTest(Instrumentation inst, TrackListActivity activity) {
instrumentation = inst;
trackListActivity = activity;
SOLO = new Solo(instrumentation, trackListActivity);
if (!isGooglePlayServicesLatest) {
SOLO.finishOpenedActivities();
Assert.fail();
Log.e(TAG, "Need update Google Play Services");
}
// Check if open MyTracks first time after install. If so, there would be a
// welcome view with accept buttons. And makes sure only check once.
if (!isCheckedFirstLaunch) {
isGooglePlayServicesLatest = isGooglePlayServicesLatest();
if (!isGooglePlayServicesLatest) {
SOLO.finishOpenedActivities();
Assert.fail();
Log.e(TAG, "Need update Google Play Services");
}
setIsEmulator();
verifyFirstLaunch();
hasActionBar = setHasActionBar();
checkLanguage();
isCheckedFirstLaunch = true;
inst.waitForIdleSync();
// Check the status of real phone. For emulator, we would fix GPS signal.
if (!isEmulator) {
findAndClickMyLocation(activity);
hasGpsSignal = !SOLO.waitForText(NO_GPS_MESSAGE_PREFIX, 1, SHORT_WAIT_TIME);
SOLO.goBack();
}
}
int trackNumber = SOLO.getCurrentViews(ListView.class).get(0).getCount();
// Delete all tracks when there are two many tracks which may make some test
// run slowly, such as sync test cases.
if (trackNumber > 3) {
deleteAllTracks();
}
// Check whether is under recording. If previous test failed, the recording
// may not be recording.
if (isUnderRecording()) {
stopRecording(true);
}
resetAllSettings(activity, false);
inst.waitForIdleSync();
}
/**
* Rotates the given activity.
*
* @param activity a given activity
*/
private static void rotateActivity(Activity activity) {
activity
.setRequestedOrientation(activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? ORIENTATION_LANDSCAPE
: ORIENTATION_PORTRAIT);
}
/**
* Accepts terms and configures units.
*/
private static void verifyFirstLaunch() {
if ((getButtonOnScreen(trackListActivity.getString(R.string.eula_accept), false, false) != null)) {
getButtonOnScreen(trackListActivity.getString(R.string.eula_accept), true, true);
}
}
/**
* Creates a simple track which can be used by subsequent test. This method
* will save a customized track name.
*
* @param numberOfGpsData number of simulated Gps data
* @param showTrackList whether stay on track list activity or track detail
* activity
*/
public static void createSimpleTrack(int numberOfGpsData, boolean showTrackList) {
startRecording();
sendGps(numberOfGpsData);
instrumentation.waitForIdleSync();
stopRecording(true);
if (showTrackList) {
SOLO.goBack();
instrumentation.waitForIdleSync();
}
}
/**
* Creates a track which contains pause during recording.
*
* @param numberOfGpsData number of simulated Gps data before pause and after
* resume
*/
public static void createTrackWithPause(int numberOfGpsData) {
startRecording();
sendGps(numberOfGpsData);
pauseRecording();
resumeRecording();
sendGps(numberOfGpsData, numberOfGpsData);
stopRecording(true);
}
/**
* Checks if there is no track in track list. For some tests need at least one
* track, the method can save time to create a new track.
*
* @param isClick if not empty, true means click any track
* @return return true if the track list is empty
*/
private static boolean isTrackListEmpty(boolean isClick) {
instrumentation.waitForIdleSync();
int trackNumber = SOLO.getCurrentViews(ListView.class).get(0).getCount();
if (trackNumber <= 0) {
return true;
}
View oneTrack = SOLO.getCurrentViews(ListView.class).get(0).getChildAt(0);
View aa = oneTrack.findViewById(R.id.list_item_name);
if (aa != null) {
trackName = (String) ((TextView) oneTrack.findViewById(R.id.list_item_name)).getText();
}
if (isClick) {
SOLO.scrollUp();
SOLO.clickOnView(oneTrack);
SOLO.waitForText(trackListActivity.getString(R.string.track_detail_chart_tab));
}
return false;
}
/**
* Create a new track if the track is empty.
*
* @param gpsNumber the number of gps signals
* @param showTrackList whether stay on track list activity or track detail
* activity
*/
public static void createTrackIfEmpty(int gpsNumber, boolean showTrackList) {
if (isTrackListEmpty(!showTrackList)) {
// Create a simple track.
createSimpleTrack(gpsNumber, showTrackList);
}
}
/**
* Starts recoding track.
*/
public static void startRecording() {
View startButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_record);
if (startButton != null && startButton.isShown()) {
SOLO.clickOnView(startButton);
}
instrumentation.waitForIdleSync();
}
/**
* Pauses recoding track.
*/
public static void pauseRecording() {
View pauseButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_record);
if (pauseButton != null && pauseButton.isShown()) {
SOLO.clickOnView(pauseButton);
}
instrumentation.waitForIdleSync();
}
/**
* Resume recoding track.
*/
public static void resumeRecording() {
View startButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_record);
if (startButton != null && startButton.isShown()) {
SOLO.clickOnView(startButton);
}
instrumentation.waitForIdleSync();
}
/**
* Checks if the MyTracks is under recording.
*
* @return true if it is under recording.
*/
private static boolean isUnderRecording() {
instrumentation.waitForIdleSync();
View view = SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop);
// TODO: understand why view can be null here
return view != null ? view.isEnabled() : false;
}
/**
* Stops recoding track.
*
* @param isSave true means should save this track
*/
public static void stopRecording(boolean isSave) {
View stopButton = SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop);
if (stopButton != null && stopButton.isShown()) {
SOLO.clickOnView(stopButton);
if (isSave) {
SOLO.waitForText(trackListActivity.getString(R.string.generic_save), 1, 5000);
// Make every track name is unique to make sure every check can be
// trusted.
long currentMillis = System.currentTimeMillis();
trackName = TRACK_NAME_PREFIX + currentMillis;
trackDescription = TRACK_DESCRIPTION_PREFIX + currentMillis;
SOLO.sendKey(KeyEvent.KEYCODE_DEL);
enterTextAvoidSoftKeyBoard(0, trackName);
enterTextAvoidSoftKeyBoard(1, activityType);
enterTextAvoidSoftKeyBoard(2, trackDescription);
SOLO.clickOnText(trackListActivity.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
} else {
instrumentation.waitForIdleSync();
}
}
}
/**
* Deletes all tracks. This method should be call when the TracksListActivity
* is shown.
*/
public static void deleteAllTracks() {
if (!isTrackListEmpty(false)) {
findMenuItem(trackListActivity.getString(R.string.menu_delete_all), true);
getButtonOnScreen(trackListActivity.getString(R.string.generic_yes), true, true);
waitTextToDisappear(trackListActivity.getString(R.string.generic_progress_title));
}
}
/**
* Checks if a button is existed in the screen.
*
* @param buttonName the name string of the button
* @param isWait whether wait the text
* @param isClick whether click the button if find it
* @return the button to search, and null means can not find the button
*/
public static View getButtonOnScreen(String buttonName, boolean isWait, boolean isClick) {
View button = null;
instrumentation.waitForIdleSync();
if (isWait) {
SOLO.waitForText(buttonName);
}
// Find on action bar.
if (hasActionBar) {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
String className = view.getClass().getName();
if (className.indexOf("ActionMenuItemView") > 0) {
String menuItemNameString = view.getContentDescription().toString();
if (menuItemNameString.equalsIgnoreCase(buttonName)) {
button = view;
break;
}
}
}
}
// Get all buttons and find.
if (button == null) {
ArrayList<Button> currentButtons = SOLO.getCurrentViews(Button.class);
for (Button oneButton : currentButtons) {
String title = (String) oneButton.getText();
if (title.equalsIgnoreCase(buttonName)) {
button = oneButton;
}
}
}
if (button != null && isClick) {
SOLO.clickOnView(button);
}
if (button == null && isClick) {
Log.d(TAG, "Don't find the button " + buttonName);
}
return button;
}
/**
* Checks whether an action bar is shown.
*
* @return false means can not check failed.
*/
@SuppressLint("NewApi")
private static boolean setHasActionBar() {
try {
return trackListActivity.getActionBar() == null ? false : true;
} catch (Throwable e) {
// For in Android which does not has action bar, here will meet a error.
return false;
}
}
/**
* Rotates all activities.
*/
public static void rotateCurrentActivity() {
rotateActivity(SOLO.getCurrentActivity());
instrumentation.waitForIdleSync();
}
/**
* Finds an item in the menu with the option to click the item.
*
* @param menuName the name of item
* @param click true means need click this menu
* @return true if find this menu
*/
public static boolean findMenuItem(String menuName, boolean click) {
instrumentation.waitForIdleSync();
boolean findResult = false;
boolean isMoreMenuOpened = false;
// ICS phone.
if (hasActionBar) {
// Firstly find in action bar.
View button = getButtonOnScreen(menuName, false, false);
if (button != null) {
findResult = true;
if (click) {
SOLO.clickOnView(button);
instrumentation.waitForIdleSync();
}
return findResult;
}
showMenuItem();
findResult = SOLO.waitForText(menuName, 1, LONG_WAIT_TIME, true);
} else {
// Non-ICS phone.
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
if (SOLO.searchText(menuName, 1, true)) {
findResult = true;
} else if (getMoreOptionView() != null) {
SOLO.clickOnView(getMoreOptionView());
findResult = SOLO.searchText(menuName, 1, true);
isMoreMenuOpened = true;
}
}
if (findResult && click) {
SOLO.clickOnView(SOLO.getText(menuName));
instrumentation.waitForIdleSync();
} else {
// Quit more menu list if opened.
if (isMoreMenuOpened) {
SOLO.goBack();
}
// Quit menu list.
SOLO.goBack();
}
return findResult;
}
/**
* Show menu item list.
*/
private static void showMenuItem() {
showMenuItem(0);
}
/**
* Gets more menu items operation is different for different Android OS. When
* get overflow button view on action, it usually be able to click. But in
* some situation, will meet an error when click it. So catch it and try
* again. In most situation, the second click will be pass.
*
* @param depth control the depth of recursion to prevent dead circulation
*/
private static void showMenuItem(int depth) {
// ICS phone.
if (hasActionBar) {
instrumentation.waitForIdleSync();
View moreButton = getMoreOptionView();
// ICS phone without menu key.
if (moreButton != null) {
try {
SOLO.clickOnView(moreButton);
} catch (Throwable e) {
if (depth < 5 && e.getMessage().indexOf("Click can not be completed") > -1) {
showMenuItem(depth++);
}
}
return;
} else {
// ICS phone with menu key.
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
}
} else {
// Non-ICS phone with menu key.
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
}
}
/**
* Finds the more option menu. It should match following conditions:
* <ul>
* <li>The view extends ImageButton.</li>
* <li>The view name equals {@link #MORE_OPTION_CLASSNAME}.</li>
* </ul>
*
* @return the more option view. Null means can not find it.
*/
private static View getMoreOptionView() {
View viewResult = null;
if (hasActionBar) {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view instanceof ImageButton && view.getClass().getName().equals(MORE_OPTION_CLASSNAME)) {
viewResult = view;
break;
}
}
} else {
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view.getClass().getName().equals(MENUITEM_CLASSNAME)) {
viewResult = view;
// No break here to get the last menu item.
}
}
}
return viewResult;
}
/**
* Finds a displayed text view with specified text in a view.
*
* @param text text to find
* @param parent which text view in in
* @return the text view, null means can not find it
*/
public static TextView findTextViewInView(String text, View parent) {
ArrayList<TextView> textViews = SOLO.getCurrentViews(TextView.class, parent);
for (TextView textView : textViews) {
String textString = (String) textView.getText();
if (textView.isShown() && textString.endsWith(text)) {
return textView;
}
}
return null;
}
/**
* Finds a displayed text view with specified text.
*
* @param text text to find
* @return the text view, null means can not find it
*/
public static TextView findTextView(String text) {
ArrayList<View> allViews = SOLO.getViews();
if (allViews != null) {
for (View view : allViews) {
if (view instanceof TextView) {
TextView textView = (TextView) view;
String textString = (String) textView.getText();
if (textView.isShown() && textString.endsWith(text)) {
return textView;
}
}
}
}
return null;
}
/**
* Finds a displayed text view with specified text and index number.
*
* @param text text to find
* @param index the index to search
* @return the text view, null means can not find it
*/
public static TextView findTextViewByIndex(String text, int index) {
int number = 1;
ArrayList<View> allViews = SOLO.getViews();
for (View view : allViews) {
if (view instanceof TextView) {
TextView textView = (TextView) view;
String textString = (String) textView.getText();
if (textView.isShown() && textString.endsWith(text)) {
if (number == index) {
return textView;
} else {
number++;
}
}
}
}
return null;
}
/**
* Resets all settings of MyTracks.
*
* @param activityMyTracks current activity
* @param keepInSettingList whether keep in setting list or not
*/
public static void resetAllSettings(Activity activityMyTracks, boolean keepInSettingList) {
findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
SOLO.clickOnText(activityMyTracks.getString(R.string.settings_advanced));
Assert.assertTrue(SOLO.waitForText(activityMyTracks.getString(R.string.settings_reset)));
SOLO.clickOnText(activityMyTracks.getString(R.string.settings_reset));
getButtonOnScreen(trackListActivity.getString(R.string.generic_yes), true, true);
Assert.assertTrue(SOLO.waitForText(activityMyTracks.getString(R.string.settings_reset_done)));
instrumentation.waitForIdleSync();
SOLO.goBack();
instrumentation.waitForIdleSync();
if (!keepInSettingList) {
SOLO.goBack();
}
}
/**
* Finds a edit text and enter text in it. This method can hides soft key
* board when input text.
*
* @param editTextIndex the index of edit text
* @param text to enter
*/
public static void enterTextAvoidSoftKeyBoard(int editTextIndex, String text) {
EditText editText = SOLO.getEditText(editTextIndex);
SOLO.enterText(editText, text);
SOLO.hideSoftKeyboard();
// Above line does not work every time. And it is should be a Robotium
// issue.
InputMethodManager imm = (InputMethodManager) trackListActivity.getApplicationContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
}
/**
* Waits n milliseconds.
*
* @param milliseconds time to sleep
*/
public static void sleep(long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
Log.e(TAG, "Unable to sleep " + milliseconds, e);
}
}
/**
* Checks whether the recording is not started.
*/
public static void checkNotRecording() {
instrumentation.waitForIdleSync();
Assert.assertEquals(trackListActivity.getString(R.string.image_record),
(String) SOLO.getCurrentActivity()
.findViewById(R.id.track_controller_record).getContentDescription());
Assert.assertFalse(
SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop).isEnabled());
Assert.assertNull(findTextView(trackListActivity.getString(R.string.generic_recording)));
Assert.assertNull(findTextView(trackListActivity.getString(R.string.generic_paused)));
Assert.assertFalse(
SOLO.getCurrentActivity().findViewById(R.id.track_controller_total_time).isShown());
}
/**
* Checks whether the MyTracks is under recording.
*/
public static void checkUnderRecording() {
instrumentation.waitForIdleSync();
Assert.assertEquals(trackListActivity.getString(R.string.image_pause), (String) SOLO
.getCurrentActivity().findViewById(R.id.track_controller_record).getContentDescription());
Assert.assertTrue(SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop)
.isEnabled());
Assert.assertNotNull(findTextView(trackListActivity.getString(R.string.generic_recording)));
Assert.assertNull(findTextView(trackListActivity.getString(R.string.generic_paused)));
String totalTimeOld = ((TextView) SOLO.getCurrentActivity().findViewById(
R.id.track_controller_total_time)).getText().toString();
sleep(2000);
String totalTimeNew = ((TextView) SOLO.getCurrentActivity().findViewById(
R.id.track_controller_total_time)).getText().toString();
Assert.assertFalse(totalTimeOld.equalsIgnoreCase(totalTimeNew));
}
/**
* Checks whether the recording is paused.
*/
public static void checkUnderPaused() {
instrumentation.waitForIdleSync();
Assert.assertEquals(trackListActivity.getString(R.string.image_record), (String) SOLO
.getCurrentActivity().findViewById(R.id.track_controller_record).getContentDescription());
Assert.assertTrue(SOLO.getCurrentActivity().findViewById(R.id.track_controller_stop)
.isEnabled());
Assert.assertNull(findTextView(trackListActivity.getString(R.string.generic_recording)));
Assert.assertNotNull(findTextView(trackListActivity.getString(R.string.generic_paused)));
String totalTimeOld = ((TextView) SOLO.getCurrentActivity().findViewById(
R.id.track_controller_total_time)).getText().toString();
sleep(2000);
String totalTimeNew = ((TextView) SOLO.getCurrentActivity().findViewById(
R.id.track_controller_total_time)).getText().toString();
Assert.assertTrue(totalTimeOld.equalsIgnoreCase(totalTimeNew));
}
/**
* Creates a way point during track recording.
*
* @param markerNumber of number of previous markers
*/
public static void createWaypoint(int markerNumber) {
findMenuItem(trackListActivity.getString(R.string.menu_markers), true);
instrumentation.waitForIdleSync();
if (markerNumber > 0 && hasGpsSignal) {
SOLO.waitForText(WAYPOINT_NAME);
int actualMarkerNumber = SOLO.getCurrentViews(ListView.class).get(0).getCount();
Assert.assertEquals(markerNumber, actualMarkerNumber);
} else {
Log.d(TAG, "marker number, hasGpsSignal: " + markerNumber + ", " + hasGpsSignal);
Assert.assertTrue(SOLO.waitForText(trackListActivity
.getString(R.string.marker_list_empty_message)));
}
findMenuItem(trackListActivity.getString(R.string.menu_insert_marker), true);
enterTextAvoidSoftKeyBoard(0, WAYPOINT_NAME + (markerNumber + 1));
enterTextAvoidSoftKeyBoard(1, WAYPOINT_TYPE + (markerNumber + 1));
enterTextAvoidSoftKeyBoard(2, WAYPOINT_DESCRIPTION + (markerNumber + 1));
SOLO.clickOnButton(trackListActivity.getString(R.string.generic_add));
instrumentation.waitForIdleSync();
if (hasGpsSignal) {
Assert.assertTrue(SOLO.waitForText(WAYPOINT_NAME, 1, LONG_WAIT_TIME, true));
} else {
Assert.assertFalse(SOLO.searchText(WAYPOINT_NAME));
}
SOLO.goBack();
}
/**
* Waits a text to disappear.
*/
public static void waitTextToDisappear(String text) {
instrumentation.waitForIdleSync();
SOLO.waitForText(text, 1, VERY_SHORT_WAIT_TIME);
while (SOLO.waitForText(text, 1, VERY_SHORT_WAIT_TIME)) {}
return;
}
/**
* Finds the My Location view and click it.
*
* @param activity
*/
private static void findAndClickMyLocation(Activity activity) {
createTrackIfEmpty(1, false);
sendGps(30);
View myLocation = SOLO.getCurrentActivity().findViewById(R.id.map_my_location);
instrumentation.waitForIdleSync();
// Find the My Location button in another if null.
if (myLocation == null) {
ArrayList<ImageButton> aa = SOLO.getCurrentViews(ImageButton.class);
for (ImageButton imageButton : aa) {
if (imageButton.getContentDescription() != null
&& imageButton.getContentDescription().equals(
activity.getString(R.string.image_my_location))) {
myLocation = imageButton;
break;
}
}
}
SOLO.clickOnView(myLocation);
}
/**
* Gets the relative start time suffix.
*/
public static String getRelativeStartTimeSuffix() {
String value = RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.get(language);
return value != null ? value : RELATIVE_START_TIME_SUFFIX_MULTILINGUAL.get("en");
}
/**
* Changes to metric units.
*/
public static void changeToMetricUnits() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
Assert.assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.settings_stats_units_title)));
// Change the preferred units
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_stats_units_title));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.unit_kilometer));
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
}
@@ -1,398 +0,0 @@
/*
* 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.endtoendtest;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.io.gdata.GDataClientFactory;
import com.google.android.apps.mytracks.io.gdata.maps.MapFeatureEntry;
import com.google.android.apps.mytracks.io.gdata.maps.MapsClient;
import com.google.android.apps.mytracks.io.gdata.maps.MapsConstants;
import com.google.android.apps.mytracks.io.gdata.maps.MapsGDataConverter;
import com.google.android.apps.mytracks.io.gdata.maps.MapsMapMetadata;
import com.google.android.apps.mytracks.io.gdata.maps.XmlMapsGDataParserFactory;
import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.io.spreadsheets.SendSpreadsheetsAsyncTask;
import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.common.gdata.AndroidXmlParserFactory;
import com.google.android.maps.mytracks.R;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.google.api.services.fusiontables.Fusiontables;
import com.google.api.services.fusiontables.model.Table;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.spreadsheet.ListEntry;
import com.google.gdata.data.spreadsheet.ListFeed;
import com.google.gdata.data.spreadsheet.WorksheetEntry;
import com.google.gdata.data.spreadsheet.WorksheetFeed;
import com.google.wireless.gdata.parser.GDataParser;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.util.Log;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
/**
* Utilities for accessing Google Drive, Google Maps, Google Fusion Tables, and
* Google Spreadsheets.
*
* @author Youtao Liu
*/
public class GoogleUtils {
public static final String ACCOUNT_1 = "mytrackstest@gmail.com";
public static final String ACCOUNT_2 = "mytrackstest2@gmail.com";
private static final String TAG = GoogleUtils.class.getSimpleName();
private static final String MY_TRACKS_PREFIX = "My Tracks";
private static final String SPREADSHEETS_NAME = MY_TRACKS_PREFIX + "-"
+ EndToEndTestUtils.activityType;
private static final String SPREADSHEETS_WORKSHEET_NAME = "Log";
private static final String SPREADSHEETS_TRANCK_NAME_COLUMN = "Name";
private static final String DRIVE_TEST_FILES_QUERY = "'root' in parents and title contains '"
+ EndToEndTestUtils.TRACK_NAME_PREFIX + "' and trashed = false";
/**
* Deletes Google Drive test files.
*
* @param context the context
* @param accountName the account name
*/
public static void deleteDriveTestFiles(Context context, String accountName) {
try {
GoogleAccountCredential googleAccountCredential = SendToGoogleUtils
.getGoogleAccountCredential(context, accountName, SendToGoogleUtils.DRIVE_SCOPE);
if (googleAccountCredential == null) {
return;
}
Drive drive = SyncUtils.getDriveService(googleAccountCredential);
com.google.api.services.drive.Drive.Files.List list = drive.files()
.list().setQ(DRIVE_TEST_FILES_QUERY);
List<File> files = list.execute().getItems();
Iterator<File> iterator = files.iterator();
while (iterator.hasNext()) {
File file = (File) iterator.next();
drive.files().delete(file.getId()).execute();
}
} catch (Exception e) {
Log.e(TAG, "Unable to delete Google Drive test files.", e);
}
}
/**
* Deletes Google Maps of the first Google account.
*
* @param context the context
* @param accountName the account name
* @param mapTitle the map title
* @return true if deletion is success.
*/
public static boolean deleteMaps(Context context, String accountName, String mapTitle) {
Account account = getGoogleAccount(context, accountName);
if (account == null) {
return false;
}
MapsClient mapsClient = new MapsClient(GDataClientFactory.getGDataClient(context),
new XmlMapsGDataParserFactory(new AndroidXmlParserFactory()));
ArrayList<MapsMapMetadata> mapMetadata = getMaps(context, account, mapsClient);
for (MapsMapMetadata data : mapMetadata) {
if (data.getDescription().indexOf(MY_TRACKS_PREFIX) > -1
&& data.getTitle().equals(mapTitle)) {
try {
mapsClient.deleteEntry(data.getGDataEditUri(), AccountManager.get(context)
.blockingGetAuthToken(account, MapsConstants.SERVICE_NAME, false));
return true;
} catch (Exception e) {
Log.e(TAG, "Unable to delete maps.", e);
return false;
}
}
}
return false;
}
/**
* Deletes all Google Maps of the first Google account
*
* @param context the context
* @param accountName the account name
*/
public static void deleteAllMaps(Context context, String accountName) {
Account account = getGoogleAccount(context, accountName);
if (account == null) {
Log.e(TAG, "Unable to get account.");
return;
}
MapsClient mapsClient = new MapsClient(GDataClientFactory.getGDataClient(context),
new XmlMapsGDataParserFactory(new AndroidXmlParserFactory()));
ArrayList<MapsMapMetadata> mapMetadata = getMaps(context, account, mapsClient);
for (MapsMapMetadata oneData : mapMetadata) {
try {
mapsClient.deleteEntry(oneData.getGDataEditUri(), AccountManager.get(context)
.blockingGetAuthToken(account, MapsConstants.SERVICE_NAME, false));
} catch (Exception e) {
Log.e(TAG, "Unable to delete maps.", e);
}
}
}
/**
* Deletes Google Fusion Tables.
*
* @param context the context
* @param accountName the account name
* @param tableName the table name
* @return true if deletion is success.
*/
public static boolean deleteFusionTables(Context context, String accountName, String tableName) {
try {
GoogleAccountCredential googleAccountCredential = SendToGoogleUtils
.getGoogleAccountCredential(context, accountName, SendToGoogleUtils.FUSION_TABLES_SCOPE);
if (googleAccountCredential == null) {
return false;
}
Fusiontables fusiontables = new Fusiontables.Builder(
AndroidHttp.newCompatibleTransport(), new GsonFactory(), googleAccountCredential).build();
List<Table> tables = fusiontables.table().list().execute().getItems();
Iterator<Table> iterator = tables.iterator();
while (iterator.hasNext()) {
Table table = (Table) iterator.next();
String name = table.getName();
if (name != null && name.equals(tableName)) {
fusiontables.table().delete(table.getTableId()).execute();
return true;
}
}
} catch (Exception e) {
Log.e(TAG, "Unable to search fusion tables.", e);
}
return false;
}
/**
* Searches Google Spreadsheets.
*
* @param context the context
* @param accountName the account name
* @return the list of spreadsheets matching the title. Null if unable to
* search.
*/
public static List<File> searchSpreadsheets(Context context, String accountName) {
try {
GoogleAccountCredential googleAccountCredential = SendToGoogleUtils
.getGoogleAccountCredential(context, accountName, SendToGoogleUtils.DRIVE_SCOPE);
if (googleAccountCredential == null) {
return null;
}
Drive drive = SyncUtils.getDriveService(googleAccountCredential);
com.google.api.services.drive.Drive.Files.List list = drive.files().list().setQ(String.format(
Locale.US, SendSpreadsheetsAsyncTask.GET_SPREADSHEET_QUERY, SPREADSHEETS_NAME));
return list.execute().getItems();
} catch (Exception e) {
Log.e(TAG, "Unable to search spreadsheets.", e);
}
return null;
}
/**
* Deletes Google Spreadsheets.
*
* @param context the context
* @param accountName the account name
* @return true if deletion is success.
*/
public static boolean deleteSpreadsheets(Context context, String accountName) {
try {
GoogleAccountCredential googleAccountCredential = SendToGoogleUtils
.getGoogleAccountCredential(context, accountName, SendToGoogleUtils.DRIVE_SCOPE);
if (googleAccountCredential == null) {
return false;
}
Drive drive = SyncUtils.getDriveService(googleAccountCredential);
com.google.api.services.drive.Drive.Files.List list = drive.files().list().setQ(String.format(
Locale.US, SendSpreadsheetsAsyncTask.GET_SPREADSHEET_QUERY, SPREADSHEETS_NAME));
List<File> files = list.execute().getItems();
Iterator<File> iterator = files.iterator();
while (iterator.hasNext()) {
File file = (File) iterator.next();
drive.files().delete(file.getId()).execute();
}
return true;
} catch (Exception e) {
Log.e(TAG, "Unable to delete spreadsheets.", e);
}
return false;
}
/**
* Deletes Google Spreadsheets row.
*
* @param context the context
* @param accountName the account name
* @param trackName the track name
* @return true if deletion is success.
*/
public static boolean deleteSpreadsheetsRow(
Context context, String accountName, String trackName) {
try {
// Get spreadsheet Id
List<File> files = searchSpreadsheets(context, accountName);
if (files == null || files.size() == 0) {
return false;
}
String spreadsheetId = files.get(0).getId();
// Get spreadsheet service
SpreadsheetService spreadsheetService = new SpreadsheetService(
"MyTracks-" + SystemUtils.getMyTracksVersion(context));
Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod());
credential.setAccessToken(
SendToGoogleUtils.getToken(context, accountName, SendToGoogleUtils.SPREADSHEETS_SCOPE));
spreadsheetService.setOAuth2Credentials(credential);
// Get work sheet
WorksheetFeed worksheetFeed = spreadsheetService.getFeed(new URL(
String.format(Locale.US, SendSpreadsheetsAsyncTask.GET_WORKSHEETS_URI, spreadsheetId)),
WorksheetFeed.class);
Iterator<WorksheetEntry> worksheetEntryIterator = worksheetFeed.getEntries().iterator();
while (worksheetEntryIterator.hasNext()) {
WorksheetEntry worksheetEntry = (WorksheetEntry) worksheetEntryIterator.next();
String worksheetTitle = worksheetEntry.getTitle().getPlainText();
if (worksheetTitle.equals(SPREADSHEETS_WORKSHEET_NAME)) {
URL url = worksheetEntry.getListFeedUrl();
Iterator<ListEntry> listEntryIterator = spreadsheetService.getFeed(url, ListFeed.class)
.getEntries().iterator();
while (listEntryIterator.hasNext()) {
ListEntry listEntry = (ListEntry) listEntryIterator.next();
String name = listEntry.getCustomElements().getValue(SPREADSHEETS_TRANCK_NAME_COLUMN);
if (name.equals(trackName)) {
listEntry.delete();
return true;
}
}
}
}
} catch (Exception e) {
Log.e(TAG, "Unable to delete spreadsheets row.", e);
}
return false;
}
/**
* Returns true if an account is available.
*/
public static boolean isAccountAvailable() {
// Check the no account dialog
if (EndToEndTestUtils.SOLO.waitForText(
EndToEndTestUtils.trackListActivity.getString(R.string.send_google_no_account_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
EndToEndTestUtils.getButtonOnScreen(
EndToEndTestUtils.trackListActivity.getString(R.string.generic_ok), false, true);
return false;
}
// Check the choose account dialog
if (EndToEndTestUtils.SOLO.waitForText(
EndToEndTestUtils.trackListActivity.getString(R.string.send_google_choose_account_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
EndToEndTestUtils.SOLO.clickOnText(ACCOUNT_1);
EndToEndTestUtils.getButtonOnScreen(
EndToEndTestUtils.trackListActivity.getString(R.string.generic_ok), false, true);
}
// Check the no account permission dialog
if (EndToEndTestUtils.SOLO.waitForText(
EndToEndTestUtils.trackListActivity.getString(R.string.send_google_no_account_permission), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
return false;
}
return true;
}
/**
* Gets the google account.
*
* @param context the context
* @param accountName the account name
*/
private static Account getGoogleAccount(Context context, String accountName) {
Account[] accounts = AccountManager.get(context).getAccountsByType(Constants.ACCOUNT_TYPE);
for (Account account : accounts) {
if (account.name.equals(accountName)) {
return account;
}
}
return null;
}
/**
* Gets Google Maps.
*
* @param context the context
* @param account the account
* @param mapsClient the map client
* @return a list of maps.
*/
private static ArrayList<MapsMapMetadata> getMaps(
Context context, Account account, MapsClient mapsClient) {
String authToken = null;
ArrayList<String> mapIds = new ArrayList<String>();
ArrayList<MapsMapMetadata> mapMetadata = new ArrayList<MapsMapMetadata>();
try {
authToken = AccountManager.get(context)
.blockingGetAuthToken(account, MapsConstants.SERVICE_NAME, false);
} catch (Exception e) {
Log.e(TAG, "Unable to get auth token.", e);
return mapMetadata;
}
GDataParser gDataParser = null;
try {
gDataParser = mapsClient.getParserForFeed(
MapFeatureEntry.class, MapsClient.getMapsFeed(), authToken);
gDataParser.init();
while (gDataParser.hasMoreData()) {
MapFeatureEntry entry = (MapFeatureEntry) gDataParser.readNextEntry(null);
mapIds.add(MapsGDataConverter.getMapidForEntry(entry));
mapMetadata.add(MapsGDataConverter.getMapMetadataForEntry(entry));
}
} catch (Exception e) {
Log.e(TAG, "Unable to get maps.", e);
} finally {
if (gDataParser != null) {
gDataParser.close();
}
}
return mapMetadata;
}
}
@@ -1,133 +0,0 @@
/*
* Copyright 2013 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.endtoendtest;
import com.google.android.maps.mytracks.R;
/**
* Run configuration for various tests.
*
* @author Youtao Liu
*/
public class RunConfiguration {
private static RunConfiguration instance;
/**
* Gets an instance of {@link RunConfiguration}.
*/
public static RunConfiguration getInstance() {
if (instance == null) {
instance = new RunConfiguration();
}
return instance;
}
/*
* Set to false as default. True to run the test. Default to false since these
* tests can take a long time.
*/
private boolean runResourceTest = false;
private boolean runSensorTest = false;
private boolean runStressTest = false;
private boolean runSyncTest = false;
private RunConfiguration() {
// Sets run sync test in run-time
setRunSyncTest(canRunSyncTest());
}
/**
* Returns true to run the resource test.
*/
public boolean getRunResourceTest() {
return runResourceTest;
}
/**
* Sets run resource test.
*
* @param run true to run
*/
public void setRunResourceTest(boolean run) {
runResourceTest = run;
}
/**
* Returns true to run the sensor test.
*/
public boolean getRunSensorTest() {
return runSensorTest;
}
/**
* Sets run sensor test.
*
* @param run true to run
*/
public void setRunSensorTest(boolean run) {
runSensorTest = run;
}
/**
* Returns true to run the stress test.
*/
public boolean getRunStressTest() {
return runStressTest;
}
/**
* Sets run stress test.
*
* @param run true to run
*/
public void setRunStressTest(boolean run) {
runStressTest = run;
}
/**
* Returns true to run the sync test.
*/
public boolean getRunSyncTest() {
return runSyncTest;
}
/**
* Sets run sync test.
*
* @param run true to run
*/
public void setRunSyncTest(boolean run) {
runSyncTest = run;
}
/**
* Returns true if can run the sync test. Needs two specific test accounts on
* the device.
*/
private boolean canRunSyncTest() {
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_drive), true);
boolean canRun = EndToEndTestUtils.SOLO.waitForText(
GoogleUtils.ACCOUNT_1, 1, EndToEndTestUtils.SHORT_WAIT_TIME)
&& EndToEndTestUtils.SOLO.waitForText(
GoogleUtils.ACCOUNT_2, 1, EndToEndTestUtils.TINY_WAIT_TIME);
EndToEndTestUtils.SOLO.clickOnText(
EndToEndTestUtils.trackListActivity.getString(R.string.generic_cancel));
return canRun;
}
}
@@ -1,172 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.ListView;
/**
* Tests creating new tracks.
*
* @author Youtao Liu
*/
public class CreateTrackTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public CreateTrackTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
EndToEndTestUtils.deleteAllTracks();
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests creating a new track and checks the relative time in
* {@link TrackListActivity}.
*/
public void testNewTrack() {
// Start a recording
EndToEndTestUtils.startRecording();
checkRecording();
// Stop the recording
EndToEndTestUtils.stopRecording(false);
// Save the track
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_save), true, true);
instrumentation.waitForIdleSync();
// Go back to the TrackListActivity
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
// Make sure "mins ago" is displayed
assertTrue(EndToEndTestUtils.SOLO.searchText(
EndToEndTestUtils.getRelativeStartTimeSuffix(), 1, false, true));
}
/**
* Tests creating a new track with two markers.
*/
public void testNewTrackWithMarker() {
// Start a recording
EndToEndTestUtils.startRecording();
checkRecording();
// Create a marker
EndToEndTestUtils.sendGps(2);
EndToEndTestUtils.createWaypoint(0);
// Send more gps points
EndToEndTestUtils.sendGps(2, 2);
EndToEndTestUtils.createWaypoint(1);
// Go back to the TrackListActivity
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
// Rotate the phone
EndToEndTestUtils.rotateCurrentActivity();
// Stop the recording
EndToEndTestUtils.stopRecording(false);
// Update edit page and save
String trackName = EndToEndTestUtils.TRACK_NAME_PREFIX + System.currentTimeMillis();
EndToEndTestUtils.SOLO.enterText(0, trackName);
EndToEndTestUtils.SOLO.enterText(1, EndToEndTestUtils.activityType);
EndToEndTestUtils.SOLO.clickOnButton(trackListActivity.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
// Check the track name in the TrackListActivity
EndToEndTestUtils.SOLO.scrollUp();
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackName, 1, EndToEndTestUtils.NORMAL_WAIT_TIME, true, false));
// Go to the TrackDetailActivity
EndToEndTestUtils.SOLO.clickOnText(trackName);
instrumentation.waitForIdleSync();
// Go to Markers
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_markers), true);
instrumentation.waitForIdleSync();
// Make sure there are two markers
assertTrue(EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount() == 2);
}
/**
* Tests creating a new track with split markers.
*/
public void testNewTrackWithSplit() {
EndToEndTestUtils.changeToMetricUnits();
EndToEndTestUtils.startRecording();
checkRecording();
EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_split_frequency), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.unit_kilometer), 0);
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
// Send gps to give a distance more than one kilometer
EndToEndTestUtils.sendGps(50);
assertTrue(
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_markers), true));
instrumentation.waitForIdleSync();
if (EndToEndTestUtils.isEmulator) {
assertTrue(EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount() > 0);
}
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
EndToEndTestUtils.stopRecording(true);
}
/**
* Checks recording.
*/
private void checkRecording() {
if (EndToEndTestUtils.hasActionBar) {
// Check the title is Recording...
assertTrue(EndToEndTestUtils.SOLO.searchText(
trackListActivity.getString(R.string.generic_recording)));
}
}
}
@@ -1,144 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.ListView;
/**
* Tests delete tracks.
*
* @author Youtao Liu
*/
public class DeleteTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public DeleteTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Deletes all tracks.
*/
public void testDeleteAllTracks() {
EndToEndTestUtils.createSimpleTrack(1, true);
assertTrue(EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount() > 0);
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_delete_all), true);
instrumentation.waitForIdleSync();
EndToEndTestUtils.rotateCurrentActivity();
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_yes), true, true);
EndToEndTestUtils.waitTextToDisappear(
trackListActivity.getString(R.string.generic_progress_title));
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.track_list_empty_message)));
assertEquals(0, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
}
/**
* Deletes one track.
*/
public void testDeleteOneTrack() {
EndToEndTestUtils.createSimpleTrack(1, true);
ListView listView = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0);
int trackCount = listView.getCount();
assertTrue(trackCount > 0);
EndToEndTestUtils.SOLO.clickOnView(listView.getChildAt(0));
EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.track_detail_chart_tab));
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_delete), true);
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_yes), true, true);
EndToEndTestUtils.waitTextToDisappear(
trackListActivity.getString(R.string.generic_progress_title));
assertEquals(
trackCount - 1, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
}
/**
* Deletes multiple tracks in {@link TrackListActivity}.
*/
public void testDeleteMultiple() {
if (!EndToEndTestUtils.hasActionBar) {
return;
}
// Create 3 tracks
for (int i = 0; i < 3; i++) {
EndToEndTestUtils.createSimpleTrack(0, true);
}
ListView listView = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0);
int trackCount = listView.getCount();
assertTrue(trackCount > 2);
// Select 3 tracks
EndToEndTestUtils.SOLO.clickLongOnView(listView.getChildAt(0));
EndToEndTestUtils.SOLO.clickOnView(listView.getChildAt(1));
EndToEndTestUtils.SOLO.clickOnView(listView.getChildAt(2));
// Deselect the first one
EndToEndTestUtils.SOLO.clickOnView(listView.getChildAt(0));
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_delete), true);
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_yes), true, true);
EndToEndTestUtils.waitTextToDisappear(
trackListActivity.getString(R.string.generic_progress_title));
assertEquals(
trackCount - 2, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
}
/**
* Deletes a recording track.
*/
public void testDeleteRecordingTrack() {
EndToEndTestUtils.startRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_delete), true);
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_yes), true, true);
EndToEndTestUtils.waitTextToDisappear(
trackListActivity.getString(R.string.generic_progress_title));
EndToEndTestUtils.checkNotRecording();
}
}
@@ -1,112 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
/**
* Tests editing a track.
*
* @author Youtao Liu
*/
public class EditTrackTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public EditTrackTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests editing a track.
*/
public void testEditTrack() {
EndToEndTestUtils.deleteAllTracks();
EndToEndTestUtils.createSimpleTrack(1, false);
// Click on the Edit menu item
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_edit), true);
// Rotate phone
EndToEndTestUtils.rotateCurrentActivity();
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.generic_save));
String newName = EndToEndTestUtils.TRACK_NAME_PREFIX + "_new" + System.currentTimeMillis();
String newActivityType = EndToEndTestUtils.activityType;
String newDescription = "new_description_" + newName;
// Clear name field
sendKeys(KeyEvent.KEYCODE_DEL);
// Enter new name
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, newName);
// Enter new activity type
EndToEndTestUtils.SOLO.clearEditText(1);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(1, newActivityType);
// Enter new description
EndToEndTestUtils.SOLO.clearEditText(2);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(2, newDescription);
// Change activity type using the activity picker
assertTrue(EndToEndTestUtils.SOLO.searchText(newActivityType));
EndToEndTestUtils.SOLO.clickOnView(EndToEndTestUtils.SOLO.getCurrentActivity()
.findViewById(R.id.track_edit_activity_type_icon));
EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.track_edit_activity_type_hint));
int walkingActivityTypeIndex = 1;
EndToEndTestUtils.SOLO.clickOnView(EndToEndTestUtils.SOLO.getImage(walkingActivityTypeIndex));
EndToEndTestUtils.SOLO.clickOnButton(trackListActivity.getString(R.string.generic_ok));
// The activity type should be replaced by the walking activity type
assertFalse(EndToEndTestUtils.SOLO.searchText(newActivityType));
assertTrue(EndToEndTestUtils.SOLO.searchText(
trackListActivity.getString(R.string.activity_type_walking)));
// Save
EndToEndTestUtils.SOLO.clickOnButton(trackListActivity.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
// Go back to the TrackListActivity
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.searchText(newName));
assertTrue(EndToEndTestUtils.SOLO.searchText(newDescription));
}
}
@@ -1,637 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.Instrumentation;
import android.location.Location;
import android.location.LocationManager;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Tests export all and import all.
*
* @author Youtao Liu
*/
public class ExportAllAndImportAllTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final String TAG = ExportAllAndImportAllTest.class.getSimpleName();
private static final String GPX_FILE_TRACK_NAME = "TestTrackName1373523959524";
private static final int GPX_FILE_TIME_INTERVAL = 9; // seconds
private static final double GPX_FILE_INIT_LATITUDE = 39.30;
private static final double GPX_FILE_INIT_LONGITUDE = 116.0;
private static final String GPX_FILE_ELEVATION_MAX = "33.3";
private static final String GPX_FILE_ELEVATION_MIN = "22.2";
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public ExportAllAndImportAllTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests export all as KML.
*/
public void testExport_kml() {
testExport(TrackFileFormat.KML);
}
/**
* Tests export all as GPX.
*/
public void testExport_gpx() {
testExport(TrackFileFormat.GPX);
}
/**
* Tests export all as CSV.
*/
public void testExport_csv() {
testExport(TrackFileFormat.CSV);
}
/**
* Tests export all as TCX.
*/
public void testExport_tcx() {
testExport(TrackFileFormat.TCX);
}
/**
* Test import all KML when there is no file.
*/
public void testImportNoFile_kml() {
testImportNoFile(TrackFileFormat.KML);
}
/**
* Test import all GPX when there is no file.
*/
public void testImportNoFile_gpx() {
testImportNoFile(TrackFileFormat.GPX);
}
/**
* Tests export all as KML and import all KML when there is only one track.
*/
public void testExportImportOne_kml() {
testExportImportOne(TrackFileFormat.KML);
}
/**
* Tests export all as GPX and import all GPX when there is only one track.
*/
public void testExportImportOne_gpx() {
testExportImportOne(TrackFileFormat.GPX);
}
/**
* Tests export all as KML and import all KML when there is only one track and
* the track contains markers.
*/
public void testExportImportOneWithMarker_kml() {
testExportImportOneWithMarker(TrackFileFormat.KML);
}
/**
* Tests export all as GPX and import all GPX when there is only one track and
* the track contains markers.
*/
public void testExportImportOneWithMarker_gpx() {
testExportImportOneWithMarker(TrackFileFormat.GPX);
}
/**
* Tests export all as KML and import all KML when there are multiple tracks.
*/
public void testExportImportMultiple_kml() {
testExportImportMultiple(TrackFileFormat.KML);
}
/**
* Tests export all as GPX and import all GPX when there are multiple tracks.
*/
public void testExportImportMultiple_gpx() {
testExportImportMultiple(TrackFileFormat.GPX);
}
/**
* Tests export all as KML and import all KML when there are multiple tracks
* and the tracks contain pauses.
*/
public void testExportImportMultipleWithPause_kml() {
testExportImportMultipleWithPause(TrackFileFormat.KML);
}
/**
* Tests export all as GPX and import all GPX when there are multiple tracks
* and the tracks contain pauses.
*/
public void testExportImportMultipleWithPause_gpx() {
testExportImportMultipleWithPause(TrackFileFormat.GPX);
}
/**
* Tests export all.
*
* @param trackFileFormat the track file format
*/
private void testExport(TrackFileFormat trackFileFormat) {
deleteExternalStorageFiles(trackFileFormat);
EndToEndTestUtils.deleteAllTracks();
// Create a new track with 1 gps point
EndToEndTestUtils.createTrackIfEmpty(1, true);
assertEquals(1, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
exportTracks(trackFileFormat, 1);
assertEquals(1, getExternalStorageFiles(trackFileFormat).length);
}
/**
* Tests import all when there is no file.
*
* @param trackFileFormat the track file format
*/
private void testImportNoFile(TrackFileFormat trackFileFormat) {
deleteExternalStorageFiles(trackFileFormat);
importTracks(trackFileFormat);
EndToEndTestUtils.SOLO.waitForText(getImportErrorMessage(trackFileFormat));
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
}
/**
* Tests export all and import all with one track.
*
* @param trackFileFormat the track file format
*/
private void testExportImportOne(TrackFileFormat trackFileFormat) {
EndToEndTestUtils.changeToMetricUnits();
showGradeElevation();
addTrackFromGpxFile();
exportImport(trackFileFormat);
checkTrackFromGpxFile();
}
/**
* Tests export all and import all with one track containing markers.
*
* @param trackFileFormat the track file format
*/
private void testExportImportOneWithMarker(TrackFileFormat trackFileFormat) {
addTrackWithMarker();
exportImport(trackFileFormat);
// Check name, activity type, and description
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.trackName));
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackName);
EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.track_detail_chart_tab));
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_edit), true);
instrumentation.waitForIdleSync();
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.trackName));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.activityType));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.trackDescription));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.generic_cancel));
// Check markers
if (EndToEndTestUtils.hasGpsSignal) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_markers), true);
// The first marker
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.WAYPOINT_NAME + 1));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.WAYPOINT_TYPE + 1));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.WAYPOINT_DESCRIPTION + 1));
// The second marker
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.WAYPOINT_NAME + 2));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.WAYPOINT_TYPE + 2));
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.WAYPOINT_DESCRIPTION + 2));
}
}
/**
* Tests export all and import all with multiple tracks.
*
* @param trackFileFormat the track file format
*/
private void testExportImportMultiple(TrackFileFormat trackFileFormat) {
addTracks();
exportImport(trackFileFormat);
}
/**
* Tests export all and import all with multiple tracks containing pauses.
*
* @param trackFileFormat the track file format
*/
private void testExportImportMultipleWithPause(TrackFileFormat trackFileFormat) {
addTracksWithPause();
exportImport(trackFileFormat);
}
/**
* Adds one track by importing it from a GPX file.
*/
private void addTrackFromGpxFile() {
EndToEndTestUtils.deleteAllTracks();
deleteExternalStorageFiles(TrackFileFormat.GPX);
createOneGpxFile();
importTracks(TrackFileFormat.GPX);
checkImportSuccess();
checkTrackFromGpxFile();
}
/**
* Adds one track with markers.
*/
private void addTrackWithMarker() {
EndToEndTestUtils.deleteAllTracks();
// Create a new track with two markers
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
// Send gps before creating the first marker
EndToEndTestUtils.sendGps(2);
EndToEndTestUtils.createWaypoint(0);
EndToEndTestUtils.sendGps(2, 2);
EndToEndTestUtils.createWaypoint(1);
EndToEndTestUtils.sendGps(2, 4);
// Back to the tracks list
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
EndToEndTestUtils.stopRecording(true);
}
/**
* Adds multiple tracks.
*/
private void addTracks() {
EndToEndTestUtils.deleteAllTracks();
// Create a new track with 3 gps points
EndToEndTestUtils.createTrackIfEmpty(3, true);
instrumentation.waitForIdleSync();
// Create an empty track
EndToEndTestUtils.createSimpleTrack(0, true);
instrumentation.waitForIdleSync();
assertEquals(2, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
}
/**
* Adds multiple tracks with pauses.
*/
private void addTracksWithPause() {
EndToEndTestUtils.deleteAllTracks();
// Create a new track with 3 gps points
EndToEndTestUtils.createTrackWithPause(3);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
// Create an empty track
EndToEndTestUtils.createTrackWithPause(0);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
assertEquals(2, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
}
/**
* Export all and import all.
*
* @param trackFileFormat the track file format
*/
private void exportImport(TrackFileFormat trackFileFormat) {
deleteExternalStorageFiles(trackFileFormat);
assertEquals(0, getExternalStorageFiles(trackFileFormat).length);
int trackCount = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
// Export all
exportTracks(trackFileFormat, trackCount);
assertEquals(trackCount, getExternalStorageFiles(trackFileFormat).length);
if (trackCount == 1) {
EndToEndTestUtils.deleteAllTracks();
}
// Import all
importTracks(trackFileFormat);
EndToEndTestUtils.rotateCurrentActivity();
checkImportSuccess();
EndToEndTestUtils.SOLO.waitForActivity(TrackListActivity.class);
assertEquals(trackCount == 1 ? 1 : trackCount * 2,
EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
}
/**
* Exports all tracks.
*
* @param trackFileFormat the track file format
* @param trackCount the track count
*/
private void exportTracks(TrackFileFormat trackFileFormat, int trackCount) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_export_all), true);
EndToEndTestUtils.instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackFileFormat.name());
EndToEndTestUtils.getButtonOnScreen(
EndToEndTestUtils.trackListActivity.getString(R.string.generic_ok), true, true);
EndToEndTestUtils.SOLO.waitForText(getExportSuccessMessage(trackCount, trackFileFormat));
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
}
/**
* Imports all tracks.
*
* @param trackFileFormat the track file format
*/
private void importTracks(TrackFileFormat trackFileFormat) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_import_all), true);
EndToEndTestUtils.SOLO.clickOnText(trackFileFormat.name());
EndToEndTestUtils.getButtonOnScreen(
EndToEndTestUtils.trackListActivity.getString(R.string.generic_ok), true, true);
}
/**
* Gets the export all success message.
*
* @param count the count of successfully exported tracks
* @param trackFileFormat the track file format
*/
private String getExportSuccessMessage(int count, TrackFileFormat trackFileFormat) {
String trackCount = trackListActivity.getResources()
.getQuantityString(R.plurals.tracks, count, count);
String path = FileUtils.getPathDisplayName(trackFileFormat.getExtension());
return trackListActivity.getString(R.string.export_external_storage_success, trackCount, path);
}
/**
* Gets the import all error message.
*
* @param trackFileFormat the track file format
*/
private String getImportErrorMessage(TrackFileFormat trackFileFormat) {
String fileCount = trackListActivity.getResources().getQuantityString(R.plurals.files, 0, 0);
String path = FileUtils.getPathDisplayName(trackFileFormat.getExtension());
return trackListActivity.getString(R.string.import_error, 0, fileCount, path);
}
/**
* Checks that import all is success.
*/
private void checkImportSuccess() {
// Waiting for the prefix is much faster than waiting for the whole string
EndToEndTestUtils.waitTextToDisappear(
trackListActivity.getString(R.string.generic_progress_title));
EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.import_success).split("%")[0]);
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
}
/**
* Creates one GPX file in the MyTracks folder.
*/
private void createOneGpxFile() {
String fileName = GPX_FILE_TRACK_NAME + "." + TrackFileFormat.GPX.getExtension();
String fileContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + "<gpx "
+ "version=\"1.1\" " + "creator=\"Created by Google My Tracks on Android.\" "
+ "xmlns=\"http://www.topografix.com/GPX/1/1\" "
+ "xmlns:topografix=\"http://www.topografix.com/GPX/Private/TopoGrafix/0/1\" "
+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
+ "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1"
+ " http://www.topografix.com/GPX/1/1/gpx.xsd"
+ " http://www.topografix.com/GPX/Private/TopoGrafix/0/1"
+ " http://www.topografix.com/GPX/Private/TopoGrafix/0/1/topografix.xsd\"> " + "<metadata> "
+ "<name><![CDATA[" + GPX_FILE_TRACK_NAME + "]]></name> "
+ "<desc><![CDATA[testTrackDescription1373523959524]]></desc> " + "</metadata> " + "<trk> "
+ "<name><![CDATA[" + GPX_FILE_TRACK_NAME + "]]></name> "
+ "<desc><![CDATA[testTrackDescription1373523959524]]></desc> "
+ "<type><![CDATA[TestActivityType]]></type> "
+ "<extensions><topografix:color>c0c0c0</topografix:color></extensions> " + "<trkseg> "
+ "<trkpt lat=\"" + GPX_FILE_INIT_LATITUDE + "\" lon=\"" + GPX_FILE_INIT_LONGITUDE + "\"> "
+ "<time>2013-07-10T08:00:00.000Z</time> <ele>" + GPX_FILE_ELEVATION_MIN + "</ele>"
+ "</trkpt> " + "<trkpt lat=\"39.2995\" lon=\"116.0005\"> "
+ "<time>2013-07-10T08:00:01.000Z</time> " + "</trkpt> "
+ "<trkpt lat=\"39.299\" lon=\"116.001\"> " + "<time>2013-07-10T08:00:02.000Z</time> "
+ "</trkpt> " + "<trkpt lat=\"39.2985\" lon=\"116.0015\"> "
+ "<time>2013-07-10T08:00:03.000Z</time> " + "</trkpt> "
+ "<trkpt lat=\"39.298\" lon=\"116.002\"> " + "<time>2013-07-10T08:00:04.000Z</time> "
+ "</trkpt> " + "<trkpt lat=\"39.2975\" lon=\"116.0025\"> "
+ "<time>2013-07-10T08:00:05.000Z</time> " + "</trkpt> "
+ "<trkpt lat=\"39.297\" lon=\"116.003\"> " + "<time>2013-07-10T08:00:06.000Z</time> "
+ "</trkpt> " + "<trkpt lat=\"39.2965\" lon=\"116.0035\"> "
+ "<time>2013-07-10T08:00:07.000Z</time> " + "</trkpt> "
+ "<trkpt lat=\"39.296\" lon=\"116.004\"> " + "<time>2013-07-10T08:00:08.000Z</time> "
+ "</trkpt> " + "<trkpt lat=\"39.2955\" lon=\"116.0045\"> "
+ "<time>2013-07-10T08:00:09.000Z</time> <ele>" + GPX_FILE_ELEVATION_MAX + "</ele>"
+ "</trkpt> " + "</trkseg> " + "</trk> " + "</gpx>";
FileOutputStream fileOutputStream = null;
try {
File file = new File(
FileUtils.getPath(TrackFileFormat.GPX.getExtension()) + File.separator + fileName);
if (!file.exists()) {
file.createNewFile();
}
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(fileContent.getBytes());
fileOutputStream.flush();
} catch (IOException e) {
Log.e(TAG, "Unable to write GPX file", e);
fail();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
Log.e(TAG, "Unable to close GPX file", e);
fail();
}
}
}
}
/**
* Checks track imported from a GPX file.
*/
private void checkTrackFromGpxFile() {
EndToEndTestUtils.SOLO.clickOnText(GPX_FILE_TRACK_NAME);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.waitForActivity(
TrackDetailActivity.class, EndToEndTestUtils.LONG_WAIT_TIME);
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
instrumentation.waitForIdleSync();
double acceptDeviation = 0.1f;
Activity activity = EndToEndTestUtils.SOLO.getCurrentActivity();
double elevationMin = Double.parseDouble(((TextView) activity.findViewById(
R.id.stats_elevation_min).findViewById(R.id.stats_value)).getText().toString());
double elevationMax = Double.parseDouble(((TextView) activity.findViewById(
R.id.stats_elevation_max).findViewById(R.id.stats_value)).getText().toString());
double distance = Double.parseDouble(((TextView) activity.findViewById(R.id.stats_distance)
.findViewById(R.id.stats_value)).getText().toString());
double averageSpeed = Double.parseDouble(((TextView) activity.findViewById(
R.id.stats_average_speed).findViewById(R.id.stats_value)).getText().toString());
assertEquals(Double.parseDouble(GPX_FILE_ELEVATION_MIN), elevationMin);
assertEquals(getGpxFileElevationMax(), elevationMax);
// in km
double calculateDistance = getGpxFileDistance();
// in km/h
double calculateAverageSpeed = calculateDistance
/ (GPX_FILE_TIME_INTERVAL + UnitConversions.S_TO_MIN * UnitConversions.MIN_TO_HR);
assertTrue((calculateDistance - distance) / calculateDistance < acceptDeviation);
assertTrue((calculateAverageSpeed - averageSpeed) / calculateAverageSpeed < acceptDeviation);
EndToEndTestUtils.SOLO.goBack();
}
/**
* Gets the GPX file distance in km.
*/
private double getGpxFileDistance() {
double distance = 0.0;
double latitude = GPX_FILE_INIT_LATITUDE;
double longitude = GPX_FILE_INIT_LONGITUDE;
Location current = new Location(LocationManager.GPS_PROVIDER);
current.setLatitude(latitude);
current.setLongitude(longitude);
for (int i = 1; i < 10; i++) {
Location next = new Location(LocationManager.GPS_PROVIDER);
next.setLatitude(latitude - 0.0005 * i);
next.setLongitude(longitude + 0.0005 * i);
distance = distance + next.distanceTo(current) * UnitConversions.M_TO_KM;
current = next;
}
return distance;
}
/**
* Gets the GPX file elevation max.
*/
private double getGpxFileElevationMax() {
/*
* Returns the highest value of all the weighted averages. Since there are
* only two elevation data points, the highest value is the weighted average
* of both points.
*/
return (Double.parseDouble(GPX_FILE_ELEVATION_MIN) + Double.parseDouble(GPX_FILE_ELEVATION_MAX))
/ 2.0;
}
/**
* Gets the external storage files.
*
* @param trackFileFormat the track file format
*/
private File[] getExternalStorageFiles(final TrackFileFormat trackFileFormat) {
FileFilter filter = new FileFilter() {
@Override
public boolean accept(File file) {
String suffix = trackFileFormat == TrackFileFormat.KML ? ".kmz"
: "." + trackFileFormat.getExtension();
return file.getName().endsWith(suffix);
}
};
File dir = new File(FileUtils.getPath(trackFileFormat.getExtension()));
File[] files = dir.listFiles(filter);
return files == null ? new File[0] : files;
}
/**
* Deletes the external storage files.
*
* @param trackFileFormat the track file format
*/
private void deleteExternalStorageFiles(TrackFileFormat trackFileFormat) {
File dir = new File(FileUtils.getPath(trackFileFormat.getExtension()));
File[] files = dir.listFiles();
if (files == null) {
return;
}
for (File file : files) {
file.delete();
}
}
/**
* Shows grade elevation.
*/
private void showGradeElevation() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
String gradeElevation = trackListActivity.getString(R.string.settings_stats_grade_elevation);
if (!EndToEndTestUtils.SOLO.isCheckBoxChecked(gradeElevation)) {
EndToEndTestUtils.SOLO.clickOnText(gradeElevation);
}
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
}
@@ -1,196 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.maps.mytracks.R;
import com.google.api.services.drive.model.File;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import java.util.List;
/**
* Tests export single track to Google. Each test would export one track to
* Google Maps, Google Fusion Tables and Google Spreadsheets.
*
* @author youtaol
*/
public class ExportSingleTrackTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public ExportSingleTrackTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
GoogleUtils.deleteAllMaps(activityMyTracks.getApplicationContext(), GoogleUtils.ACCOUNT_1);
GoogleUtils.deleteDriveTestFiles(
activityMyTracks.getApplicationContext(), GoogleUtils.ACCOUNT_1);
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Checks all services and send to google.
*/
public void testCreateAndSendTrack_send() {
// Create a new track.
EndToEndTestUtils.createSimpleTrack(1, false);
instrumentation.waitForIdleSync();
checkSendTrackToGoogle();
}
/**
* Checks all services and send to google.
*/
public void testCreateAndSendTrack_sendPausedTrack() {
EndToEndTestUtils.deleteAllTracks();
EndToEndTestUtils.createTrackWithPause(3);
instrumentation.waitForIdleSync();
checkSendTrackToGoogle();
}
/**
* Sends two tracks with same activity. Two tracks should be in the same
* spreadsheet.
*/
public void testSendTwoTracksWithSameActivity() {
String testActivity = "(TestActivity)";
EndToEndTestUtils.activityType = testActivity;
GoogleUtils.deleteSpreadsheets(
EndToEndTestUtils.trackListActivity.getApplicationContext(), GoogleUtils.ACCOUNT_1);
EndToEndTestUtils.createSimpleTrack(1, false);
boolean result = sendToGoogle(activityMyTracks.getString(R.string.export_google_maps))
&& sendToGoogle(activityMyTracks.getString(R.string.export_google_fusion_tables))
&& sendToGoogle(activityMyTracks.getString(R.string.export_google_spreadsheets));
result = result && sendToGoogle(activityMyTracks.getString(R.string.export_google_maps))
&& sendToGoogle(activityMyTracks.getString(R.string.export_google_fusion_tables))
&& sendToGoogle(activityMyTracks.getString(R.string.export_google_spreadsheets));
// Result is true mean has account bound with this device and send
// successful.
if (result) {
List<File> fileList = GoogleUtils.searchSpreadsheets(
activityMyTracks.getApplicationContext(), GoogleUtils.ACCOUNT_1);
assertEquals(1, fileList.size());
}
}
/**
* Checks the process of sending track to google.
*/
private void checkSendTrackToGoogle() {
if (!sendToGoogle(activityMyTracks.getString(R.string.export_google_maps))
|| !sendToGoogle(activityMyTracks.getString(R.string.export_google_fusion_tables))
|| !sendToGoogle(activityMyTracks.getString(R.string.export_google_spreadsheets))) {
return;
}
// Check whether all data is correct on Google Drive, Maps, Documents, and
// Spreadsheet.
// assertTrue(SyncTestUtils.checkFile(EndToEndTestUtils.trackName, true,
// SyncTestUtils.getGoogleDrive(activityMyTracks.getApplicationContext())));
assertTrue(GoogleUtils.deleteMaps(
activityMyTracks.getApplicationContext(), GoogleUtils.ACCOUNT_1,
EndToEndTestUtils.trackName));
assertTrue(GoogleUtils.deleteFusionTables(
activityMyTracks.getApplicationContext(), GoogleUtils.ACCOUNT_1,
EndToEndTestUtils.trackName));
assertTrue(GoogleUtils.deleteSpreadsheetsRow(
activityMyTracks.getApplicationContext(), GoogleUtils.ACCOUNT_1,
EndToEndTestUtils.trackName));
}
/**
* Sends a track to Google.
*
* @param exportDestination destination to export
* @return true means send successfully
*/
private boolean sendToGoogle(String exportDestination) {
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_export), true);
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.export_title));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(exportDestination);
instrumentation.waitForIdleSync();
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.menu_export), true,
true);
instrumentation.waitForIdleSync();
if (!GoogleUtils.isAccountAvailable()) {
return false;
}
// Following check the process of "Send to Google", the second condition is
// in case the export has done.
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.generic_progress_title))
|| EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.generic_success_title)));
// Waiting the send is finish. Should double check it for the progress
// dialog may disappear and display again while switch to next send(There
// are four sends currently, there are send to drive, maps, fusion table and
// spreadsheet).
while (EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.generic_progress_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)
|| EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.generic_progress_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {}
if (exportDestination.endsWith(activityMyTracks.getString(R.string.export_google_maps))) {
// Check whether the result dialog is display.
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.share_track_share_url)));
} else {
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.generic_success_title)));
}
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
return true;
}
/**
* Sends a large track to Google.
*/
public void testSendLargeTrackToGoogle() {
EndToEndTestUtils.deleteAllTracks();
EndToEndTestUtils.createSimpleTrack(200, false);
instrumentation.waitForIdleSync();
checkSendTrackToGoogle();
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.activityType = EndToEndTestUtils.DEFAULT_ACTIVITY_TYPE;
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,189 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.widget.ListView;
import java.util.Locale;
/**
* Tests menu items.
*
* @author Youtao Liu
*/
public class MenuItemsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public MenuItemsTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests following More menu items.
* <ul>
* <li>Aggregated statistics in {@link TrackListActivity}</li>
* <li>Help & feedback in {@link TrackListActivity}</li>
* <li>Help & feedback in {@link TrackDetailActivity}</li>
* <li>Export in {@link TrackDetailActivity}</li>
* </ul>
*/
public void testMoreMenuItems() {
// Aggregated statistics in TrackListActivity
EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_aggregated_statistics), true);
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.stats_distance));
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
// Help & feedback in TrackListActivity
checkHelpFeedbackPage();
EndToEndTestUtils.createSimpleTrack(1, false);
instrumentation.waitForIdleSync();
// Help & feedback in TrackDetailActivity
checkHelpFeedbackPage();
// Export in TrackDetailActivity
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_export), true);
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.export_title));
}
/**
* Tests the search menu. When search is displayed, the track controller
* should be hidden.
*/
public void testSearchMenu() {
EndToEndTestUtils.deleteAllTracks();
EndToEndTestUtils.createSimpleTrack(0, true);
assertTrue(isTrackControllerShown());
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_search), true);
assertFalse(isTrackControllerShown());
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, EndToEndTestUtils.trackName);
sendKeys(KeyEvent.KEYCODE_ENTER);
instrumentation.waitForIdleSync();
assertEquals(1, EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount());
// TODO: not sure why the following fails. It passes in debug mode.
// assertFalse(isTrackControllerShown());
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
assertTrue(isTrackControllerShown());
}
/**
* Checks the voice frequency and the split frequency menu. When recording,
* they should be in both the {@link TrackDetailActivity} menu and the
* recording settings. When not recording, they should only be in the
* recording settings.
*/
public void testFrequencyMenu() {
EndToEndTestUtils.startRecording();
assertTrue(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_voice_frequency), false));
assertTrue(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_split_frequency), false));
checkFrequencyInSettings();
EndToEndTestUtils.stopRecording(true);
assertFalse(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_voice_frequency), false));
assertFalse(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_split_frequency), false));
checkFrequencyInSettings();
}
/**
* Tests start and stop gps.
*/
public void testGpsMenu() {
// Start gps
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_start_gps), true);
EndToEndTestUtils.waitTextToDisappear(trackListActivity.getString(R.string.menu_start_gps));
assertTrue(
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_stop_gps), false));
// Stop gps
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_stop_gps), true);
EndToEndTestUtils.waitTextToDisappear(trackListActivity.getString(R.string.menu_stop_gps));
assertTrue(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_start_gps), false));
}
/**
* Checks the help & feedback page.
*/
private void checkHelpFeedbackPage() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_help_feedback), true);
assertNotNull(EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.menu_feedback).toUpperCase(Locale.getDefault()), true,
false));
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
}
/**
* Returns true if the track controller is shown.
*/
private boolean isTrackControllerShown() {
return trackListActivity.findViewById(R.id.track_controler_container).isShown();
}
/**
* Checks that the frequency options exists in settings.
*/
private void checkFrequencyInSettings() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_recording));
assertTrue(EndToEndTestUtils.SOLO.searchText(
trackListActivity.getString(R.string.menu_voice_frequency), 1, true, true));
assertTrue(EndToEndTestUtils.SOLO.searchText(
trackListActivity.getString(R.string.menu_split_frequency), 1, true, true));
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
}
@@ -1,75 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
/**
* Tests the my location button.
*
* @author Youtao Liu
*/
public class MyLocationTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public MyLocationTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests the my location button.
*/
public void testMyLocation() {
EndToEndTestUtils.deleteAllTracks();
EndToEndTestUtils.createSimpleTrack(1, false);
View myLocation = EndToEndTestUtils.SOLO.getCurrentActivity()
.findViewById(R.id.map_my_location);
EndToEndTestUtils.SOLO.clickOnView(myLocation);
instrumentation.waitForIdleSync();
if (EndToEndTestUtils.isEmulator) {
EndToEndTestUtils.SOLO.waitForText(
GoogleLocationUtils.getGpsDisabledMyLocationMessage(trackListActivity), 1,
EndToEndTestUtils.SHORT_WAIT_TIME);
} else {
// TODO How to verify my location is shown on the map?
}
}
}
@@ -1,152 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import android.app.Instrumentation;
import android.location.Location;
import android.test.ActivityInstrumentationTestCase2;
/**
* Tests pause and resume during a recording.
*
* @author Youtao Liu
*/
public class PauseResumeTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final int SEND_INTERVAL = 100; // ms
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public PauseResumeTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests stop after a pause.
*/
public void testStopAfterPause() {
int firstBatch = 3;
int secondBatch = 10;
EndToEndTestUtils.checkNotRecording();
// Start a recording
EndToEndTestUtils.startRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.sendGps(firstBatch);
// Pause the recording
EndToEndTestUtils.pauseRecording();
EndToEndTestUtils.checkUnderPaused();
EndToEndTestUtils.sendGps(secondBatch, firstBatch);
// Stop the recording
EndToEndTestUtils.stopRecording(true);
checkTrackLocation(firstBatch, 1, 0);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.checkNotRecording();
}
/**
* Tests stop after a resume.
*/
public void testStopAfterResume() {
int firstBatch = 3;
int secondBatch = 5;
int thirdBatch = 7;
EndToEndTestUtils.checkNotRecording();
// Start a recording
EndToEndTestUtils.startRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.sendGps(firstBatch);
// Pause the recording
EndToEndTestUtils.pauseRecording();
EndToEndTestUtils.checkUnderPaused();
// Send gps signal after pause
EndToEndTestUtils.sendGps(secondBatch, firstBatch, SEND_INTERVAL);
// Resume the recording
EndToEndTestUtils.resumeRecording();
EndToEndTestUtils.checkUnderRecording();
EndToEndTestUtils.sendGps(thirdBatch, firstBatch + secondBatch);
// Stop the recordinga
EndToEndTestUtils.stopRecording(true);
checkTrackLocation(firstBatch + secondBatch, 1, 1);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.checkNotRecording();
}
/**
* Check the last track's location.
*
* @param expectedPoint the number of expected points
* @param expectedPause the number of expected pauses
* @param expectedResume the number of expected resumes
*/
private void checkTrackLocation(int expectedPoint, int expectedPause, int expectedResume) {
if (EndToEndTestUtils.isEmulator) {
int point = 0;
int pause = 0;
int resume = 0;
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(
trackListActivity.getApplicationContext());
long trackId = myTracksProviderUtils.getLastTrack().getId();
LocationIterator locationIterator = myTracksProviderUtils.getTrackPointLocationIterator(
trackId, 0, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
while (locationIterator.hasNext()) {
Location location = locationIterator.next();
double latitude = location.getLatitude();
if (latitude == TrackRecordingService.PAUSE_LATITUDE) {
pause++;
} else if (latitude == TrackRecordingService.RESUME_LATITUDE) {
resume++;
} else {
point++;
}
}
assertEquals(expectedPoint, point);
assertEquals(expectedPause, pause);
assertEquals(expectedResume, resume);
}
}
}
@@ -1,296 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.CheckBox;
import junit.framework.Assert;
/**
* Tests the settings.
*
* @author Youtao Liu
*/
public class SettingsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final String GMAIL_COM = "gmail.com";
private static final String NEW_ACTIVITY_TYPE = "NewActivityType";
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public SettingsTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Tests changing preferred units to imperial.
*/
public void testPreferredUnits_imperial() {
testPreferredUnits(R.string.unit_mile);
}
/**
* Tests changing preferred units to metric.
*/
public void testPreferredUnits_metric() {
testPreferredUnits(R.string.unit_kilometer);
}
/**
* Tests changing preferred units while recording and viewing the chart tab.
*/
public void testPreferredUnitsRecording_chart() {
testPreferredUnitsRecording(R.string.track_detail_chart_tab);
}
/**
* Tests changing preferred units while recording and viewing the stats tab.
*/
public void testPreferredUnitsRecording_stats() {
testPreferredUnitsRecording(R.string.track_detail_stats_tab);
}
/**
* Tests changing preferred units while recording and viewing the map tab.
*/
public void testPreferredUnitsRecording_map() {
testPreferredUnitsRecording(R.string.track_detail_map_tab);
}
/**
* Tests grade/elevation and latitude/longitude..
*/
public void testGradeElevationAndLatitudeLongitude() {
// Ennable grade/elevation and latitude/longitude
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.settings_stats_units_title)));
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_stats_grade_elevation));
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_stats_coordinate));
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
// Start recording and check stats tab
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.stats_elevation), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME, true));
assertTrue(
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.stats_grade)));
assertTrue(
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.stats_latitude)));
assertTrue(
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.stats_longitude)));
// Stop recording and check stats tab
EndToEndTestUtils.stopRecording(true);
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.stats_elevation), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME, true));
assertTrue(
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.stats_grade)));
assertNull(
EndToEndTestUtils.findTextView(trackListActivity.getString(R.string.stats_latitude)));
assertNull(
EndToEndTestUtils.findTextView(trackListActivity.getString(R.string.stats_longitude)));
}
/**
* Tests default track name and default activity type.
*/
public void testDefaultTrackNameAndDefaultActivityType() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_recording));
// Change the default track name to number
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_recording_track_name_title));
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_recording_track_name_number_option));
// Change the default activity type to NEW_ACTIVITY_TYPE
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_recording_default_activity_title));
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, NEW_ACTIVITY_TYPE);
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
EndToEndTestUtils.stopRecording(false);
assertTrue(EndToEndTestUtils.SOLO.searchText(
trackListActivity.getString(R.string.track_name_format).split(" ")[0]));
assertTrue(EndToEndTestUtils.SOLO.searchText(NEW_ACTIVITY_TYPE));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.generic_save));
}
/**
* Tests track color setting for fixed thresholds.
*/
public void testTrackColor_fixed() {
testTrackColor(R.string.settings_map_track_color_mode_fixed,
R.string.settings_map_track_color_mode_fixed_summary);
}
/**
* Tests track color setting for dynamic thresholds.
*/
public void testTrackColorSettings_dynamic() {
testTrackColor(R.string.settings_map_track_color_mode_dynamic,
R.string.settings_map_track_color_mode_dynamic_summary);
}
/**
* Tests track color setting for single color.
*/
public void testTrackColorSettings_single() {
testTrackColor(R.string.settings_map_track_color_mode_single,
R.string.settings_map_track_color_mode_single);
}
/**
* Tests allow access.
*/
public void testAllowAccess() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_advanced));
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.settings_sharing_allow_access), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME));
EndToEndTestUtils.SOLO.clickOnCheckBox(0);
assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.settings_sharing_allow_access_confirm_message), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME));
EndToEndTestUtils.SOLO.clickOnButton(trackListActivity.getString(R.string.generic_yes));
instrumentation.waitForIdleSync();
assertEquals(true, EndToEndTestUtils.SOLO.getCurrentViews(CheckBox.class).get(0).isChecked());
EndToEndTestUtils.SOLO.goBack();
}
/**
* Tests sync.
*/
public void testSync() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.menu_sync_drive));
// Whether there is a gmail.com account
if (!EndToEndTestUtils.SOLO.waitForText(GMAIL_COM, 1, EndToEndTestUtils.TINY_WAIT_TIME)) {
return;
}
// Click the first gmail.com account
EndToEndTestUtils.SOLO.clickOnText(GMAIL_COM, 0);
instrumentation.waitForIdleSync();
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.sync_drive_confirm_message).split("%")[0], 1,
EndToEndTestUtils.SHORT_WAIT_TIME);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.generic_no));
EndToEndTestUtils.SOLO.goBack();
assertEquals(false,
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_sync_now), false));
}
/**
* Tests preferred units.
*
* @param unitId the unit id
*/
private void testPreferredUnits(int unitId) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
Assert.assertTrue(EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.settings_stats_units_title)));
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_stats_units_title));
instrumentation.waitForIdleSync();
String unit = trackListActivity.getString(unitId);
EndToEndTestUtils.SOLO.clickOnText(unit);
EndToEndTestUtils.SOLO.searchText(unit);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
/**
* Tests preferred units while recording.
*
* @param tabId the tab id
*/
private void testPreferredUnitsRecording(int tabId) {
testPreferredUnits(R.string.unit_kilometer);
EndToEndTestUtils.startRecording();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(tabId));
EndToEndTestUtils.sendGps(3);
testPreferredUnits(R.string.unit_mile);
EndToEndTestUtils.sendGps(3, 3);
EndToEndTestUtils.stopRecording(true);
}
/**
* Tests track color setting.
*
* @param modeId the mode id
* @param summaryId the summary id
*/
private void testTrackColor(int modeId, int summaryId) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.menu_map));
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.settings_map_track_color_mode));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(modeId));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(summaryId));
}
}
@@ -1,125 +0,0 @@
/*
* Copyright 2013 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.apps.mytracks.endtoendtest.sync.SyncTestUtils;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.CheckBox;
import java.util.ArrayList;
/**
* Tests the share feature.
*
* @author youtaol
*/
public class ShareTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity activityMyTracks;
public ShareTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
activityMyTracks = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
}
/**
* Tests the share one track.
*/
public void testShare() {
EndToEndTestUtils.resetAllSettings(activityMyTracks, false);
EndToEndTestUtils.createTrackIfEmpty(0, false);
// Click share again and confirm the share.
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_share), true);
// Whether can found any account.
if (EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.send_google_no_account_title), 1,
EndToEndTestUtils.VERY_SHORT_WAIT_TIME)) {
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.generic_ok));
return;
}
boolean isAccount2Bound = false;
// If Choose account dialog prompt, choose the first account.
if (EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.send_google_choose_account_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {
// Whether can found account2.
if (EndToEndTestUtils.SOLO.waitForText(
GoogleUtils.ACCOUNT_2, 1, EndToEndTestUtils.VERY_SHORT_WAIT_TIME)) {
isAccount2Bound = true;
}
EndToEndTestUtils.SOLO.clickOnText(GoogleUtils.ACCOUNT_1);
EndToEndTestUtils.getButtonOnScreen(
activityMyTracks.getString(R.string.generic_ok), true, true);
}
// Check all check boxes.
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.share_track_title)));
ArrayList<CheckBox> checkBoxs = EndToEndTestUtils.SOLO.getCurrentViews(CheckBox.class);
for (int i = 0; i < checkBoxs.size(); i++) {
if (!checkBoxs.get(i).isChecked()) {
EndToEndTestUtils.SOLO.clickOnView(checkBoxs.get(i));
instrumentation.waitForIdleSync();
}
}
// Input account to share and click OK button.
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.share_track_emails_hint)));
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, GoogleUtils.ACCOUNT_2);
EndToEndTestUtils
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
// Waiting the send is finish.
while (EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.generic_progress_title), 1,
EndToEndTestUtils.SHORT_WAIT_TIME)) {}
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.SOLO
.getString(R.string.share_track_share_url_title)));
EndToEndTestUtils.SOLO.goBack();
// Make more checks if the second account is also bound with this device.
if (isAccount2Bound) {
EndToEndTestUtils.SOLO.goBack();
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_2);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.track_list_shared_with_me), 1,
EndToEndTestUtils.SUPER_LONG_WAIT_TIME));
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.trackName, 1,
EndToEndTestUtils.SUPER_LONG_WAIT_TIME));
}
}
}
@@ -1,180 +0,0 @@
/*
* 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.endtoendtest.common;
import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.fragments.ChartFragment;
import com.google.android.apps.mytracks.fragments.StatsFragment;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.Display;
import android.view.View;
import junit.framework.Assert;
/**
* Tests switching views and the menu list of each view.
*
* @author Youtao Liu
*/
public class ViewsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public ViewsTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
@Override
protected void tearDown() throws Exception {
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
/**
* Switches tab from {@link MyTracksMapFragment} to {@link ChartFragment},
* then to {@link StatsFragment}, and then to {@link MyTracksMapFragment}. In
* each tab, checks menu items like settings and map layer.
*/
public void testSwitchTabAndViewMenu() {
EndToEndTestUtils.createTrackIfEmpty(3, true);
EndToEndTestUtils.SOLO.scrollUp();
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackName, 1, true);
// Switch to chart view
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_chart_tab));
EndToEndTestUtils.rotateCurrentActivity();
assertTrue(
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), false));
assertFalse(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_map_layer), false));
// Switch to stats view
EndToEndTestUtils.SOLO.clickOnText(
trackListActivity.getString(R.string.track_detail_stats_tab));
assertTrue(
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), false));
assertFalse(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_map_layer), false));
// Switch to map view
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.track_detail_map_tab));
EndToEndTestUtils.rotateCurrentActivity();
assertTrue(
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), false));
assertTrue(EndToEndTestUtils.findMenuItem(
trackListActivity.getString(R.string.menu_map_layer), false));
}
/**
* Test selecting map layer.
*/
public void testMapLayer() {
EndToEndTestUtils.createTrackIfEmpty(1, false);
selectMapLayer(R.string.menu_terrain);
selectMapLayer(R.string.menu_satellite_with_streets);
selectMapLayer(R.string.menu_satellite);
selectMapLayer(R.string.menu_map);
}
/**
* Tests the track controller position in landscape view and portrait view on
* {@link TrackListActivity} and {@link TrackDetailActivity}.
*/
public void testTrackControllerPostion() {
checkTrackControllerPosition();
EndToEndTestUtils.rotateCurrentActivity();
instrumentation.waitForIdleSync();
checkTrackControllerPosition();
EndToEndTestUtils.startRecording();
instrumentation.waitForIdleSync();
checkTrackControllerPosition();
EndToEndTestUtils.rotateCurrentActivity();
instrumentation.waitForIdleSync();
checkTrackControllerPosition();
EndToEndTestUtils.stopRecording(true);
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
checkTrackControllerPosition();
EndToEndTestUtils.rotateCurrentActivity();
instrumentation.waitForIdleSync();
checkTrackControllerPosition();
}
/**
* Selects a map layer
*
* @param id the map layer id
*/
private void selectMapLayer(int id) {
// Make sure can see the map tab
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.track_detail_map_tab));
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_map_layer), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(id));
EndToEndTestUtils.getButtonOnScreen(
trackListActivity.getString(R.string.generic_ok), true, true);
instrumentation.waitForIdleSync();
}
/**
* Checks the position of track controller in landscape view and portrait
* view.
*/
@SuppressWarnings("deprecation")
private void checkTrackControllerPosition() {
View controller = EndToEndTestUtils.SOLO.getCurrentActivity()
.findViewById(R.id.track_controler_container);
Display display = EndToEndTestUtils.SOLO.getCurrentActivity()
.getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
if (width > height) {
// In landscape view
Assert.assertTrue(controller.getWidth() < controller.getHeight());
Assert.assertTrue(controller.getTop() < height / 2);
Assert.assertTrue(controller.getRight() < width / 2);
} else {
// In portrait view
Assert.assertTrue(controller.getWidth() > controller.getHeight());
Assert.assertTrue(controller.getTop() > height / 2);
Assert.assertTrue(controller.getRight() > width / 2);
}
}
}
@@ -1,155 +0,0 @@
package com.google.android.apps.mytracks.endtoendtest.others;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Environment;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import junit.framework.Assert;
/**
* A utility to support the big test cases, such as sensor test, stress test and
* so forth which under the package
* {@link com.google.android.apps.mytracks.endtoendtest.others}.
*
* @author Youtao Liu
*/
public class BigTestUtils {
public static final String DISABLE_MESSAGE = "This test is disabled";
public static final String MYTRACKS_PROCESS_NAME = "com.google.android.maps.mytracks";
public static final String MYTRACKS_TEST_INFO_FILE = "MyTracksTestInfo.txt";
private static final String TAG = BigTestUtils.class.getSimpleName();
/**
* Gets the memory usage of MyTracks process. This method would get the Pss
* memory. Pss is the amount of memory shared with other processes, accounted
* in a way that the amount is divided evenly between the processes that share
* it. This is memory that would not be released if the process was
* terminated, but is indicative of the amount that this process is
* "contributing" to the overall memory load.
*
* @param context
*/
public static String getMyTracksPssMemoryInfo(Context context) {
int MyTracksProcessId = -1;
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Activity.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
if (runningAppProcessInfo.processName.equalsIgnoreCase(MYTRACKS_PROCESS_NAME)) {
MyTracksProcessId = runningAppProcessInfo.pid;
break;
}
}
if (MyTracksProcessId == -1) {
Assert.fail();
}
int pids[] = { MyTracksProcessId };
android.os.Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
int memoryUsage = memoryInfoArray[0].getTotalPss();
return String.format(Locale.US, " MyTracks TotalPss Memory: %d (kB) ", memoryUsage);
}
/**
* Gets the battery info of device, and then writes it to a file.
*
* @param context the context of application
*/
public static String getBatteryUsageInfo(Context context) {
Intent batteryIntent = context.getApplicationContext().registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int rawlevel = batteryIntent.getIntExtra("level", -1);
double scale = batteryIntent.getIntExtra("scale", -1);
return String.format("Device has %s of %s battery left", rawlevel, scale);
}
/**
* Writes a string to battery info file. This method would add a time string
* before the given value.
*
* @param string string to write
* @param isAppend true means append to file
*/
public static void writeToFile(String string, boolean isAppend) {
String path = Environment.getExternalStorageDirectory() + File.separator
+ MYTRACKS_TEST_INFO_FILE;
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File(path), isAppend);
OutputStreamWriter osw = new OutputStreamWriter(fileOutputStream);
try {
// Write the string to the file
osw.write(string);
} finally {
osw.flush();
osw.close();
}
} catch (Exception e) {
Log.e(TAG, "Meet error when write test info to file.", e);
}
return;
}
/**
* Monitors the battery and memory usage during test, and writes the usage
* info to a local file.
*
* @param context application context
* @param interval the milliseconds to get usage info
* @param testTime the total test milliseconds
*/
public static void moniterTest(Context context, int interval, int testTime) {
long startTime = System.currentTimeMillis();
while ((System.currentTimeMillis() - startTime) < testTime) {
String memoryUsageString = getMyTracksPssMemoryInfo(context);
String batteryUsageString = getBatteryUsageInfo(context);
String oneInfo = String.format("{%s: memory use %s, battery left %s. \r\n",
String.format("{%1$tm/%1$td/%1$tY %1$tH:%1$tM:%1$tS", new Date()), memoryUsageString,
batteryUsageString);
writeToFile(oneInfo, true);
Log.d(TAG, oneInfo);
EndToEndTestUtils.sleep(interval);
}
}
/**
* Unlocks and wakes up the device.
*/
public static void unlockAndWakeupDevice() {
// The menu item of setting should be found if the screen is not locked.
try {
EndToEndTestUtils.SOLO.getCurrentActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Window wind = EndToEndTestUtils.SOLO.getCurrentActivity().getWindow();
wind.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
wind.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
wind.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
}
});
} catch (Exception e) {
Log.e(TAG, "Meet error when unlock device screen, may the device is not locked.", e);
}
}
}
@@ -1,177 +0,0 @@
/*
* 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.endtoendtest.others;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
import android.app.Instrumentation;
import android.content.Context;
import android.content.DialogInterface;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
/**
* Tests the battery and memory usage of long tracks. As this test may be run a
* long time test and without connect to desktop computer during test. The test
* result will be recorded to a file. And at the beginning of test, it need
* user's confirm by click a button.
*
* @author Youtao Liu
*/
public class ResourceUsageTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final String TAG = ResourceUsageTest.class.getSimpleName();
public ResourceUsageTest() {
super(TrackListActivity.class);
}
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
private boolean runTest = false;
private static boolean isUserConfirmed = false;
private Context context;
/**
* Default duration for each test is half one hour.
*/
private int TEST_DURATION_IN_MILLISECONDS = 30 * 60 * 1000;
private int INTERVALE_TO_CHECK = 5 * 60 * 1000;
@Override
protected void setUp() throws Exception {
super.setUp();
runTest = RunConfiguration.getInstance().getRunResourceTest();
if (!runTest) {
return;
}
instrumentation = getInstrumentation();
trackListActivity = getActivity();
context = trackListActivity.getApplicationContext();
instrumentation.waitForIdleSync();
EndToEndTestUtils.setupForDebug(instrumentation, trackListActivity);
BigTestUtils.unlockAndWakeupDevice();
if (!isUserConfirmed) {
confirmTest();
}
BigTestUtils.writeToFile("Test case start:" + getName() + "\r\n", true);
}
/**
* Prompts a dialog to make user confirm whether start the test.
*/
private void confirmTest() {
try {
trackListActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
new AlertDialog.Builder(EndToEndTestUtils.SOLO.getCurrentActivity())
.setTitle("Confirm long time test.")
.setMessage(
String
.format(
"Please disconnect the power cord of your device and click 'Start' button. Each case need run %d minutes, and the battery/memory usage will be recorded in every %d minutes.",
TEST_DURATION_IN_MILLISECONDS / 1000 / 60, INTERVALE_TO_CHECK / 60 / 1000))
.setPositiveButton("Start Test", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
isUserConfirmed = true;
runTest = true;
BigTestUtils.writeToFile("Test start:\r\n", false);
}
}).setNegativeButton("Cancel Test", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
isUserConfirmed = true;
runTest = false;
fail();
}
}).show();
}
});
} catch (Throwable e) {
Log.e(TAG, "Meet error when create confirm dialog.", e);
}
// Waiting user confirm the testing
while (!isUserConfirmed) {
EndToEndTestUtils.sleep(EndToEndTestUtils.TINY_WAIT_TIME);
}
}
/**
* Tests the resource usage when display track list activity during recording.
*/
public void testBatteryUsage_showTrackList() {
recordingLongTrack(true, R.string.track_detail_map_tab);
}
/**
* Tests the resource usage when display map view during recording.
*/
public void testBatteryUsage_showMapView() {
recordingLongTrack(false, R.string.track_detail_map_tab);
}
/**
* Tests the resource usage when display chart view during recording.
*/
public void testBatteryUsage_showChartView() {
recordingLongTrack(false, R.string.track_detail_chart_tab);
}
/**
* Tests the resource usage when display stats view during recording.
*/
public void testBatteryUsage_showStatsView() {
recordingLongTrack(false, R.string.track_detail_stats_tab);
}
/**
* Records a long time track and keeps in the specified tab or in tracks list
* during recording.
*
* @param isShowTracksList true means show tracks list
* @param tabNameId the name string id of tab, it's useless when the first
* parameter is true.
*/
public void recordingLongTrack(boolean isShowTracksList, int tabNameId) {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
if (isShowTracksList) {
EndToEndTestUtils.SOLO.goBack();
} else {
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(tabNameId));
}
BigTestUtils.moniterTest(context, INTERVALE_TO_CHECK, TEST_DURATION_IN_MILLISECONDS);
BigTestUtils.unlockAndWakeupDevice();
EndToEndTestUtils.stopRecording(true);
}
@Override
protected void tearDown() throws Exception {
if (!runTest) {
return;
}
EndToEndTestUtils.SOLO.finishOpenedActivities();
BigTestUtils.writeToFile("Test case done:" + getName() + "\r\n\r\n", true);
super.tearDown();
}
}
@@ -1,247 +0,0 @@
/*
* 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.endtoendtest.others;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Tests connecting to sensors.
*
* @author Youtao Liu
*/
public class SensorTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final String TAG = SensorTest.class.getSimpleName();
private static final String ZEPHYR_NAME = "HXM";
private static final String POLAR_NAME = "Polar";
public SensorTest() {
super(TrackListActivity.class);
}
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
private boolean runTest = false;
@Override
protected void setUp() throws Exception {
runTest = RunConfiguration.getInstance().getRunSensorTest();
super.setUp();
if (!runTest) {
return;
}
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
/**
* Tests connecting to a Zephyr Bluetooth sensor while not recording. Before this test, a Zephyr
* sensor must be paired with the device.
*/
public void testConnectZephyrBluetoothSensor_notRecording() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_zephyr, ZEPHYR_NAME, false);
}
/**
* Tests connecting to a Zephyr Bluetooth sensor while under recording. Before this test, a Zephyr
* sensor must be paired with the device.
*/
public void testConnectZephyrBluetoothSensor_underRecording() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_zephyr, ZEPHYR_NAME, true);
}
/**
* Tests connecting to a Polar Bluetooth sensor while not recording. Before this test, a Polar
* sensor must be paired with the device.
*/
public void testConnectPolarBluetoothSensor_notRecording() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_polar, POLAR_NAME, false);
}
/**
* Tests connecting to a Polar Bluetooth sensor while under recording. Before this test, a Polar
* sensor must be paired with the device.
*/
public void testConnectPolarBluetoothSensor_underRecording() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
bluetoothSensorTest(R.string.settings_sensor_type_polar, POLAR_NAME, true);
}
/**
* Set the paired sensor.
*
* @param sensorTypeStringId the string id of paired sensors type
* @param nameString part of the sensor name string which can distinguish
* different Bluetooth sensors
* @param isUnderRecording true means test under recording
*/
private void bluetoothSensorTest(int sensorTypeStringId, String nameString,
boolean isUnderRecording) {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor_type));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(sensorTypeStringId));
checkPairedSensorsNumber(nameString);
// Set the paired sensor.
EndToEndTestUtils.SOLO.clickOnText(nameString);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
if (isUnderRecording) {
assertTrue(checkSensorsStatus_underRecording());
} else {
assertTrue(checkSensorsStatus_notRecording());
}
}
/**
* Checks the number of paired sensors.
*/
private void checkPairedSensorsNumber(String nameString) {
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.settings_sensor_bluetooth_sensor));
instrumentation.waitForIdleSync();
ArrayList<ListView> allListViews = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class);
int number = allListViews.get(0).getCount();
if (number > 0
&& EndToEndTestUtils.SOLO.waitForText(nameString, 1, EndToEndTestUtils.SHORT_WAIT_TIME)) {
return;
}
Log.d(TAG, "No sensor is paried");
fail("No bluetooth sensor is paired. Please pair at Settings->Bluetooth before running the test.");
}
/**
* Tests connecting to a cadence ANT+ sensor.
*/
public void testConnectANTSensor_Cadence() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
useANTSeonsor();
assertTrue(checkSensorsStatus_notRecording());
checkANTSensorsStatus(R.id.sensor_state_cadence);
}
/**
* Tests connecting to cadence and heart rate ANT+ sensors at the same time.
*/
public void testConnectTwoANTSensors() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
useANTSeonsor();
assertTrue(checkSensorsStatus_notRecording());
checkANTSensorsStatus(R.id.sensor_state_cadence);
checkANTSensorsStatus(R.id.sensor_state_heart_rate);
}
/**
* Sets the setting to use ANT+ sensor
*/
private void useANTSeonsor() {
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_settings), true);
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity.getString(R.string.settings_sensor_type));
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.settings_sensor_type_ant));
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.goBack();
}
/**
* Checks whether the ANT+ sensor is connected with MyTracks.
*
* @param viewID the id to check which is not equal with None
*/
private void checkANTSensorsStatus(int viewID) {
TextView sensorValueText = ((TextView) EndToEndTestUtils.SOLO.getCurrentActivity()
.findViewById(viewID));
assertNotNull(sensorValueText);
String realValue = sensorValueText.getText().toString();
String noneValue = trackListActivity.getString(R.string.value_none);
assertNotSame(realValue, noneValue);
}
/**
* Checks whether the sensor is connected with MyTracks during recording.
*
* @return true means the sensor is connected with MyTracks
*/
private boolean checkSensorsStatus_underRecording() {
EndToEndTestUtils.instrumentation.waitForIdleSync();
EndToEndTestUtils.startRecording();
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_sensor_state), true);
boolean result = EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.sensor_state_connected), 1,
EndToEndTestUtils.LONG_WAIT_TIME);
EndToEndTestUtils.stopRecording(true);
return result;
}
/**
* Checks whether the sensor is connected with MyTracks while not under recording.
*
* @return true means the sensor is connected with MyTracks
*/
private boolean checkSensorsStatus_notRecording() {
EndToEndTestUtils.instrumentation.waitForIdleSync();
EndToEndTestUtils.createTrackIfEmpty(0, false);
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_sensor_state), true);
return EndToEndTestUtils.SOLO.waitForText(
trackListActivity.getString(R.string.sensor_state_connected), 1,
EndToEndTestUtils.LONG_WAIT_TIME);
}
@Override
protected void tearDown() throws Exception {
if (!runTest) {
return;
}
EndToEndTestUtils.SOLO.finishOpenedActivities();
super.tearDown();
}
}
@@ -1,197 +0,0 @@
/*
* 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.endtoendtest.others;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.maps.mytracks.R;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.widget.ListView;
/**
* Stress test of MyTracks.
*
* @author Youtao Liu
*/
public class StressTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private static final String TAG = StressTest.class.getSimpleName();
private static final int TEST_DURATION_IN_MILLISECONDS = 30 * 60 * 1000;
private static final int MAX_TRACK_NUMBER = 30;
private boolean runTest = false;
private long startTime = 0;
private int numberOfTracks;
public StressTest() {
super(TrackListActivity.class);
}
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
@Override
protected void setUp() throws Exception {
runTest = RunConfiguration.getInstance().getRunStressTest();
super.setUp();
if (!runTest) {
return;
}
instrumentation = getInstrumentation();
trackListActivity = getActivity();
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
BigTestUtils.unlockAndWakeupDevice();
startTime = System.currentTimeMillis();
}
/**
* Records tracks and deletes them when there are more than
* {@link #MAX_TRACK_NUMBER} tracks. Keeps sending different GPS locations in
* each track, making it closer to the real stress.
*/
public void testRecordAndDeleteTracks() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
for (int i = 0; (System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS; i++) {
EndToEndTestUtils.startRecording();
// Points in a tracks keep increasing.
EndToEndTestUtils.sendGps(i * 10, 0, 10);
EndToEndTestUtils.stopRecording(true);
EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.instrumentation.waitForIdleSync();
numberOfTracks = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
if (numberOfTracks > MAX_TRACK_NUMBER) {
EndToEndTestUtils.deleteAllTracks();
}
logStatus(i);
}
}
/**
* Rotates screen when display map view. Keeps sending different GPS locations
* in each track, making it closer to the real stress.
*/
public void testRotateMapViewInTrackDetailActivity() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
for (int i = 0; (System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS; i++) {
EndToEndTestUtils.sendGps(10, i * 10);
EndToEndTestUtils.rotateCurrentActivity();
Log.d(TAG, String.format("Totate %d times in %d minutes!", i,
(System.currentTimeMillis() - startTime) / 1000 / 60));
}
}
/**
* Switches view between MAP, CHART and STAT.
*/
public void testSwitchTabs() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
int i = 0;
while ((System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS) {
EndToEndTestUtils.SOLO
.clickOnText(trackListActivity.getString(R.string.track_detail_map_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_chart_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_stats_tab));
instrumentation.waitForIdleSync();
logStatus(++i);
}
EndToEndTestUtils.stopRecording(true);
}
/**
* Records a long track.
*/
public void testRecordLongTrack() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
int gpsNumber = 5000;
for (int i = 0; i < gpsNumber / 10; i++) {
EndToEndTestUtils.sendGps(10, i * 10);
}
EndToEndTestUtils.stopRecording(true);
}
/**
* Switches view between MAP, CHART and STAT. And create way points, pause and
* resume the track during recording.
*/
public void testSwitchTabs_wayPoints() {
if (!runTest) {
Log.d(TAG, BigTestUtils.DISABLE_MESSAGE);
return;
}
EndToEndTestUtils.startRecording();
int i = 0;
while ((System.currentTimeMillis() - startTime) < TEST_DURATION_IN_MILLISECONDS) {
// Create one way points.
EndToEndTestUtils.sendGps(10, 10 * i);
EndToEndTestUtils.createWaypoint(i);
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.generic_recording));
EndToEndTestUtils.pauseRecording();
EndToEndTestUtils.SOLO
.clickOnText(trackListActivity.getString(R.string.track_detail_map_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_chart_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnText(trackListActivity
.getString(R.string.track_detail_stats_tab));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.generic_paused));
EndToEndTestUtils.resumeRecording();
logStatus(++i);
}
EndToEndTestUtils.stopRecording(true);
}
/**
* Logs status.
*
* @param times the number of times this test has been run
*/
private void logStatus(int times) {
int minutes =
(int) (TEST_DURATION_IN_MILLISECONDS - (System.currentTimeMillis() - startTime)) / 60
/ 1000;
Log.d(TAG, String.format(
"This test has run %d times and will be finished in %d minutes!", times, minutes));
Log.d(TAG, String.format("There are %d tracks!", numberOfTracks));
}
}
@@ -1,159 +0,0 @@
/*
* Copyright 2013 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.endtoendtest.sync;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.maps.mytracks.R;
import com.google.api.services.drive.Drive;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.ListView;
/**
* Tests the situation when user use multiple account in MyTracks.
*
* @author Youtao Liu
*/
public class MultiAccountsSyncTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Drive drive;
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public MultiAccountsSyncTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
SyncTestUtils.setUpForSyncTest(instrumentation, trackListActivity);
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_1);
drive = SyncTestUtils
.getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
}
/**
* Tests sync tracks with Google Drive of two accounts with following
* sequence:
* <ul>
* <li>1. Enable sync with account1.</li>
* <li>2. Create a track.</li>
* <li>3. Enable sync with account2.</li>
* <li>4. Create a track.</li>
* <li>5. Sync and check</li>
* <li>6. Enable sync with account1.</li>
* <li>7. Sync and check</li>
* <li>8. Enable sync with account2.</li>
* <li>9. Check</li>
* </ul>
*/
public void testSyncTracksWithMultiAccounts() throws Exception {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_1);
// Create tracks with first track.
EndToEndTestUtils.createSimpleTrack(0, true);
// Create tracks with second track.
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_2);
EndToEndTestUtils.createSimpleTrack(0, true);
// Sync with Google Drive and then check it of the second account.
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
drive = SyncTestUtils.getGoogleDrive(trackListActivity.getApplicationContext());
SyncTestUtils.checkFilesNumber(drive);
// Check Google Drive of the first account.
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_1);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
drive = SyncTestUtils.getGoogleDrive(trackListActivity.getApplicationContext());
SyncTestUtils.checkFilesNumber(drive);
// Back to account1 change check that files are still existed.
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_2);
drive = SyncTestUtils.getGoogleDrive(trackListActivity.getApplicationContext());
SyncTestUtils.checkFilesNumber(drive);
}
/**
* Tests the behavior of MyTracks about delete operation and switch accounts
* with following sequence.:
* <ul>
* <li>1. Create 3 tracks.</li>
* <li>2. Delete 1 track.</li>
* <li>3. Sync with account2(account2 should have 2 files).</li>
* <li>4. Delete 1 track (account2 should have 1 file).</li>
* <li>5. Sync with account 1 (account 1 should have 1 file, account2 should
* also have 1 file).</li>
* </ul>
*/
public void testDeleteTracksWithMultiAccounts() throws Exception {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.createSimpleTrack(0, true);
// Delete one track.
EndToEndTestUtils.SOLO.clickOnView(EndToEndTestUtils.SOLO.getCurrentViews(ListView.class)
.get(0).getChildAt(0));
EndToEndTestUtils.instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.clickOnMenuItem(EndToEndTestUtils.trackListActivity
.getString(R.string.menu_delete));
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackListActivity
.getString(R.string.generic_yes));
// Switch account and delete another track.
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_2);
EndToEndTestUtils.SOLO.clickOnView(EndToEndTestUtils.SOLO.getCurrentViews(ListView.class)
.get(0).getChildAt(0));
EndToEndTestUtils.SOLO.clickOnMenuItem(EndToEndTestUtils.trackListActivity
.getString(R.string.menu_delete));
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackListActivity
.getString(R.string.generic_yes));
// Check Google Drive of the first account.
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_1);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
drive = SyncTestUtils.getGoogleDrive(trackListActivity.getApplicationContext());
SyncTestUtils.checkFilesNumber(drive);
// Check Google Drive of the second account.
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_2);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
drive = SyncTestUtils.getGoogleDrive(trackListActivity.getApplicationContext());
SyncTestUtils.checkFilesNumber(drive);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
EndToEndTestUtils.SOLO.finishOpenedActivities();
}
}
@@ -1,165 +0,0 @@
/*
* Copyright 2013 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.endtoendtest.sync;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.maps.mytracks.R;
import com.google.api.services.drive.Drive;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import java.io.IOException;
/**
* Tests making changes on Google Drive when syncing My Tracks with Google
* Drive.
*
* @author Youtao Liu
*/
public class SyncDriveWithMyTracksTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Drive drive;
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public SyncDriveWithMyTracksTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
SyncTestUtils.setUpForSyncTest(instrumentation, trackListActivity);
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_1);
drive = SyncTestUtils
.getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
}
/**
* Deletes all tracks in MyTracks and checks in Google Drive.
*
* @throws IOException
*/
public void testDeleteAllTracksInMyTracks() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFilesNumber(drive);
}
/**
* Deletes one track in MyTracks and checks it in Google Drive.
*
* @throws IOException
*/
public void testDeleteOneTracksInMyTracks() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
EndToEndTestUtils.createTrackIfEmpty(2, false);
EndToEndTestUtils.SOLO.clickOnMenuItem(EndToEndTestUtils.trackListActivity
.getString(R.string.menu_delete));
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackListActivity
.getString(R.string.generic_yes));
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFile(EndToEndTestUtils.trackName, false, drive);
}
/**
* Creates one empty track and one non-empty track in MyTracks and then check
* them in Google Drive.
*
* @throws IOException
*/
public void testCreateTracksInMyTracks() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.createSimpleTrack(3, true);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFilesNumber(drive);
}
/**
* Edits a tracks in MyTracks and checks it on Google Drive after sync.
*
* @throws IOException
*/
public void testEditTrackInMyTracks() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
EndToEndTestUtils.createTrackIfEmpty(3, true);
// Sync this track.
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFile(EndToEndTestUtils.trackName, true, drive);
String oldTrack = SyncTestUtils.getContentOfFile(
SyncTestUtils.getFile(EndToEndTestUtils.trackName, drive), drive);
String oldTrackName = EndToEndTestUtils.trackName;
// Edit this track.
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackName);
EndToEndTestUtils.findMenuItem(trackListActivity.getString(R.string.menu_edit), true);
String newTrackName = EndToEndTestUtils.TRACK_NAME_PREFIX + "_new" + System.currentTimeMillis();
String newType = EndToEndTestUtils.activityType + newTrackName;
String newDesc = "desc" + newTrackName;
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.waitForText(trackListActivity.getString(R.string.generic_save));
sendKeys(KeyEvent.KEYCODE_DEL);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(0, newTrackName);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(1, newType);
EndToEndTestUtils.enterTextAvoidSoftKeyBoard(2, newDesc);
EndToEndTestUtils.SOLO.clickOnButton(trackListActivity.getString(R.string.generic_save));
instrumentation.waitForIdleSync();
EndToEndTestUtils.SOLO.goBack();
instrumentation.waitForIdleSync();
// Sync again.
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
// Check.
SyncTestUtils.checkFile(oldTrackName, false, drive);
SyncTestUtils.checkFile(newTrackName, true, drive);
String newTrack = SyncTestUtils.getContentOfFile(SyncTestUtils.getFile(newTrackName, drive),
drive);
assertNotSame(oldTrack, newTrack);
assertTrue(newTrack.indexOf(newTrackName) > 0);
assertTrue(newTrack.indexOf(newType) > 0);
assertTrue(newTrack.indexOf(newDesc) > 0);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
EndToEndTestUtils.SOLO.finishOpenedActivities();
}
}
@@ -1,127 +0,0 @@
/*
* Copyright 2013 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.endtoendtest.sync;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.maps.mytracks.R;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import java.io.IOException;
/**
* Tests making changes on My Tracks when syncing My Tracks with Google Drive.
*
* @author Youtao Liu
*/
public class SyncMyTracksWithDriveTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
private Drive drive;
private Instrumentation instrumentation;
private TrackListActivity trackListActivity;
public SyncMyTracksWithDriveTest() {
super(TrackListActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
trackListActivity = getActivity();
SyncTestUtils.setUpForSyncTest(instrumentation, trackListActivity);
SyncTestUtils.enableSync(GoogleUtils.ACCOUNT_1);
drive = SyncTestUtils
.getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
}
/**
* Deletes all tracks on Google Drive and checks in MyTracks.
*
* @throws IOException
*/
public void testDeleteAllTracksOnDrive() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
EndToEndTestUtils.createTrackIfEmpty(0, true);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFilesNumber(drive);
SyncTestUtils.removeKMLFiles(drive);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkTracksNumber(0);
}
/**
* Deletes one file on Google Drive and checks it in MyTracks.
*
* @throws IOException
*/
public void testDeleteOneFileOnDrive() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
instrumentation.waitForIdleSync();
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFilesNumber(drive);
// Remove one track from Google Drive
File file = SyncTestUtils.getFile(EndToEndTestUtils.trackName, drive);
SyncTestUtils.removeFile(file, drive);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFilesNumber(drive);
SyncTestUtils.checkTracksNumber(1);
}
/**
* Tests deleting and creating MyTracks folder on Google Dive by MyTracks.
*
* @throws IOException
*/
public void testCreateMyTracksOnDrive() throws IOException {
if (!RunConfiguration.getInstance().getRunSyncTest()) {
return;
}
instrumentation.waitForIdleSync();
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.createSimpleTrack(0, true);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
instrumentation.waitForIdleSync();
SyncTestUtils.checkFilesNumber(drive);
File folder = SyncUtils.getMyTracksFolder(trackListActivity.getApplicationContext(), drive);
assertNotNull(folder);
SyncTestUtils.removeFile(folder, drive);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
SyncTestUtils.checkFilesNumber(drive);
}
}
@@ -1,311 +0,0 @@
/*
* Copyright 2013 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.endtoendtest.sync;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.endtoendtest.EndToEndTestUtils;
import com.google.android.apps.mytracks.endtoendtest.GoogleUtils;
import com.google.android.apps.mytracks.endtoendtest.RunConfiguration;
import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.maps.mytracks.R;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import android.app.Instrumentation;
import android.content.Context;
import android.util.Log;
import android.widget.ListView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import junit.framework.Assert;
/**
* Utilites for Google Drive sync endtoend test.
*
* @author Youtao Liu
*/
public class SyncTestUtils {
private static final String TAG = SyncTestUtils.class.getSimpleName();
public static boolean isCheckedRunSyncTest = false;
public static final String KML_FILE_POSTFIX = ".kml";
public static final long MAX_TIME_TO_WAIT_SYNC = 100000;
/**
* Sets up sync tests.
*
* @param instrumentation the instrumentation is used for test
* @param trackListActivity the startup activity
* @return a Google Drive object
*/
public static Drive setUpForSyncTest(Instrumentation instrumentation,
TrackListActivity trackListActivity) throws IOException, GoogleAuthException {
if (!isCheckedRunSyncTest || RunConfiguration.getInstance().getRunSyncTest()) {
EndToEndTestUtils.setupForAllTest(instrumentation, trackListActivity);
}
if (!isCheckedRunSyncTest) {
isCheckedRunSyncTest = true;
}
if (RunConfiguration.getInstance().getRunSyncTest()) {
enableSync(GoogleUtils.ACCOUNT_1);
Drive drive1 = getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
removeKMLFiles(drive1);
EndToEndTestUtils.deleteAllTracks();
enableSync(GoogleUtils.ACCOUNT_2);
Drive drive2 = getGoogleDrive(EndToEndTestUtils.trackListActivity.getApplicationContext());
removeKMLFiles(drive2);
EndToEndTestUtils.deleteAllTracks();
return drive2;
}
return null;
}
/**
* Gets drive object of Google Drive.
*
* @param context the context of application
* @return a Google Drive object
*/
public static Drive getGoogleDrive(Context context) throws IOException, GoogleAuthException {
String googleAccount = PreferencesUtils.getString(context, R.string.google_account_key,
PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT);
GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential(context,
googleAccount, SendToGoogleUtils.DRIVE_SCOPE);
return SyncUtils.getDriveService(credential);
}
/**
* Gets KML files from Google Drive of current account.
*
* @param context the context of application
* @param drive a Google Drive object
* @return KML file on Google drive
* @throws IOException
*/
public static List<File> getDriveFiles(Context context, Drive drive) throws IOException {
File folder = SyncUtils.getMyTracksFolder(context, drive);
if (folder == null) {
return new ArrayList<File>();
}
String folderId = folder.getId();
return drive.files().list()
.setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_FILES_QUERY, folderId)).execute()
.getItems();
}
/**
* Finds whether a file is existed by the name of track.
*
* @param trackName name of track
* @param drive a Google Drive object
* @return the file be found
* @throws IOException
*/
public static File getFile(String trackName, Drive drive) throws IOException {
List<File> files = getDriveFiles(EndToEndTestUtils.trackListActivity.getApplicationContext(),
drive);
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
String title = file.getTitle();
if (title.equals(trackName + KML_FILE_POSTFIX)) {
return file;
}
}
return null;
}
/**
* Removes all KML files on Google Drive.
*
* @param drive a Google Drive object
* @throws IOException
*/
public static void removeKMLFiles(Drive drive) throws IOException {
List<File> files = getDriveFiles(
EndToEndTestUtils.trackListActivity.getApplicationContext(), drive);
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
removeFile(file, drive);
}
}
/**
* Removes one file on Google Drive.
*
* @param file the file to remove
* @param drive a Google Drive object
* @throws IOException
*/
public static void removeFile(File file, Drive drive) throws IOException {
drive.files().trash(file.getId()).execute();
}
/**
* Enables sync feature in MyTracks settings.
*
* @param accountName the account which is used to sync with
*/
public static void enableSync(String accountName) {
// EndToEndTestUtils.instrumentation.waitForIdleSync();
// EndToEndTestUtils.findMenuItem(
// EndToEndTestUtils.activityMytracks.getString(R.string.menu_settings), true);
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.settings_google));
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.settings_google_account_title));
// EndToEndTestUtils.instrumentation.waitForIdleSync();
//
// // Whether test account is bound.
// if (EndToEndTestUtils.SOLO.waitForText(accountName, 1, EndToEndTestUtils.SHORT_WAIT_TIME)) {
// EndToEndTestUtils.SOLO.clickOnText(accountName);
// EndToEndTestUtils.instrumentation.waitForIdleSync();
//
// if (EndToEndTestUtils.findTextView(EndToEndTestUtils.activityMytracks
// .getString(R.string.settings_google_account_confirm_title)) != null) {
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.generic_yes));
// }
// } else {
// Assert.fail();
// return;
// }
//
// EndToEndTestUtils.SOLO.waitForDialogToClose(EndToEndTestUtils.SHORT_WAIT_TIME);
// EndToEndTestUtils.instrumentation.waitForIdleSync();
// CheckBox syncCheckBox = EndToEndTestUtils.SOLO.getCurrentViews(CheckBox.class).get(0);
// if (!syncCheckBox.isChecked()) {
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.menu_sync_drive));
//
// EndToEndTestUtils.SOLO.waitForText(
// EndToEndTestUtils.activityMytracks.getString(R.string.sync_drive_confirm_message).split(
// "%")[0], 1, EndToEndTestUtils.SHORT_WAIT_TIME);
// Assert.assertTrue(EndToEndTestUtils.SOLO.searchText(accountName, true));
// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks
// .getString(R.string.generic_yes));
// }
//
// // Add this sleep to work around a exception after switch account.
// EndToEndTestUtils.sleep(15000);
// EndToEndTestUtils.SOLO.goBack();
// EndToEndTestUtils.SOLO.goBack();
// EndToEndTestUtils.instrumentation.waitForIdleSync();
}
/**
* Checks the files number on Google Drive
*
* @param drive a Google Drive object
* @throws IOException
*/
public static void checkFilesNumber(Drive drive) throws IOException {
EndToEndTestUtils.instrumentation.waitForIdleSync();
long startTime = System.currentTimeMillis();
int trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
List<File> files = getDriveFiles(EndToEndTestUtils.trackListActivity.getApplicationContext(),
drive);
while (System.currentTimeMillis() - startTime < MAX_TIME_TO_WAIT_SYNC) {
try {
if (files.size() == trackNumber) {
return;
}
trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
files = getDriveFiles(EndToEndTestUtils.trackListActivity.getApplicationContext(), drive);
EndToEndTestUtils.sleep(EndToEndTestUtils.SHORT_WAIT_TIME);
EndToEndTestUtils.findMenuItem(
EndToEndTestUtils.trackListActivity.getString(R.string.menu_sync_now), true);
} catch (GoogleJsonResponseException e) {
Log.e(TAG, e.getMessage(), e);
}
}
Assert.assertEquals(files.size(), trackNumber);
}
/**
* Checks the files number on Google Drive
*
* @param number number of files on Google Drive
*/
public static void checkTracksNumber(int number) {
long startTime = System.currentTimeMillis();
int trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
while (System.currentTimeMillis() - startTime < MAX_TIME_TO_WAIT_SYNC) {
if (trackNumber == number) {
return;
}
trackNumber = EndToEndTestUtils.SOLO.getCurrentViews(ListView.class).get(0).getCount();
Log.d(TAG, trackNumber + ":" + number);
}
Assert.assertEquals(trackNumber, number);
}
/**
* Checks one file on Google Drive
*
* @param trackName the name of track
* @param shouldExist true means this track should be existed
* @param drive a Google Drive object
* @return true means the actual result is same as expectation
* @throws IOException
*/
public static boolean checkFile(String trackName, boolean shouldExist, Drive drive)
throws IOException {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < MAX_TIME_TO_WAIT_SYNC) {
boolean exist = getFile(trackName, drive) != null;
if (exist == shouldExist) {
return true;
}
}
Assert.fail();
return false;
}
/**
* Gets the content of a file on Google Drive.
*
* @param file file to read
* @param drive a Google Drive object
* @return the string content of the file
* @throws IOException
*/
public static String getContentOfFile(File file, Drive drive) throws IOException {
HttpResponse resp = drive.getRequestFactory()
.buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
BufferedReader br = new BufferedReader(new InputStreamReader(resp.getContent()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
String fileContent = sb.toString();
br.close();
return fileContent;
}
}
@@ -193,10 +193,9 @@ public class TrackRecordingServiceTest extends ServiceTestCase<TestRecordingServ
providerUtils = MyTracksProviderUtils.Factory.get(context);
SharedPreferences sharedPreferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
// Let's use default values.
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(sharedPreferences.edit().clear());
sharedPreferences.edit().clear().apply();
// Disable auto resume by default.
updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, 0);
@@ -15,10 +15,9 @@ public class SensorManagerFactoryTest extends AndroidTestCase {
protected void setUp() throws Exception {
super.setUp();
SharedPreferences sharedPreferences = getContext().getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
SharedPreferences sharedPreferences = getContext().getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
// Let's use default values.
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(sharedPreferences.edit().clear());
sharedPreferences.edit().clear().apply();
}
@SmallTest
-9
View File
@@ -34,19 +34,10 @@ limitations under the License.
<uses-permission android:name="com.dsi.ant.permission.ANT_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Permissions to upload tracks -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.local" />
<!-- Permission for Android sync provider -->
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<!-- Permission to access Google services to communicate with the map servers. -->
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!-- Permission to read phone state so voice announcement will not interrupt ongoing calls -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Permission to read/write external storage -->
@@ -91,15 +91,13 @@ public abstract class AbstractSendToGoogleActivity extends AbstractMyTracksActiv
}
@Override
public void onItemCheckedStateChanged(
ActionMode mode, int position, long id, boolean checked) {
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
mode.invalidate();
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (contextualActionModeCallback.onClick(
item.getItemId(), getCheckedPositions(listView), listView.getCheckedItemIds())) {
if (contextualActionModeCallback.onClick(item.getItemId(), getCheckedPositions(listView), listView.getCheckedItemIds())) {
mode.finish();
}
return true;
@@ -128,8 +126,7 @@ public abstract class AbstractSendToGoogleActivity extends AbstractMyTracksActiv
});
}
public static void configureSearchWidget(
Activity activity, final MenuItem menuItem, final TrackController trackController) {
public static void configureSearchWidget(Activity activity, final MenuItem menuItem, final TrackController trackController) {
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity.getComponentName()));
@@ -1,62 +0,0 @@
/*
* 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;
import android.graphics.Paint;
import android.graphics.Path;
/**
* Represents a colored {@code Path} to save its relative color for drawing.
* @author Vangelis S.
*/
public class ColoredPath {
private final Path path;
private final Paint pathPaint;
/**
* Constructor for a ColoredPath by color.
*/
public ColoredPath(int color) {
path = new Path();
pathPaint = new Paint();
pathPaint.setColor(color);
pathPaint.setStrokeWidth(3);
pathPaint.setStyle(Paint.Style.STROKE);
pathPaint.setAntiAlias(true);
}
/**
* Constructor for a ColoredPath by Paint.
*/
public ColoredPath(Paint paint) {
path = new Path();
pathPaint = paint;
}
/**
* @return the path
*/
public Path getPath() {
return path;
}
/**
* @return the pathPaint
*/
public Paint getPathPaint() {
return pathPaint;
}
}
@@ -25,11 +25,6 @@ public class Constants {
private Constants() {}
/**
* The google account type.
*/
public static final String ACCOUNT_TYPE = "com.google";
/**
* Maximum number of waypoints that will be loaded at one time.
*/
@@ -24,6 +24,7 @@ import com.google.android.apps.mytracks.content.SearchEngineProvider;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.fragments.ConfirmDeleteDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
import com.google.android.apps.mytracks.services.MyTracksLocationManager;
@@ -72,7 +73,7 @@ import java.util.SortedSet;
*
* @author Rodrigo Damazio
*/
public class SearchListActivity extends AbstractSendToGoogleActivity implements DeleteMarkerCaller {
public class SearchListActivity extends AbstractSendToGoogleActivity implements DeleteMarkerCaller, ConfirmDeleteDialogFragment.ConfirmDeleteCaller {
private static final String TAG = SearchListActivity.class.getSimpleName();
@@ -25,13 +25,9 @@ import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.fragments.ChartFragment;
import com.google.android.apps.mytracks.fragments.ChooseActivityTypeDialogFragment;
import com.google.android.apps.mytracks.fragments.ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller;
import com.google.android.apps.mytracks.fragments.ExportDialogFragment;
import com.google.android.apps.mytracks.fragments.ExportDialogFragment.ExportCaller;
import com.google.android.apps.mytracks.fragments.ExportDialogFragment.ExportType;
import com.google.android.apps.mytracks.fragments.ConfirmDeleteDialogFragment;
import com.google.android.apps.mytracks.fragments.FrequencyDialogFragment;
import com.google.android.apps.mytracks.fragments.StatsFragment;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.exporter.SaveActivity;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.settings.SettingsActivity;
import com.google.android.apps.mytracks.util.CalorieUtils;
@@ -44,7 +40,6 @@ import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtil
import com.google.android.apps.mytracks.util.TrackUtils;
import com.google.android.maps.mytracks.R;
import android.accounts.Account;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -52,7 +47,6 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.view.ViewPager;
@@ -76,7 +70,7 @@ import java.util.Date;
* @author Rodrigo Damazio
*/
public class TrackDetailActivity extends AbstractSendToGoogleActivity
implements ChooseActivityTypeCaller, ExportCaller {
implements ChooseActivityTypeCaller, ConfirmDeleteDialogFragment.ConfirmDeleteCaller {
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_MARKER_ID = "marker_id";
@@ -111,7 +105,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
private MenuItem insertMarkerMenuItem;
private MenuItem insertPhotoMenuItem;
private MenuItem shareMenuItem;
private MenuItem exportMenuItem;
private MenuItem voiceFrequencyMenuItem;
private MenuItem splitFrequencyMenuItem;
private MenuItem sensorStateMenuItem;
@@ -351,7 +344,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
shareMenuItem.setEnabled(!isSharedWithMe);
shareMenuItem.setVisible(!isSharedWithMe);
exportMenuItem = menu.findItem(R.id.track_detail_export);
voiceFrequencyMenuItem = menu.findItem(R.id.track_detail_voice_frequency);
splitFrequencyMenuItem = menu.findItem(R.id.track_detail_split_frequency);
sensorStateMenuItem = menu.findItem(R.id.track_detail_sensor_state);
@@ -405,11 +397,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
PreferencesUtils.SPLIT_FREQUENCY_DEFAULT, R.string.menu_split_frequency)
.show(getSupportFragmentManager(), FrequencyDialogFragment.FREQUENCY_DIALOG_TAG);
return true;
case R.id.track_detail_export:
Track track = myTracksProviderUtils.getTrack(trackId);
boolean hideDrive = track != null ? track.isSharedWithMe() : true;
new ExportDialogFragment().show(getSupportFragmentManager(), ExportDialogFragment.EXPORT_DIALOG_TAG);
return true;
case R.id.track_detail_edit:
intent = IntentUtils.newIntent(this, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId);
@@ -443,16 +430,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
return super.onTrackballEvent(event);
}
public void onExportDone(
ExportType exportType, TrackFileFormat trackFileFormat, Account account) {
if (exportType == ExportType.EXTERNAL_STORAGE) {
Intent intent = IntentUtils.newIntent(this, SaveActivity.class)
.putExtra(SaveActivity.EXTRA_TRACK_IDS, new long[] { trackId })
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) trackFileFormat);
startActivity(intent);
}
}
@Override
protected TrackRecordingServiceConnection getTrackRecordingServiceConnection() {
return trackRecordingServiceConnection;
@@ -538,9 +515,6 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
if (shareMenuItem != null && shareMenuItem.isEnabled()) {
shareMenuItem.setVisible(!isRecording);
}
if (exportMenuItem != null) {
exportMenuItem.setVisible(!isRecording);
}
if (voiceFrequencyMenuItem != null) {
voiceFrequencyMenuItem.setVisible(isRecording);
}
@@ -579,9 +553,4 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
@Override
public void onExportDone(ExportType exportType, TrackFileFormat trackFileFormat) {
//TODO
}
}
@@ -50,6 +50,7 @@ import android.widget.Toast;
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.fragments.ConfirmDeleteDialogFragment;
import com.google.android.apps.mytracks.fragments.FileTypeDialogFragment;
import com.google.android.apps.mytracks.fragments.FileTypeDialogFragment.FileTypeCaller;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
@@ -79,7 +80,7 @@ import java.util.Locale;
*
* @author Leif Hendrik Wilden
*/
public class TrackListActivity extends AbstractSendToGoogleActivity implements FileTypeCaller {
public class TrackListActivity extends AbstractSendToGoogleActivity implements FileTypeCaller, ConfirmDeleteDialogFragment.ConfirmDeleteCaller {
private static final String TAG = TrackListActivity.class.getSimpleName();
private static final String[] PROJECTION = new String[] { TracksColumns._ID, TracksColumns.NAME,
@@ -1,82 +0,0 @@
/*
* Copyright 2013 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.fragments;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
/**
* A DialogFrament to prompt user to sync to Google Drive after saving first track.
*
* @author Jimmy Shih
*/
public class EnableSyncDialogFragment extends AbstractMyTracksDialogFragment {
/**
* Interface for caller of this dialog fragment.
*
* @author Jimmy Shih
*/
public interface EnableSyncCaller {
/**
* Called when enable sync is done.
*/
public void onEnableSyncDone(boolean enable);
}
public static final String ENABLE_SYNC_DIALOG_TAG = "enableSyncDialog";
private EnableSyncCaller caller;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
caller = (EnableSyncCaller) activity;
} catch (ClassCastException e) {
throw new ClassCastException(
activity.toString() + " must implement " + EnableSyncCaller.class.getSimpleName());
}
}
@Override
protected Dialog createDialog() {
return new AlertDialog.Builder(getActivity()).setMessage(R.string.sync_drive_enable_message)
.setNegativeButton(R.string.generic_no, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
caller.onEnableSyncDone(false);
}
}).setPositiveButton(R.string.generic_yes, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
caller.onEnableSyncDone(true);
}
}).setTitle(R.string.sync_drive_enable_title).create();
}
@Override
public void onCancel(DialogInterface arg0) {
caller.onEnableSyncDone(false);
}
}
@@ -1,187 +0,0 @@
/*
* 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.fragments;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import java.util.ArrayList;
/**
* A DialogFragment to export a track.
*
* @author Jimmy Shih
*/
public class ExportDialogFragment extends AbstractMyTracksDialogFragment {
/**
* Export types.
*
* @author Jimmy Shih
*/
public enum ExportType {
EXTERNAL_STORAGE(R.string.export_external_storage);
final int resId;
ExportType(int resId) {
this.resId = resId;
}
}
/**
* Interface for caller of this dialog fragment.
*
* @author Jimmy Shih
*/
public interface ExportCaller {
/**
* Called when export is done.
*
* @param exportType the export type
* @param trackFileFormat the track file format
*/
public void onExportDone(
ExportType exportType, TrackFileFormat trackFileFormat);
}
public static final String EXPORT_DIALOG_TAG = "export";
private ExportCaller caller;
// UI elements
private Spinner exportTypeOptions;
private RadioGroup exportExternalStorageOptions;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
caller = (ExportCaller) activity;
} catch (ClassCastException e) {
throw new ClassCastException(
activity.toString() + " must implement " + ExportCaller.class.getSimpleName());
}
}
@Override
protected Dialog createDialog() {
FragmentActivity fragmentActivity = getActivity();
// Get views
View view = fragmentActivity.getLayoutInflater().inflate(R.layout.export, null);
exportExternalStorageOptions = (RadioGroup) view.findViewById(
R.id.export_external_storage_options);
// Setup exportExternalStorageOptions
setExternalStorageOption(
(RadioButton) view.findViewById(R.id.export_external_storage_kml), TrackFileFormat.KML);
setExternalStorageOption(
(RadioButton) view.findViewById(R.id.export_external_storage_gpx), TrackFileFormat.GPX);
setExternalStorageOption(
(RadioButton) view.findViewById(R.id.export_external_storage_csv), TrackFileFormat.CSV);
setExternalStorageOption(
(RadioButton) view.findViewById(R.id.export_external_storage_tcx), TrackFileFormat.TCX);
TrackFileFormat trackFileFormat = TrackFileFormat.valueOf(PreferencesUtils.getString(
fragmentActivity, R.string.export_external_storage_format_key,
PreferencesUtils.EXPORT_EXTERNAL_STORAGE_FORMAT_DEFAULT));
exportExternalStorageOptions.check(getExternalStorageFormatId(trackFileFormat));
return new AlertDialog.Builder(fragmentActivity)
.setNegativeButton(R.string.generic_cancel, null)
.setPositiveButton(R.string.menu_export, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
FragmentActivity context = getActivity();
TrackFileFormat format = null;
PreferencesUtils.setString(context, R.string.export_type_key, ExportType.EXTERNAL_STORAGE.name());
format = getTrackFileFormat(exportExternalStorageOptions.getCheckedRadioButtonId());
PreferencesUtils.setString(context, R.string.export_external_storage_format_key, format.name());
caller.onExportDone(ExportType.EXTERNAL_STORAGE, format);
}
})
.setTitle(R.string.export_title).setView(view).create();
}
/**
* Sets an external storage option.
*
* @param radioButton the radio button
* @param trackFileFormat the track file format
*/
private void setExternalStorageOption(RadioButton radioButton, TrackFileFormat trackFileFormat) {
radioButton.setText(getString(R.string.export_external_storage_option, trackFileFormat.name(),
FileUtils.getPathDisplayName(trackFileFormat.getExtension())));
}
/**
* Gets the external storage format id from a track file format.
*
* @param trackFileFormat the track file format
*/
private int getExternalStorageFormatId(TrackFileFormat trackFileFormat) {
switch (trackFileFormat) {
case KML:
return R.id.export_external_storage_kml;
case GPX:
return R.id.export_external_storage_gpx;
case CSV:
return R.id.export_external_storage_csv;
default:
return R.id.export_external_storage_tcx;
}
}
/**
* Gets the track file format from an external storage format id.
*
* @param externalStorageFormatId the external storage format id
*/
private TrackFileFormat getTrackFileFormat(int externalStorageFormatId) {
switch (externalStorageFormatId) {
case R.id.export_external_storage_kml:
return TrackFileFormat.KML;
case R.id.export_external_storage_gpx:
return TrackFileFormat.GPX;
case R.id.export_external_storage_csv:
return TrackFileFormat.CSV;
default:
return TrackFileFormat.TCX;
}
}
}
@@ -39,10 +39,9 @@ import java.util.UUID;
*/
public class BluetoothConnectionManager {
// My Tracks UUID
public static final UUID MY_TRACKS_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Message types sent to hander
// Message types sent to handler
public static final int MESSAGE_DEVICE_NAME = 1;
public static final int MESSAGE_READ = 2;
@@ -37,8 +37,6 @@ import java.io.File;
public class IntentUtils {
public static final String TEXT_PLAIN_TYPE = "text/plain";
private static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth";
private static final String TWITTER_PACKAGE_NAME = "com.twitter.android";
private IntentUtils() {}
@@ -54,33 +52,6 @@ public class IntentUtils {
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
}
/**
* Creates an intent to share a track url with an app.
*
* @param context the context
* @param trackId the track id
* @param trackUrl the track url
* @param packageName the sharing app package name
* @param className the sharing app class name
*/
public static final Intent newShareUrlIntent(
Context context, long trackId, String trackUrl, String packageName, String className) {
Track track = MyTracksProviderUtils.Factory.get(context).getTrack(trackId);
String trackDescription = track == null ? ""
: new DescriptionGeneratorImpl(context).generateTrackDescription(track, null, null, false);
boolean urlOnly = TWITTER_PACKAGE_NAME.equals(packageName)
|| BLUETOOTH_PACKAGE_NAME.equals(packageName);
return new Intent(Intent.ACTION_SEND)
.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.share_track_subject))
.putExtra(Intent.EXTRA_TEXT, urlOnly
? trackUrl
: context.getString(R.string.share_track_share_url_body, trackUrl, trackDescription))
.setComponent(new ComponentName(packageName, className))
.setType(TEXT_PLAIN_TYPE);
}
/**
* Creates an intent to share a track file with an app.
*
@@ -17,7 +17,6 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.fragments.ExportDialogFragment.ExportType;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.gms.location.DetectedActivity;
import com.google.android.maps.mytracks.R;
-41
View File
@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2010 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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ScrollView" >
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="8dp" >
<RadioGroup
android:id="@+id/export_external_storage_options"
style="@style/ExportRadioGroup" >
<RadioButton
android:id="@+id/export_external_storage_kml"
style="@style/TextMedium" />
<RadioButton
android:id="@+id/export_external_storage_gpx"
style="@style/TextMedium" />
<RadioButton
android:id="@+id/export_external_storage_csv"
style="@style/TextMedium" />
<RadioButton
android:id="@+id/export_external_storage_tcx"
style="@style/TextMedium" />
</RadioGroup>
</LinearLayout>
</ScrollView>
@@ -38,11 +38,6 @@ limitations under the License.
android:id="@+id/track_detail_markers"
android:orderInCategory="5"
android:title="@string/menu_markers"/>
<item
android:icon="@drawable/ic_menu_export"
android:id="@+id/track_detail_export"
android:orderInCategory="8"
android:title="@string/menu_export"/>
<item
android:icon="@drawable/ic_menu_edit"
android:id="@+id/track_detail_edit"
@@ -73,9 +68,4 @@ limitations under the License.
android:id="@+id/track_detail_settings"
android:orderInCategory="14"
android:title="@string/menu_settings"/>
<item
android:icon="@drawable/ic_menu_help_feedback"
android:id="@+id/track_detail_help_feedback"
android:orderInCategory="15"
android:title="@string/menu_help_feedback"/>
</menu>
@@ -72,10 +72,6 @@ Google은 이용자에 대한 위치정보의 이용∙제공사실을 위치정
대표자: 염동훈\n
주소 : 서울 강남구 역삼동 737 강남파이낸스센터 22층\n
전화번호 : (02) 531-9000\n</string>
<string name="export_google_drive_url">drive.google.com</string>
<string name="export_google_fusion_tables_url">google.com/fusiontables</string>
<string name="export_google_maps_url">maps.google.com</string>
<string name="export_google_spreadsheets_url">drive.google.com</string>
<string name="marker_statistics_icon_url">http://maps.google.com/mapfiles/ms/micons/ylw-pushpin.png</string>
<string name="marker_waypoint_icon_url">http://maps.google.com/mapfiles/ms/micons/blue-pushpin.png</string>
<string name="my_tracks_help_url">http://support.google.com/gmm/bin/topic.py?topic=2391064&amp;hl=%1$s</string>
-58
View File
@@ -623,64 +623,6 @@ limitations under the License.
%2$s the directory. E.g., '/MyTracks/kml'.">
Exported %1$s to %2$s
</string>
<string name="export_google_drive"
translation_description="When exporting a track, the option to export to Google Drive.">
Google Drive
</string>
<string name="export_google_error"
translation_description="When exporting a track, the error message.
%1$s service name. E.g, Google Maps.
%2$s service url. E.g, maps.google.com.">
An error has occurred. Unable to export to %1$s (%2$s). Please try again.
</string>
<string name="export_google_error_public"
translation_description="The error message when not able to make a track public.
%1$s service name. E.g, Google Drive.
%2$s service url. E.g, drive.google.com.">
Unable to make track public in %1$s (%2$s)
</string>
<string name="export_google_fusion_tables"
translation_description="When exporting a track, the option to export to Google Fusion Tables.">
Google Fusion Tables
</string>
<string name="export_google_fusion_tables_private"
translation_description="When exporting a track to Google Fusion Tables, the option to export as
a new private table as opposed to a new public table.">
as new private table
</string>
<string name="export_google_fusion_tables_public"
translation_description="When exporting a track to Google Fusion Tables, the option to export as
a new public table as opposed to a new private table.">
as new public table
</string>
<string name="export_google_maps"
translation_description="When exporting a track, the option to export to Google Maps.">
Google Maps
</string>
<string name="export_google_maps_public"
translation_description="When exporting a track to Google Maps, the option to export as a new
public map as opposed to a new unlisted map.">
as new public map
</string>
<string name="export_google_maps_unlisted"
translation_description="When exporting a track to Google Maps, the option to export as a new
unlisted map as opposed to a new public map.">
as new unlisted map
</string>
<string name="export_google_spreadsheets"
translation_description="When exporting a track, the option to export to Google Spreadsheets.">
Google Spreadsheets
</string>
<string name="export_google_success"
translation_description="When sending a track to Google, the additional comment on the bottom of
the result page.
%1$s service name. E.g, Google Maps.
%2$s service url. E.g, maps.google.com.">
Track exported to %1$s (%2$s). It may take a few minutes for it to appear.
</string>
<string name="export_title"
translation_description="The dialog title when exporting a track.">
Export to&#8230;