michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0:
michael@0: package org.mozilla.gecko.sync.config.activities;
michael@0:
michael@0: import java.util.HashMap;
michael@0: import java.util.Map;
michael@0: import java.util.Map.Entry;
michael@0: import java.util.Set;
michael@0:
michael@0: import org.mozilla.gecko.R;
michael@0: import org.mozilla.gecko.background.common.log.Logger;
michael@0: import org.mozilla.gecko.sync.SyncConfiguration;
michael@0: import org.mozilla.gecko.sync.ThreadPool;
michael@0: import org.mozilla.gecko.sync.setup.SyncAccounts;
michael@0: import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
michael@0:
michael@0: import android.accounts.Account;
michael@0: import android.accounts.AccountManager;
michael@0: import android.app.Activity;
michael@0: import android.app.AlertDialog;
michael@0: import android.content.Context;
michael@0: import android.content.DialogInterface;
michael@0: import android.content.DialogInterface.OnDismissListener;
michael@0: import android.content.SharedPreferences;
michael@0: import android.os.Bundle;
michael@0: import android.widget.ListView;
michael@0: import android.widget.Toast;
michael@0:
michael@0: /**
michael@0: * Provides a user-facing interface for selecting engines to sync. This activity
michael@0: * can be launched from the Sync Settings preferences screen, and will save the
michael@0: * selected engines to the
michael@0: * SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC
pref.
michael@0: *
michael@0: * On launch, it displays the engines stored in the saved pref if it exists, or
michael@0: * SyncConfiguration.enabledEngineNames()
if it doesn't, defaulting
michael@0: * to SyncConfiguration.validEngineNames()
if neither exists.
michael@0: *
michael@0: * During a sync, the
michael@0: * SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC
pref will
michael@0: * be cleared after the engine changes are applied to meta/global.
michael@0: */
michael@0:
michael@0: public class SelectEnginesActivity extends Activity implements
michael@0: DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener {
michael@0: public final static String LOG_TAG = "SelectEnginesAct";
michael@0:
michael@0: protected AccountManager mAccountManager;
michael@0: protected Context mContext;
michael@0:
michael@0: // Collections names corresponding to displayed (localized) engine options.
michael@0: final String[] _collectionsNames = new String[] {
michael@0: "bookmarks",
michael@0: "passwords",
michael@0: "history",
michael@0: "tabs"
michael@0: };
michael@0:
michael@0: // Engine names localized for display in Sync Settings.
michael@0: protected String[] _options;
michael@0: // Selection state of engines corresponding to _options array.
michael@0: final boolean[] _selections = new boolean[_collectionsNames.length];
michael@0: protected Account account;
michael@0: protected SharedPreferences accountPrefs;
michael@0:
michael@0: @Override
michael@0: public void onCreate(Bundle savedInstanceState) {
michael@0: super.onCreate(savedInstanceState);
michael@0: mContext = getApplicationContext();
michael@0: mAccountManager = AccountManager.get(mContext);
michael@0: _options = new String[] {
michael@0: getString(R.string.sync_configure_engines_title_bookmarks),
michael@0: getString(R.string.sync_configure_engines_title_passwords),
michael@0: getString(R.string.sync_configure_engines_title_history),
michael@0: getString(R.string.sync_configure_engines_title_tabs) };
michael@0:
michael@0: // Fetch account prefs for configuring engines.
michael@0: ThreadPool.run(new Runnable() {
michael@0: @Override
michael@0: public void run() {
michael@0: Account[] accounts = SyncAccounts.syncAccounts(mContext);
michael@0: if (accounts.length == 0) {
michael@0: Logger.error(LOG_TAG, "Failed to get account!");
michael@0: finish();
michael@0: return;
michael@0: } else {
michael@0: // Only supports one account per type.
michael@0: account = accounts[0];
michael@0: try {
michael@0: if (accountPrefs == null) {
michael@0: accountPrefs = SyncAccounts.blockingPrefsFromDefaultProfileV0(mContext, mAccountManager, account);
michael@0: }
michael@0: } catch (Exception e) {
michael@0: Logger.error(LOG_TAG, "Failed to get sync account info or shared preferences.", e);
michael@0: finish();
michael@0: }
michael@0: setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections);
michael@0: }
michael@0: }
michael@0: });
michael@0: }
michael@0:
michael@0: @Override
michael@0: public void onResume() {
michael@0: super.onResume();
michael@0: if (accountPrefs != null) {
michael@0: setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections);
michael@0: }
michael@0: AlertDialog dialog = new AlertDialog.Builder(this)
michael@0: .setTitle(R.string.sync_configure_engines_sync_my_title)
michael@0: .setMultiChoiceItems(_options, _selections, this)
michael@0: .setIcon(R.drawable.icon).setPositiveButton(android.R.string.ok, this)
michael@0: .setNegativeButton(android.R.string.cancel, this).create();
michael@0:
michael@0: dialog.setOnDismissListener(new OnDismissListener() {
michael@0: @Override
michael@0: public void onDismiss(DialogInterface dialog) {
michael@0: finish();
michael@0: }
michael@0: });
michael@0:
michael@0: dialog.show();
michael@0: }
michael@0:
michael@0: private static Set getEnginesFromPrefs(SharedPreferences syncPrefs) {
michael@0: Set engines = SyncConfiguration.getEnabledEngineNames(syncPrefs);
michael@0: if (engines == null) {
michael@0: engines = SyncConfiguration.validEngineNames();
michael@0: }
michael@0: return engines;
michael@0: }
michael@0:
michael@0: /**
michael@0: * Fetches the engine names that should be displayed as selected for syncing.
michael@0: * Check first for selected engines set by this activity, then the enabled
michael@0: * engines, and finally default to the set of valid engine names for Android
michael@0: * Sync if neither exists.
michael@0: *
michael@0: * @param syncPrefs
michael@0: * SharedPreferences
of Account being modified.
michael@0: * @return Set of engine names to display as selected. Should never be
michael@0: * null.
michael@0: */
michael@0: public static Set getEnginesToSelect(SharedPreferences syncPrefs) {
michael@0: Set engines = getEnginesFromPrefs(syncPrefs);
michael@0: Map engineSelections = SyncConfiguration.getUserSelectedEngines(syncPrefs);
michael@0: if (engineSelections != null) {
michael@0: for (Entry pair : engineSelections.entrySet()) {
michael@0: if (pair.getValue()) {
michael@0: engines.add(pair.getKey());
michael@0: } else {
michael@0: engines.remove(pair.getKey());
michael@0: }
michael@0: }
michael@0: }
michael@0: return engines;
michael@0: }
michael@0:
michael@0: public void setSelectionsInArray(Set selected, boolean[] array) {
michael@0: for (int i = 0; i < _collectionsNames.length; i++) {
michael@0: array[i] = selected.contains(_collectionsNames[i]);
michael@0: }
michael@0: }
michael@0:
michael@0: @Override
michael@0: public void onClick(DialogInterface dialog, int which) {
michael@0: if (which == DialogInterface.BUTTON_POSITIVE) {
michael@0: Logger.debug(LOG_TAG, "Saving selected engines.");
michael@0: saveSelections();
michael@0: setResult(RESULT_OK);
michael@0: Toast.makeText(this, R.string.sync_notification_savedprefs, Toast.LENGTH_SHORT).show();
michael@0: } else {
michael@0: setResult(RESULT_CANCELED);
michael@0: }
michael@0: finish();
michael@0: }
michael@0:
michael@0: @Override
michael@0: public void onClick(DialogInterface dialog, int which, boolean isChecked) {
michael@0: // Display multi-selection clicks in UI.
michael@0: _selections[which] = isChecked;
michael@0: ListView selectionsList = ((AlertDialog) dialog).getListView();
michael@0: selectionsList.setItemChecked(which, isChecked);
michael@0: }
michael@0:
michael@0: /**
michael@0: * Persists engine selection state to SharedPreferences if it has changed.
michael@0: *
michael@0: * @return true if changed, false otherwise.
michael@0: */
michael@0: private void saveSelections() {
michael@0: boolean[] origSelections = new boolean[_options.length];
michael@0: setSelectionsInArray(getEnginesFromPrefs(accountPrefs), origSelections);
michael@0:
michael@0: Map engineSelections = new HashMap();
michael@0: for (int i = 0; i < _selections.length; i++) {
michael@0: if (_selections[i] != origSelections[i]) {
michael@0: engineSelections.put(_collectionsNames[i], _selections[i]);
michael@0: }
michael@0: }
michael@0:
michael@0: // No GlobalSession.config, so store directly to prefs.
michael@0: SyncConfiguration.storeSelectedEnginesToPrefs(accountPrefs, engineSelections);
michael@0:
michael@0: // Request immediate sync.
michael@0: SyncAdapter.requestImmediateSync(account, null);
michael@0: }
michael@0: }