From 774a19ae839752e154e9b9cb01c7c8d0487fd878 Mon Sep 17 00:00:00 2001 From: Ricki Hirner Date: Wed, 1 Feb 2017 01:14:19 +0100 Subject: [PATCH] AccountSettingsActivity: use loader * use Loader for AccountSettingsActivity sync intervals (fixes Android 7 display "issues") * SyncManager: allow prepare() to skip synchronization --- .../syncadapter/CalendarSyncManager.java | 3 +- .../syncadapter/ContactsSyncManager.java | 4 +- .../davdroid/syncadapter/SyncManager.java | 10 ++- .../davdroid/ui/AccountSettingsActivity.java | 85 +++++++++++++++---- 4 files changed, 81 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java index 345ddaff..28b81073 100644 --- a/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java +++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java @@ -61,8 +61,9 @@ public class CalendarSyncManager extends SyncManager { } @Override - protected void prepare() throws ContactsStorageException { + protected boolean prepare() throws ContactsStorageException { journal = new JournalEntryManager(httpClient, remote, localCalendar().getName()); + return true; } @Override diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java index 05956620..751b0931 100644 --- a/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java +++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java @@ -75,7 +75,7 @@ public class ContactsSyncManager extends SyncManager { } @Override - protected void prepare() throws ContactsStorageException, CalendarStorageException { + protected boolean prepare() throws ContactsStorageException, CalendarStorageException { // prepare local address book localCollection = new LocalAddressBook(account, provider); LocalAddressBook localAddressBook = localAddressBook(); @@ -88,6 +88,8 @@ public class ContactsSyncManager extends SyncManager { localAddressBook.updateSettings(values); journal = new JournalEntryManager(httpClient, remote, info.url); + + return true; } @Override diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java index e82d1c46..43966e27 100644 --- a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java +++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java @@ -124,7 +124,10 @@ abstract public class SyncManager { String syncPhase = SYNC_PHASE_PREPARE; try { App.log.info("Sync phase: " + syncPhase); - prepare(); + if (!prepare()) { + App.log.info("No reason to synchronize, aborting"); + return; + } if (Thread.interrupted()) return; @@ -219,7 +222,10 @@ abstract public class SyncManager { } - abstract protected void prepare() throws ContactsStorageException, CalendarStorageException; + /** Prepares synchronization (for instance, allocates necessary resources). + * @return whether actual synchronization is required / can be made. true = synchronization + * shall be continued, false = synchronization can be skipped */ + abstract protected boolean prepare() throws ContactsStorageException, CalendarStorageException; abstract protected void processSyncEntry(SyncEntry cEntry) throws IOException, ContactsStorageException, CalendarStorageException, InvalidCalendarException; diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java index de6f973f..499ba60b 100644 --- a/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java +++ b/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java @@ -9,11 +9,17 @@ package at.bitfire.davdroid.ui; import android.accounts.Account; +import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; +import android.content.SyncStatusObserver; import android.os.Bundle; import android.provider.CalendarContract; import android.provider.ContactsContract; +import android.support.v4.app.LoaderManager; import android.support.v4.app.NavUtils; +import android.support.v4.content.AsyncTaskLoader; +import android.support.v4.content.Loader; import android.support.v7.app.AppCompatActivity; import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.ListPreference; @@ -23,10 +29,7 @@ import android.support.v7.preference.SwitchPreferenceCompat; import android.text.TextUtils; import android.view.MenuItem; -import java.util.logging.Level; - import at.bitfire.davdroid.AccountSettings; -import at.bitfire.davdroid.App; import at.bitfire.davdroid.InvalidAccountException; import at.bitfire.davdroid.R; import at.bitfire.davdroid.ui.setup.DetectConfigurationFragment; @@ -66,7 +69,7 @@ public class AccountSettingsActivity extends AppCompatActivity { } - public static class AccountSettingsFragment extends PreferenceFragmentCompat { + public static class AccountSettingsFragment extends PreferenceFragmentCompat implements LoaderManager.LoaderCallbacks { Account account; @Override @@ -74,7 +77,8 @@ public class AccountSettingsActivity extends AppCompatActivity { super.onCreate(savedInstanceState); account = getArguments().getParcelable(EXTRA_ACCOUNT); - refresh(); + + getLoaderManager().initLoader(0, getArguments(), this); } @Override @@ -82,13 +86,14 @@ public class AccountSettingsActivity extends AppCompatActivity { addPreferencesFromResource(R.xml.settings_account); } - public void refresh() { - final AccountSettings settings; + @Override + public Loader onCreateLoader(int id, Bundle args) { + return new AccountSettingsLoader(getContext(), (Account)args.getParcelable(EXTRA_ACCOUNT)); + } - try { - settings = new AccountSettings(getActivity(), account); - } catch(InvalidAccountException e) { - App.log.log(Level.INFO, "Account is invalid or doesn't exist (anymore)", e); + @Override + public void onLoadFinished(Loader loader, final AccountSettings settings) { + if (settings == null) { getActivity().finish(); return; } @@ -100,7 +105,7 @@ public class AccountSettingsActivity extends AppCompatActivity { public boolean onPreferenceChange(Preference preference, Object newValue) { LoginCredentials credentials = newValue != null ? new LoginCredentials(account.name, (String) newValue) : null; LoginCredentialsChangeFragment.newInstance(account, credentials).show(getFragmentManager(), null); - refresh(); + getLoaderManager().restartLoader(0, getArguments(), AccountSettingsFragment.this); return false; } }); @@ -118,7 +123,7 @@ public class AccountSettingsActivity extends AppCompatActivity { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { settings.setSyncInterval(ContactsContract.AUTHORITY, Long.parseLong((String)newValue)); - refresh(); + getLoaderManager().restartLoader(0, getArguments(), AccountSettingsFragment.this); return false; } }); @@ -139,7 +144,7 @@ public class AccountSettingsActivity extends AppCompatActivity { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { settings.setSyncInterval(CalendarContract.AUTHORITY, Long.parseLong((String)newValue)); - refresh(); + getLoaderManager().restartLoader(0, getArguments(), AccountSettingsFragment.this); return false; } }); @@ -160,7 +165,7 @@ public class AccountSettingsActivity extends AppCompatActivity { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, Long.parseLong((String)newValue)); - refresh(); + getLoaderManager().restartLoader(0, getArguments(), AccountSettingsFragment.this); return false; } }); @@ -175,7 +180,7 @@ public class AccountSettingsActivity extends AppCompatActivity { @Override public boolean onPreferenceChange(Preference preference, Object wifiOnly) { settings.setSyncWiFiOnly((Boolean)wifiOnly); - refresh(); + getLoaderManager().restartLoader(0, getArguments(), AccountSettingsFragment.this); return false; } }); @@ -192,11 +197,57 @@ public class AccountSettingsActivity extends AppCompatActivity { public boolean onPreferenceChange(Preference preference, Object newValue) { String ssid = (String)newValue; settings.setSyncWifiOnlySSID(!TextUtils.isEmpty(ssid) ? ssid : null); - refresh(); + getLoaderManager().restartLoader(0, getArguments(), AccountSettingsFragment.this); return false; } }); } + + @Override + public void onLoaderReset(Loader loader) { + } + + } + + + private static class AccountSettingsLoader extends AsyncTaskLoader implements SyncStatusObserver { + + final Account account; + Object listenerHandle; + + public AccountSettingsLoader(Context context, Account account) { + super(context); + this.account = account; + } + + @Override + protected void onStartLoading() { + forceLoad(); + + listenerHandle = ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, this); + } + + @Override + protected void onStopLoading() { + ContentResolver.removeStatusChangeListener(listenerHandle); + } + + @Override + public AccountSettings loadInBackground() { + AccountSettings settings; + try { + settings = new AccountSettings(getContext(), account); + } catch(InvalidAccountException e) { + return null; + } + return settings; + } + + @Override + public void onStatusChanged(int which) { + forceLoad(); + } + } }