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