diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/settings')
6 files changed, 271 insertions, 3 deletions
diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java new file mode 100644 index 000000000..06ab1e2d2 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java @@ -0,0 +1,193 @@ +/* + * 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.settings; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.text.TextUtils; +import android.widget.ListView; +import android.widget.Toast; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.define.ProductionFlags; +import com.android.inputmethod.latin.utils.LoginAccountUtils; + +import javax.annotation.Nullable; + +/** + * "Accounts & Privacy" settings sub screen. + * + * This settings sub screen handles the following preferences: + * <li> Account selection/management for IME + * <li> TODO: Sync preferences + * <li> TODO: Privacy preferences + */ +public final class AccountsSettingsFragment extends SubScreenFragment { + static final String PREF_ACCCOUNT_SWITCHER = "account_switcher"; + + private final DialogInterface.OnClickListener mAccountSelectedListener = + new AccountSelectedListener(); + private final DialogInterface.OnClickListener mAccountSignedOutListener = + new AccountSignedOutListener(); + + @Override + public void onCreate(final Bundle icicle) { + super.onCreate(icicle); + addPreferencesFromResource(R.xml.prefs_screen_accounts); + + final Resources res = getResources(); + final Context context = getActivity(); + + // When we are called from the Settings application but we are not already running, some + // singleton and utility classes may not have been initialized. We have to call + // initialization method of these classes here. See {@link LatinIME#onCreate()}. + SubtypeSwitcher.init(context); + + if (ProductionFlags.IS_METRICS_LOGGING_SUPPORTED) { + final Preference enableMetricsLogging = + findPreference(Settings.PREF_ENABLE_METRICS_LOGGING); + if (enableMetricsLogging != null) { + final String enableMetricsLoggingTitle = res.getString( + R.string.enable_metrics_logging, getApplicationName()); + enableMetricsLogging.setTitle(enableMetricsLoggingTitle); + } + } else { + removePreference(Settings.PREF_ENABLE_METRICS_LOGGING); + } + } + + @Override + public void onResume() { + super.onResume(); + refreshAccountSelection(); + } + + @Override + public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { + // TODO: Look at the preference that changed before refreshing the view. + refreshAccountSelection(); + } + + private void refreshAccountSelection() { + final String currentAccount = getCurrentlySelectedAccount(); + final Preference accountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER); + if (currentAccount == null) { + // No account is currently selected. + accountSwitcher.setSummary(getString(R.string.no_accounts_selected)); + } else { + // Set the currently selected account. + accountSwitcher.setSummary(getString(R.string.account_selected, currentAccount)); + } + final Context context = getActivity(); + final String[] accountsForLogin = LoginAccountUtils.getAccountsForLogin(context); + accountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (accountsForLogin.length == 0) { + // TODO: Handle account addition. + Toast.makeText(getActivity(), + getString(R.string.account_select_cancel), Toast.LENGTH_SHORT).show(); + } else { + createAccountPicker(accountsForLogin, currentAccount).show(); + } + return true; + } + }); + + // TODO: Depending on the account selection, enable/disable preferences that + // depend on an account. + } + + @Nullable + private String getCurrentlySelectedAccount() { + return getSharedPreferences().getString(Settings.PREF_ACCOUNT_NAME, null); + } + + /** + * Creates an account picker dialog showing the given accounts in a list and selecting + * the selected account by default. + * The list of accounts must not be null/empty. + * + * Package-private for testing. + */ + AlertDialog createAccountPicker(final String[] accounts, + final String selectedAccount) { + if (accounts == null || accounts.length == 0) { + throw new IllegalArgumentException("List of accounts must not be empty"); + } + + // See if the currently selected account is in the list. + // If it is, the entry is selected, and a sign-out button is provided. + // If it isn't, select the 0th account by default which will get picked up + // if the user presses OK. + int index = 0; + boolean isSignedIn = false; + for (int i = 0; i < accounts.length; i++) { + if (TextUtils.equals(accounts[i], selectedAccount)) { + index = i; + isSignedIn = true; + break; + } + } + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) + .setTitle(R.string.account_select_title) + .setSingleChoiceItems(accounts, index, null) + .setPositiveButton(R.string.account_select_ok, mAccountSelectedListener) + .setNegativeButton(R.string.account_select_cancel, null); + if (isSignedIn) { + builder.setNeutralButton(R.string.account_select_sign_out, mAccountSignedOutListener); + } + return builder.create(); + } + + /** + * Listener for an account being selected from the picker. + * Persists the account to shared preferences. + */ + class AccountSelectedListener implements DialogInterface.OnClickListener { + @Override + public void onClick(DialogInterface dialog, int which) { + final ListView lv = ((AlertDialog)dialog).getListView(); + final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition()); + getSharedPreferences() + .edit() + .putString(Settings.PREF_ACCOUNT_NAME, (String) selectedItem) + .apply(); + } + } + + /** + * Listener for sign-out being initiated from from the picker. + * Removed the account from shared preferences. + */ + class AccountSignedOutListener implements DialogInterface.OnClickListener { + @Override + public void onClick(DialogInterface dialog, int which) { + getSharedPreferences() + .edit() + .remove(Settings.PREF_ACCOUNT_NAME) + .apply(); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java index 00f2c73dd..a6cb55db1 100644 --- a/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java @@ -93,14 +93,16 @@ public final class AdvancedSettingsFragment extends SubScreenFragment { removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON); } + // If metrics logging isn't supported, or account sign in is enabled + // don't show the logging preference. + // TODO: Eventually when we enable account sign in by default, + // we'll remove logging preference from here. if (ProductionFlags.IS_METRICS_LOGGING_SUPPORTED) { final Preference enableMetricsLogging = findPreference(Settings.PREF_ENABLE_METRICS_LOGGING); if (enableMetricsLogging != null) { - final int applicationLabelRes = context.getApplicationInfo().labelRes; - final String applicationName = res.getString(applicationLabelRes); final String enableMetricsLoggingTitle = res.getString( - R.string.enable_metrics_logging, applicationName); + R.string.enable_metrics_logging, getApplicationName()); enableMetricsLogging.setTitle(enableMetricsLoggingTitle); } } else { diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 529f8a093..a171fc330 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -43,6 +43,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang private static final String TAG = Settings.class.getSimpleName(); // Settings screens public static final String SCREEN_PREFERENCES = "screen_preferences"; + public static final String SCREEN_ACCOUNTS = "screen_accounts"; public static final String SCREEN_APPEARANCE = "screen_appearance"; public static final String SCREEN_THEME = "screen_theme"; public static final String SCREEN_MULTILINGUAL = "screen_multilingual"; @@ -104,6 +105,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal"; public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging"; + public static final String PREF_ACCOUNT_NAME = "pref_account_name"; // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead. // This is being used only for the backward compatibility. diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java index 4fc17387f..8c4801798 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java @@ -25,6 +25,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.define.ProductionFlags; import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.FeedbackUtils; import com.android.inputmethodcommon.InputMethodSettingsFragment; @@ -51,6 +52,10 @@ public final class SettingsFragment extends InputMethodSettingsFragment { final Preference multilingualOptions = findPreference(Settings.SCREEN_MULTILINGUAL); preferenceScreen.removePreference(multilingualOptions); } + if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) { + final Preference accountsPreference = findPreference(Settings.SCREEN_ACCOUNTS); + preferenceScreen.removePreference(accountsPreference); + } } @Override diff --git a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java index ca5b395ce..240f8f89b 100644 --- a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java @@ -20,6 +20,7 @@ import android.app.backup.BackupManager; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Resources; import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; @@ -79,6 +80,16 @@ abstract class SubScreenFragment extends PreferenceFragment return getPreferenceManager().getSharedPreferences(); } + /** + * Gets the application name to display on the UI. + */ + final String getApplicationName() { + final Context context = getActivity(); + final Resources res = getResources(); + final int applicationLabelRes = context.getApplicationInfo().labelRes; + return res.getString(applicationLabelRes); + } + @Override public void addPreferencesFromResource(final int preferencesResId) { super.addPreferencesFromResource(preferencesResId); diff --git a/java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java b/java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java new file mode 100644 index 000000000..254bc6567 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java @@ -0,0 +1,55 @@ +/* + * 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.settings; + +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.Intent; +import android.os.Bundle; + +/** + * Test activity to use when testing preference fragments. <br/> + * Usage: <br/> + * Create an ActivityInstrumentationTestCase2 for this activity + * and call setIntent() with an intent that specifies the fragment to load in the activity. + * The fragment can then be obtained from this activity and used for testing/verification. + */ +public final class TestFragmentActivity extends Activity { + /** + * The fragment name that should be loaded when starting this activity. + * This must be specified when starting this activity, as this activity is only + * meant to test fragments from instrumentation tests. + */ + public static final String EXTRA_SHOW_FRAGMENT = "show_fragment"; + + public Fragment mFragment; + + @Override + protected void onCreate(final Bundle savedState) { + super.onCreate(savedState); + final Intent intent = getIntent(); + final String fragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT); + if (fragmentName == null) { + throw new IllegalArgumentException("No fragment name specified for testing"); + } + + mFragment = Fragment.instantiate(this, fragmentName); + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction().add(mFragment, fragmentName).commit(); + } +} |