/* * 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.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.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.googleapis.extensions.android.gms.auth.GoogleAccountCredential; import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; import com.google.api.services.drive.Drive; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.Permission; import com.google.api.services.drive.model.PermissionList; import android.accounts.Account; import android.content.Context; import java.io.IOException; /** * AsyncTask to send a track to Google Drive. * * @author Jimmy Shih */ public class SendDriveAsyncTask extends AbstractSendAsyncTask { private final long trackId; private final Account account; private final String[] acl; private final boolean isPublic; private final Context context; private final MyTracksProviderUtils myTracksProviderUtils; public SendDriveAsyncTask( SendDriveActivity activity, long trackId, Account account, String acl, boolean isPublic) { super(activity); this.trackId = trackId; this.account = account; if (acl != null) { this.acl = acl.split(","); } else { this.acl = null; } this.isPublic = isPublic; context = activity.getApplicationContext(); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context); } @Override protected void closeConnection() {} @Override protected boolean performTask() { try { GoogleAccountCredential credential = SendToGoogleUtils.getGoogleAccountCredential( context, account.name, SendToGoogleUtils.DRIVE_SCOPE); if (credential == null) { return false; } Drive drive = SyncUtils.getDriveService(credential); File folder = SyncUtils.getMyTracksFolder(context, drive); if (folder == null) { return false; } String folderId = folder.getId(); if (folderId == null) { return false; } Track track = myTracksProviderUtils.getTrack(trackId); String driveId = track.getDriveId(); String syncAccount = PreferencesUtils.getString( context, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); boolean sameAccount = account.name.equals(syncAccount); if (sameAccount && driveId != null && !driveId.equals("")) { File driveFile = drive.files().get(driveId).execute(); if (driveFile != null && updateDriveFile(drive, driveFile, folderId, track)) { addPermission(drive, driveFile); return true; } // clear sync state SyncUtils.updateTrack(myTracksProviderUtils, track, null); } // insert new drive file File file = SyncUtils.insertDriveFile( drive, folderId, context, myTracksProviderUtils, track, false, sameAccount); if (file == null) { return false; } addPermission(drive, file); return true; } catch (UserRecoverableAuthException e) { 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(); } } /** * Updates a drive file using info from a track. Returns true if successful. * * @param drive the drive * @param driveFile the drive file * @param folderId the folder id of the drive file * @param track the track */ private boolean updateDriveFile(Drive drive, File driveFile, String folderId, Track track) throws IOException { if (!SyncUtils.isInMyTracksAndValid(driveFile, folderId)) { return false; } long driveModifiedTime = driveFile.getModifiedDate().getValue(); long modifiedTime = track.getModifiedTime(); if (driveModifiedTime != modifiedTime) { return SyncUtils.updateDriveFile( drive, driveFile, context, myTracksProviderUtils, track, true); } return true; } @Override protected void invalidateToken() {} /** * Adds permission. * * @param drive the drive * @param file the drive file */ private void addPermission(Drive drive, File file) throws IOException { if (isPublic) { boolean hasPublic = false; PermissionList permissionList = drive.permissions().list(file.getId()).execute(); for (Permission permission : permissionList.getItems()) { String role = permission.getRole(); if (role.equals("reader") || role.equals("writer")) { if (permission.getType().equals("anyone")) { hasPublic = true; break; } } } if (!hasPublic) { Permission permission = new Permission(); permission.setRole("reader"); permission.setType("anyone"); permission.setValue(""); drive.permissions().insert(file.getId(), permission).execute(); } shareUrl = file.getAlternateLink(); } if (acl != null) { for (String email : acl) { email = email.trim(); if (!email.equals("")) { Permission permission = new Permission(); permission.setRole("reader"); permission.setType("user"); permission.setValue(email); drive.permissions().insert(file.getId(), permission).execute(); } } } } }