From b17a3bc4e8a77905ca567f3876c4e37191d7aae5 Mon Sep 17 00:00:00 2001 From: Sandeep Siddhartha Date: Mon, 13 Oct 2014 14:49:02 -0700 Subject: [PATCH] Move sync policy related code out of account settings Bug: 17981687 Bug: 17464069 Change-Id: I0ae3400564fd346cc84af74dfef65f01cc1ce6a8 --- .../accounts/AccountStateChangedListener.java | 66 +++++++++++++++++ .../settings/AccountsSettingsFragment.java | 55 +++------------ .../AccountsSettingsFragmentTests.java | 70 ------------------- 3 files changed, 76 insertions(+), 115 deletions(-) create mode 100644 java-overridable/src/com/android/inputmethod/latin/accounts/AccountStateChangedListener.java diff --git a/java-overridable/src/com/android/inputmethod/latin/accounts/AccountStateChangedListener.java b/java-overridable/src/com/android/inputmethod/latin/accounts/AccountStateChangedListener.java new file mode 100644 index 000000000..c0a599c6e --- /dev/null +++ b/java-overridable/src/com/android/inputmethod/latin/accounts/AccountStateChangedListener.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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.android.inputmethod.latin.accounts; + +import android.support.annotation.NonNull; + +import javax.annotation.Nullable; + +/** + * Handles changes to account used to sign in to the keyboard. + * e.g. account switching/sign-in/sign-out from the keyboard + * user toggling the sync preference. + */ +public class AccountStateChangedListener { + + /** + * Called when the current account being used in keyboard is signed out. + * + * @param oldAccount the account that was signed out of. + */ + public static void onAccountSignedOut(@NonNull String oldAccount) { + } + + /** + * Called when the user signs-in to the keyboard. + * This may be called when the user switches accounts to sign in with a different account. + * + * @param oldAccount the previous account that was being used for sign-in. + * May be null for a fresh sign-in. + * @param newAccount the account being used for sign-in. + */ + public static void onAccountSignedIn(@Nullable String oldAccount, @NonNull String newAccount) { + } + + /** + * Called when the user toggles the sync preference. + * + * @param account the account being used for sync. + * @param syncEnabled indicates whether sync has been enabled or not. + */ + public static void onSyncPreferenceChanged(@Nullable String account, boolean syncEnabled) { + } + + /** + * Forces an immediate sync to happen. + * This should only be used for debugging purposes. + * + * @param account the account to use for sync. + */ + public static void forceSync(@Nullable String account) { + } +} diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java index 5e6521fc4..4bd15d037 100644 --- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java @@ -19,9 +19,7 @@ package com.android.inputmethod.latin.settings; import static com.android.inputmethod.latin.settings.LocalSettingsConstants.PREF_ACCOUNT_NAME; import static com.android.inputmethod.latin.settings.LocalSettingsConstants.PREF_ENABLE_CLOUD_SYNC; -import android.accounts.Account; import android.app.AlertDialog; -import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; @@ -37,6 +35,7 @@ import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.accounts.LoginAccountUtils; +import com.android.inputmethod.latin.accounts.AccountStateChangedListener; import com.android.inputmethod.latin.define.ProductionFlags; import javax.annotation.Nullable; @@ -52,7 +51,6 @@ import javax.annotation.Nullable; public final class AccountsSettingsFragment extends SubScreenFragment { private static final String PREF_SYNC_NOW = "pref_beanstalk"; - @UsedForTesting static final String AUTHORITY = "com.android.inputmethod.latin.provider"; static final String PREF_ACCCOUNT_SWITCHER = "account_switcher"; private final DialogInterface.OnClickListener mAccountChangedListener = @@ -111,7 +109,8 @@ public final class AccountsSettingsFragment extends SubScreenFragment { prefs.getString(PREF_ACCOUNT_NAME, null)); } else if (TextUtils.equals(key, PREF_ENABLE_CLOUD_SYNC)) { final boolean syncEnabled = prefs.getBoolean(PREF_ENABLE_CLOUD_SYNC, false); - updateSyncPolicy(syncEnabled, getSignedInAccountName()); + AccountStateChangedListener.onSyncPreferenceChanged( + getSignedInAccountName(), syncEnabled); } } @@ -177,36 +176,6 @@ public final class AccountsSettingsFragment extends SubScreenFragment { syncPreference.setSummary(R.string.cloud_sync_summary_disabled_signed_out); } - /** - * Given a non-null accountToUse, this method looks at the enabled value to either - * set or unset the syncable property of the sync authority. - * If the account is null, this method is a no-op currently, but we may want - * to perform some cleanup in the future. - * - * @param enabled indicates whether the sync preference is enabled or not. - * @param accountToUse indicaes the account to be used for sync, or null if the user - * is not logged in. - */ - @UsedForTesting - void updateSyncPolicy(boolean enabled, @Nullable String accountToUse) { - if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) { - return; - } - - if (accountToUse != null) { - final int syncable = enabled ? 1 : 0; - ContentResolver.setIsSyncable( - new Account(accountToUse, LoginAccountUtils.ACCOUNT_TYPE), - AUTHORITY, syncable); - // TODO: Also add a periodic sync here. - // See ContentResolver.addPeriodicSync - } else { - // Without an account, we cannot really set the sync to off. - // Hopefully the account sign-out listener would have taken care of that for us. - // But cases such as clear data are still not handled cleanly. - } - } - @Nullable String getSignedInAccountName() { return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null); @@ -261,22 +230,20 @@ public final class AccountsSettingsFragment extends SubScreenFragment { class AccountChangedListener implements DialogInterface.OnClickListener { @Override public void onClick(DialogInterface dialog, int which) { + final String oldAccount = getSignedInAccountName(); switch (which) { case DialogInterface.BUTTON_POSITIVE: // Signed in final ListView lv = ((AlertDialog)dialog).getListView(); - final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition()); + final String newAccount = + (String) lv.getItemAtPosition(lv.getCheckedItemPosition()); getSharedPreferences() .edit() - .putString(PREF_ACCOUNT_NAME, (String) selectedItem) + .putString(PREF_ACCOUNT_NAME, newAccount) .apply(); - // Attempt starting sync for the new account if sync was - // previously enabled. - // If not, stop it. - updateSyncPolicy(isSyncEnabled(), getSignedInAccountName()); + AccountStateChangedListener.onAccountSignedIn(oldAccount, newAccount); break; case DialogInterface.BUTTON_NEUTRAL: // Signed out - // Stop sync for the account that's being signed out of. - updateSyncPolicy(false, getSignedInAccountName()); + AccountStateChangedListener.onAccountSignedOut(oldAccount); getSharedPreferences() .edit() .remove(PREF_ACCOUNT_NAME) @@ -292,9 +259,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment { class SyncNowListener implements Preference.OnPreferenceClickListener { @Override public boolean onPreferenceClick(final Preference preference) { - ContentResolver.requestSync( - new Account(getSignedInAccountName(), LoginAccountUtils.ACCOUNT_TYPE), - AUTHORITY, Bundle.EMPTY); + AccountStateChangedListener.forceSync(getSignedInAccountName()); return true; } } diff --git a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java index 273d7faf7..2ef8b548f 100644 --- a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java +++ b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java @@ -16,21 +16,14 @@ package com.android.inputmethod.latin.settings; -import static com.android.inputmethod.latin.settings.AccountsSettingsFragment.AUTHORITY; - -import android.accounts.Account; import android.app.AlertDialog; import android.app.Dialog; -import android.content.ContentResolver; import android.content.Intent; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.MediumTest; import android.view.View; import android.widget.ListView; -import com.android.inputmethod.latin.accounts.LoginAccountUtils; -import com.android.inputmethod.latin.define.ProductionFlags; - import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -39,9 +32,6 @@ public class AccountsSettingsFragmentTests extends ActivityInstrumentationTestCase2 { private static final String FRAG_NAME = AccountsSettingsFragment.class.getName(); private static final long TEST_TIMEOUT_MILLIS = 5000; - private static final String TEST_ACCOUNT_NAME = "AccountsSettingsFragmentTests"; - private static final Account TEST_ACCOUNT = - new Account(TEST_ACCOUNT_NAME, LoginAccountUtils.ACCOUNT_TYPE); private AlertDialog mDialog; @@ -57,13 +47,6 @@ public class AccountsSettingsFragmentTests setActivityIntent(intent); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); - // reset the syncable state to unknown - ContentResolver.setIsSyncable(TEST_ACCOUNT, AUTHORITY, -1); - } - public void testEmptyAccounts() { final AccountsSettingsFragment fragment = (AccountsSettingsFragment) getActivity().mFragment; @@ -146,57 +129,4 @@ public class AccountsSettingsFragmentTests assertEquals(View.VISIBLE, mDialog.getButton(Dialog.BUTTON_NEGATIVE).getVisibility()); assertEquals(View.VISIBLE, mDialog.getButton(Dialog.BUTTON_POSITIVE).getVisibility()); } - - public void testUpdateSyncPolicy_enable() { - // This test is a no-op when ENABLE_PERSONAL_DICTIONARY_SYNC is not enabled - if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) { - return; - } - // Should be unknown by default. - assertTrue(ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY) < 0); - - final AccountsSettingsFragment fragment = - (AccountsSettingsFragment) getActivity().mFragment; - fragment.updateSyncPolicy(true, TEST_ACCOUNT_NAME); - - // Should be syncable now. - assertEquals(1, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY)); - } - - public void testUpdateSyncPolicy_disable() { - // This test is a no-op when ENABLE_PERSONAL_DICTIONARY_SYNC is not enabled - if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) { - return; - } - // Should be unknown by default. - assertTrue(ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY) < 0); - - final AccountsSettingsFragment fragment = - (AccountsSettingsFragment) getActivity().mFragment; - fragment.updateSyncPolicy(false, TEST_ACCOUNT_NAME); - - // Should not be syncable now. - assertEquals(0, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY)); - } - - public void testUpdateSyncPolicy_enableDisable() { - // This test is a no-op when ENABLE_PERSONAL_DICTIONARY_SYNC is not enabled - if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) { - return; - } - // Should be unknown by default. - assertTrue(ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY) < 0); - - final AccountsSettingsFragment fragment = - (AccountsSettingsFragment) getActivity().mFragment; - fragment.updateSyncPolicy(true, TEST_ACCOUNT_NAME); - - // Should be syncable now. - assertEquals(1, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY)); - - fragment.updateSyncPolicy(false, TEST_ACCOUNT_NAME); - - // Should not be syncable now. - assertEquals(0, ContentResolver.getIsSyncable(TEST_ACCOUNT, AUTHORITY)); - } }