10c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project/*
20c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
30c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
40c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
50c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * you may not use this file except in compliance with the License.
60c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * You may obtain a copy of the License at
70c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
80c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
90c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * See the License for the specific language governing permissions and
140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * limitations under the License.
150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */
160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpackage com.android.browser;
180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
2064144e49208df145c8362dfa037335c7b9210167Jeff Hamiltonimport android.app.Fragment;
218402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.app.LoaderManager;
22eb07b178e8efa86756edbb935e43e9658b5da3fbDianne Hackbornimport android.content.ClipData;
23bef7a759aa57894124c67ff4912ea595cdc92ce1Michael Kolbimport android.content.ClipboardManager;
248402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.content.ContentUris;
2580f32627140aefe828ad539f66fc439d1580bae7Dianne Hackbornimport android.content.Context;
2671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reckimport android.content.CursorLoader;
270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
288402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.content.Loader;
294f61ee45c1a2794d4254998c735a320fa6718eddJohn Reckimport android.content.SharedPreferences;
30b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reckimport android.content.res.Configuration;
31b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reckimport android.content.res.Resources;
328402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.database.Cursor;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
348402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.graphics.BitmapFactory;
35f94abcf44fc1611f76e55461f48220e621fc31b7John Reckimport android.graphics.BitmapFactory.Options;
368402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.net.Uri;
37c8490818ccb693ed2610366d2e91fb290e40c372John Reckimport android.os.AsyncTask;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
3969bd7077becb42438513fa80c98d0b48c8a23a41Jeff Hamiltonimport android.provider.BrowserContract;
4071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reckimport android.provider.BrowserContract.Accounts;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
42db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamiltonimport android.view.ContextMenu.ContextMenuInfo;
4364144e49208df145c8362dfa037335c7b9210167Jeff Hamiltonimport android.view.LayoutInflater;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
47db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamiltonimport android.view.ViewGroup;
4871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reckimport android.widget.ExpandableListView;
4971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reckimport android.widget.ExpandableListView.OnChildClickListener;
50feb941d4be5daaf439f6b463f423618caee15892Leon Scrogginsimport android.widget.Toast;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
521e9815d4c4864790fde2ad1e216058f922060c92John Reckimport com.android.browser.provider.BrowserProvider2;
539db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reckimport com.android.browser.view.BookmarkExpandableView;
549db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reckimport com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo;
55e7c97de989b75a591d598da63e0bef51831462d4John Reck
564f61ee45c1a2794d4254998c735a320fa6718eddJohn Reckimport org.json.JSONException;
574f61ee45c1a2794d4254998c735a320fa6718eddJohn Reckimport org.json.JSONObject;
584f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck
5971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reckimport java.util.HashMap;
6071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck
61608baa78f4071409294f79b37e7ffa9ca96c4223John Reckinterface BookmarksPageCallbacks {
62608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    // Return true if handled
63608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    boolean onBookmarkSelected(Cursor c, boolean isFolder);
64608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    // Return true if handled
65d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck    boolean onOpenInNewWindow(String... urls);
66608baa78f4071409294f79b37e7ffa9ca96c4223John Reck}
67608baa78f4071409294f79b37e7ffa9ca96c4223John Reck
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project/**
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *  View showing the user's bookmarks in the browser.
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */
7164144e49208df145c8362dfa037335c7b9210167Jeff Hamiltonpublic class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
729db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reck        LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller,
73d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck        OnChildClickListener {
748402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
75e7c97de989b75a591d598da63e0bef51831462d4John Reck    public static class ExtraDragState {
76e7c97de989b75a591d598da63e0bef51831462d4John Reck        public int childPosition;
77e7c97de989b75a591d598da63e0bef51831462d4John Reck        public int groupPosition;
78e7c97de989b75a591d598da63e0bef51831462d4John Reck    }
79e7c97de989b75a591d598da63e0bef51831462d4John Reck
808402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    static final String LOGTAG = "browser";
818402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
8271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    static final int LOADER_ACCOUNTS = 1;
8371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    static final int LOADER_BOOKMARKS = 100;
848402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
85801ecb73006a3062cdfeacf7ad6016e0a358671cMichael Kolb    static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
864f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck    static final String PREF_GROUP_STATE = "bbp_group_state";
87801ecb73006a3062cdfeacf7ad6016e0a358671cMichael Kolb
8871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    static final String ACCOUNT_TYPE = "account_type";
8971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    static final String ACCOUNT_NAME = "account_name";
9071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck
91608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    BookmarksPageCallbacks mCallbacks;
920ce8a942a895cfe1d432076a95f3ed3798ccb002John Reck    View mRoot;
939db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reck    BookmarkExpandableView mGrid;
948402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    boolean mDisableNewWindow;
95608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    boolean mEnableContextMenu = true;
968402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    View mEmptyView;
97608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    View mHeader;
9871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
994f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck    JSONObject mState;
100370a4f3e47b740fd10b9028aae9e87e17254caa8Michael Kolb
1018402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    @Override
1028402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
10371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        if (id == LOADER_ACCOUNTS) {
10471efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            return new AccountsLoader(getActivity());
10571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        } else if (id >= LOADER_BOOKMARKS) {
10671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            String accountType = args.getString(ACCOUNT_TYPE);
10771efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            String accountName = args.getString(ACCOUNT_NAME);
10871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            BookmarksLoader bl = new BookmarksLoader(getActivity(),
10971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                    accountType, accountName);
11071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            return bl;
11171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        } else {
11271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            throw new UnsupportedOperationException("Unknown loader id " + id);
1138402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
1148402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
1158402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1168402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    @Override
117db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamilton    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
11871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        if (loader.getId() == LOADER_ACCOUNTS) {
11971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            LoaderManager lm = getLoaderManager();
12071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            int id = LOADER_BOOKMARKS;
12171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            while (cursor.moveToNext()) {
12271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                String accountName = cursor.getString(0);
12371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                String accountType = cursor.getString(1);
12471efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                Bundle args = new Bundle();
12571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                args.putString(ACCOUNT_NAME, accountName);
12671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                args.putString(ACCOUNT_TYPE, accountType);
12771efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter(
128af991f93d09bf4d2db3c7a8c03ca3ca4352bed83John Reck                        getActivity());
12971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                mBookmarkAdapters.put(id, adapter);
1304f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                boolean expand = true;
1314f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                try {
1324f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                    expand = mState.getBoolean(accountName != null ? accountName
1334f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                            : BookmarkExpandableView.LOCAL_ACCOUNT_NAME);
1344f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                } catch (JSONException e) {} // no state for accountName
1354f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                mGrid.addAccount(accountName, adapter, expand);
13671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                lm.restartLoader(id, args, this);
13771efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                id++;
138db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamilton            }
13971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // TODO: Figure out what a reload of these means
14071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // Currently, a reload is triggered whenever bookmarks change
14171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // This is less than ideal
14271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // It also causes UI flickering as a new adapter is created
14371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // instead of re-using an existing one when the account_name is the
14471efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // same.
14571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            // For now, this is a one-shot load
14671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
14771efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        } else if (loader.getId() >= LOADER_BOOKMARKS) {
14871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
14971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            adapter.changeCursor(cursor);
15039772c83f8e210eed1186b66f5f4841aa41776eeDianne Hackborn        }
15139772c83f8e210eed1186b66f5f4841aa41776eeDianne Hackborn    }
15239772c83f8e210eed1186b66f5f4841aa41776eeDianne Hackborn
153522a438d69486914a364c2fe0934c08269b1129fJohn Reck    @Override
15439772c83f8e210eed1186b66f5f4841aa41776eeDianne Hackborn    public void onLoaderReset(Loader<Cursor> loader) {
1553ad8d5cf0911ba015e019bc75e8fb13c091efe0eJohn Reck        if (loader.getId() >= LOADER_BOOKMARKS) {
1563ad8d5cf0911ba015e019bc75e8fb13c091efe0eJohn Reck            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
1573ad8d5cf0911ba015e019bc75e8fb13c091efe0eJohn Reck            adapter.changeCursor(null);
1583ad8d5cf0911ba015e019bc75e8fb13c091efe0eJohn Reck        }
1598402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
1608402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
1620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
16354ed3aa8417f4c6a27eecb9caf10f742a705b6e0John Reck        if (!(item.getMenuInfo() instanceof BookmarkContextMenuInfo)) {
16454ed3aa8417f4c6a27eecb9caf10f742a705b6e0John Reck            return false;
16554ed3aa8417f4c6a27eecb9caf10f742a705b6e0John Reck        }
16654ed3aa8417f4c6a27eecb9caf10f742a705b6e0John Reck        BookmarkContextMenuInfo i = (BookmarkContextMenuInfo) item.getMenuInfo();
1670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If we have no menu info, we can't tell which item was selected.
1680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (i == null) {
169c8cae086f23bd8f3d740befcdbbda9a8688cc2a3Leon Scroggins            return false;
1700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
171095292f343583627ecd150fb4d1b34767402630fNicolas Catania
172e7c97de989b75a591d598da63e0bef51831462d4John Reck        if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) {
173e7c97de989b75a591d598da63e0bef51831462d4John Reck            return true;
174e7c97de989b75a591d598da63e0bef51831462d4John Reck        }
175e7c97de989b75a591d598da63e0bef51831462d4John Reck        return super.onContextItemSelected(item);
176e7c97de989b75a591d598da63e0bef51831462d4John Reck    }
177e7c97de989b75a591d598da63e0bef51831462d4John Reck
178e7c97de989b75a591d598da63e0bef51831462d4John Reck    public boolean handleContextItem(int itemId, int groupPosition,
179e7c97de989b75a591d598da63e0bef51831462d4John Reck            int childPosition) {
180e7c97de989b75a591d598da63e0bef51831462d4John Reck        final Activity activity = getActivity();
181e7c97de989b75a591d598da63e0bef51831462d4John Reck        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
182e7c97de989b75a591d598da63e0bef51831462d4John Reck
183e7c97de989b75a591d598da63e0bef51831462d4John Reck        switch (itemId) {
1840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        case R.id.open_context_menu_id:
185e7c97de989b75a591d598da63e0bef51831462d4John Reck            loadUrl(adapter, childPosition);
1860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            break;
1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        case R.id.edit_context_menu_id:
188e7c97de989b75a591d598da63e0bef51831462d4John Reck            editBookmark(adapter, childPosition);
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            break;
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        case R.id.shortcut_context_menu_id:
191e7c97de989b75a591d598da63e0bef51831462d4John Reck            Cursor c = adapter.getItem(childPosition);
192608baa78f4071409294f79b37e7ffa9ca96c4223John Reck            activity.sendBroadcast(createShortcutIntent(getActivity(), c));
1930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            break;
1940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        case R.id.delete_context_menu_id:
195e7c97de989b75a591d598da63e0bef51831462d4John Reck            displayRemoveBookmarkDialog(adapter, childPosition);
1960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            break;
1970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        case R.id.new_window_context_menu_id:
198e7c97de989b75a591d598da63e0bef51831462d4John Reck            openInNewWindow(adapter, childPosition);
1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            break;
2008402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        case R.id.share_link_context_menu_id: {
201e7c97de989b75a591d598da63e0bef51831462d4John Reck            Cursor cursor = adapter.getItem(childPosition);
2028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Controller.sharePage(activity,
2038402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
2048402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
2058402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON),
2068402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL));
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            break;
2088402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
2090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        case R.id.copy_url_context_menu_id:
210e7c97de989b75a591d598da63e0bef51831462d4John Reck            copy(getUrl(adapter, childPosition));
211feb941d4be5daaf439f6b463f423618caee15892Leon Scroggins            break;
2128402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        case R.id.homepage_context_menu_id: {
213e7c97de989b75a591d598da63e0bef51831462d4John Reck            BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition));
21464144e49208df145c8362dfa037335c7b9210167Jeff Hamilton            Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
215feb941d4be5daaf439f6b463f423618caee15892Leon Scroggins            break;
2168402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
217a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins        // Only for the Most visited page
2188402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        case R.id.save_to_bookmarks_menu_id: {
219e7c97de989b75a591d598da63e0bef51831462d4John Reck            Cursor cursor = adapter.getItem(childPosition);
2208402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
2218402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
222a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins            // If the site is bookmarked, the item becomes remove from
223a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins            // bookmarks.
22464144e49208df145c8362dfa037335c7b9210167Jeff Hamilton            Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name);
225a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins            break;
2268402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        default:
228e7c97de989b75a591d598da63e0bef51831462d4John Reck            return false;
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
233608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    static Bitmap getBitmap(Cursor cursor, int columnIndex) {
234f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        return getBitmap(cursor, columnIndex, null);
235f94abcf44fc1611f76e55461f48220e621fc31b7John Reck    }
236f94abcf44fc1611f76e55461f48220e621fc31b7John Reck
237f94abcf44fc1611f76e55461f48220e621fc31b7John Reck    static ThreadLocal<Options> sOptions = new ThreadLocal<Options>() {
238f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        @Override
239f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        protected Options initialValue() {
240f94abcf44fc1611f76e55461f48220e621fc31b7John Reck            return new Options();
241f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        };
242f94abcf44fc1611f76e55461f48220e621fc31b7John Reck    };
243f94abcf44fc1611f76e55461f48220e621fc31b7John Reck    static Bitmap getBitmap(Cursor cursor, int columnIndex, Bitmap inBitmap) {
2448402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        byte[] data = cursor.getBlob(columnIndex);
2458402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        if (data == null) {
2468402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            return null;
2478402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
248f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        Options opts = sOptions.get();
249f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        opts.inBitmap = inBitmap;
250f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        opts.inSampleSize = 1;
251f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        opts.inScaled = false;
252f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        try {
253f94abcf44fc1611f76e55461f48220e621fc31b7John Reck            return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
254f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        } catch (IllegalArgumentException ex) {
255f94abcf44fc1611f76e55461f48220e621fc31b7John Reck            // Failed to re-use bitmap, create a new one
256f94abcf44fc1611f76e55461f48220e621fc31b7John Reck            return BitmapFactory.decodeByteArray(data, 0, data.length);
257f94abcf44fc1611f76e55461f48220e621fc31b7John Reck        }
2588402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
2598402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
260c8490818ccb693ed2610366d2e91fb290e40c372John Reck    private MenuItem.OnMenuItemClickListener mContextItemClickListener =
261c8490818ccb693ed2610366d2e91fb290e40c372John Reck            new MenuItem.OnMenuItemClickListener() {
262c8490818ccb693ed2610366d2e91fb290e40c372John Reck        @Override
263c8490818ccb693ed2610366d2e91fb290e40c372John Reck        public boolean onMenuItemClick(MenuItem item) {
264c8490818ccb693ed2610366d2e91fb290e40c372John Reck            return onContextItemSelected(item);
265c8490818ccb693ed2610366d2e91fb290e40c372John Reck        }
266c8490818ccb693ed2610366d2e91fb290e40c372John Reck    };
267c8490818ccb693ed2610366d2e91fb290e40c372John Reck
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
2698402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
27071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo;
27171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition);
27271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        Cursor cursor = adapter.getItem(info.childPosition);
2731cebb445779da9ca597621c79b020d6e5ea54fb2John Reck        if (!canEdit(cursor)) {
2741cebb445779da9ca597621c79b020d6e5ea54fb2John Reck            return;
2751cebb445779da9ca597621c79b020d6e5ea54fb2John Reck        }
2765e8a40f0b4a191735f7f5fcefceb26cc1146e4e5Leon Scroggins        boolean isFolder
2775e8a40f0b4a191735f7f5fcefceb26cc1146e4e5Leon Scroggins                = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
278801ecb73006a3062cdfeacf7ad6016e0a358671cMichael Kolb
27964144e49208df145c8362dfa037335c7b9210167Jeff Hamilton        final Activity activity = getActivity();
28064144e49208df145c8362dfa037335c7b9210167Jeff Hamilton        MenuInflater inflater = activity.getMenuInflater();
2818402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        inflater.inflate(R.menu.bookmarkscontext, menu);
282c8490818ccb693ed2610366d2e91fb290e40c372John Reck        if (isFolder) {
283c8490818ccb693ed2610366d2e91fb290e40c372John Reck            menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true);
284c8490818ccb693ed2610366d2e91fb290e40c372John Reck        } else {
285c8490818ccb693ed2610366d2e91fb290e40c372John Reck            menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true);
286c8490818ccb693ed2610366d2e91fb290e40c372John Reck            if (mDisableNewWindow) {
287c8490818ccb693ed2610366d2e91fb290e40c372John Reck                menu.findItem(R.id.new_window_context_menu_id).setVisible(false);
288c8490818ccb693ed2610366d2e91fb290e40c372John Reck            }
2898402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
290c8490818ccb693ed2610366d2e91fb290e40c372John Reck        BookmarkItem header = new BookmarkItem(activity);
29183c0151b266f4789cb1728294eac98e3dba0ed53John Reck        header.setEnableScrolling(true);
292c8490818ccb693ed2610366d2e91fb290e40c372John Reck        populateBookmarkItem(cursor, header, isFolder);
293c8490818ccb693ed2610366d2e91fb290e40c372John Reck        menu.setHeaderView(header);
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
295c8490818ccb693ed2610366d2e91fb290e40c372John Reck        int count = menu.size();
296c8490818ccb693ed2610366d2e91fb290e40c372John Reck        for (int i = 0; i < count; i++) {
297c8490818ccb693ed2610366d2e91fb290e40c372John Reck            menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener);
2988402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
2998402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
3008402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
3011cebb445779da9ca597621c79b020d6e5ea54fb2John Reck    boolean canEdit(Cursor c) {
302d18ac4b36b057a6a403cb060dfc10761b7394548John Reck        int type = c.getInt(BookmarksLoader.COLUMN_INDEX_TYPE);
303d18ac4b36b057a6a403cb060dfc10761b7394548John Reck        return type == BrowserContract.Bookmarks.BOOKMARK_TYPE_BOOKMARK
304d18ac4b36b057a6a403cb060dfc10761b7394548John Reck                || type == BrowserContract.Bookmarks.BOOKMARK_TYPE_FOLDER;
3051cebb445779da9ca597621c79b020d6e5ea54fb2John Reck    }
3061cebb445779da9ca597621c79b020d6e5ea54fb2John Reck
307c8490818ccb693ed2610366d2e91fb290e40c372John Reck    private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) {
3088402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
309c8490818ccb693ed2610366d2e91fb290e40c372John Reck        if (isFolder) {
310c8490818ccb693ed2610366d2e91fb290e40c372John Reck            item.setUrl(null);
311c8490818ccb693ed2610366d2e91fb290e40c372John Reck            Bitmap bitmap =
3125a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb                BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark);
313c8490818ccb693ed2610366d2e91fb290e40c372John Reck            item.setFavicon(bitmap);
31460e333622004cdcab73ceaacdd932fc05f8d6c77John Reck            new LookupBookmarkCount(getActivity(), item)
31560e333622004cdcab73ceaacdd932fc05f8d6c77John Reck                    .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
316c8490818ccb693ed2610366d2e91fb290e40c372John Reck        } else {
317c8490818ccb693ed2610366d2e91fb290e40c372John Reck            String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
318c8490818ccb693ed2610366d2e91fb290e40c372John Reck            item.setUrl(url);
319c8490818ccb693ed2610366d2e91fb290e40c372John Reck            Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
320c8490818ccb693ed2610366d2e91fb290e40c372John Reck            item.setFavicon(bitmap);
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3228402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  Create a new BrowserBookmarksPage.
326095292f343583627ecd150fb4d1b34767402630fNicolas Catania     */
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
32864144e49208df145c8362dfa037335c7b9210167Jeff Hamilton    public void onCreate(Bundle icicle) {
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
3304f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
3314f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        try {
3324f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            mState = new JSONObject(prefs.getString(PREF_GROUP_STATE, "{}"));
3334f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        } catch (JSONException e) {
3344f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            // Parse failed, clear preference and start with empty state
3354f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            prefs.edit().remove(PREF_GROUP_STATE).apply();
3364f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            mState = new JSONObject();
3374f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        }
33864144e49208df145c8362dfa037335c7b9210167Jeff Hamilton        Bundle args = getArguments();
339bc92285a27fa629d630d3ea0d0608f13a6de5deeLeon Scroggins        mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
3408f295d12fca05149753b4b0c127e1ec6c2e27d2fJohn Reck        setHasOptionsMenu(true);
3412d963a2899afbe000d1ab498f94de87f25e33184John Reck        if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) {
3422d963a2899afbe000d1ab498f94de87f25e33184John Reck            mCallbacks = new CombinedBookmarksCallbackWrapper(
3432d963a2899afbe000d1ab498f94de87f25e33184John Reck                    (CombinedBookmarksCallbacks) getActivity());
3442d963a2899afbe000d1ab498f94de87f25e33184John Reck        }
34564144e49208df145c8362dfa037335c7b9210167Jeff Hamilton    }
3468402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
3474f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck    @Override
3484f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck    public void onPause() {
3494f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        super.onPause();
3504f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        try {
3514f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            mState = mGrid.saveGroupState();
3524f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            // Save state
3534f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
3544f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            prefs.edit()
3554f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                    .putString(PREF_GROUP_STATE, mState.toString())
3564f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck                    .apply();
3574f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        } catch (JSONException e) {
3584f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck            // Not critical, ignore
3594f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck        }
3604f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck    }
3614f61ee45c1a2794d4254998c735a320fa6718eddJohn Reck
3622d963a2899afbe000d1ab498f94de87f25e33184John Reck    private static class CombinedBookmarksCallbackWrapper
3632d963a2899afbe000d1ab498f94de87f25e33184John Reck            implements BookmarksPageCallbacks {
3642d963a2899afbe000d1ab498f94de87f25e33184John Reck
3652d963a2899afbe000d1ab498f94de87f25e33184John Reck        private CombinedBookmarksCallbacks mCombinedCallback;
3662d963a2899afbe000d1ab498f94de87f25e33184John Reck
3672d963a2899afbe000d1ab498f94de87f25e33184John Reck        private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) {
3682d963a2899afbe000d1ab498f94de87f25e33184John Reck            mCombinedCallback = cb;
3692d963a2899afbe000d1ab498f94de87f25e33184John Reck        }
3702d963a2899afbe000d1ab498f94de87f25e33184John Reck
3712d963a2899afbe000d1ab498f94de87f25e33184John Reck        @Override
3722d963a2899afbe000d1ab498f94de87f25e33184John Reck        public boolean onOpenInNewWindow(String... urls) {
3732d963a2899afbe000d1ab498f94de87f25e33184John Reck            mCombinedCallback.openInNewTab(urls);
3742d963a2899afbe000d1ab498f94de87f25e33184John Reck            return true;
3752d963a2899afbe000d1ab498f94de87f25e33184John Reck        }
3762d963a2899afbe000d1ab498f94de87f25e33184John Reck
3772d963a2899afbe000d1ab498f94de87f25e33184John Reck        @Override
3782d963a2899afbe000d1ab498f94de87f25e33184John Reck        public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
3792d963a2899afbe000d1ab498f94de87f25e33184John Reck            if (isFolder) {
3802d963a2899afbe000d1ab498f94de87f25e33184John Reck                return false;
3812d963a2899afbe000d1ab498f94de87f25e33184John Reck            }
3822d963a2899afbe000d1ab498f94de87f25e33184John Reck            mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c));
3832d963a2899afbe000d1ab498f94de87f25e33184John Reck            return true;
3842d963a2899afbe000d1ab498f94de87f25e33184John Reck        }
3852d963a2899afbe000d1ab498f94de87f25e33184John Reck    };
3862d963a2899afbe000d1ab498f94de87f25e33184John Reck
38764144e49208df145c8362dfa037335c7b9210167Jeff Hamilton    @Override
38864144e49208df145c8362dfa037335c7b9210167Jeff Hamilton    public View onCreateView(LayoutInflater inflater, ViewGroup container,
38964144e49208df145c8362dfa037335c7b9210167Jeff Hamilton            Bundle savedInstanceState) {
3900ce8a942a895cfe1d432076a95f3ed3798ccb002John Reck        mRoot = inflater.inflate(R.layout.bookmarks, container, false);
3910ce8a942a895cfe1d432076a95f3ed3798ccb002John Reck        mEmptyView = mRoot.findViewById(android.R.id.empty);
3928402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
3939db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reck        mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid);
39471efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        mGrid.setOnChildClickListener(this);
39571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
39671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        mGrid.setBreadcrumbController(this);
397608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        setEnableContextMenu(mEnableContextMenu);
398608baa78f4071409294f79b37e7ffa9ca96c4223John Reck
399db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamilton        // Start the loaders
400db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamilton        LoaderManager lm = getLoaderManager();
40171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        lm.restartLoader(LOADER_ACCOUNTS, null, this);
4028402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
4030ce8a942a895cfe1d432076a95f3ed3798ccb002John Reck        return mRoot;
40464144e49208df145c8362dfa037335c7b9210167Jeff Hamilton    }
405801ecb73006a3062cdfeacf7ad6016e0a358671cMichael Kolb
406608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    @Override
407608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    public void onDestroyView() {
408608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        super.onDestroyView();
40971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        mGrid.setBreadcrumbController(null);
410c3c46d7731006ba78497c61aa4fec34d58ac182eJohn Reck        mGrid.clearAccounts();
41171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        LoaderManager lm = getLoaderManager();
41271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        lm.destroyLoader(LOADER_ACCOUNTS);
41371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        for (int id : mBookmarkAdapters.keySet()) {
41471efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            lm.destroyLoader(id);
41571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        }
41671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        mBookmarkAdapters.clear();
417095292f343583627ecd150fb4d1b34767402630fNicolas Catania    }
418095292f343583627ecd150fb4d1b34767402630fNicolas Catania
41971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
4209db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reck        return mGrid.getChildAdapter(groupPosition);
42171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    }
42271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck
42371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private BreadCrumbView getBreadCrumbs(int groupPosition) {
4249db9529bdb7490ccd72fbe66f7e9c9d7cdd73899John Reck        return mGrid.getBreadCrumbs(groupPosition);
42571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    }
426db90aa83e0d99212af3ee063360cdaf4cdb61e94Jeff Hamilton
42771efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    @Override
42871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    public boolean onChildClick(ExpandableListView parent, View v,
42971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            int groupPosition, int childPosition, long id) {
43071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
43171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        Cursor cursor = adapter.getItem(childPosition);
432608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
433608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        if (mCallbacks != null &&
434608baa78f4071409294f79b37e7ffa9ca96c4223John Reck                mCallbacks.onBookmarkSelected(cursor, isFolder)) {
43571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            return true;
436328ea87539544e6aff7d850347ce9b57ba4ce1adBen Murdoch        }
437328ea87539544e6aff7d850347ce9b57ba4ce1adBen Murdoch
438608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        if (isFolder) {
439370a4f3e47b740fd10b9028aae9e87e17254caa8Michael Kolb            String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
4408402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            Uri uri = ContentUris.withAppendedId(
4418402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
44271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            BreadCrumbView crumbs = getBreadCrumbs(groupPosition);
44371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            if (crumbs != null) {
444370a4f3e47b740fd10b9028aae9e87e17254caa8Michael Kolb                // update crumbs
44571efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                crumbs.pushView(title, uri);
446cece1fe59c45893bb46e321917aa881705ab0b7eJohn Reck                crumbs.setVisibility(View.VISIBLE);
447370a4f3e47b740fd10b9028aae9e87e17254caa8Michael Kolb            }
44871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            loadFolder(groupPosition, uri);
449fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        }
45071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        return true;
4518402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
453608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
4548402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
455ccaa8964a7c3cb6aec75e4c366e29524e8304abfMichael Kolb        String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
4568402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
4578402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
458608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private void loadUrl(BrowserBookmarksAdapter adapter, int position) {
46271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        if (mCallbacks != null && adapter != null) {
46371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            mCallbacks.onBookmarkSelected(adapter.getItem(position), false);
464608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        }
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46771efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) {
468608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        if (mCallbacks != null) {
46971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            Cursor c = adapter.getItem(position);
4701b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1;
4711b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            if (isFolder) {
4721b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck                long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
4731b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck                new OpenAllInTabsTask(id).execute();
4741b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            } else {
475d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck                mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c));
4761b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            }
4771b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        }
4781b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck    }
4791b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck
4801b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck    class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> {
4811b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        long mFolderId;
4821b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        public OpenAllInTabsTask(long id) {
4831b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            mFolderId = id;
4841b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        }
4851b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck
4861b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        @Override
4871b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        protected Cursor doInBackground(Void... params) {
4881b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            Context c = getActivity();
4891b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            if (c == null) return null;
4901b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c),
4911b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck                    BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?",
4921b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck                    new String[] { Long.toString(mFolderId) }, null);
493608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        }
4941b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck
4951b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        @Override
4961b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        protected void onPostExecute(Cursor result) {
497d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck            if (mCallbacks != null && result.getCount() > 0) {
498d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck                String[] urls = new String[result.getCount()];
499d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck                int i = 0;
5001b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck                while (result.moveToNext()) {
501d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck                    urls[i++] = BrowserBookmarksPage.getUrl(result);
5021b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck                }
503d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779John Reck                mCallbacks.onOpenInNewWindow(urls);
5041b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck            }
5051b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck        }
5061b3c66ed83cb83ba1be775d5f108f698f0d4ee1fJohn Reck
5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
508095292f343583627ecd150fb4d1b34767402630fNicolas Catania
50971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private void editBookmark(BrowserBookmarksAdapter adapter, int position) {
51064144e49208df145c8362dfa037335c7b9210167Jeff Hamilton        Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
51171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        Cursor cursor = adapter.getItem(position);
5128402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        Bundle item = new Bundle();
513bef7a759aa57894124c67ff4912ea595cdc92ce1Michael Kolb        item.putString(BrowserContract.Bookmarks.TITLE,
5148402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
515bef7a759aa57894124c67ff4912ea595cdc92ce1Michael Kolb        item.putString(BrowserContract.Bookmarks.URL,
5168402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                cursor.getString(BookmarksLoader.COLUMN_INDEX_URL));
5178402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
5188402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        if (data != null) {
519bef7a759aa57894124c67ff4912ea595cdc92ce1Michael Kolb            item.putParcelable(BrowserContract.Bookmarks.FAVICON,
5208402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    BitmapFactory.decodeByteArray(data, 0, data.length));
5218402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
522c8490818ccb693ed2610366d2e91fb290e40c372John Reck        item.putLong(BrowserContract.Bookmarks._ID,
523c8490818ccb693ed2610366d2e91fb290e40c372John Reck                cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
524052ce667ce77c4fb3208c0b0dacba7be79c072d9Leon Scroggins III        item.putLong(BrowserContract.Bookmarks.PARENT,
525052ce667ce77c4fb3208c0b0dacba7be79c072d9Leon Scroggins III                cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT));
526c8490818ccb693ed2610366d2e91fb290e40c372John Reck        intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item);
527c8490818ccb693ed2610366d2e91fb290e40c372John Reck        intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER,
528c8490818ccb693ed2610366d2e91fb290e40c372John Reck                cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1);
529c8490818ccb693ed2610366d2e91fb290e40c372John Reck        startActivity(intent);
5300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
531095292f343583627ecd150fb4d1b34767402630fNicolas Catania
53271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter,
53371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            int position) {
5340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Put up a dialog asking if the user really wants to
5350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // delete the bookmark
53671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        Cursor cursor = adapter.getItem(position);
53775630678154c89662b7f8e5fb19d0b77a2d7abb8Leon Scroggins        long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
53875630678154c89662b7f8e5fb19d0b77a2d7abb8Leon Scroggins        String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
53964144e49208df145c8362dfa037335c7b9210167Jeff Hamilton        Context context = getActivity();
54075630678154c89662b7f8e5fb19d0b77a2d7abb8Leon Scroggins        BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null);
5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
54371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private String getUrl(BrowserBookmarksAdapter adapter, int position) {
54471efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        return getUrl(adapter.getItem(position));
545608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    }
546608baa78f4071409294f79b37e7ffa9ca96c4223John Reck
547608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    /* package */ static String getUrl(Cursor c) {
548608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        return c.getString(BookmarksLoader.COLUMN_INDEX_URL);
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
550801ecb73006a3062cdfeacf7ad6016e0a358671cMichael Kolb
5510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
55264144e49208df145c8362dfa037335c7b9210167Jeff Hamilton        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
55364144e49208df145c8362dfa037335c7b9210167Jeff Hamilton                Context.CLIPBOARD_SERVICE);
554bf1d10af39eb23d68db69a8eda9e12e62f1a9682Dianne Hackborn        cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString())));
5550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
556370a4f3e47b740fd10b9028aae9e87e17254caa8Michael Kolb
557b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    @Override
558b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    public void onConfigurationChanged(Configuration newConfig) {
559b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        super.onConfigurationChanged(newConfig);
560b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        Resources res = getActivity().getResources();
56171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
5620ce8a942a895cfe1d432076a95f3ed3798ccb002John Reck        int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop);
563f3828cd09f12cbf2980af72187628a608db8e938John Reck        mRoot.setPadding(0, paddingTop, 0, 0);
5649fdd981a245b59952338374ba6a264742498fc4cJohn Reck        getActivity().invalidateOptionsMenu();
565b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    }
566b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck
567608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    /**
568608baa78f4071409294f79b37e7ffa9ca96c4223John Reck     * BreadCrumb controller callback
569608baa78f4071409294f79b37e7ffa9ca96c4223John Reck     */
570608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    @Override
57171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    public void onTop(BreadCrumbView view, int level, Object data) {
57271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        int groupPosition = (Integer) view.getTag(R.id.group_position);
57389f73c1146f474641881e3e20c77cfbfc18fa313John Reck        Uri uri = (Uri) data;
57489f73c1146f474641881e3e20c77cfbfc18fa313John Reck        if (uri == null) {
57589f73c1146f474641881e3e20c77cfbfc18fa313John Reck            // top level
57689f73c1146f474641881e3e20c77cfbfc18fa313John Reck            uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
57789f73c1146f474641881e3e20c77cfbfc18fa313John Reck        }
57871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        loadFolder(groupPosition, uri);
579cece1fe59c45893bb46e321917aa881705ab0b7eJohn Reck        if (level <= 1) {
580cece1fe59c45893bb46e321917aa881705ab0b7eJohn Reck            view.setVisibility(View.GONE);
581cece1fe59c45893bb46e321917aa881705ab0b7eJohn Reck        } else {
582cece1fe59c45893bb46e321917aa881705ab0b7eJohn Reck            view.setVisibility(View.VISIBLE);
583cece1fe59c45893bb46e321917aa881705ab0b7eJohn Reck        }
58489f73c1146f474641881e3e20c77cfbfc18fa313John Reck    }
58589f73c1146f474641881e3e20c77cfbfc18fa313John Reck
58689f73c1146f474641881e3e20c77cfbfc18fa313John Reck    /**
58789f73c1146f474641881e3e20c77cfbfc18fa313John Reck     * @param uri
58889f73c1146f474641881e3e20c77cfbfc18fa313John Reck     */
58971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    private void loadFolder(int groupPosition, Uri uri) {
59089f73c1146f474641881e3e20c77cfbfc18fa313John Reck        LoaderManager manager = getLoaderManager();
59171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        // This assumes groups are ordered the same as loaders
59271efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        BookmarksLoader loader = (BookmarksLoader) ((Loader<?>)
59371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck                manager.getLoader(LOADER_BOOKMARKS + groupPosition));
59489f73c1146f474641881e3e20c77cfbfc18fa313John Reck        loader.setUri(uri);
59589f73c1146f474641881e3e20c77cfbfc18fa313John Reck        loader.forceLoad();
596608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    }
597608baa78f4071409294f79b37e7ffa9ca96c4223John Reck
598608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
599608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        mCallbacks = callbackListener;
600608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    }
601608baa78f4071409294f79b37e7ffa9ca96c4223John Reck
602608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    public void setEnableContextMenu(boolean enable) {
603608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        mEnableContextMenu = enable;
604608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        if (mGrid != null) {
605608baa78f4071409294f79b37e7ffa9ca96c4223John Reck            if (mEnableContextMenu) {
606608baa78f4071409294f79b37e7ffa9ca96c4223John Reck                registerForContextMenu(mGrid);
607608baa78f4071409294f79b37e7ffa9ca96c4223John Reck            } else {
608608baa78f4071409294f79b37e7ffa9ca96c4223John Reck                unregisterForContextMenu(mGrid);
609608baa78f4071409294f79b37e7ffa9ca96c4223John Reck                mGrid.setLongClickable(false);
610608baa78f4071409294f79b37e7ffa9ca96c4223John Reck            }
611608baa78f4071409294f79b37e7ffa9ca96c4223John Reck        }
612608baa78f4071409294f79b37e7ffa9ca96c4223John Reck    }
613c8490818ccb693ed2610366d2e91fb290e40c372John Reck
614c8490818ccb693ed2610366d2e91fb290e40c372John Reck    private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> {
615c8490818ccb693ed2610366d2e91fb290e40c372John Reck        Context mContext;
616c8490818ccb693ed2610366d2e91fb290e40c372John Reck        BookmarkItem mHeader;
617c8490818ccb693ed2610366d2e91fb290e40c372John Reck
618c8490818ccb693ed2610366d2e91fb290e40c372John Reck        public LookupBookmarkCount(Context context, BookmarkItem header) {
619914c5591baeb86bf30a5bc28930071442a822d60Ben Murdoch            mContext = context.getApplicationContext();
620c8490818ccb693ed2610366d2e91fb290e40c372John Reck            mHeader = header;
621c8490818ccb693ed2610366d2e91fb290e40c372John Reck        }
622c8490818ccb693ed2610366d2e91fb290e40c372John Reck
623c8490818ccb693ed2610366d2e91fb290e40c372John Reck        @Override
624c8490818ccb693ed2610366d2e91fb290e40c372John Reck        protected Integer doInBackground(Long... params) {
625c8490818ccb693ed2610366d2e91fb290e40c372John Reck            if (params.length != 1) {
626c8490818ccb693ed2610366d2e91fb290e40c372John Reck                throw new IllegalArgumentException("Missing folder id!");
627c8490818ccb693ed2610366d2e91fb290e40c372John Reck            }
628c8490818ccb693ed2610366d2e91fb290e40c372John Reck            Uri uri = BookmarkUtils.getBookmarksUri(mContext);
629c8490818ccb693ed2610366d2e91fb290e40c372John Reck            Cursor c = mContext.getContentResolver().query(uri,
630c8490818ccb693ed2610366d2e91fb290e40c372John Reck                    null, BrowserContract.Bookmarks.PARENT + "=?",
631c8490818ccb693ed2610366d2e91fb290e40c372John Reck                    new String[] {params[0].toString()}, null);
632c8490818ccb693ed2610366d2e91fb290e40c372John Reck            return c.getCount();
633c8490818ccb693ed2610366d2e91fb290e40c372John Reck        }
634c8490818ccb693ed2610366d2e91fb290e40c372John Reck
635c8490818ccb693ed2610366d2e91fb290e40c372John Reck        @Override
636c8490818ccb693ed2610366d2e91fb290e40c372John Reck        protected void onPostExecute(Integer result) {
637c8490818ccb693ed2610366d2e91fb290e40c372John Reck            if (result > 0) {
638c8490818ccb693ed2610366d2e91fb290e40c372John Reck                mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount,
639c8490818ccb693ed2610366d2e91fb290e40c372John Reck                        result));
640c8490818ccb693ed2610366d2e91fb290e40c372John Reck            } else if (result == 0) {
641c8490818ccb693ed2610366d2e91fb290e40c372John Reck                mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty));
642c8490818ccb693ed2610366d2e91fb290e40c372John Reck            }
643c8490818ccb693ed2610366d2e91fb290e40c372John Reck        }
644c8490818ccb693ed2610366d2e91fb290e40c372John Reck    }
64589f73c1146f474641881e3e20c77cfbfc18fa313John Reck
64671efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck    static class AccountsLoader extends CursorLoader {
64789f73c1146f474641881e3e20c77cfbfc18fa313John Reck
64871efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        static String[] ACCOUNTS_PROJECTION = new String[] {
64971efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            Accounts.ACCOUNT_NAME,
65071efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck            Accounts.ACCOUNT_TYPE
65171efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        };
65289f73c1146f474641881e3e20c77cfbfc18fa313John Reck
65371efc2bbf08574425a387c992e24cb9eaf0a6e6cJohn Reck        public AccountsLoader(Context context) {
6541e9815d4c4864790fde2ad1e216058f922060c92John Reck            super(context, Accounts.CONTENT_URI
6551e9815d4c4864790fde2ad1e216058f922060c92John Reck                    .buildUpon()
6561e9815d4c4864790fde2ad1e216058f922060c92John Reck                    .appendQueryParameter(BrowserProvider2.PARAM_ALLOW_EMPTY_ACCOUNTS, "false")
6571e9815d4c4864790fde2ad1e216058f922060c92John Reck                    .build(),
6581e9815d4c4864790fde2ad1e216058f922060c92John Reck                    ACCOUNTS_PROJECTION, null, null, null);
65989f73c1146f474641881e3e20c77cfbfc18fa313John Reck        }
660522a438d69486914a364c2fe0934c08269b1129fJohn Reck
661522a438d69486914a364c2fe0934c08269b1129fJohn Reck    }
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
663