GeneralPreferencesFragment.java revision 035a56419c1d2562be1e86273ebfe4c43c4f0c66
1a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton/*
2a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * Copyright (C) 2010 The Android Open Source Project
3a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton *
4a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License");
5a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * you may not use this file except in compliance with the License.
6a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * You may obtain a copy of the License at
7a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton *
8a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton *      http://www.apache.org/licenses/LICENSE-2.0
9a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton *
10a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * Unless required by applicable law or agreed to in writing, software
11a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS,
12a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * See the License for the specific language governing permissions and
14a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton * limitations under the License
15a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton */
16a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
17a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonpackage com.android.browser.preferences;
18a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
19a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport com.android.browser.BrowserBookmarksPage;
20035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reckimport com.android.browser.BrowserHomepagePreference;
21035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reckimport com.android.browser.BrowserPreferencesPage;
22af55452d7f37c20201663b80ca77b64457323361Ben Murdochimport com.android.browser.BrowserSettings;
23a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport com.android.browser.R;
24a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
25a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.accounts.Account;
26a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.accounts.AccountManager;
27a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.app.AlertDialog;
28a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.app.Dialog;
29a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.app.DialogFragment;
30a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.app.Fragment;
31a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.ContentProviderOperation;
32a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.ContentResolver;
33a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.ContentValues;
34a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.Context;
35a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.DialogInterface;
36a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.OperationApplicationException;
37a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.content.SharedPreferences;
3845ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reckimport android.content.SharedPreferences.OnSharedPreferenceChangeListener;
39a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.database.Cursor;
40f801fe2516298e08286cc161d7eb143635db205aBen Murdochimport android.os.AsyncTask;
41a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.os.Bundle;
42a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.os.RemoteException;
43a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.preference.Preference;
44a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.preference.Preference.OnPreferenceClickListener;
45a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.preference.PreferenceFragment;
46a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.preference.PreferenceManager;
47af55452d7f37c20201663b80ca77b64457323361Ben Murdochimport android.preference.PreferenceScreen;
48a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.provider.BrowserContract;
49a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.provider.BrowserContract.Bookmarks;
50a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.provider.BrowserContract.ChromeSyncColumns;
51a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.util.Log;
52a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.view.LayoutInflater;
53a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.view.View;
54a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.view.View.OnClickListener;
55a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.widget.Button;
56a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport android.widget.LinearLayout;
57a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
58a9bad830efad4c098e6f874704dedc005958aedfJeff Hamiltonimport java.util.ArrayList;
59a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
60035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reckpublic class GeneralPreferencesFragment extends PreferenceFragment
61035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        implements OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
62a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    static final String TAG = "PersonalPreferencesFragment";
63a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
64a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    static final String PREF_CHROME_SYNC = "sync_with_chrome";
65a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
66a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    Preference mChromeSync;
67a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    boolean mEnabled;
6845ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    SharedPreferences mSharedPrefs;
69a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
70a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    @Override
71a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    public void onCreate(Bundle savedInstanceState) {
72a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        super.onCreate(savedInstanceState);
73a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
74a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        // Load the XML preferences file
75035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        addPreferencesFromResource(R.xml.general_preferences);
76035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck
77035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        Preference e = findPreference(BrowserSettings.PREF_HOMEPAGE);
78035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        e.setOnPreferenceChangeListener(this);
79035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        e.setSummary(getPreferenceScreen().getSharedPreferences()
80035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck                .getString(BrowserSettings.PREF_HOMEPAGE, null));
81035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        ((BrowserHomepagePreference) e).setCurrentPage(
82035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck                getActivity().getIntent().getStringExtra(BrowserPreferencesPage.CURRENT_PAGE));
83035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck    }
84035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck
85035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck    @Override
86035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck    public boolean onPreferenceChange(Preference pref, Object objValue) {
87035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        if (getActivity() == null) {
88035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck            // We aren't attached, so don't accept preferences changes from the
89035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck            // invisible UI.
90035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck            Log.w("PageContentPreferencesFragment", "onPreferenceChange called from detached fragment!");
91035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck            return false;
92035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        }
93035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck
94035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        if (pref.getKey().equals(BrowserSettings.PREF_HOMEPAGE)) {
95035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck            pref.setSummary((String) objValue);
96035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck            return true;
97035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        }
98035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck
99035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck        return false;
100a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    }
101a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
102a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    @Override
103a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    public void onResume() {
104a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        super.onResume();
105a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
106a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        // Setup the proper state for the sync with chrome item
107a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        mChromeSync = findPreference(PREF_CHROME_SYNC);
10845ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        refreshUi();
10945ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
11045ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        mSharedPrefs.registerOnSharedPreferenceChangeListener(mListener);
111a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    }
112a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
11345ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    @Override
11445ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    public void onPause() {
11545ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        super.onPause();
11645ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck
11745ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        mSharedPrefs.unregisterOnSharedPreferenceChangeListener(mListener);
11845ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    }
11945ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck
12045ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    OnSharedPreferenceChangeListener mListener
12145ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck            = new OnSharedPreferenceChangeListener() {
12245ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        @Override
12345ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        public void onSharedPreferenceChanged(
12445ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck                SharedPreferences sharedPreferences, String key) {
12545ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck            if (BrowserBookmarksPage.PREF_ACCOUNT_NAME.equals(key)
12645ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck                    || BrowserBookmarksPage.PREF_ACCOUNT_TYPE.equals(key)) {
12745ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck                refreshUi();
12845ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck            }
12945ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        }
13045ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck
13145ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    };
13245ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck
133c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch    private class GetAccountsTask extends AsyncTask<Void, Void, String> {
134f801fe2516298e08286cc161d7eb143635db205aBen Murdoch        private Context mContext;
135f801fe2516298e08286cc161d7eb143635db205aBen Murdoch
136f801fe2516298e08286cc161d7eb143635db205aBen Murdoch        GetAccountsTask(Context ctx) {
137f801fe2516298e08286cc161d7eb143635db205aBen Murdoch            mContext = ctx;
138f801fe2516298e08286cc161d7eb143635db205aBen Murdoch        }
139f801fe2516298e08286cc161d7eb143635db205aBen Murdoch
14045ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        @Override
141c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch        protected String doInBackground(Void... unused) {
142f801fe2516298e08286cc161d7eb143635db205aBen Murdoch            AccountManager am = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
143f801fe2516298e08286cc161d7eb143635db205aBen Murdoch            Account[] accounts = am.getAccountsByType("com.google");
144f801fe2516298e08286cc161d7eb143635db205aBen Murdoch            if (accounts == null || accounts.length == 0) {
145f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                // No Google accounts setup, don't offer Chrome sync
146f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                if (mChromeSync != null) {
147f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                    getPreferenceScreen().removePreference(mChromeSync);
148f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                }
149a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            } else {
150c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                // Google accounts are present.
151f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
152f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                Bundle args = mChromeSync.getExtras();
153f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                args.putParcelableArray("accounts", accounts);
154f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                mEnabled = BrowserContract.Settings.isSyncEnabled(mContext);
155035a56419c1d2562be1e86273ebfe4c43c4f0c66John Reck                mChromeSync.setOnPreferenceClickListener(GeneralPreferencesFragment.this);
156c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch
157f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                if (!mEnabled) {
158f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                    // Setup a link to the enable wizard
159c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                    return mContext.getResources().getString(
160c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                            R.string.pref_personal_sync_with_chrome_summary);
161f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                } else {
162f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                    // Chrome sync is enabled, setup a link to account switcher
163c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                    String accountName = prefs.getString(
164c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                            BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
165f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                    args.putString("curAccount", accountName);
166c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                    return accountName;
167f801fe2516298e08286cc161d7eb143635db205aBen Murdoch                }
168a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
169f801fe2516298e08286cc161d7eb143635db205aBen Murdoch
170f801fe2516298e08286cc161d7eb143635db205aBen Murdoch            return null;
171a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
172c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch
17345ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        @Override
174c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch        protected void onPostExecute(String summary) {
175c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch            if (summary != null) {
176c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch                mChromeSync.setSummary(summary);
177c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch            }
178c9d0fdde15f7cefb29a5eb3f659890b2c4917f82Ben Murdoch        }
179f801fe2516298e08286cc161d7eb143635db205aBen Murdoch    }
180f801fe2516298e08286cc161d7eb143635db205aBen Murdoch
18145ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    void refreshUi() {
18245ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck        new GetAccountsTask(getActivity()).execute();
183af55452d7f37c20201663b80ca77b64457323361Ben Murdoch
184af55452d7f37c20201663b80ca77b64457323361Ben Murdoch        PreferenceScreen autoFillSettings =
185af55452d7f37c20201663b80ca77b64457323361Ben Murdoch                (PreferenceScreen)findPreference(BrowserSettings.PREF_AUTOFILL_PROFILE);
186af55452d7f37c20201663b80ca77b64457323361Ben Murdoch        autoFillSettings.setDependency(BrowserSettings.PREF_AUTOFILL_ENABLED);
187a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    }
188a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
189a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    @Override
190a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    public boolean onPreferenceClick(Preference preference) {
191a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        Fragment frag;
192a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        if (mEnabled) {
193a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            frag = new AccountChooserDialog();
194a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        } else {
195a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            frag = new ImportWizardDialog();
196a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
197a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        frag.setArguments(preference.getExtras());
198a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        getFragmentManager().openTransaction()
199a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                .add(frag, null)
200a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                .commit();
201a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        return true;
202a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    }
203a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
20445ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    public static class AccountChooserDialog extends DialogFragment
205a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            implements DialogInterface.OnClickListener {
206a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
207a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        AlertDialog mDialog;
208a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
209a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        @Override
210a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        public Dialog onCreateDialog(Bundle savedInstanceState) {
211a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Bundle args = getArguments();
212a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Account[] accounts = (Account[]) args.getParcelableArray("accounts");
213a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            String curAccount = args.getString("curAccount");
214a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            int length = accounts.length;
215a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            int curAccountOffset = 0;
216a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            CharSequence[] accountNames = new CharSequence[length];
217a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            for (int i = 0; i < length; i++) {
218a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                String name = accounts[i].name;
219a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                if (name.equals(curAccount)) {
220a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    curAccountOffset = i;
221a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                }
222a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                accountNames[i] = name;
223a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
224a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
225a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            mDialog = new AlertDialog.Builder(getActivity())
226a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .setIcon(android.R.drawable.ic_dialog_alert)
227a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .setTitle("Choose account") // STOPSHIP localize
228a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .setSingleChoiceItems(accountNames, curAccountOffset, this)
229a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .create();
230a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            return mDialog;
231a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
232a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
233a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        @Override
234a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        public void onClick(DialogInterface dialog, int which) {
235a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            String accountName = mDialog.getListView().getAdapter().getItem(which).toString();
236a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
237a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            prefs.edit().putString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, accountName).apply();
238a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            dismiss();
239a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
240a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    }
241a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
24245ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck    public static class ImportWizardDialog extends DialogFragment implements OnClickListener {
243a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        View mRemoveButton;
244a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        View mCancelButton;
245a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        String mDefaultAccount;
246a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
247a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        @Override
248a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        public Dialog onCreateDialog(Bundle savedInstanceState) {
249a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Context context = getActivity();
250a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Dialog dialog = new Dialog(context);
251a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            dialog.setTitle(R.string.import_bookmarks_dialog_title);
252a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            dialog.setContentView(R.layout.import_bookmarks_dialog);
253a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            mRemoveButton = dialog.findViewById(R.id.remove);
254a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            mRemoveButton.setOnClickListener(this);
255a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            mCancelButton = dialog.findViewById(R.id.cancel);
256a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            mCancelButton.setOnClickListener(this);
257a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
258a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            LayoutInflater inflater = dialog.getLayoutInflater();
259a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            LinearLayout accountList = (LinearLayout) dialog.findViewById(R.id.accountList);
260a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Account[] accounts = (Account[]) getArguments().getParcelableArray("accounts");
261a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            mDefaultAccount = accounts[0].name;
262a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            int length = accounts.length;
263a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            for (int i = 0; i < length; i++) {
264a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                Button button = (Button) inflater.inflate(R.layout.import_bookmarks_dialog_button,
265a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        null);
266a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                button.setText(context.getString(R.string.import_bookmarks_dialog_import,
267a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        accounts[i].name));
268a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                button.setTag(accounts[i].name);
269a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                button.setOnClickListener(this);
270a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                accountList.addView(button);
271a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
272a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
273a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            return dialog;
274a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
275a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
276a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        @Override
277a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        public void onClick(View view) {
278a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            if (view == mCancelButton) {
279a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                dismiss();
280a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                return;
281a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
282a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
283a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            ContentResolver resolver = getActivity().getContentResolver();
284a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
285a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            String accountName;
286a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            if (view == mRemoveButton) {
287a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                // The user chose to remove their old bookmarks, delete them now
288a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                resolver.delete(Bookmarks.CONTENT_URI,
289a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        Bookmarks.PARENT + "=1 AND " + Bookmarks.ACCOUNT_NAME + " IS NULL", null);
290a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                accountName = mDefaultAccount;
291a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            } else {
292a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                // The user chose to migrate their old bookmarks to the account they're syncing
293a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                accountName = view.getTag().toString();
294a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                migrateBookmarks(resolver, accountName);
295a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
296a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
297a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            // Record the fact that we turned on sync
298a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            BrowserContract.Settings.setSyncEnabled(getActivity(), true);
299a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            prefs.edit()
300a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .putString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, "com.google")
301a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .putString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, accountName)
302a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    .apply();
303a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
304a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            // Enable bookmark sync on all accounts
305a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Account[] accounts = (Account[]) getArguments().getParcelableArray("accounts");
306a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            for (Account account : accounts) {
307a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                ContentResolver.setIsSyncable(account, BrowserContract.AUTHORITY, 1);
308a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
309a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
310a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            dismiss();
311a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
312a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
313a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        /**
314a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton         * Migrates bookmarks to the given account
315a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton         */
316a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        void migrateBookmarks(ContentResolver resolver, String accountName) {
317a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            Cursor cursor = null;
318a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            try {
319a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                // Re-parent the bookmarks in the default root folder
320a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                cursor = resolver.query(Bookmarks.CONTENT_URI, new String[] { Bookmarks._ID },
321a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        Bookmarks.ACCOUNT_NAME + " =? AND " +
322a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            ChromeSyncColumns.SERVER_UNIQUE + " =?",
323a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        new String[] { accountName,
324a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR },
325a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        null);
326a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                ContentValues values = new ContentValues();
327a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                if (cursor == null || !cursor.moveToFirst()) {
328a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // The root folders don't exist for the account, create them now
329a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ArrayList<ContentProviderOperation> ops =
330a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            new ArrayList<ContentProviderOperation>();
331a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
332a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Chrome sync root folder
333a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.clear();
334a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(ChromeSyncColumns.SERVER_UNIQUE, ChromeSyncColumns.FOLDER_NAME_ROOT);
335a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.TITLE, "Google Chrome");
336a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.POSITION, 0);
337a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.IS_FOLDER, true);
338a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.DIRTY, true);
339a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ops.add(ContentProviderOperation.newInsert(
340a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            Bookmarks.CONTENT_URI.buildUpon().appendQueryParameter(
341a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                                    BrowserContract.CALLER_IS_SYNCADAPTER, "true").build())
342a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValues(values)
343a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .build());
344a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
345a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Bookmarks folder
346a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.clear();
347a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(ChromeSyncColumns.SERVER_UNIQUE,
348a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            ChromeSyncColumns.FOLDER_NAME_BOOKMARKS);
349a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.TITLE, "Bookmarks");
350a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.POSITION, 0);
351a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.IS_FOLDER, true);
352a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.DIRTY, true);
353a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ops.add(ContentProviderOperation.newInsert(Bookmarks.CONTENT_URI)
354a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValues(values)
355a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValueBackReference(Bookmarks.PARENT, 0)
356a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .build());
357a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
358a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Bookmarks Bar folder
359a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.clear();
360a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(ChromeSyncColumns.SERVER_UNIQUE,
361a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR);
362a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.TITLE, "Bookmarks Bar");
363a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.POSITION, 0);
364a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.IS_FOLDER, true);
365a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.DIRTY, true);
366a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ops.add(ContentProviderOperation.newInsert(Bookmarks.CONTENT_URI)
367a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValues(values)
368a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValueBackReference(Bookmarks.PARENT, 1)
369a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .build());
370a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
371a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Other Bookmarks folder
372a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.clear();
373a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(ChromeSyncColumns.SERVER_UNIQUE,
374a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS);
375a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.TITLE, "Other Bookmarks");
376a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.POSITION, 1000);
377a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.IS_FOLDER, true);
378a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.DIRTY, true);
379a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ops.add(ContentProviderOperation.newInsert(Bookmarks.CONTENT_URI)
380a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValues(values)
381a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValueBackReference(Bookmarks.PARENT, 1)
382a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .build());
383a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
384a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Re-parent the existing bookmarks to the newly create bookmarks bar folder
385a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ops.add(ContentProviderOperation.newUpdate(Bookmarks.CONTENT_URI)
386a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValueBackReference(Bookmarks.PARENT, 2)
387a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withSelection(Bookmarks.PARENT + "=?",
388a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                                        new String[] { Integer.toString(1) })
389a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .build());
390a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
391a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Mark all non-root folder items as belonging to the new account
392a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.clear();
393a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.ACCOUNT_TYPE, "com.google");
394a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.ACCOUNT_NAME, accountName);
395a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    ops.add(ContentProviderOperation.newUpdate(Bookmarks.CONTENT_URI)
396a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withValues(values)
397a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .withSelection(Bookmarks.ACCOUNT_NAME + " IS NULL AND " +
398a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                                    Bookmarks._ID + "<>1", null)
399a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            .build());
40045ceccb271fcbf301c7c3d5e0c77ae1e53f28cdaJohn Reck
401a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    try {
402a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        resolver.applyBatch(BrowserContract.AUTHORITY, ops);
403a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    } catch (RemoteException e) {
404a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        Log.e(TAG, "failed to create root folder for account " + accountName, e);
405a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        return;
406a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    } catch (OperationApplicationException e) {
407a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        Log.e(TAG, "failed to create root folder for account " + accountName, e);
408a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                        return;
409a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    }
410a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                } else {
411a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.PARENT, cursor.getLong(0));
412a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    resolver.update(Bookmarks.CONTENT_URI, values, Bookmarks.PARENT + "=?",
413a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            new String[] { Integer.toString(1) });
414a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton
415a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    // Mark all bookmarks at all levels as part of the new account
416a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.clear();
417a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.ACCOUNT_TYPE, "com.google");
418a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    values.put(Bookmarks.ACCOUNT_NAME, accountName);
419a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                    resolver.update(Bookmarks.CONTENT_URI, values,
420a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            Bookmarks.ACCOUNT_NAME + " IS NULL AND " + Bookmarks._ID + "<>1",
421a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                            null);
422a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                }
423a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            } finally {
424a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton                if (cursor != null) cursor.close();
425a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton            }
426a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton        }
427a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton    }
428a9bad830efad4c098e6f874704dedc005958aedfJeff Hamilton}
429