From d4aec65f65baf0122cd3d59155307d1ba326f803 Mon Sep 17 00:00:00 2001 From: Sandeep Siddhartha Date: Mon, 22 Sep 2014 16:45:05 -0700 Subject: [PATCH] Add account change receiver to handle account removal Also cleanup the manifest to group similar components together. Moving LoginAccountUtils to its own package Bug: 17464068 Change-Id: Iad7928855531d58334b1e4039bb45b97dde75462 --- .../LoginAccountUtils.java | 2 +- java/AndroidManifest.xml | 108 ++++++++++-------- .../accounts/AccountsChangedReceiver.java | 72 ++++++++++++ .../settings/AccountsSettingsFragment.java | 2 +- .../latin/settings/SettingsValues.java | 4 + .../AccountsChangedReceiverTests.java | 106 +++++++++++++++++ 6 files changed, 244 insertions(+), 50 deletions(-) rename java-overridable/src/com/android/inputmethod/latin/{utils => accounts}/LoginAccountUtils.java (96%) create mode 100644 java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java create mode 100644 tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java diff --git a/java-overridable/src/com/android/inputmethod/latin/utils/LoginAccountUtils.java b/java-overridable/src/com/android/inputmethod/latin/accounts/LoginAccountUtils.java similarity index 96% rename from java-overridable/src/com/android/inputmethod/latin/utils/LoginAccountUtils.java rename to java-overridable/src/com/android/inputmethod/latin/accounts/LoginAccountUtils.java index faada29b8..2dc001c83 100644 --- a/java-overridable/src/com/android/inputmethod/latin/utils/LoginAccountUtils.java +++ b/java-overridable/src/com/android/inputmethod/latin/accounts/LoginAccountUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.inputmethod.latin.utils; +package com.android.inputmethod.latin.accounts; import android.content.Context; diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml index b29a6e286..2249be7f4 100644 --- a/java/AndroidManifest.xml +++ b/java/AndroidManifest.xml @@ -37,6 +37,7 @@ android:supportsRtl="true" android:allowBackup="true"> + @@ -56,6 +57,11 @@ android:resource="@xml/spellchecker" /> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java b/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java new file mode 100644 index 000000000..9445ce4c3 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiver.java @@ -0,0 +1,72 @@ +/* + * 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.accounts.AccountManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.util.Log; + +import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.latin.settings.Settings; + +/** + * {@link BroadcastReceiver} for {@link AccountManager#LOGIN_ACCOUNTS_CHANGED_ACTION}. + */ +public class AccountsChangedReceiver extends BroadcastReceiver { + static final String TAG = "AccountsChangedReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + if (!AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) { + Log.w(TAG, "Received unknown broadcast: " + intent); + return; + } + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + final String currentAccount = prefs.getString(Settings.PREF_ACCOUNT_NAME, null); + if (currentAccount != null) { + final String[] accounts = getAccountsForLogin(context); + boolean accountFound = false; + for (String account : accounts) { + if (TextUtils.equals(currentAccount, account)) { + accountFound = true; + break; + } + } + // The current account was not found in the list of accounts, remove it. + if (!accountFound) { + Log.i(TAG, "The current account was removed from the system: " + currentAccount); + prefs.edit() + .remove(Settings.PREF_ACCOUNT_NAME) + .apply(); + } + } + } + + /** + * Helper method to help test this receiver. + */ + @UsedForTesting + protected String[] getAccountsForLogin(Context context) { + return LoginAccountUtils.getAccountsForLogin(context); + } +} diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java index 06ab1e2d2..ffb0ad7bf 100644 --- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java @@ -30,8 +30,8 @@ import android.widget.Toast; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.accounts.LoginAccountUtils; import com.android.inputmethod.latin.define.ProductionFlags; -import com.android.inputmethod.latin.utils.LoginAccountUtils; import javax.annotation.Nullable; diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 3339ab57f..964d5ce33 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -64,6 +64,7 @@ public class SettingsValues { public final boolean mSoundOn; public final boolean mKeyPreviewPopupOn; public final boolean mShowsVoiceInputKey; + public final String mAccountName; public final boolean mIncludesOtherImesInLanguageSwitchList; public final boolean mShowsLanguageSwitchKey; public final boolean mUseContactsDict; @@ -140,6 +141,7 @@ public class SettingsValues { mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res) && mInputAttributes.mShouldShowVoiceInputKey && SubtypeSwitcher.getInstance().isShortcutImeEnabled(); + mAccountName = prefs.getString(Settings.PREF_ACCOUNT_NAME, null); final String autoCorrectionThresholdRawValue = prefs.getString( Settings.PREF_AUTO_CORRECTION_THRESHOLD, res.getString(R.string.auto_correction_threshold_mode_index_modest)); @@ -383,6 +385,8 @@ public class SettingsValues { sb.append("" + mKeyPreviewPopupOn); sb.append("\n mShowsVoiceInputKey = "); sb.append("" + mShowsVoiceInputKey); + sb.append("\n mAccountName = "); + sb.append("" + mAccountName); sb.append("\n mIncludesOtherImesInLanguageSwitchList = "); sb.append("" + mIncludesOtherImesInLanguageSwitchList); sb.append("\n mShowsLanguageSwitchKey = "); diff --git a/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java b/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java new file mode 100644 index 000000000..3319eec3b --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java @@ -0,0 +1,106 @@ +/* + * 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.accounts.AccountManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.test.AndroidTestCase; + +import com.android.inputmethod.latin.settings.Settings; + +/** + * Tests for {@link AccountsChangedReceiver}. + */ +public class AccountsChangedReceiverTests extends AndroidTestCase { + private static final String ACCOUNT_1 = "account1@example.com"; + private static final String ACCOUNT_2 = "account2@example.com"; + + private SharedPreferences mPrefs; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + // Remove all preferences before the next test. + mPrefs.edit().clear(); + } + + public void testUnknownIntent() { + updateAccountName(ACCOUNT_1); + AccountsChangedReceiver reciever = new AccountsChangedReceiver(); + reciever.onReceive(getContext(), new Intent("some-random-action")); + // Account should *not* be removed from preferences. + assertAccountName(ACCOUNT_1); + } + + public void testAccountRemoved() { + updateAccountName(ACCOUNT_1); + AccountsChangedReceiver reciever = new AccountsChangedReceiver() { + @Override + protected String[] getAccountsForLogin(Context context) { + return new String[] {ACCOUNT_2}; + } + }; + reciever.onReceive(getContext(), new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION)); + // Account should be removed from preferences. + assertAccountName(null); + } + + public void testAccountRemoved_noAccounts() { + updateAccountName(ACCOUNT_2); + AccountsChangedReceiver reciever = new AccountsChangedReceiver() { + @Override + protected String[] getAccountsForLogin(Context context) { + return new String[0]; + } + }; + reciever.onReceive(getContext(), new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION)); + // Account should be removed from preferences. + assertAccountName(null); + } + + public void testAccountNotRemoved() { + updateAccountName(ACCOUNT_2); + AccountsChangedReceiver reciever = new AccountsChangedReceiver() { + @Override + protected String[] getAccountsForLogin(Context context) { + return new String[] {ACCOUNT_1, ACCOUNT_2}; + } + }; + reciever.onReceive(getContext(), new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION)); + // Account should *not* be removed from preferences. + assertAccountName(ACCOUNT_2); + } + + private void updateAccountName(String accountName) { + mPrefs.edit() + .putString(Settings.PREF_ACCOUNT_NAME, accountName) + .commit(); + } + + private void assertAccountName(String expectedAccountName) { + assertEquals(expectedAccountName, mPrefs.getString(Settings.PREF_ACCOUNT_NAME, null)); + } +}