Also sync "Shared with me" KML files.

This commit is contained in:
Jimmy Shih
2013-02-02 13:16:04 -08:00
parent 0fac9767fe
commit f26a8799fa
7 changed files with 144 additions and 78 deletions
+5 -5
View File
@@ -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.
</string>
<string name="settings_google_account_title"
translation_description="In the 'Google' settings, the option to switch Google account.
@@ -1747,9 +1748,8 @@ limitations under the License.
%1$s account name. E.g., 'foo@foo.com'.
%2$s folder name. E.g., 'My Tracks'.">
Check the files in %1$s Google Drive &#8216;%2$s&#8217; 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 &#8216;%2$s&#8217; folder will be treated as new. If not
desired, move the files to a different folder beforehand.
</string>
<string name="settings_google_drive_sync_summary_on"
translation_description="In the 'Google' settings, the summary for the 'Sync Google Drive'
@@ -208,7 +208,7 @@ public class MyTracksProvider extends ContentProvider {
getContext(), R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT);
if (driveSync) {
driveIds = where != null ? getDriveIds(null, where, selectionArgs)
: getDriveIds(new String[] { TracksColumns.DRIVEID }, SyncUtils.DRIVE_IDS_QUERY, null);
: getDriveIds(new String[] { TracksColumns.DRIVEID }, SyncUtils.DRIVE_ID_TRACKS_BY_ME_QUERY, null);
}
}
@@ -84,11 +84,10 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
String driveId = track.getDriveId();
if (driveId != null && !driveId.equals("")) {
File driveFile = drive.files().get(driveId).execute();
if (SyncUtils.isDriveFileValid(driveFile, folderId)) {
if (SyncUtils.updateDriveFile(context, myTracksProviderUtils, drive, driveFile, track)) {
addPermission(drive, driveId);
return true;
}
if (SyncUtils.isValid(driveFile, folderId)
&& SyncUtils.updateDriveFile(context, myTracksProviderUtils, drive, driveFile, track)) {
addPermission(drive, driveId);
return true;
}
track.setDriveId("");
track.setModifiedTime(-1L);
@@ -134,27 +134,17 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
About about = drive.about().get().setFields(ABOUT_GET_FIELDS).execute();
long largestChangeId = about.getLargestChangeId();
// Get all drive files
Files.List request = drive.files()
.list().setQ(String.format(Locale.US, SyncUtils.GET_KML_FILES_QUERY, folderId));
Map<String, File> idToFileMap = new HashMap<String, File>();
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<String, File> 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<String, File> getFiles(Files.List request) {
Map<String, File> idToFileMap = new HashMap<String, File>();
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 {
@@ -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
@@ -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);
}
/**
@@ -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)) {