diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml
index 1f41f0b1b..21934680e 100644
--- a/MyTracks/res/values/strings.xml
+++ b/MyTracks/res/values/strings.xml
@@ -1732,8 +1732,9 @@ limitations under the License.
account.
%1$s account name. E.g., 'foo@foo.com'.">
- This will remove any mappings between tracks and %1$s Google Drive. After removal, when sending
- to Google Drive or syncing with Google Drive, all tracks will be treated as new.
+ This will remove mappings between tracks and %1$s Google Drive. No tracks and no Google Drive
+ files will get removed. After switching account, when sending to Google Drive or syncing with
+ Google Drive, all tracks will be treated as new.
- Check the files in %1$s Google Drive ‘%2$s’ folder. Files not mapped to existing
- tracks will be synced as new tracks. If not desired, move those files to a different folder
- beforehand.
+ All files in the %1$s Google Drive ‘%2$s’ folder will be treated as new. If not
+ desired, move the files to a different folder beforehand.
idToFileMap = new HashMap();
-
- do {
- try {
- FileList files = request.execute();
-
- for (File file : files.getItems()) {
- idToFileMap.put(file.getId(), file);
- }
- request.setPageToken(files.getNextPageToken());
- } catch (IOException e) {
- Log.e(TAG, "IOException", e);
- request.setPageToken(null);
- }
- } while (request.getPageToken() != null && request.getPageToken().length() > 0);
-
- // Handle new drive files
+ // Get all the KML files in the "My Drive:/My Tracks" folder
+ Files.List request = drive.files().list()
+ .setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_FILES_QUERY, folderId));
+ Map idToFileMap = getFiles(request);
insertNewDriveFiles(idToFileMap.values());
+
+ // Get all the KML files in the "Shared with me:/" folder
+ request = drive.files().list().setQ(SyncUtils.SHARED_WITH_ME_FILES_QUERY);
+ idToFileMap = getFiles(request);
+ insertNewDriveFiles(idToFileMap.values());
+
PreferencesUtils.setLong(context, R.string.drive_largest_change_id_key, largestChangeId);
}
@@ -172,8 +162,13 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
String deletedIds[] = TextUtils.split(driveDeletedList, ";");
for (String id : deletedIds) {
File driveFile = drive.files().get(id).execute();
- if (SyncUtils.isDriveFileValid(driveFile, folderId)) {
- drive.files().trash(id).execute();
+ if (SyncUtils.isInFolder(driveFile, folderId)) {
+ if (!driveFile.getLabels().getTrashed()) {
+ drive.files().trash(id).execute();
+ }
+ // if trashed, ignore
+ } else if (SyncUtils.isSharedWithMe(driveFile)) {
+ drive.files().delete(id).execute();
}
}
PreferencesUtils.setString(
@@ -185,7 +180,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Cursor cursor = null;
try {
// Get all the local tracks with drive file id
- cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_IDS_QUERY, null, null);
+ cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_ID_TRACKS_QUERY, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
Track track = myTracksProviderUtils.createTrack(cursor);
@@ -203,19 +198,22 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
}
changes.remove(driveId);
} else {
+ if (!track.isSharedWithMe()) {
- // Handle the case the track has changed
- File driveFile = drive.files().get(driveId).execute();
- if (SyncUtils.isDriveFileValid(driveFile, folderId)) {
- mergeFiles(track, driveFile);
- } else {
- /*
- * Track has a drive id, but the drive id is no longer valid.
- * E.g., the file is moved to another folder. Clear the drive id.
- */
- track.setDriveId("");
- track.setModifiedTime(-1L);
- myTracksProviderUtils.updateTrack(track);
+ // Handle the case the track has changed
+ File driveFile = drive.files().get(driveId).execute();
+ if (SyncUtils.isValid(driveFile, folderId)) {
+ mergeFiles(track, driveFile);
+ } else {
+ /*
+ * Track has a drive id, but the drive id is no longer valid.
+ * E.g., the file is moved to another folder. Clear the drive
+ * id.
+ */
+ track.setDriveId("");
+ track.setModifiedTime(-1L);
+ myTracksProviderUtils.updateTrack(track);
+ }
}
}
} while (cursor.moveToNext());
@@ -243,9 +241,9 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
private void insertNewTracks(String folderId) throws IOException {
Cursor cursor = null;
try {
- cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.NO_DRIVE_ID_QUERY, null, null);
+ cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.NO_DRIVE_ID_TRACKS_QUERY, null, null);
long recordingTrackId = PreferencesUtils.getLong(context, R.string.recording_track_id_key);
-
+
if (cursor != null && cursor.moveToFirst()) {
do {
Track track = myTracksProviderUtils.createTrack(cursor);
@@ -280,6 +278,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Track track = myTracksProviderUtils.getTrack(tracksIds[0]);
track.setDriveId(driveFile.getId());
track.setModifiedTime(driveFile.getModifiedDate().getValue());
+ track.setSharedWithMe(driveFile.getSharedWithMeDate() != null);
myTracksProviderUtils.updateTrack(track);
Log.d(TAG, "Add from Google Drive " + track.getName());
}
@@ -289,6 +288,30 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
}
}
+ /**
+ * Gets all the files from a request.
+ *
+ * @param request the request
+ * @return a map of file id to file
+ */
+ private Map getFiles(Files.List request) {
+ Map idToFileMap = new HashMap();
+ do {
+ try {
+ FileList files = request.execute();
+
+ for (File file : files.getItems()) {
+ idToFileMap.put(file.getId(), file);
+ }
+ request.setPageToken(files.getNextPageToken());
+ } catch (IOException e) {
+ Log.e(TAG, "IOException", e);
+ request.setPageToken(null);
+ }
+ } while (request.getPageToken() != null && request.getPageToken().length() > 0);
+ return idToFileMap;
+ }
+
/**
* Gets the Drive changes in the My Tracks folder. Includes deleted files.
*
@@ -310,7 +333,13 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
} else {
File file = change.getFile();
if (SyncUtils.isInFolder(file, folderId)) {
- changes.put(change.getFileId(), file.getLabels().getTrashed() ? null : file);
+ if (file.getLabels().getTrashed()) {
+ changes.put(change.getFileId(), null);
+ } else {
+ changes.put(change.getFileId(), file);
+ }
+ } else if (SyncUtils.isSharedWithMe(file)) {
+ changes.put(change.getFileId(), file);
}
}
}
@@ -359,6 +388,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Track newTrack = myTracksProviderUtils.getTrack(tracksIds[0]);
newTrack.setDriveId(driveFile.getId());
newTrack.setModifiedTime(driveModifiedTime);
+ newTrack.setSharedWithMe(driveFile.getSharedWithMeDate() != null);
myTracksProviderUtils.updateTrack(newTrack);
} else {
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 fb2d2b966..8bbc2198f 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
@@ -65,20 +65,38 @@ import java.util.Locale;
*/
public class SyncUtils {
+ // Request code to obtain Drive permission
public static final int DRIVE_PERMISSION_REQUEST_CODE = 1;
- public static final String DRIVE_IDS_QUERY = TracksColumns.DRIVEID + " IS NOT NULL AND "
+ // Get tracks with drive id
+ public static final String DRIVE_ID_TRACKS_QUERY = TracksColumns.DRIVEID + " IS NOT NULL AND "
+ TracksColumns.DRIVEID + "!=''";
- public static final String NO_DRIVE_ID_QUERY = TracksColumns.DRIVEID + " IS NULL OR "
+
+ // Get tracks with drive id that are owned by me, not tracks ashared with me.
+ public static final String DRIVE_ID_TRACKS_BY_ME_QUERY = DRIVE_ID_TRACKS_QUERY + " AND "
+ + TracksColumns.SHAREDWITHME + "!=1";
+
+ // Get tracks without drive id
+ public static final String NO_DRIVE_ID_TRACKS_QUERY = TracksColumns.DRIVEID + " IS NULL OR "
+ TracksColumns.DRIVEID + "=''";
+ // KML mime type
public static final String KML_MIME_TYPE = "application/vnd.google-earth.kml+xml";
- public static final String GET_KML_FILES_QUERY = "'%s' in parents and mimeType = '"
+
+ // Get My Tracks folder KML files
+ public static final String MY_TRACKS_FOLDER_FILES_QUERY = "'%s' in parents and mimeType = '"
+ KML_MIME_TYPE + "' and trashed = false";
-
+
+ // Get shared with me KML files
+ public static final String SHARED_WITH_ME_FILES_QUERY = "sharedWithMe and mimeType = '"
+ + KML_MIME_TYPE + "'";
+
+ // Folder mime type
private static final String FOLDER_MIME_TYPE = "application/vnd.google-apps.folder";
+
+ // Get My Tracks folder
@VisibleForTesting
- public static final String GET_MY_TRACKS_FOLDER_QUERY =
+ public static final String MY_TRACKS_FOLDER_QUERY =
"'root' in parents and title = '%s' and mimeType = '" + FOLDER_MIME_TYPE
+ "' and trashed = false";
@@ -164,7 +182,7 @@ public class SyncUtils {
}
return null;
}
-
+
/**
* Cancels any notification to request drive permission.
*
@@ -236,7 +254,7 @@ public class SyncUtils {
try {
String folderName = context.getString(R.string.my_tracks_app_name);
List list = drive.files()
- .list().setQ(String.format(Locale.US, GET_MY_TRACKS_FOLDER_QUERY, folderName));
+ .list().setQ(String.format(Locale.US, MY_TRACKS_FOLDER_QUERY, folderName));
FileList result = list.execute();
for (File file : result.getItems()) {
if (file.getTitle().equals(folderName)) {
@@ -254,21 +272,33 @@ public class SyncUtils {
}
/**
- * Returns true if the drive file is a kml file in the My Tracks folder and
- * not trashed.
+ * Returns true if the drive file is a Shared with me KML file.
+ *
+ * @param driveFile the drive file
+ */
+ public static boolean isSharedWithMe(File driveFile) {
+ if (driveFile == null) {
+ return false;
+ }
+ if (!SyncUtils.KML_MIME_TYPE.equals(driveFile.getMimeType())) {
+ return false;
+ }
+ return driveFile.getSharedWithMeDate() != null;
+ }
+
+ /**
+ * Returns true if the drive file is a valid KML file in the My Tracks folder
+ * and not trashed.
*
* @param driveFile the drive file
* @param folderId the My Tracks folder id
*/
- public static boolean isDriveFileValid(File driveFile, String folderId) {
- if (isInFolder(driveFile, folderId)) {
- return !driveFile.getLabels().getTrashed();
- }
- return false;
+ public static boolean isValid(File driveFile, String folderId) {
+ return isInFolder(driveFile, folderId) && !driveFile.getLabels().getTrashed();
}
/**
- * Returns true if the drive file is a kml file in the My Tracks folder.
+ * Returns true if the drive file is a KML file in the My Tracks folder.
*
* @param driveFile the drive file
* @param folderId the My Tracks folder id
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 795556459..e19d9af05 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java
@@ -121,6 +121,7 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON);
} else {
handleSync(false);
+ clearSyncState();
}
return false;
}
@@ -198,8 +199,8 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
@Override
public void onClick(DialogInterface d, int button) {
googleAccountPreference.setValue(newValue);
- clearSyncState();
handleSync(false);
+ clearSyncState();
updateUiByAccountName(newValue);
}
});
@@ -215,25 +216,25 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
}
/**
- * Clears the sync state.
+ * Clears the sync state. Assumes sync is turned off. Do not want clearing the
+ * state to cause sync activities.
*/
private void clearSyncState() {
- PreferencesUtils.setLong(this, R.string.drive_largest_change_id_key,
- PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT);
- PreferencesUtils.setString(
- this, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
-
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
Cursor cursor = null;
try {
- cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_IDS_QUERY, null, null);
+ cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_ID_TRACKS_QUERY, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
Track track = myTracksProviderUtils.createTrack(cursor);
- track.setDriveId("");
- track.setModifiedTime(-1L);
- track.setSharedWithMe(false);
- myTracksProviderUtils.updateTrack(track);
+ if (track.isSharedWithMe()) {
+ myTracksProviderUtils.deleteTrack(track.getId());
+ } else {
+ track.setDriveId("");
+ track.setModifiedTime(-1L);
+ track.setSharedWithMe(false);
+ myTracksProviderUtils.updateTrack(track);
+ }
} while (cursor.moveToNext());
}
} finally {
@@ -241,6 +242,12 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
cursor.close();
}
}
+ PreferencesUtils.setLong(this, R.string.drive_largest_change_id_key,
+ PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT);
+
+ // Clear the driveDeletedList last
+ PreferencesUtils.setString(
+ this, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
}
/**
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 3420e6ba3..f756b6077 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
@@ -138,7 +138,7 @@ public class SyncTestUtils {
}
String folderId = folder.getId();
return drive.files().list()
- .setQ(String.format(Locale.US, SyncUtils.GET_KML_FILES_QUERY, folderId)).execute()
+ .setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_FILES_QUERY, folderId)).execute()
.getItems();
}
@@ -330,7 +330,7 @@ public class SyncTestUtils {
try {
String folderName = context.getString(R.string.my_tracks_app_name);
com.google.api.services.drive.Drive.Files.List list = drive.files().list()
- .setQ(String.format(Locale.US, SyncUtils.GET_MY_TRACKS_FOLDER_QUERY, folderName));
+ .setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_QUERY, folderName));
FileList result = list.execute();
for (File file : result.getItems()) {
if (file.getTitle().equals(folderName)) {