diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/drive/SendDriveAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/drive/SendDriveAsyncTask.java index 6cd363b80..b34303246 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/drive/SendDriveAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/drive/SendDriveAsyncTask.java @@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.drive; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask; +import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.gms.auth.GoogleAuthException; import com.google.android.gms.auth.UserRecoverableAuthException; @@ -69,8 +70,8 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask { @Override protected boolean performTask() { try { - GoogleAccountCredential credential = SyncUtils.getGoogleAccountCredential( - context, account.name); + GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential( + context, account.name, SendToGoogleUtils.DRIVE_SCOPE); if (credential == null) { return false; } @@ -102,16 +103,18 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask { } addPermission(drive, id); return true; - } catch (UserRecoverableAuthIOException e) { - SyncUtils.sendNotification(context, account.name, e.getIntent()); - return false; - } catch (IOException e) { - return retryTask(); } catch (UserRecoverableAuthException e) { - SyncUtils.sendNotification(context, account.name, e.getIntent()); + SendToGoogleUtils.sendNotification( + context, account.name, e.getIntent(), SendToGoogleUtils.DRIVE_NOTIFICATION_ID); return false; } catch (GoogleAuthException e) { return retryTask(); + } catch (UserRecoverableAuthIOException e) { + SendToGoogleUtils.sendNotification( + context, account.name, e.getIntent(), SendToGoogleUtils.DRIVE_NOTIFICATION_ID); + return false; + } catch (IOException e) { + return retryTask(); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java index e94eafb17..17ed23cd8 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java @@ -11,39 +11,33 @@ import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint.WaypointType; import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask; import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; -import com.google.android.apps.mytracks.stats.TripStatisticsUpdater; -import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.LocationUtils; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.apps.mytracks.util.SystemUtils; +import com.google.android.gms.auth.GoogleAuthException; +import com.google.android.gms.auth.UserRecoverableAuthException; import com.google.android.maps.mytracks.R; -import com.google.api.client.googleapis.GoogleHeaders; -import com.google.api.client.googleapis.MethodOverride; -import com.google.api.client.http.GenericUrl; -import com.google.api.client.http.HttpRequest; -import com.google.api.client.http.HttpRequestFactory; -import com.google.api.client.http.HttpResponse; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.InputStreamContent; -import com.google.common.annotations.VisibleForTesting; +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.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; +import com.google.api.client.json.gson.GsonFactory; +import com.google.api.services.fusiontables.Fusiontables; +import com.google.api.services.fusiontables.Fusiontables.Query.Sql; +import com.google.api.services.fusiontables.model.Column; +import com.google.api.services.fusiontables.model.PointStyle; +import com.google.api.services.fusiontables.model.StyleFunction; +import com.google.api.services.fusiontables.model.StyleSetting; +import com.google.api.services.fusiontables.model.Table; +import com.google.api.services.fusiontables.model.Template; import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; import android.content.Context; import android.database.Cursor; import android.location.Location; import android.util.Log; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.Vector; /** * AsyncTask to send a track to Google Fusion Tables. @@ -52,20 +46,10 @@ import java.util.Vector; */ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { - @VisibleForTesting - public static final String APP_NAME_PREFIX = "Google-MyTracks-"; - private static final String SQL_KEY = "sql="; - @VisibleForTesting - public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; - @VisibleForTesting - public static final String - FUSION_TABLES_BASE_URL = "https://www.google.com/fusiontables/api/query"; + private static final String TAG = SendFusionTablesAsyncTask.class.getSimpleName(); private static final int MAX_POINTS_PER_UPLOAD = 2048; - @VisibleForTesting - public static final String GDATA_VERSION = "2"; - private static final int PROGRESS_CREATE_TABLE = 0; - private static final int PROGRESS_UNLIST_TABLE = 5; + private static final int PROGRESS_SET_STYLE = 5; private static final int PROGRESS_UPLOAD_DATA_MIN = 10; private static final int PROGRESS_UPLOAD_DATA_MAX = 90; private static final int PROGRESS_UPLOAD_WAYPOINTS = 95; @@ -78,17 +62,11 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { private static final String MARKER_TYPE_WAYPOINT = "large_blue"; private static final String MARKER_TYPE_STATISTICS = "large_yellow"; - private static final String TAG = SendFusionTablesAsyncTask.class.getSimpleName(); - - private final Context context; private final long trackId; private final Account account; + private final Context context; private final MyTracksProviderUtils myTracksProviderUtils; - private final HttpRequestFactory httpRequestFactory; - // The following variables are for per upload states - private String authToken; - private String tableId; int currentSegment; public SendFusionTablesAsyncTask( @@ -96,119 +74,131 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { super(activity); this.trackId = trackId; this.account = account; - context = activity.getApplicationContext(); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context); - HttpTransport transport = ApiAdapterFactory.getApiAdapter().getHttpTransport(); - httpRequestFactory = transport.createRequestFactory(new MethodOverride()); } @Override - protected void closeConnection() { - // No action needed for Google Fusion Tables - } + protected void closeConnection() {} @Override - protected void saveResult() { - Track track = myTracksProviderUtils.getTrack(trackId); - if (track == null) { - Log.d(TAG, "No track for " + trackId); - return; - } - track.setTableId(tableId); - myTracksProviderUtils.updateTrack(track); - } + protected void saveResult() {} @Override protected boolean performTask() { - // Reset the per upload states - authToken = null; - tableId = null; - currentSegment = 1; - try { - authToken = AccountManager.get(context) - .blockingGetAuthToken(account, SendFusionTablesUtils.SERVICE, false); - } catch (OperationCanceledException e) { - Log.d(TAG, "Unable to get auth token", e); - return retryTask(); - } catch (AuthenticatorException e) { - Log.d(TAG, "Unable to get auth token", e); + // Reset the per upload states + currentSegment = 1; + + GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential( + context, account.name, SendToGoogleUtils.FUSION_TABLES_SCOPE); + if (credential == null) { + return false; + } + Fusiontables fusiontables = new Fusiontables.Builder( + AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build(); + + Track track = myTracksProviderUtils.getTrack(trackId); + if (track == null) { + Log.d(TAG, "No track for " + trackId); + return false; + } + + // Create a new table + publishProgress(PROGRESS_CREATE_TABLE); + String tableId = createNewTable(fusiontables, track); + if (tableId == null) { + return retryTask(); + } + + publishProgress(PROGRESS_SET_STYLE); + setStyle(fusiontables, tableId); + setTemplate(fusiontables, tableId); + + // Upload all the track points plus the start and end markers + publishProgress(PROGRESS_UPLOAD_DATA_MIN); + if (!uploadAllTrackPoints(fusiontables, tableId, track)) { + return false; + } + + // Upload all the waypoints + publishProgress(PROGRESS_UPLOAD_WAYPOINTS); + if (!uploadWaypoints(fusiontables, tableId)) { + return false; + } + + track.setTableId(tableId); + myTracksProviderUtils.updateTrack(track); + + publishProgress(PROGRESS_COMPLETE); + return true; + + } catch (UserRecoverableAuthException e) { + SendToGoogleUtils.sendNotification( + context, account.name, e.getIntent(), SendToGoogleUtils.FUSION_TABLES_NOTIFICATION_ID); + return false; + } catch (GoogleAuthException e) { return retryTask(); + } catch (UserRecoverableAuthIOException e) { + SendToGoogleUtils.sendNotification( + context, account.name, e.getIntent(), SendToGoogleUtils.FUSION_TABLES_NOTIFICATION_ID); + return false; } catch (IOException e) { - Log.d(TAG, "Unable to get auth token", e); return retryTask(); } - - Track track = myTracksProviderUtils.getTrack(trackId); - if (track == null) { - Log.d(TAG, "No track for " + trackId); - return false; - } - - // Create a new table - publishProgress(PROGRESS_CREATE_TABLE); - if (!createNewTable(track)) { - // Retry upload in case the auth token is invalid - return retryTask(); - } - - // Unlist table - publishProgress(PROGRESS_UNLIST_TABLE); - if (!unlistTable()) { - return false; - } - - // Upload all the track points plus the start and end markers - publishProgress(PROGRESS_UPLOAD_DATA_MIN); - if (!uploadAllTrackPoints(track)) { - return false; - } - - // Upload all the waypoints - publishProgress(PROGRESS_UPLOAD_WAYPOINTS); - if (!uploadWaypoints()) { - return false; - } - - publishProgress(PROGRESS_COMPLETE); - return true; } @Override - protected void invalidateToken() { - AccountManager.get(context).invalidateAuthToken(Constants.ACCOUNT_TYPE, authToken); - } + protected void invalidateToken() {} /** * Creates a new table. * + * @param fusiontables fusion tables * @param track the track - * @return true if success. + * @return the table id if success. */ - private boolean createNewTable(Track track) { - String query = "CREATE TABLE '" + SendFusionTablesUtils.escapeSqlString(track.getName()) - + "' (name:STRING,description:STRING,geometry:LOCATION,marker:STRING)"; - return sendQuery(query, true); + private String createNewTable(Fusiontables fusiontables, Track track) throws IOException { + Table table = new Table(); + table.setName(track.getName()); + table.setDescription(track.getDescription()); + table.setIsExportable(true); + table.setColumns(Arrays.asList(new Column().setName("name").setType("STRING"), + new Column().setName("description").setType("STRING"), + new Column().setName("geometry").setType("LOCATION"), + new Column().setName("icon").setType("STRING"))); + return fusiontables.table().insert(table).execute().getTableId(); + } + + private void setStyle(Fusiontables fusiontables, String tableId) throws IOException { + StyleFunction styleFunction = new StyleFunction(); + styleFunction.setColumnName("icon"); + PointStyle pointStyle = new PointStyle(); + pointStyle.setIconStyler(styleFunction); + StyleSetting styleSetting = new StyleSetting(); + styleSetting.setTableId(tableId); + styleSetting.setMarkerOptions(pointStyle); + + fusiontables.style().insert(tableId, styleSetting).execute(); + } + + private void setTemplate(Fusiontables fusiontables, String tableId) throws IOException { + Template template = new Template(); + template.setTableId(tableId); + template.setAutomaticColumnNames(Arrays.asList("name", "description")); + fusiontables.template().insert(tableId, template).execute(); } /** - * Unlists a table. - * - * @return true if success. - */ - private boolean unlistTable() { - String query = "UPDATE TABLE " + tableId + " SET VISIBILITY = UNLISTED"; - return sendQuery(query, false); - } - - /** - * Uploads all the points in a track. + * Uploads all the points in a track. * * + * @param fusiontables fusion tables + * @param tableId the table id * @param track the track * @return true if success. */ - private boolean uploadAllTrackPoints(Track track) { + private boolean uploadAllTrackPoints(Fusiontables fusiontables, String tableId, Track track) + throws IOException { Cursor cursor = null; try { cursor = myTracksProviderUtils.getTrackPointCursor(trackId, -1L, -1, false); @@ -221,15 +211,6 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); Location lastLocation = null; - // For chart server, limit the number of elevation readings to 250. - int elevationSamplingFrequency = Math.max(1, (int) (count / 250.0)); - Vector distances = new Vector(); - Vector elevations = new Vector(); - TripStatisticsUpdater tripStatisticsUpdater = new TripStatisticsUpdater( - track.getTripStatistics().getStartTime()); - int minRecordingDistance = PreferencesUtils.getInt(context, - R.string.min_recording_distance_key, PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT); - for (int i = 0; i < count; i++) { cursor.moveToPosition(i); @@ -239,17 +220,9 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { if (i == 0) { // Create a start marker String name = context.getString(R.string.marker_label_start, track.getName()); - if (!createNewPoint(name, "", location, MARKER_TYPE_START)) { - Log.d(TAG, "Unable to create the start marker"); - return false; - } + createNewPoint(fusiontables, tableId, name, "", location, MARKER_TYPE_START); } - tripStatisticsUpdater.addLocation(location, minRecordingDistance); - if (i % elevationSamplingFrequency == 0) { - distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance()); - elevations.add(tripStatisticsUpdater.getSmoothedElevation()); - } if (LocationUtils.isValidLocation(location)) { lastLocation = location; } @@ -257,7 +230,7 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { // Upload periodically int readCount = i + 1; if (readCount % MAX_POINTS_PER_UPLOAD == 0) { - if (!prepareAndUploadPoints(track, locations, false)) { + if (!prepareAndUploadPoints(fusiontables, tableId, track, locations, false)) { Log.d(TAG, "Unable to upload points"); return false; } @@ -267,25 +240,18 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { } // Do a final upload with the remaining locations - if (!prepareAndUploadPoints(track, locations, true)) { + if (!prepareAndUploadPoints(fusiontables, tableId, track, locations, true)) { Log.d(TAG, "Unable to upload points"); return false; } // Create an end marker - if (lastLocation != null) { - distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance()); - elevations.add(tripStatisticsUpdater.getSmoothedElevation()); - DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context); - track.setDescription( - descriptionGenerator.generateTrackDescription(track, distances, elevations, true)); + if (lastLocation != null) { String name = context.getString(R.string.marker_label_end, track.getName()); - if (!createNewPoint(name, track.getDescription(), lastLocation, MARKER_TYPE_END)) { - Log.d(TAG, "Unable to create the end marker"); - return false; - } + DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context); + String description = descriptionGenerator.generateTrackDescription(track, null, null, true); + createNewPoint(fusiontables, tableId, name, description, lastLocation, MARKER_TYPE_END); } - return true; } finally { if (cursor != null) { @@ -297,11 +263,14 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { /** * Prepares and uploads a list of locations from a track. * + * @param fusiontables fusion tables + * @param tableId the table id * @param track the track * @param locations the locations from the track * @param lastBatch true if it is the last batch of locations */ - private boolean prepareAndUploadPoints(Track track, List locations, boolean lastBatch) { + private boolean prepareAndUploadPoints(Fusiontables fusiontables, String tableId, Track track, + List locations, boolean lastBatch) throws IOException { // Prepare locations ArrayList splitTracks = SendToGoogleUtils.prepareLocations(track, locations); @@ -312,10 +281,7 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { splitTrack.setName(context.getString( R.string.send_google_track_part_label, splitTrack.getName(), currentSegment)); } - if (!createNewLineString(splitTrack)) { - Log.d(TAG, "Upload points failed"); - return false; - } + createNewLineString(fusiontables, tableId, splitTrack); currentSegment++; } return true; @@ -324,24 +290,28 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { /** * Uploads all the waypoints. * + * @param fusiontables fusion tables + * @param tableId the table id * @return true if success. + * @throws IOException */ - private boolean uploadWaypoints() { + private boolean uploadWaypoints(Fusiontables fusiontables, String tableId) throws IOException { Cursor cursor = null; try { cursor = myTracksProviderUtils.getWaypointCursor( trackId, -1L, Constants.MAX_LOADED_WAYPOINTS_POINTS); if (cursor != null && cursor.moveToFirst()) { - // This will skip the first waypoint (it carries the stats for the - // track). + /* + * This will skip the first waypoint (it carries the stats for the + * track). + */ while (cursor.moveToNext()) { Waypoint wpt = myTracksProviderUtils.createWaypoint(cursor); String type = wpt.getType() == WaypointType.STATISTICS ? MARKER_TYPE_STATISTICS : MARKER_TYPE_WAYPOINT; - if (!createNewPoint(wpt.getName(), wpt.getDescription(), wpt.getLocation(), type)) { - Log.d(TAG, "Upload waypoints failed"); - return false; - } + String description = wpt.getDescription().replaceAll("\n", "
"); + createNewPoint( + fusiontables, tableId, wpt.getName(), description, wpt.getLocation(), type); } } return true; @@ -355,110 +325,37 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { /** * Creates a new row in Google Fusion Tables representing a marker as a point. * + * @param fusiontables fusion tables + * @param tableId the table id * @param name the marker name * @param description the marker description * @param location the marker location * @param type the marker type - * @return true if success. */ - private boolean createNewPoint(String name, String description, Location location, String type) { - String query = "INSERT INTO " + tableId + " (name,description,geometry,marker) VALUES " - + SendFusionTablesUtils.formatSqlValues( - name, description, SendFusionTablesUtils.getKmlPoint(location), type); - return sendQuery(query, false); + private void createNewPoint(Fusiontables fusiontables, String tableId, String name, + String description, Location location, String type) throws IOException { + String values = SendFusionTablesUtils.formatSqlValues( + name, description, SendFusionTablesUtils.getKmlPoint(location), type); + Sql sql = fusiontables.query() + .sql("INSERT INTO " + tableId + " (name,description,geometry,icon) VALUES " + values); + sql.execute(); } /** * Creates a new row in Google Fusion Tables representing the track as a line * segment. * + * @param fusiontables fusion tables + * @param tableId the table id * @param track the track - * @return true if success. */ - private boolean createNewLineString(Track track) { - String query = "INSERT INTO " + tableId - + " (name,description,geometry) VALUES " + SendFusionTablesUtils.formatSqlValues( - track.getName(), track.getDescription(), - SendFusionTablesUtils.getKmlLineString(track.getLocations())); - return sendQuery(query, false); - } - - /** - * Sends a query to Google Fusion Tables. - * - * @param query the Fusion Tables SQL query - * @param setTableId true to set the table id - * @return true if success. - */ - private boolean sendQuery(String query, boolean setTableId) { - Log.d(TAG, "SendQuery: " + query); - - if (isCancelled()) { - return false; - } - - GenericUrl url = new GenericUrl(FUSION_TABLES_BASE_URL); - String sql; - try { - sql = SQL_KEY + URLEncoder.encode(query, "UTF-8"); - } catch (UnsupportedEncodingException e1) { - Log.d(TAG, "Unable to encode query", e1); - return false; - } - ByteArrayInputStream inputStream = new ByteArrayInputStream(sql.getBytes()); - InputStreamContent inputStreamContent = new InputStreamContent(null, inputStream); - HttpRequest request; - try { - request = httpRequestFactory.buildPostRequest(url, inputStreamContent); - } catch (IOException e) { - Log.d(TAG, "Unable to build request", e); - return false; - } - - GoogleHeaders headers = new GoogleHeaders(); - headers.setApplicationName(APP_NAME_PREFIX + SystemUtils.getMyTracksVersion(context)); - headers.setGDataVersion(GDATA_VERSION); - headers.setGoogleLogin(authToken); - headers.setContentType(CONTENT_TYPE); - request.setHeaders(headers); - - HttpResponse response; - try { - response = request.execute(); - } catch (IOException e) { - Log.d(TAG, "Unable to execute request", e); - return false; - } - boolean isSuccess = response.isSuccessStatusCode(); - if (isSuccess) { - InputStream content = null; - try { - content = response.getContent(); - if (setTableId) { - tableId = SendFusionTablesUtils.getTableId(content); - if (tableId == null) { - Log.d(TAG, "tableId is null"); - return false; - } - } - } catch (IOException e) { - Log.d(TAG, "Unable to get response", e); - return false; - } finally { - if (content != null) { - try { - content.close(); - } catch (IOException e) { - Log.d(TAG, "Unable to close content", e); - } - } - } - } else { - Log.d(TAG, - "sendQuery failed: " + response.getStatusMessage() + ": " + response.getStatusCode()); - return false; - } - return true; + private void createNewLineString(Fusiontables fusiontables, String tableId, Track track) + throws IOException { + String values = SendFusionTablesUtils.formatSqlValues(track.getName(), track.getDescription(), + SendFusionTablesUtils.getKmlLineString(track.getLocations())); + Sql sql = fusiontables.query() + .sql("INSERT INTO " + tableId + " (name,description,geometry) VALUES " + values); + sql.execute(); } /** diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java index 1e5aafdd2..74f0aa35b 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java @@ -22,9 +22,6 @@ import com.google.common.annotations.VisibleForTesting; import android.location.Location; import android.util.Log; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Locale; @@ -107,7 +104,8 @@ public class SendFusionTablesUtils { * @param string the string * @return the escaped string. */ - public static String escapeSqlString(String string) { + @VisibleForTesting + static String escapeSqlString(String string) { return string.replaceAll("'", "''"); } @@ -160,45 +158,4 @@ public class SendFusionTablesUtils { builder.append(location.getAltitude()); } } - - /** - * Gets the table id from an input streawm. - * - * @param inputStream input stream - * @return table id or null if not available. - */ - public static String getTableId(InputStream inputStream) { - if (inputStream == null) { - Log.d(TAG, "inputStream is null"); - return null; - } - byte[] result = new byte[1024]; - int read; - try { - read = inputStream.read(result); - } catch (IOException e) { - Log.d(TAG, "Unable to read result", e); - return null; - } - if (read == -1) { - Log.d(TAG, "no data read"); - return null; - } - String s; - try { - s = new String(result, 0, read, UTF8); - } catch (UnsupportedEncodingException e) { - Log.d(TAG, "Unable to parse result", e); - return null; - } - - String[] lines = s.split("\n"); - if (lines.length > 1 && lines[0].equals(TABLE_ID)) { - // returns the next line - return lines[1]; - } else { - Log.d(TAG, "Response is not valid: " + s); - return null; - } - } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/AccountChooserActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/AccountChooserActivity.java index 517cded18..1ab0d36f2 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/AccountChooserActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/AccountChooserActivity.java @@ -20,13 +20,11 @@ import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.io.docs.SendDocsActivity; import com.google.android.apps.mytracks.io.drive.SendDriveActivity; import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesActivity; -import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesUtils; import com.google.android.apps.mytracks.io.gdata.docs.DocumentsClient; import com.google.android.apps.mytracks.io.gdata.docs.SpreadsheetsClient; import com.google.android.apps.mytracks.io.gdata.maps.MapsConstants; import com.google.android.apps.mytracks.io.maps.ChooseMapActivity; import com.google.android.apps.mytracks.io.maps.SendMapsActivity; -import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; @@ -50,12 +48,12 @@ import java.io.IOException; /** * A chooser to select an account. - * + * * @author Jimmy Shih */ public class AccountChooserActivity extends Activity { - private static final String TAG = AccountChooserActivity.class.getSimpleName(); + private static final String TAG = AccountChooserActivity.class.getSimpleName(); private static final int DIALOG_NO_ACCOUNT_ID = 0; private static final int DIALOG_CHOOSER_ID = 1; @@ -72,20 +70,20 @@ public class AccountChooserActivity extends Activity { showDialog(DIALOG_NO_ACCOUNT_ID); return; } - + if (accounts.length == 1) { sendRequest.setAccount(accounts[0]); PreferencesUtils.setString(this, R.string.google_account_key, accounts[0].name); - checkDrivePermission(accounts[0].name); + checkDrivePermission(); return; } - String googleAccount = PreferencesUtils.getString(this, R.string.google_account_key, - PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + String googleAccount = PreferencesUtils.getString( + this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); for (int i = 0; i < accounts.length; i++) { if (accounts[i].name.equals(googleAccount)) { sendRequest.setAccount(accounts[i]); - checkDrivePermission(accounts[i].name); + checkDrivePermission(); return; } } @@ -95,39 +93,43 @@ public class AccountChooserActivity extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case SyncUtils.DRIVE_PERMISSION_REQUEST_CODE: - SyncUtils.cancelNotification(this); + case SendToGoogleUtils.DRIVE_PERMISSION_REQUEST_CODE: + SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.DRIVE_NOTIFICATION_ID); if (resultCode == Activity.RESULT_OK) { driveCallback.onSuccess(); } else { driveCallback.onFailure(); } break; + case SendToGoogleUtils.FUSION_TABLES_PERMISSION_REQUEST_CODE: + SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.FUSION_TABLES_NOTIFICATION_ID); + if (resultCode == Activity.RESULT_OK) { + fusionTablesCallback.onSuccess(); + } else { + fusionTablesCallback.onFailure(); + } + break; default: super.onActivityResult(requestCode, resultCode, data); } } - + @Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_NO_ACCOUNT_ID: - return new AlertDialog.Builder(this) - .setCancelable(true) + return new AlertDialog.Builder(this).setCancelable(true) .setMessage(R.string.send_google_no_account_message) .setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override + @Override public void onCancel(DialogInterface dialog) { finish(); } - }) - .setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() { + }).setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { finish(); } - }) - .setTitle(R.string.send_google_no_account_title) - .create(); + }).setTitle(R.string.send_google_no_account_title).create(); case DIALOG_CHOOSER_ID: return createChooserDialog(); default: @@ -143,103 +145,115 @@ public class AccountChooserActivity extends Activity { for (int i = 0; i < accounts.length; i++) { choices[i] = accounts[i].name; } - return new AlertDialog.Builder(this) - .setCancelable(true) + return new AlertDialog.Builder(this).setCancelable(true) .setNegativeButton(R.string.generic_cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { finish(); } - }) - .setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override + }).setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override public void onCancel(DialogInterface dialog) { finish(); } - }) - .setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() { + }).setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); Account account = accounts[position]; PreferencesUtils.setString( AccountChooserActivity.this, R.string.google_account_key, account.name); sendRequest.setAccount(account); - checkDrivePermission(account.name); + checkDrivePermission(); } - }) - .setSingleChoiceItems(choices, 0, null) - .setTitle(R.string.send_google_choose_account_title) - .create(); + }).setSingleChoiceItems(choices, 0, null) + .setTitle(R.string.send_google_choose_account_title).create(); } - + /** * Checks the Drive permission. - * - * @param accountName the account name */ - private void checkDrivePermission(String accountName) { + private void checkDrivePermission() { if (sendRequest.isSendDrive()) { - SyncUtils.checkPermissionByActivity(this, accountName, driveCallback); + SendToGoogleUtils.checkPermissionByActivity(this, sendRequest.getAccount().name, + SendToGoogleUtils.DRIVE_SCOPE, SendToGoogleUtils.DRIVE_PERMISSION_REQUEST_CODE, + driveCallback); } else { driveCallback.onSuccess(); } } - + + /** + * Checks the Fusion Tables permission. + */ + private void checkFusionTablesPermission() { + if (sendRequest.isSendFusionTables()) { + SendToGoogleUtils.checkPermissionByActivity(this, sendRequest.getAccount().name, + SendToGoogleUtils.FUSION_TABLES_SCOPE, + SendToGoogleUtils.FUSION_TABLES_PERMISSION_REQUEST_CODE, fusionTablesCallback); + } else { + fusionTablesCallback.onSuccess(); + } + } + private PermissionCallback spreadsheetsCallback = new PermissionCallback() { - @Override + @Override public void onSuccess() { startNextActivity(); - } - @Override + } + + @Override public void onFailure() { handleNoAccountPermission(); } }; - + private PermissionCallback docsCallback = new PermissionCallback() { - @Override + @Override public void onSuccess() { getPermission(SpreadsheetsClient.SERVICE, sendRequest.isSendDocs(), spreadsheetsCallback); - } - @Override + } + + @Override public void onFailure() { handleNoAccountPermission(); } }; - + private PermissionCallback fusionTablesCallback = new PermissionCallback() { - @Override + @Override public void onSuccess() { getPermission(DocumentsClient.SERVICE, sendRequest.isSendDocs(), docsCallback); - } - @Override + } + + @Override public void onFailure() { handleNoAccountPermission(); } }; - + private PermissionCallback mapsCallback = new PermissionCallback() { - @Override + @Override public void onSuccess() { - getPermission( - SendFusionTablesUtils.SERVICE, sendRequest.isSendFusionTables(), fusionTablesCallback); + checkFusionTablesPermission(); } - @Override + + @Override public void onFailure() { handleNoAccountPermission(); } }; - + private PermissionCallback driveCallback = new PermissionCallback() { - @Override + @Override public void onSuccess() { getPermission(MapsConstants.SERVICE_NAME, sendRequest.isSendMaps(), mapsCallback); } - @Override + + @Override public void onFailure() { handleNoAccountPermission(); } }; - + /** * Gets the user permission to access a service. * @@ -252,7 +266,7 @@ public class AccountChooserActivity extends Activity { if (needPermission) { AccountManager.get(this).getAuthToken(sendRequest.getAccount(), authTokenType, null, this, new AccountManagerCallback() { - @Override + @Override public void run(AccountManagerFuture future) { try { if (future.getResult().getString(AccountManager.KEY_AUTHTOKEN) != null) { @@ -290,7 +304,6 @@ public class AccountChooserActivity extends Activity { * !sendMaps && !sendFusionTables && sendDocs -> {@link SendDocsActivity} *

* !sendMaps && !sendFusionTables && !sendDocs -> {@link UploadResultActivity} - * */ private void startNextActivity() { Class next; @@ -310,7 +323,7 @@ public class AccountChooserActivity extends Activity { startActivity(intent); finish(); } - + /** * Handles when not able to get account permission. */ diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendToGoogleUtils.java b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendToGoogleUtils.java index 04ad9c201..b0417cb8a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendToGoogleUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendToGoogleUtils.java @@ -19,11 +19,25 @@ package com.google.android.apps.mytracks.io.sendtogoogle; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.LocationUtils; +import com.google.android.gms.auth.GoogleAuthException; +import com.google.android.gms.auth.UserRecoverableAuthException; +import com.google.android.maps.mytracks.R; +import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; +import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; +import com.google.api.services.drive.DriveScopes; +import com.google.api.services.fusiontables.FusiontablesScopes; import com.google.common.annotations.VisibleForTesting; +import android.app.Activity; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; import android.location.Location; +import android.support.v4.app.NotificationCompat; import android.util.Log; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -36,6 +50,16 @@ public class SendToGoogleUtils { private static final String TAG = SendToGoogleUtils.class.getSimpleName(); + // Request code to obtain Drive permission + public static final int DRIVE_PERMISSION_REQUEST_CODE = 1; + public static final String DRIVE_SCOPE = DriveScopes.DRIVE; + public static final int DRIVE_NOTIFICATION_ID = 1; + + // Request code to obtain Fusion Tables permission + public static final int FUSION_TABLES_PERMISSION_REQUEST_CODE = 2; + public static final String FUSION_TABLES_SCOPE = FusiontablesScopes.FUSIONTABLES; + public static final int FUSION_TABLES_NOTIFICATION_ID = 2; + private SendToGoogleUtils() {} /** @@ -115,4 +139,105 @@ public class SendToGoogleUtils { splitTracks.add(segment); return true; } + + /** + * Gets the google account credential. + * + * @param context the context + * @param accountName the account name + * @param scope the scope + */ + public static GoogleAccountCredential getGoogleAccountCredential( + Context context, String accountName, String scope) throws IOException, GoogleAuthException { + GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context, scope); + credential.setSelectedAccountName(accountName); + credential.getToken(); + return credential; + } + + /** + * Checks permission by an activity. Will start an activity to request + * permission using the request code. + * + * @param activity the activity + * @param accountName the account name + * @param scope the scope + * @param requestCode the request code + * @param permissionCallback the permission callback + */ + public static void checkPermissionByActivity(final Activity activity, final String accountName, + final String scope, final int requestCode, final PermissionCallback permissionCallback) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + try { + getGoogleAccountCredential(activity, accountName, scope); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + permissionCallback.onSuccess(); + } + }); + } catch (UserRecoverableAuthException e) { + activity.startActivityForResult(e.getIntent(), requestCode); + } catch (GoogleAuthException e) { + Log.e(TAG, "GoogleAuthException", e); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + permissionCallback.onFailure(); + } + }); + } catch (UserRecoverableAuthIOException e) { + activity.startActivityForResult(e.getIntent(), requestCode); + } catch (IOException e) { + Log.e(TAG, "IOException", e); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + permissionCallback.onFailure(); + } + }); + } + } + }); + thread.start(); + } + + /** + * Sends a notification to request permission. + * + * @param context the context + * @param accountName the account name + * @param intent the intent + * @param notificaitonId the notification id + */ + public static void sendNotification( + Context context, String accountName, Intent intent, int notificaitonId) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).addFlags(Intent.FLAG_FROM_BACKGROUND); + + PendingIntent pendingIntent = PendingIntent.getActivity( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setAutoCancel(true) + .setContentIntent(pendingIntent) + .setContentText(context.getString(R.string.permission_request_message, accountName)) + .setContentTitle(context.getString(R.string.permission_request_title)) + .setSmallIcon(android.R.drawable.ic_dialog_alert) + .setTicker(context.getString(R.string.permission_request_title)); + NotificationManager notificationManager = (NotificationManager) context.getSystemService( + Context.NOTIFICATION_SERVICE); + notificationManager.notify(notificaitonId, builder.build()); + } + + /** + * Cancels any notification to request a permission. + * + * @param context the context + * @param notificationId the notification id + */ + public static void cancelNotification(Context context, int notificationId) { + NotificationManager notificationManager = (NotificationManager) context.getSystemService( + Context.NOTIFICATION_SERVICE); + notificationManager.cancel(notificationId); + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncAdapter.java index c0a798de2..19c499fef 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncAdapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncAdapter.java @@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.sync; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.io.file.KmlImporter; +import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.gms.auth.GoogleAuthException; import com.google.android.gms.auth.UserRecoverableAuthException; @@ -101,8 +102,8 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter { } try { - GoogleAccountCredential credential = SyncUtils.getGoogleAccountCredential( - context, account.name); + GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential( + context, account.name, SendToGoogleUtils.DRIVE_SCOPE); if (credential == null) { return; } @@ -125,11 +126,13 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter { } insertNewTracks(folderId); } catch (UserRecoverableAuthException e) { - SyncUtils.sendNotification(context, account.name, e.getIntent()); + SendToGoogleUtils.sendNotification( + context, account.name, e.getIntent(), SendToGoogleUtils.DRIVE_NOTIFICATION_ID); } catch (GoogleAuthException e) { Log.e(TAG, "GoogleAuthException", e); } catch (UserRecoverableAuthIOException e) { - SyncUtils.sendNotification(context, account.name, e.getIntent()); + SendToGoogleUtils.sendNotification( + context, account.name, e.getIntent(), SendToGoogleUtils.DRIVE_NOTIFICATION_ID); } catch (IOException e) { Log.e(TAG, "IOException", e); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java index de944a12c..7c8bb0c6a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java @@ -22,11 +22,8 @@ import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.io.file.TrackFileFormat; import com.google.android.apps.mytracks.io.file.TrackWriter; -import com.google.android.apps.mytracks.io.sendtogoogle.PermissionCallback; import com.google.android.apps.mytracks.util.FileUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.gms.auth.GoogleAuthException; -import com.google.android.gms.auth.UserRecoverableAuthException; import com.google.android.maps.mytracks.R; import com.google.api.client.extensions.android.http.AndroidHttp; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; @@ -35,7 +32,6 @@ import com.google.api.client.http.FileContent; import com.google.api.client.json.gson.GsonFactory; import com.google.api.services.drive.Drive; import com.google.api.services.drive.Drive.Files.List; -import com.google.api.services.drive.DriveScopes; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.FileList; import com.google.api.services.drive.model.ParentReference; @@ -43,14 +39,9 @@ import com.google.common.annotations.VisibleForTesting; import android.accounts.Account; import android.accounts.AccountManager; -import android.app.Activity; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.NotificationCompat; import android.util.Log; import java.io.FileInputStream; @@ -70,9 +61,6 @@ import java.util.Locale; */ public class SyncUtils { - // Request code to obtain Drive permission - public static final int DRIVE_PERMISSION_REQUEST_CODE = 1; - // Get tracks with drive id public static final String DRIVE_ID_TRACKS_QUERY = TracksColumns.DRIVEID + " IS NOT NULL AND " + TracksColumns.DRIVEID + "!=''"; @@ -103,106 +91,9 @@ public class SyncUtils { private static final String TAG = SyncUtils.class.getSimpleName(); private static final String SYNC_AUTHORITY = "com.google.android.maps.mytracks"; - private static final int NOTIFICATION_ID = 0; private SyncUtils() {} - /** - * Gets the google account credential. - * - * @param context the context - * @param accountName the account name - */ - public static GoogleAccountCredential getGoogleAccountCredential( - Context context, String accountName) throws IOException, GoogleAuthException { - GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2( - context, DriveScopes.DRIVE); - credential.setSelectedAccountName(accountName); - credential.getToken(); - return credential; - } - - /** - * Checks permission by an activity. Will start an activity to request - * permission with request code {@link #DRIVE_PERMISSION_REQUEST_CODE}. - * - * @param activity the activity - * @param accountName the account name - * @param permissionCallback the permission callback - */ - public static void checkPermissionByActivity(final Activity activity, final String accountName, - final PermissionCallback permissionCallback) { - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - try { - getGoogleAccountCredential(activity, accountName); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - permissionCallback.onSuccess(); - } - }); - } catch (UserRecoverableAuthException e) { - activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE); - } catch (GoogleAuthException e) { - Log.e(TAG, "GoogleAuthException", e); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - permissionCallback.onFailure(); - } - }); - } catch (UserRecoverableAuthIOException e) { - activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE); - } catch (IOException e) { - Log.e(TAG, "IOException", e); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - permissionCallback.onFailure(); - } - }); - } - } - }); - thread.start(); - } - - /** - * Sends a notification to request permission. - * - * @param context the context - * @param accountName the account name - * @param intent the intent - */ - public static void sendNotification(Context context, String accountName, Intent intent) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).addFlags(Intent.FLAG_FROM_BACKGROUND); - - PendingIntent pendingIntent = PendingIntent.getActivity( - context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setAutoCancel(true) - .setContentIntent(pendingIntent) - .setContentText(context.getString(R.string.permission_request_message, accountName)) - .setContentTitle(context.getString(R.string.permission_request_title)) - .setSmallIcon(android.R.drawable.ic_dialog_alert) - .setTicker(context.getString(R.string.permission_request_title)); - NotificationManager notificationManager = (NotificationManager) context.getSystemService( - Context.NOTIFICATION_SERVICE); - notificationManager.notify(NOTIFICATION_ID, builder.build()); - } - - /** - * Cancels any notification to request drive permission. - * - * @param context the context - */ - public static void cancelNotification(Context context) { - NotificationManager notificationManager = (NotificationManager) context.getSystemService( - Context.NOTIFICATION_SERVICE); - notificationManager.cancel(NOTIFICATION_ID); - } - /** * Syncs now for the current account. * diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java index ecccc3cf4..2c8d90791 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java @@ -20,6 +20,7 @@ import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.io.sendtogoogle.PermissionCallback; +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.DialogUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; @@ -143,8 +144,8 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case SyncUtils.DRIVE_PERMISSION_REQUEST_CODE: - SyncUtils.cancelNotification(this); + case SendToGoogleUtils.DRIVE_PERMISSION_REQUEST_CODE: + SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.DRIVE_NOTIFICATION_ID); if (resultCode == Activity.RESULT_OK) { permissionCallback.onSuccess(); } else { @@ -173,8 +174,9 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity { String googleAccount = PreferencesUtils.getString( GoogleSettingsActivity.this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); - SyncUtils.checkPermissionByActivity( - GoogleSettingsActivity.this, googleAccount, permissionCallback); + SendToGoogleUtils.checkPermissionByActivity(GoogleSettingsActivity.this, + googleAccount, SendToGoogleUtils.DRIVE_SCOPE, + SendToGoogleUtils.DRIVE_PERMISSION_REQUEST_CODE, permissionCallback); } }); break; diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java index 8c8f02205..4d85afd19 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java @@ -20,8 +20,6 @@ import com.google.android.apps.mytracks.stats.TripStatistics; import android.location.Location; -import java.io.ByteArrayInputStream; -import java.io.InputStream; import java.util.ArrayList; import junit.framework.TestCase; @@ -225,62 +223,4 @@ public class SendFusionTablesUtilsTest extends TestCase { SendFusionTablesUtils.appendLocation(location, builder); assertEquals("10.1,20.2,30.3", builder.toString()); } - - /** - * Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with a null - * inputstream. - */ - public void testGetTableId_null() { - assertEquals(null, SendFusionTablesUtils.getTableId(null)); - } - - /** - * Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an - * inputstream containing no data. - */ - public void testGetTableId_no_data() { - InputStream inputStream = new ByteArrayInputStream(new byte[0]); - assertEquals(null, SendFusionTablesUtils.getTableId(inputStream)); - } - - /** - * Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an empty - * inputstream. - */ - public void testGetTableId_empty() { - String string = ""; - InputStream inputStream = new ByteArrayInputStream(string.getBytes()); - assertEquals(null, SendFusionTablesUtils.getTableId(inputStream)); - } - - /** - * Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an one - * line inputstream. - */ - public void testGetTableId_one_line() { - String string = "tableid"; - InputStream inputStream = new ByteArrayInputStream(string.getBytes()); - assertEquals(null, SendFusionTablesUtils.getTableId(inputStream)); - } - - /** - * Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an - * inputstream not containing "tableid". - */ - public void testGetTableId_no_table_id() { - String string = "error\n123"; - InputStream inputStream = new ByteArrayInputStream(string.getBytes()); - assertEquals(null, SendFusionTablesUtils.getTableId(inputStream)); - } - - /** - * Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with a valid - * inputstream. - */ - public void testGetTableId() { - String string = "tableid\n123"; - InputStream inputStream = null; - inputStream = new ByteArrayInputStream(string.getBytes()); - assertEquals("123", SendFusionTablesUtils.getTableId(inputStream)); - } } \ No newline at end of file diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java index fa3feb179..26f29cb5c 100644 --- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java +++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java @@ -17,7 +17,6 @@ package com.google.android.apps.mytracks.endtoendtest; import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.io.docs.SendDocsUtils; -import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesAsyncTask; import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesUtils; import com.google.android.apps.mytracks.io.gdata.GDataClientFactory; import com.google.android.apps.mytracks.io.gdata.docs.DocumentsClient; @@ -63,11 +62,17 @@ import java.util.Locale; * @author Youtao Liu */ public class GoogleUtils { + public static final String DOCUMENT_NAME_PREFIX = "My Tracks"; public static final String ACCOUNT_NAME_1 = "mytrackstest@gmail.com"; public static final String ACCOUNT_NAME_2 = "mytrackstest2@gmail.com"; public static final String SPREADSHEET_NAME = DOCUMENT_NAME_PREFIX + "-" + EndToEndTestUtils.activityType; + private static final String APP_NAME_PREFIX = "Google-MyTracks-"; + private static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String FUSION_TABLES_BASE_URL = "https://www.google.com/fusiontables/api/query"; + private static final String GDATA_VERSION = "2"; + /** * Gets the account to access Google Services. * @@ -408,7 +413,7 @@ public class GoogleUtils { String fusionTableAuthToken = AccountManager.get(context).blockingGetAuthToken(getAccount(context), SendFusionTablesUtils.SERVICE, false); - GenericUrl url = new GenericUrl(SendFusionTablesAsyncTask.FUSION_TABLES_BASE_URL); + GenericUrl url = new GenericUrl(FUSION_TABLES_BASE_URL); String sql = "sql=" + query; ByteArrayInputStream inputStream = new ByteArrayInputStream(sql.getBytes()); InputStreamContent inputStreamContent = new InputStreamContent(null, inputStream); @@ -418,11 +423,11 @@ public class GoogleUtils { .createRequestFactory(new MethodOverride())).buildPostRequest(url, inputStreamContent); GoogleHeaders headers = new GoogleHeaders(); - headers.setApplicationName(SendFusionTablesAsyncTask.APP_NAME_PREFIX + headers.setApplicationName(APP_NAME_PREFIX + SystemUtils.getMyTracksVersion(context)); - headers.setGDataVersion(SendFusionTablesAsyncTask.GDATA_VERSION); + headers.setGDataVersion(GDATA_VERSION); headers.setGoogleLogin(fusionTableAuthToken); - headers.setContentType(SendFusionTablesAsyncTask.CONTENT_TYPE); + headers.setContentType(CONTENT_TYPE); request.setHeaders(headers); HttpResponse response; diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/sync/SyncTestUtils.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/sync/SyncTestUtils.java index f16751e75..4f7041242 100644 --- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/sync/SyncTestUtils.java +++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/sync/SyncTestUtils.java @@ -18,6 +18,7 @@ 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.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; @@ -119,8 +120,8 @@ public class SyncTestUtils { 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 = SyncUtils.getGoogleAccountCredential( - context, googleAccount); + GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential( + context, googleAccount, SendToGoogleUtils.DRIVE_SCOPE); return SyncUtils.getDriveService(credential); }