/* * Copyright (c) 2015 Jonas Kalderstam. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.nononsenseapps.notepad.util; import android.accounts.Account; import android.accounts.AccountManager; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import com.nononsenseapps.notepad.data.service.gtasks.GTasksSyncDelay; import com.nononsenseapps.notepad.R; import com.nononsenseapps.notepad.data.local.sql.MyContentProvider; import java.util.Calendar; /** * Helper methods related to Google Tasks synchronization. This should be the only place where * sync is requested/managed. */ public class SyncGtaskHelper { // Sync types public static final int MANUAL = 0; public static final int ONCHANGE = 2; public static final String KEY_LAST_SYNC = "lastSync"; public static void requestSyncIf(final Context context, final int TYPE) { if (!isGTasksConfigured(context)) { return; } switch (TYPE) { case MANUAL: forceGTaskSyncNow(context); break; case ONCHANGE: requestDelayedGTasksSync(context); break; } } public static boolean isGTasksConfigured(final Context context) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); final String accountName = prefs.getString(context.getString(R.string .const_preference_gtask_account_key), ""); final boolean syncEnabled = prefs.getBoolean(context.getString(R.string .const_preference_gtask_enabled_key), false); return syncEnabled & !accountName.isEmpty(); } /** * Finds and returns the account of the name given * * @param accountName email of google account * @return a Google Account */ public static Account getAccount(@NonNull AccountManager manager, @NonNull String accountName) { Account[] accounts = manager.getAccountsByType("com.google"); for (Account account : accounts) { if (account.name.equals(accountName)) { return account; } } return null; } /** * Removes account name from sharedpreferences if one is saved. */ @SuppressLint("CommitPrefEdits") public static void disableSync(@NonNull Context context) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences (context); sharedPreferences.edit().putBoolean(context.getString(R.string .const_preference_gtask_enabled_key), false).commit(); toggleSync(context, sharedPreferences); } /** * If the toggle is not successful in setting sync to on, removes account name from * sharedpreferences. * * @return the status of the sync after enabling/disabling it. */ public static boolean toggleSync(@NonNull Context context, @NonNull SharedPreferences sharedPreferences) { final boolean enabled = sharedPreferences.getBoolean(context.getString(R.string .const_preference_gtask_enabled_key), false); String accountName = sharedPreferences.getString(context.getString(R.string .const_preference_gtask_account_key), ""); boolean currentlyEnabled = false; if (!accountName.isEmpty()) { Account account = getAccount(AccountManager.get(context), accountName); if (account != null) { if (enabled) { // set syncable ContentResolver.setSyncAutomatically(account, MyContentProvider.AUTHORITY, true); ContentResolver.setIsSyncable(account, MyContentProvider.AUTHORITY, 1); // Also set sync frequency long pollFrequency = 3600; // Set periodic syncing ContentResolver.addPeriodicSync(account, MyContentProvider.AUTHORITY, Bundle .EMPTY, pollFrequency); currentlyEnabled = true; } else { ContentResolver.setSyncAutomatically(account, MyContentProvider.AUTHORITY, false); } } } if (!currentlyEnabled) { forgetAccountOnce(context, sharedPreferences); disableSyncOnce(context, sharedPreferences); } return currentlyEnabled; } /** * Returns true if at least 5 minutes have passed since last sync. */ public static boolean enoughTimeSinceLastSync(final Context context) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); // Let 5 mins elapse before sync on start again final long now = Calendar.getInstance().getTimeInMillis(); final long lastSync = prefs.getLong(KEY_LAST_SYNC, 0); final long fivemins = 5 * 60 * 1000; return fivemins < (now - lastSync); } /** * Disables gtask sync, but only if it's not already disabled (so * we don't call listeners on removal of already removed values) */ private static void disableSyncOnce(@NonNull Context context, @NonNull SharedPreferences sharedPreferences) { if (sharedPreferences.getBoolean(context.getString(R.string .const_preference_gtask_enabled_key), false)) { sharedPreferences.edit().putBoolean(context.getString(R.string .const_preference_gtask_enabled_key), false).apply(); } } /** * Removes the account name from shared preferences, but only if we have an account name (so * we don't call listeners on removal of already removed values) */ private static void forgetAccountOnce(@NonNull Context context, @NonNull SharedPreferences sharedPreferences) { if (sharedPreferences.contains(context.getString(R.string .const_preference_gtask_account_key))) { sharedPreferences.edit().remove(context.getString(R.string .const_preference_gtask_account_key)).apply(); } } /** * Request sync right now. */ private static void forceGTaskSyncNow(final Context context) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); // Do nothing if gtask not enabled if (!isGTasksConfigured(context)) { return; } final String accountName = prefs.getString(context.getString(R.string .const_preference_gtask_account_key), ""); if (!accountName.isEmpty()) { Account account = getAccount(AccountManager.get(context), accountName); // Don't start a new sync if one is already going if (!ContentResolver.isSyncActive(account, MyContentProvider.AUTHORITY)) { Bundle options = new Bundle(); // This will force a sync regardless of what the setting is // in accounts manager. Only use it here where the user has // manually desired a sync to happen NOW. options.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); options.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); ContentResolver.requestSync(account, MyContentProvider.AUTHORITY, options); // Set last sync time to now prefs.edit().putLong(KEY_LAST_SYNC, Calendar.getInstance().getTimeInMillis()) .apply(); } } } private static void requestDelayedGTasksSync(final Context context) { context.startService(new Intent(context, GTasksSyncDelay.class)); } }