Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | package org.mozilla.gecko.sync.config.activities; |
michael@0 | 6 | |
michael@0 | 7 | import java.util.HashMap; |
michael@0 | 8 | import java.util.Map; |
michael@0 | 9 | import java.util.Map.Entry; |
michael@0 | 10 | import java.util.Set; |
michael@0 | 11 | |
michael@0 | 12 | import org.mozilla.gecko.R; |
michael@0 | 13 | import org.mozilla.gecko.background.common.log.Logger; |
michael@0 | 14 | import org.mozilla.gecko.sync.SyncConfiguration; |
michael@0 | 15 | import org.mozilla.gecko.sync.ThreadPool; |
michael@0 | 16 | import org.mozilla.gecko.sync.setup.SyncAccounts; |
michael@0 | 17 | import org.mozilla.gecko.sync.syncadapter.SyncAdapter; |
michael@0 | 18 | |
michael@0 | 19 | import android.accounts.Account; |
michael@0 | 20 | import android.accounts.AccountManager; |
michael@0 | 21 | import android.app.Activity; |
michael@0 | 22 | import android.app.AlertDialog; |
michael@0 | 23 | import android.content.Context; |
michael@0 | 24 | import android.content.DialogInterface; |
michael@0 | 25 | import android.content.DialogInterface.OnDismissListener; |
michael@0 | 26 | import android.content.SharedPreferences; |
michael@0 | 27 | import android.os.Bundle; |
michael@0 | 28 | import android.widget.ListView; |
michael@0 | 29 | import android.widget.Toast; |
michael@0 | 30 | |
michael@0 | 31 | /** |
michael@0 | 32 | * Provides a user-facing interface for selecting engines to sync. This activity |
michael@0 | 33 | * can be launched from the Sync Settings preferences screen, and will save the |
michael@0 | 34 | * selected engines to the |
michael@0 | 35 | * <code>SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC</code> pref. |
michael@0 | 36 | * |
michael@0 | 37 | * On launch, it displays the engines stored in the saved pref if it exists, or |
michael@0 | 38 | * <code>SyncConfiguration.enabledEngineNames()</code> if it doesn't, defaulting |
michael@0 | 39 | * to <code>SyncConfiguration.validEngineNames()</code> if neither exists. |
michael@0 | 40 | * |
michael@0 | 41 | * During a sync, the |
michael@0 | 42 | * <code>SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC</code> pref will |
michael@0 | 43 | * be cleared after the engine changes are applied to meta/global. |
michael@0 | 44 | */ |
michael@0 | 45 | |
michael@0 | 46 | public class SelectEnginesActivity extends Activity implements |
michael@0 | 47 | DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener { |
michael@0 | 48 | public final static String LOG_TAG = "SelectEnginesAct"; |
michael@0 | 49 | |
michael@0 | 50 | protected AccountManager mAccountManager; |
michael@0 | 51 | protected Context mContext; |
michael@0 | 52 | |
michael@0 | 53 | // Collections names corresponding to displayed (localized) engine options. |
michael@0 | 54 | final String[] _collectionsNames = new String[] { |
michael@0 | 55 | "bookmarks", |
michael@0 | 56 | "passwords", |
michael@0 | 57 | "history", |
michael@0 | 58 | "tabs" |
michael@0 | 59 | }; |
michael@0 | 60 | |
michael@0 | 61 | // Engine names localized for display in Sync Settings. |
michael@0 | 62 | protected String[] _options; |
michael@0 | 63 | // Selection state of engines corresponding to _options array. |
michael@0 | 64 | final boolean[] _selections = new boolean[_collectionsNames.length]; |
michael@0 | 65 | protected Account account; |
michael@0 | 66 | protected SharedPreferences accountPrefs; |
michael@0 | 67 | |
michael@0 | 68 | @Override |
michael@0 | 69 | public void onCreate(Bundle savedInstanceState) { |
michael@0 | 70 | super.onCreate(savedInstanceState); |
michael@0 | 71 | mContext = getApplicationContext(); |
michael@0 | 72 | mAccountManager = AccountManager.get(mContext); |
michael@0 | 73 | _options = new String[] { |
michael@0 | 74 | getString(R.string.sync_configure_engines_title_bookmarks), |
michael@0 | 75 | getString(R.string.sync_configure_engines_title_passwords), |
michael@0 | 76 | getString(R.string.sync_configure_engines_title_history), |
michael@0 | 77 | getString(R.string.sync_configure_engines_title_tabs) }; |
michael@0 | 78 | |
michael@0 | 79 | // Fetch account prefs for configuring engines. |
michael@0 | 80 | ThreadPool.run(new Runnable() { |
michael@0 | 81 | @Override |
michael@0 | 82 | public void run() { |
michael@0 | 83 | Account[] accounts = SyncAccounts.syncAccounts(mContext); |
michael@0 | 84 | if (accounts.length == 0) { |
michael@0 | 85 | Logger.error(LOG_TAG, "Failed to get account!"); |
michael@0 | 86 | finish(); |
michael@0 | 87 | return; |
michael@0 | 88 | } else { |
michael@0 | 89 | // Only supports one account per type. |
michael@0 | 90 | account = accounts[0]; |
michael@0 | 91 | try { |
michael@0 | 92 | if (accountPrefs == null) { |
michael@0 | 93 | accountPrefs = SyncAccounts.blockingPrefsFromDefaultProfileV0(mContext, mAccountManager, account); |
michael@0 | 94 | } |
michael@0 | 95 | } catch (Exception e) { |
michael@0 | 96 | Logger.error(LOG_TAG, "Failed to get sync account info or shared preferences.", e); |
michael@0 | 97 | finish(); |
michael@0 | 98 | } |
michael@0 | 99 | setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections); |
michael@0 | 100 | } |
michael@0 | 101 | } |
michael@0 | 102 | }); |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | @Override |
michael@0 | 106 | public void onResume() { |
michael@0 | 107 | super.onResume(); |
michael@0 | 108 | if (accountPrefs != null) { |
michael@0 | 109 | setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections); |
michael@0 | 110 | } |
michael@0 | 111 | AlertDialog dialog = new AlertDialog.Builder(this) |
michael@0 | 112 | .setTitle(R.string.sync_configure_engines_sync_my_title) |
michael@0 | 113 | .setMultiChoiceItems(_options, _selections, this) |
michael@0 | 114 | .setIcon(R.drawable.icon).setPositiveButton(android.R.string.ok, this) |
michael@0 | 115 | .setNegativeButton(android.R.string.cancel, this).create(); |
michael@0 | 116 | |
michael@0 | 117 | dialog.setOnDismissListener(new OnDismissListener() { |
michael@0 | 118 | @Override |
michael@0 | 119 | public void onDismiss(DialogInterface dialog) { |
michael@0 | 120 | finish(); |
michael@0 | 121 | } |
michael@0 | 122 | }); |
michael@0 | 123 | |
michael@0 | 124 | dialog.show(); |
michael@0 | 125 | } |
michael@0 | 126 | |
michael@0 | 127 | private static Set<String> getEnginesFromPrefs(SharedPreferences syncPrefs) { |
michael@0 | 128 | Set<String> engines = SyncConfiguration.getEnabledEngineNames(syncPrefs); |
michael@0 | 129 | if (engines == null) { |
michael@0 | 130 | engines = SyncConfiguration.validEngineNames(); |
michael@0 | 131 | } |
michael@0 | 132 | return engines; |
michael@0 | 133 | } |
michael@0 | 134 | |
michael@0 | 135 | /** |
michael@0 | 136 | * Fetches the engine names that should be displayed as selected for syncing. |
michael@0 | 137 | * Check first for selected engines set by this activity, then the enabled |
michael@0 | 138 | * engines, and finally default to the set of valid engine names for Android |
michael@0 | 139 | * Sync if neither exists. |
michael@0 | 140 | * |
michael@0 | 141 | * @param syncPrefs |
michael@0 | 142 | * <code>SharedPreferences</code> of Account being modified. |
michael@0 | 143 | * @return Set<String> of engine names to display as selected. Should never be |
michael@0 | 144 | * null. |
michael@0 | 145 | */ |
michael@0 | 146 | public static Set<String> getEnginesToSelect(SharedPreferences syncPrefs) { |
michael@0 | 147 | Set<String> engines = getEnginesFromPrefs(syncPrefs); |
michael@0 | 148 | Map<String, Boolean> engineSelections = SyncConfiguration.getUserSelectedEngines(syncPrefs); |
michael@0 | 149 | if (engineSelections != null) { |
michael@0 | 150 | for (Entry<String, Boolean> pair : engineSelections.entrySet()) { |
michael@0 | 151 | if (pair.getValue()) { |
michael@0 | 152 | engines.add(pair.getKey()); |
michael@0 | 153 | } else { |
michael@0 | 154 | engines.remove(pair.getKey()); |
michael@0 | 155 | } |
michael@0 | 156 | } |
michael@0 | 157 | } |
michael@0 | 158 | return engines; |
michael@0 | 159 | } |
michael@0 | 160 | |
michael@0 | 161 | public void setSelectionsInArray(Set<String> selected, boolean[] array) { |
michael@0 | 162 | for (int i = 0; i < _collectionsNames.length; i++) { |
michael@0 | 163 | array[i] = selected.contains(_collectionsNames[i]); |
michael@0 | 164 | } |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | @Override |
michael@0 | 168 | public void onClick(DialogInterface dialog, int which) { |
michael@0 | 169 | if (which == DialogInterface.BUTTON_POSITIVE) { |
michael@0 | 170 | Logger.debug(LOG_TAG, "Saving selected engines."); |
michael@0 | 171 | saveSelections(); |
michael@0 | 172 | setResult(RESULT_OK); |
michael@0 | 173 | Toast.makeText(this, R.string.sync_notification_savedprefs, Toast.LENGTH_SHORT).show(); |
michael@0 | 174 | } else { |
michael@0 | 175 | setResult(RESULT_CANCELED); |
michael@0 | 176 | } |
michael@0 | 177 | finish(); |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | @Override |
michael@0 | 181 | public void onClick(DialogInterface dialog, int which, boolean isChecked) { |
michael@0 | 182 | // Display multi-selection clicks in UI. |
michael@0 | 183 | _selections[which] = isChecked; |
michael@0 | 184 | ListView selectionsList = ((AlertDialog) dialog).getListView(); |
michael@0 | 185 | selectionsList.setItemChecked(which, isChecked); |
michael@0 | 186 | } |
michael@0 | 187 | |
michael@0 | 188 | /** |
michael@0 | 189 | * Persists engine selection state to SharedPreferences if it has changed. |
michael@0 | 190 | * |
michael@0 | 191 | * @return true if changed, false otherwise. |
michael@0 | 192 | */ |
michael@0 | 193 | private void saveSelections() { |
michael@0 | 194 | boolean[] origSelections = new boolean[_options.length]; |
michael@0 | 195 | setSelectionsInArray(getEnginesFromPrefs(accountPrefs), origSelections); |
michael@0 | 196 | |
michael@0 | 197 | Map<String, Boolean> engineSelections = new HashMap<String, Boolean>(); |
michael@0 | 198 | for (int i = 0; i < _selections.length; i++) { |
michael@0 | 199 | if (_selections[i] != origSelections[i]) { |
michael@0 | 200 | engineSelections.put(_collectionsNames[i], _selections[i]); |
michael@0 | 201 | } |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | // No GlobalSession.config, so store directly to prefs. |
michael@0 | 205 | SyncConfiguration.storeSelectedEnginesToPrefs(accountPrefs, engineSelections); |
michael@0 | 206 | |
michael@0 | 207 | // Request immediate sync. |
michael@0 | 208 | SyncAdapter.requestImmediateSync(account, null); |
michael@0 | 209 | } |
michael@0 | 210 | } |