mobile/android/base/sync/config/activities/SelectEnginesActivity.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/sync/config/activities/SelectEnginesActivity.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,210 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +package org.mozilla.gecko.sync.config.activities;
     1.9 +
    1.10 +import java.util.HashMap;
    1.11 +import java.util.Map;
    1.12 +import java.util.Map.Entry;
    1.13 +import java.util.Set;
    1.14 +
    1.15 +import org.mozilla.gecko.R;
    1.16 +import org.mozilla.gecko.background.common.log.Logger;
    1.17 +import org.mozilla.gecko.sync.SyncConfiguration;
    1.18 +import org.mozilla.gecko.sync.ThreadPool;
    1.19 +import org.mozilla.gecko.sync.setup.SyncAccounts;
    1.20 +import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
    1.21 +
    1.22 +import android.accounts.Account;
    1.23 +import android.accounts.AccountManager;
    1.24 +import android.app.Activity;
    1.25 +import android.app.AlertDialog;
    1.26 +import android.content.Context;
    1.27 +import android.content.DialogInterface;
    1.28 +import android.content.DialogInterface.OnDismissListener;
    1.29 +import android.content.SharedPreferences;
    1.30 +import android.os.Bundle;
    1.31 +import android.widget.ListView;
    1.32 +import android.widget.Toast;
    1.33 +
    1.34 +/**
    1.35 + * Provides a user-facing interface for selecting engines to sync. This activity
    1.36 + * can be launched from the Sync Settings preferences screen, and will save the
    1.37 + * selected engines to the
    1.38 + * <code>SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC</code> pref.
    1.39 + *
    1.40 + * On launch, it displays the engines stored in the saved pref if it exists, or
    1.41 + * <code>SyncConfiguration.enabledEngineNames()</code> if it doesn't, defaulting
    1.42 + * to <code>SyncConfiguration.validEngineNames()</code> if neither exists.
    1.43 + *
    1.44 + * During a sync, the
    1.45 + * <code>SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC</code> pref will
    1.46 + * be cleared after the engine changes are applied to meta/global.
    1.47 + */
    1.48 +
    1.49 +public class SelectEnginesActivity extends Activity implements
    1.50 +    DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener {
    1.51 +  public final static String LOG_TAG = "SelectEnginesAct";
    1.52 +
    1.53 +  protected AccountManager mAccountManager;
    1.54 +  protected Context mContext;
    1.55 +
    1.56 +  // Collections names corresponding to displayed (localized) engine options.
    1.57 +  final String[] _collectionsNames = new String[] {
    1.58 +    "bookmarks",
    1.59 +    "passwords",
    1.60 +    "history",
    1.61 +    "tabs"
    1.62 +  };
    1.63 +
    1.64 +  // Engine names localized for display in Sync Settings.
    1.65 +  protected String[] _options;
    1.66 +  // Selection state of engines corresponding to _options array.
    1.67 +  final boolean[] _selections = new boolean[_collectionsNames.length];
    1.68 +  protected Account account;
    1.69 +  protected SharedPreferences accountPrefs;
    1.70 +
    1.71 +  @Override
    1.72 +  public void onCreate(Bundle savedInstanceState) {
    1.73 +    super.onCreate(savedInstanceState);
    1.74 +    mContext = getApplicationContext();
    1.75 +    mAccountManager = AccountManager.get(mContext);
    1.76 +    _options = new String[] {
    1.77 +        getString(R.string.sync_configure_engines_title_bookmarks),
    1.78 +        getString(R.string.sync_configure_engines_title_passwords),
    1.79 +        getString(R.string.sync_configure_engines_title_history),
    1.80 +        getString(R.string.sync_configure_engines_title_tabs) };
    1.81 +
    1.82 +    // Fetch account prefs for configuring engines.
    1.83 +    ThreadPool.run(new Runnable() {
    1.84 +      @Override
    1.85 +      public void run() {
    1.86 +        Account[] accounts = SyncAccounts.syncAccounts(mContext);
    1.87 +        if (accounts.length == 0) {
    1.88 +          Logger.error(LOG_TAG, "Failed to get account!");
    1.89 +          finish();
    1.90 +          return;
    1.91 +        } else {
    1.92 +          // Only supports one account per type.
    1.93 +          account = accounts[0];
    1.94 +          try {
    1.95 +            if (accountPrefs == null) {
    1.96 +              accountPrefs = SyncAccounts.blockingPrefsFromDefaultProfileV0(mContext, mAccountManager, account);
    1.97 +            }
    1.98 +          } catch (Exception e) {
    1.99 +            Logger.error(LOG_TAG, "Failed to get sync account info or shared preferences.", e);
   1.100 +            finish();
   1.101 +          }
   1.102 +          setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections);
   1.103 +        }
   1.104 +      }
   1.105 +    });
   1.106 +  }
   1.107 +
   1.108 +  @Override
   1.109 +  public void onResume() {
   1.110 +    super.onResume();
   1.111 +    if (accountPrefs != null) {
   1.112 +      setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections);
   1.113 +    }
   1.114 +    AlertDialog dialog = new AlertDialog.Builder(this)
   1.115 +        .setTitle(R.string.sync_configure_engines_sync_my_title)
   1.116 +        .setMultiChoiceItems(_options, _selections, this)
   1.117 +        .setIcon(R.drawable.icon).setPositiveButton(android.R.string.ok, this)
   1.118 +        .setNegativeButton(android.R.string.cancel, this).create();
   1.119 +
   1.120 +    dialog.setOnDismissListener(new OnDismissListener() {
   1.121 +      @Override
   1.122 +      public void onDismiss(DialogInterface dialog) {
   1.123 +        finish();
   1.124 +      }
   1.125 +    });
   1.126 +
   1.127 +    dialog.show();
   1.128 +  }
   1.129 +
   1.130 +  private static Set<String> getEnginesFromPrefs(SharedPreferences syncPrefs) {
   1.131 +    Set<String> engines = SyncConfiguration.getEnabledEngineNames(syncPrefs);
   1.132 +    if (engines == null) {
   1.133 +      engines = SyncConfiguration.validEngineNames();
   1.134 +    }
   1.135 +    return engines;
   1.136 +  }
   1.137 +
   1.138 +  /**
   1.139 +   * Fetches the engine names that should be displayed as selected for syncing.
   1.140 +   * Check first for selected engines set by this activity, then the enabled
   1.141 +   * engines, and finally default to the set of valid engine names for Android
   1.142 +   * Sync if neither exists.
   1.143 +   *
   1.144 +   * @param syncPrefs
   1.145 +   *          <code>SharedPreferences</code> of Account being modified.
   1.146 +   * @return Set<String> of engine names to display as selected. Should never be
   1.147 +   *         null.
   1.148 +   */
   1.149 +  public static Set<String> getEnginesToSelect(SharedPreferences syncPrefs) {
   1.150 +    Set<String> engines = getEnginesFromPrefs(syncPrefs);
   1.151 +    Map<String, Boolean> engineSelections = SyncConfiguration.getUserSelectedEngines(syncPrefs);
   1.152 +    if (engineSelections != null) {
   1.153 +      for (Entry<String, Boolean> pair : engineSelections.entrySet()) {
   1.154 +        if (pair.getValue()) {
   1.155 +          engines.add(pair.getKey());
   1.156 +        } else {
   1.157 +          engines.remove(pair.getKey());
   1.158 +        }
   1.159 +      }
   1.160 +    }
   1.161 +    return engines;
   1.162 +  }
   1.163 +
   1.164 +  public void setSelectionsInArray(Set<String> selected, boolean[] array) {
   1.165 +    for (int i = 0; i < _collectionsNames.length; i++) {
   1.166 +      array[i] = selected.contains(_collectionsNames[i]);
   1.167 +    }
   1.168 +  }
   1.169 +
   1.170 +  @Override
   1.171 +  public void onClick(DialogInterface dialog, int which) {
   1.172 +    if (which == DialogInterface.BUTTON_POSITIVE) {
   1.173 +      Logger.debug(LOG_TAG, "Saving selected engines.");
   1.174 +      saveSelections();
   1.175 +      setResult(RESULT_OK);
   1.176 +      Toast.makeText(this, R.string.sync_notification_savedprefs, Toast.LENGTH_SHORT).show();
   1.177 +    } else {
   1.178 +      setResult(RESULT_CANCELED);
   1.179 +    }
   1.180 +    finish();
   1.181 +  }
   1.182 +
   1.183 +  @Override
   1.184 +  public void onClick(DialogInterface dialog, int which, boolean isChecked) {
   1.185 +    // Display multi-selection clicks in UI.
   1.186 +    _selections[which] = isChecked;
   1.187 +    ListView selectionsList = ((AlertDialog) dialog).getListView();
   1.188 +    selectionsList.setItemChecked(which, isChecked);
   1.189 +  }
   1.190 +
   1.191 +  /**
   1.192 +   * Persists engine selection state to SharedPreferences if it has changed.
   1.193 +   *
   1.194 +   * @return true if changed, false otherwise.
   1.195 +   */
   1.196 +  private void saveSelections() {
   1.197 +    boolean[] origSelections = new boolean[_options.length];
   1.198 +    setSelectionsInArray(getEnginesFromPrefs(accountPrefs), origSelections);
   1.199 +
   1.200 +    Map<String, Boolean> engineSelections = new HashMap<String, Boolean>();
   1.201 +    for (int i = 0; i < _selections.length; i++) {
   1.202 +      if (_selections[i] != origSelections[i]) {
   1.203 +        engineSelections.put(_collectionsNames[i], _selections[i]);
   1.204 +      }
   1.205 +    }
   1.206 +
   1.207 +    // No GlobalSession.config, so store directly to prefs.
   1.208 +    SyncConfiguration.storeSelectedEnginesToPrefs(accountPrefs, engineSelections);
   1.209 +
   1.210 +    // Request immediate sync.
   1.211 +    SyncAdapter.requestImmediateSync(account, null);
   1.212 +  }
   1.213 +}

mercurial