Add retry when sending a track to Google Drive.

This commit is contained in:
Jimmy Shih
2013-02-05 14:37:47 -08:00
parent c0ec72f66a
commit 49d055ce36
3 changed files with 81 additions and 63 deletions
@@ -20,14 +20,16 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track; 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.AbstractSendAsyncTask;
import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; 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.Drive;
import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.Permission; import com.google.api.services.drive.model.Permission;
import android.accounts.Account; import android.accounts.Account;
import android.content.Context; import android.content.Context;
import android.util.Log;
import java.io.IOException; import java.io.IOException;
@@ -38,12 +40,10 @@ import java.io.IOException;
*/ */
public class SendDriveAsyncTask extends AbstractSendAsyncTask { public class SendDriveAsyncTask extends AbstractSendAsyncTask {
private static final String TAG = SendDriveAsyncTask.class.getSimpleName();
private final long trackId; private final long trackId;
private final Account account; private final Account account;
private final Context context;
private final String[] acl; private final String[] acl;
private final Context context;
private final MyTracksProviderUtils myTracksProviderUtils; private final MyTracksProviderUtils myTracksProviderUtils;
public SendDriveAsyncTask(SendDriveActivity activity, long trackId, Account account, String acl) { public SendDriveAsyncTask(SendDriveActivity activity, long trackId, Account account, String acl) {
@@ -68,18 +68,18 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
@Override @Override
protected boolean performTask() { protected boolean performTask() {
GoogleAccountCredential credential = SyncUtils.getCredential(context, account.name);
if (credential == null) {
return false;
}
Drive drive = SyncUtils.getDriveService(credential);
String folderId = SyncUtils.getMyTracksFolder(context, drive);
if (folderId == null) {
return false;
}
try { try {
GoogleAccountCredential credential = SyncUtils.getGoogleAccountCredential(
context, account.name);
if (credential == null) {
return false;
}
Drive drive = SyncUtils.getDriveService(credential);
String folderId = SyncUtils.getMyTracksFolder(context, drive);
if (folderId == null) {
return false;
}
Track track = myTracksProviderUtils.getTrack(trackId); Track track = myTracksProviderUtils.getTrack(trackId);
String driveId = track.getDriveId(); String driveId = track.getDriveId();
if (driveId != null && !driveId.equals("")) { if (driveId != null && !driveId.equals("")) {
@@ -91,6 +91,7 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
} }
track.setDriveId(""); track.setDriveId("");
track.setModifiedTime(-1L); track.setModifiedTime(-1L);
track.setSharedWithMe(false);
myTracksProviderUtils.updateTrack(track); myTracksProviderUtils.updateTrack(track);
} }
@@ -100,9 +101,16 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
} }
addPermission(drive, id); addPermission(drive, id);
return true; return true;
} catch (IOException e) { } catch (UserRecoverableAuthIOException e) {
Log.e(TAG, "IOException", e); SyncUtils.sendNotification(context, account.name, e.getIntent());
return false; return false;
} catch (IOException e) {
return retryTask();
} catch (UserRecoverableAuthException e) {
SyncUtils.sendNotification(context, account.name, e.getIntent());
return false;
} catch (GoogleAuthException e) {
return retryTask();
} }
} }
@@ -110,7 +118,7 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
protected void invalidateToken() {} protected void invalidateToken() {}
/** /**
* Adds permision. * Adds permission.
* *
* @param drive the drive * @param drive the drive
* @param driveId the drive id * @param driveId the drive id
@@ -104,12 +104,11 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
driveAccountName = account.name; driveAccountName = account.name;
} }
String folderId = SyncUtils.getMyTracksFolder(context, drive);
if (folderId == null) {
return;
}
try { try {
String folderId = SyncUtils.getMyTracksFolder(context, drive);
if (folderId == null) {
return;
}
long largestChangeId = PreferencesUtils.getLong( long largestChangeId = PreferencesUtils.getLong(
context, R.string.drive_largest_change_id_key); context, R.string.drive_largest_change_id_key);
if (largestChangeId == PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT) { if (largestChangeId == PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT) {
@@ -30,6 +30,7 @@ import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import com.google.api.client.extensions.android.http.AndroidHttp; 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.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent; import com.google.api.client.http.FileContent;
import com.google.api.client.json.gson.GsonFactory; import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive; import com.google.api.services.drive.Drive;
@@ -98,7 +99,7 @@ public class SyncUtils {
@VisibleForTesting @VisibleForTesting
public static final String MY_TRACKS_FOLDER_QUERY = public static final String MY_TRACKS_FOLDER_QUERY =
"'root' in parents and title = '%s' and mimeType = '" + FOLDER_MIME_TYPE "'root' in parents and title = '%s' and mimeType = '" + FOLDER_MIME_TYPE
+ "' and trashed = false and not sharedWithMe"; + "' and trashed = false";
private static final String TAG = SyncUtils.class.getSimpleName(); private static final String TAG = SyncUtils.class.getSimpleName();
private static final String SYNC_AUTHORITY = "com.google.android.maps.mytracks"; private static final String SYNC_AUTHORITY = "com.google.android.maps.mytracks";
@@ -129,16 +130,18 @@ public class SyncUtils {
}); });
} catch (UserRecoverableAuthException e) { } catch (UserRecoverableAuthException e) {
activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE); activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE);
} catch (IOException e) { } catch (GoogleAuthException e) {
Log.e(TAG, "IOException", e); Log.e(TAG, "GoogleAuthException", e);
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
permissionCallback.onFailure(); permissionCallback.onFailure();
} }
}); });
} catch (GoogleAuthException e) { } catch (UserRecoverableAuthIOException e) {
Log.e(TAG, "GoogleAuthException", e); activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE);
} catch (IOException e) {
Log.e(TAG, "IOException", e);
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -161,25 +164,14 @@ public class SyncUtils {
try { try {
return getGoogleAccountCredential(context, accountName); return getGoogleAccountCredential(context, accountName);
} catch (UserRecoverableAuthException e) { } catch (UserRecoverableAuthException e) {
Intent intent = e.getIntent(); sendNotification(context, accountName, e.getIntent());
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());
} catch (IOException e) {
Log.e(TAG, "IOException", e);
} catch (GoogleAuthException e) { } catch (GoogleAuthException e) {
Log.e(TAG, "GoogleAuthException", e); Log.e(TAG, "GoogleAuthException", e);
} } catch (UserRecoverableAuthIOException e) {
sendNotification(context, accountName, e.getIntent());
} catch (IOException e) {
Log.e(TAG, "IOException", e);
}
return null; return null;
} }
@@ -250,25 +242,20 @@ public class SyncUtils {
* @param context the context * @param context the context
* @param drive the drive * @param drive the drive
*/ */
public static String getMyTracksFolder(Context context, Drive drive) { public static String getMyTracksFolder(Context context, Drive drive) throws IOException {
try { String folderName = context.getString(R.string.my_tracks_app_name);
String folderName = context.getString(R.string.my_tracks_app_name); List list = drive.files()
List list = drive.files() .list().setQ(String.format(Locale.US, MY_TRACKS_FOLDER_QUERY, folderName));
.list().setQ(String.format(Locale.US, MY_TRACKS_FOLDER_QUERY, folderName)); FileList result = list.execute();
FileList result = list.execute(); for (File file : result.getItems()) {
for (File file : result.getItems()) { if (file.getTitle().equals(folderName)) {
if (file.getTitle().equals(folderName)) { return file.getId();
return file.getId();
}
} }
File file = new File();
file.setTitle(folderName);
file.setMimeType(FOLDER_MIME_TYPE);
return drive.files().insert(file).execute().getId();
} catch (IOException e) {
Log.e(TAG, "IOException", e);
return null;
} }
File file = new File();
file.setTitle(folderName);
file.setMimeType(FOLDER_MIME_TYPE);
return drive.files().insert(file).execute().getId();
} }
/** /**
@@ -364,6 +351,7 @@ public class SyncUtils {
String id = uploadedFile.getId(); String id = uploadedFile.getId();
track.setDriveId(id); track.setDriveId(id);
track.setModifiedTime(uploadedFile.getModifiedDate().getValue()); track.setModifiedTime(uploadedFile.getModifiedDate().getValue());
track.setSharedWithMe(false);
myTracksProviderUtils.updateTrack(track); myTracksProviderUtils.updateTrack(track);
return id; return id;
} finally { } finally {
@@ -417,7 +405,7 @@ public class SyncUtils {
* @param context the context * @param context the context
* @param accountName the account name * @param accountName the account name
*/ */
private static GoogleAccountCredential getGoogleAccountCredential( public static GoogleAccountCredential getGoogleAccountCredential(
Context context, String accountName) throws IOException, GoogleAuthException { Context context, String accountName) throws IOException, GoogleAuthException {
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2( GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
context, DriveScopes.DRIVE); context, DriveScopes.DRIVE);
@@ -426,6 +414,29 @@ public class SyncUtils {
return credential; return credential;
} }
/**
* 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());
}
/** /**
* Gets a file from a track. * Gets a file from a track.
* *