From 29cffa96e6ee7493f789e4ca46079f5c6ebca4df Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Tue, 7 Jan 2014 17:02:02 -0800 Subject: [PATCH] Update sync to Google Drive setting --- MyTracks/res/values/keys.xml | 1 - MyTracks/res/values/strings.xml | 35 +-- MyTracks/res/xml/google_settings.xml | 27 -- MyTracks/res/xml/settings.xml | 8 +- .../fragments/EnableSyncDialogFragment.java | 1 - .../settings/GoogleSettingsActivity.java | 280 ------------------ .../mytracks/settings/SettingsActivity.java | 240 ++++++++++++++- .../endtoendtest/RunConfiguration.java | 32 +- .../endtoendtest/common/SettingTest.java | 85 +++--- .../endtoendtest/sync/SyncTestUtils.java | 89 +++--- 10 files changed, 348 insertions(+), 450 deletions(-) delete mode 100644 MyTracks/res/xml/google_settings.xml delete mode 100644 MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index 0447b6560..e69ecbde2 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -73,7 +73,6 @@ limitations under the License. settingsAdvanced settingsChart - settingsGoogle settingsMap settingsMapMediumDisplay settingsMapPercentageDisplay diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 400d5b39a..70c5043e6 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -1553,37 +1553,14 @@ limitations under the License. - - Accounts & sync - - - This will remove any association between your tracks and %1$s Google Drive. Google Drive sync - will be turned off. No tracks will be deleted on %1$s Google Drive. - - - Switch account? - - - Switch account + + No account found to sync to Google Drive All tracks will be synced to %1$s Google Drive diff --git a/MyTracks/res/xml/google_settings.xml b/MyTracks/res/xml/google_settings.xml deleted file mode 100644 index bcef69986..000000000 --- a/MyTracks/res/xml/google_settings.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/MyTracks/res/xml/settings.xml b/MyTracks/res/xml/settings.xml index 8f830cbc2..b8f5e938d 100644 --- a/MyTracks/res/xml/settings.xml +++ b/MyTracks/res/xml/settings.xml @@ -16,10 +16,10 @@ limitations under the License. --> - + entries = new ArrayList(); - List entryValues = new ArrayList(); - Account[] accounts = AccountManager.get(this).getAccountsByType(Constants.ACCOUNT_TYPE); - for (Account account : accounts) { - entries.add(account.name); - entryValues.add(account.name); - } - entries.add(getString(R.string.value_none)); - entryValues.add(PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); - - googleAccountPreference.setEntries(entries.toArray(new CharSequence[entries.size()])); - googleAccountPreference.setEntryValues(entryValues.toArray(new CharSequence[entries.size()])); - googleAccountPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String newGoogleAccount = (String) newValue; - String googleAccount = PreferencesUtils.getString( - GoogleSettingsActivity.this, R.string.google_account_key, - PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); - if (googleAccount == null - || googleAccount.equals(PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT)) { - updateUiByAccountName(newGoogleAccount); - return true; - } - if (!googleAccount.equals(newGoogleAccount)) { - Bundle newBundle = new Bundle(); - newBundle.putString(ACCOUNT_NAME_KEY, newGoogleAccount); - showDialog(DIALOG_CONFIRM_SWITCH_ACCOUNT, newBundle); - } - return false; - } - }); - - driveSyncPreference = (CheckBoxPreference) findPreference(getString(R.string.drive_sync_key)); - driveSyncPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if ((Boolean) newValue) { - showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON); - } else { - handleSync(false); - } - return false; - } - }); - - updateUiByAccountName(PreferencesUtils.getString( - this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT)); - } - - @Deprecated - public Object onRetainNonConfigurationInstance() { - if (asyncTask != null) { - asyncTask.setActivity(null); - } - return asyncTask; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case DRIVE_REQUEST_CODE: - SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.DRIVE_NOTIFICATION_ID); - if (resultCode == Activity.RESULT_OK) { - onDrivePermissionSuccess(); - } else { - onDrivePermissionFailure(); - } - break; - default: - super.onActivityResult(requestCode, resultCode, data); - } - } - - @Override - protected Dialog onCreateDialog(int id, Bundle bundle) { - Dialog dialog; - switch (id) { - case DIALOG_CONFIRM_SWITCH_ACCOUNT: - dialog = DialogUtils.createConfirmationDialog(this, - R.string.settings_google_account_confirm_title, - getString(R.string.settings_google_account_confirm_message), null); - break; - case DIALOG_CONFIRM_DRIVE_SYNC_ON: - dialog = DialogUtils.createConfirmationDialog(this, R.string.sync_drive_title, - getString(R.string.sync_drive_confirm_message), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int button) { - if (asyncTask == null) { - final String googleAccount = PreferencesUtils.getString( - GoogleSettingsActivity.this, R.string.google_account_key, - PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); - asyncTask = new CheckPermissionAsyncTask( - GoogleSettingsActivity.this, googleAccount, SendToGoogleUtils.DRIVE_SCOPE); - asyncTask.execute(); - } - } - }); - break; - default: - dialog = null; - } - return dialog; - } - - @Override - public void onCheckPermissionDone(String scope, boolean success, Intent userRecoverableIntent) { - asyncTask = null; - if (success) { - onDrivePermissionSuccess(); - } else { - if (userRecoverableIntent != null) { - startActivityForResult(userRecoverableIntent, DRIVE_REQUEST_CODE); - } else { - onDrivePermissionFailure(); - } - } - } - - private void onDrivePermissionSuccess() { - handleSync(true); - } - - private void onDrivePermissionFailure() { - Toast.makeText( - GoogleSettingsActivity.this, R.string.send_google_no_account_message, Toast.LENGTH_LONG) - .show(); - } - - @Override - protected void onPrepareDialog(int id, Dialog dialog, Bundle bundle) { - AlertDialog alertDialog = (AlertDialog) dialog; - String googleAccount = PreferencesUtils.getString( - this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); - switch (id) { - case DIALOG_CONFIRM_SWITCH_ACCOUNT: - final String newValue = bundle.getString(ACCOUNT_NAME_KEY); - alertDialog.setMessage( - getString(R.string.settings_google_account_confirm_message, googleAccount)); - alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.generic_yes), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int button) { - googleAccountPreference.setValue(newValue); - handleSync(false); - updateUiByAccountName(newValue); - } - }); - break; - case DIALOG_CONFIRM_DRIVE_SYNC_ON: - alertDialog.setMessage(getString(R.string.sync_drive_confirm_message, googleAccount, - getString(R.string.my_tracks_app_name))); - break; - default: - } - super.onPrepareDialog(id, dialog, bundle); - } - - /** - * Handles sync. - * - * @param value true to sync - */ - private void handleSync(boolean value) { - driveSyncPreference.setChecked(value); - - // Turn off everything - SyncUtils.disableSync(this); - - if (value) { - - // Turn on sync - ContentResolver.setMasterSyncAutomatically(true); - - // Enable sync for account - String googleAccount = PreferencesUtils.getString( - this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); - Account[] accounts = AccountManager.get(this).getAccountsByType(Constants.ACCOUNT_TYPE); - for (Account account : accounts) { - if (account.name.equals(googleAccount)) { - SyncUtils.enableSync(account); - break; - } - } - } else { - SyncUtils.clearSyncState(this); - } - } - - /** - * Updates UI by account. - * - * @param accountName the account name - */ - private void updateUiByAccountName(String accountName) { - boolean hasAccount = !PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT.equals(accountName); - googleAccountPreference.setSummary( - hasAccount ? accountName : getString(R.string.value_unknown)); - driveSyncPreference.setEnabled(hasAccount); - driveSyncPreference.setSummaryOn( - getString(R.string.settings_google_drive_sync_summary_on, accountName)); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java index 35280417c..0b922e176 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java @@ -16,29 +16,90 @@ package com.google.android.apps.mytracks.settings; +import com.google.android.apps.mytracks.Constants; +import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; +import com.google.android.apps.mytracks.io.sync.SyncUtils; +import com.google.android.apps.mytracks.services.tasks.CheckPermissionAsyncTask; +import com.google.android.apps.mytracks.services.tasks.CheckPermissionAsyncTask.CheckPermissionCaller; +import com.google.android.apps.mytracks.util.DialogUtils; import com.google.android.apps.mytracks.util.IntentUtils; +import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; +import android.accounts.Account; +import android.accounts.AccountManager; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.ContentResolver; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; +import android.widget.Toast; /** * An activity for accessing settings. * - * @author Leif Hendrik Wilden - * @author Rodrigo Damazio + * @author Jimmy Shih */ -public class SettingsActivity extends AbstractSettingsActivity { +public class SettingsActivity extends AbstractSettingsActivity implements CheckPermissionCaller { + + private static final int DIALOG_NO_ACCOUNT = 0; + private static final int DIALOG_CHOOSE_ACCOUNT = 1; + private static final int DIALOG_CONFIRM_DRIVE_SYNC_ON = 2; + + private static final int DRIVE_REQUEST_CODE = 0; + + private CheckBoxPreference syncDrivePreference; + private CheckPermissionAsyncTask syncDriveAsyncTask; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); + + Object retained = getLastNonConfigurationInstance(); + if (retained instanceof CheckPermissionAsyncTask) { + syncDriveAsyncTask = (CheckPermissionAsyncTask) retained; + syncDriveAsyncTask.setActivity(this); + } + addPreferencesFromResource(R.xml.settings); - configPreference(R.string.settings_google_key, GoogleSettingsActivity.class); + syncDrivePreference = (CheckBoxPreference) findPreference(getString(R.string.drive_sync_key)); + syncDrivePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if ((Boolean) newValue) { + Account[] accounts = AccountManager.get(SettingsActivity.this) + .getAccountsByType(Constants.ACCOUNT_TYPE); + if (accounts.length == 0) { + PreferencesUtils.setString(SettingsActivity.this, R.string.google_account_key, + PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + handleSync(false); + showDialog(DIALOG_NO_ACCOUNT); + } else if (accounts.length == 1) { + PreferencesUtils.setString( + SettingsActivity.this, R.string.google_account_key, accounts[0].name); + showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON); + } else { + showDialog(DIALOG_CHOOSE_ACCOUNT); + } + } else { + PreferencesUtils.setString(SettingsActivity.this, R.string.google_account_key, + PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + handleSync(false); + } + return false; + } + }); + updateSyncDriveSummary(); + configPreference(R.string.settings_map_key, MapSettingsActivity.class); configPreference(R.string.settings_chart_key, ChartSettingsActivity.class); configPreference(R.string.settings_stats_key, StatsSettingsActivity.class); @@ -47,6 +108,177 @@ public class SettingsActivity extends AbstractSettingsActivity { configPreference(R.string.settings_advanced_key, AdvancedSettingsActivity.class); } + @Deprecated + public Object onRetainNonConfigurationInstance() { + if (syncDriveAsyncTask != null) { + syncDriveAsyncTask.setActivity(null); + } + return syncDriveAsyncTask; + } + + @Override + protected Dialog onCreateDialog(int id, Bundle bundle) { + final Dialog dialog; + switch (id) { + case DIALOG_NO_ACCOUNT: + dialog = new AlertDialog.Builder(this).setMessage( + R.string.settings_google_drive_sync_no_account) + .setTitle(R.string.send_google_no_account_title) + .setPositiveButton(R.string.generic_ok, null).create(); + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + + @Override + public void onShow(DialogInterface dialogInterface) { + DialogUtils.setDialogTitleDivider(SettingsActivity.this, dialog); + } + }); + break; + case DIALOG_CHOOSE_ACCOUNT: + Account[] accounts = AccountManager.get(SettingsActivity.this) + .getAccountsByType(Constants.ACCOUNT_TYPE); + final String[] choices = new String[accounts.length]; + for (int i = 0; i < accounts.length; i++) { + choices[i] = accounts[i].name; + } + dialog = new AlertDialog.Builder(this).setNegativeButton(R.string.generic_cancel, null) + .setPositiveButton(R.string.generic_ok, new OnClickListener() { + @SuppressWarnings("deprecation") + @Override + public void onClick(DialogInterface dialogInterface, int which) { + int position = ((AlertDialog) dialogInterface).getListView() + .getCheckedItemPosition(); + PreferencesUtils.setString( + SettingsActivity.this, R.string.google_account_key, choices[position]); + dismissDialog(DIALOG_CHOOSE_ACCOUNT); + showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON); + } + }).setSingleChoiceItems(choices, 0, null) + .setTitle(R.string.send_google_choose_account_title).create(); + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + + @Override + public void onShow(DialogInterface dialogInterface) { + DialogUtils.setDialogTitleDivider(SettingsActivity.this, dialog); + } + }); + break; + case DIALOG_CONFIRM_DRIVE_SYNC_ON: + dialog = DialogUtils.createConfirmationDialog(this, R.string.sync_drive_title, + getString(R.string.sync_drive_confirm_message), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface d, int button) { + if (syncDriveAsyncTask == null) { + String googleAccount = PreferencesUtils.getString(SettingsActivity.this, + R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + syncDriveAsyncTask = new CheckPermissionAsyncTask( + SettingsActivity.this, googleAccount, SendToGoogleUtils.DRIVE_SCOPE); + syncDriveAsyncTask.execute(); + } + } + }); + break; + default: + dialog = null; + } + return dialog; + } + + @SuppressWarnings("deprecation") + @Override + protected void onPrepareDialog(int id, Dialog dialog, Bundle bundle) { + if (id == DIALOG_CONFIRM_DRIVE_SYNC_ON) { + AlertDialog alertDialog = (AlertDialog) dialog; + String googleAccount = PreferencesUtils.getString( + this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + alertDialog.setMessage(getString(R.string.sync_drive_confirm_message, googleAccount, + getString(R.string.my_tracks_app_name))); + } + super.onPrepareDialog(id, dialog, bundle); + } + + @Override + public void onCheckPermissionDone(String scope, boolean success, Intent userRecoverableIntent) { + syncDriveAsyncTask = null; + if (success) { + onDrivePermissionSuccess(); + } else { + if (userRecoverableIntent != null) { + startActivityForResult(userRecoverableIntent, DRIVE_REQUEST_CODE); + } else { + onDrivePermissionFailure(); + } + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case DRIVE_REQUEST_CODE: + SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.DRIVE_NOTIFICATION_ID); + if (resultCode == Activity.RESULT_OK) { + onDrivePermissionSuccess(); + } else { + onDrivePermissionFailure(); + } + break; + default: + super.onActivityResult(requestCode, resultCode, data); + } + } + + private void onDrivePermissionSuccess() { + handleSync(true); + } + + private void onDrivePermissionFailure() { + Toast.makeText( + SettingsActivity.this, R.string.settings_google_drive_sync_no_account, Toast.LENGTH_LONG) + .show(); + } + + /** + * Handles sync. + * + * @param value true to sync + */ + private void handleSync(boolean value) { + syncDrivePreference.setChecked(value); + updateSyncDriveSummary(); + + // Turn off everything + SyncUtils.disableSync(this); + + if (value) { + + // Turn on sync + ContentResolver.setMasterSyncAutomatically(true); + + // Enable sync for account + String googleAccount = PreferencesUtils.getString( + this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + Account[] accounts = AccountManager.get(this).getAccountsByType(Constants.ACCOUNT_TYPE); + for (Account account : accounts) { + if (account.name.equals(googleAccount)) { + SyncUtils.enableSync(account); + break; + } + } + } else { + SyncUtils.clearSyncState(this); + } + } + + /** + * Updates UI by account. + */ + private void updateSyncDriveSummary() { + String googleAccount = PreferencesUtils.getString( + this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT); + boolean hasAccount = !PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT.equals(googleAccount); + syncDrivePreference.setSummaryOn( + hasAccount ? getString(R.string.settings_google_drive_sync_summary_on, googleAccount) : ""); + } + /** * Configures a preference by starting a new activity when it is clicked. * diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/RunConfiguration.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/RunConfiguration.java index 6ece55d4e..cebdfb771 100644 --- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/RunConfiguration.java +++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/RunConfiguration.java @@ -15,7 +15,6 @@ */ package com.google.android.apps.mytracks.endtoendtest; -import com.google.android.maps.mytracks.R; /** * Places all the test configuration in this class. @@ -51,20 +50,21 @@ public class RunConfiguration { * @return true means can run sync tests in this device */ public static boolean canRunSyncTest() { - EndToEndTestUtils.findMenuItem( - EndToEndTestUtils.activityMytracks.getString(R.string.menu_settings), true); - EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks - .getString(R.string.settings_google)); - EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks - .getString(R.string.settings_google_account_title)); - boolean canRunSyncE2ETest = EndToEndTestUtils.SOLO.waitForText(GoogleUtils.ACCOUNT_NAME_1, 1, - EndToEndTestUtils.SHORT_WAIT_TIME) - && EndToEndTestUtils.SOLO.waitForText(GoogleUtils.ACCOUNT_NAME_2, 1, - EndToEndTestUtils.TINY_WAIT_TIME); - EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks - .getString(R.string.generic_cancel)); - EndToEndTestUtils.SOLO.goBack(); - EndToEndTestUtils.SOLO.goBack(); - return canRunSyncE2ETest; + return true; +// EndToEndTestUtils.findMenuItem( +// EndToEndTestUtils.activityMytracks.getString(R.string.menu_settings), true); +// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks +// .getString(R.string.settings_google)); +// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks +// .getString(R.string.settings_google_account_title)); +// boolean canRunSyncE2ETest = EndToEndTestUtils.SOLO.waitForText(GoogleUtils.ACCOUNT_NAME_1, 1, +// EndToEndTestUtils.SHORT_WAIT_TIME) +// && EndToEndTestUtils.SOLO.waitForText(GoogleUtils.ACCOUNT_NAME_2, 1, +// EndToEndTestUtils.TINY_WAIT_TIME); +// EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.activityMytracks +// .getString(R.string.generic_cancel)); +// EndToEndTestUtils.SOLO.goBack(); +// EndToEndTestUtils.SOLO.goBack(); +// return canRunSyncE2ETest; } } diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java index 2248bbf01..913be29e5 100644 --- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java +++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java @@ -18,7 +18,6 @@ package com.google.android.apps.mytracks.endtoendtest.common; import com.google.android.apps.mytracks.ChartView; 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.util.PreferencesUtils; import com.google.android.maps.mytracks.R; @@ -363,48 +362,48 @@ public class SettingTest extends ActivityInstrumentationTestCase2