Change SWE app properties back to stock Android

- Changed project package name from com.android.swe.browser
back to com.android.browser along with code references to
old package name.
- Changes to AndroidManifest making it conform closer to stock
browser manifest.
- Changed app and apk name back to Browser.

Change-Id: I778ee1d1197bd50bd4a4850eef6d1d7f4ef0ad0b
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
new file mode 100644
index 0000000..a255d28
--- /dev/null
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.LoaderManager;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ExpandableListView;
+import android.widget.ExpandableListView.OnChildClickListener;
+import android.widget.Toast;
+
+import com.android.browser.R;
+import com.android.browser.platformsupport.BrowserContract;
+import com.android.browser.platformsupport.BrowserContract.Accounts;
+import com.android.browser.provider.BrowserProvider2;
+import com.android.browser.view.BookmarkExpandableView;
+import com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo;
+
+import java.util.HashMap;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+interface BookmarksPageCallbacks {
+    // Return true if handled
+    boolean onBookmarkSelected(Cursor c, boolean isFolder);
+    // Return true if handled
+    boolean onOpenInNewWindow(String... urls);
+}
+
+/**
+ *  View showing the user's bookmarks in the browser.
+ */
+public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
+        LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller,
+        OnChildClickListener {
+
+    public static class ExtraDragState {
+        public int childPosition;
+        public int groupPosition;
+    }
+
+    static final String LOGTAG = "browser";
+
+    static final int LOADER_ACCOUNTS = 1;
+    static final int LOADER_BOOKMARKS = 100;
+
+    static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
+    static final String PREF_GROUP_STATE = "bbp_group_state";
+
+    static final String ACCOUNT_TYPE = "account_type";
+    static final String ACCOUNT_NAME = "account_name";
+
+    static final long DEFAULT_FOLDER_ID = -1;
+
+    BookmarksPageCallbacks mCallbacks;
+    View mRoot;
+    BookmarkExpandableView mGrid;
+    boolean mDisableNewWindow;
+    boolean mEnableContextMenu = true;
+    View mEmptyView;
+    View mHeader;
+    HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
+    JSONObject mState;
+    long mCurrentFolderId = BrowserProvider2.FIXED_ID_ROOT;
+
+    @Override
+    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+        if (id == LOADER_ACCOUNTS) {
+            return new AccountsLoader(getActivity());
+        } else if (id >= LOADER_BOOKMARKS) {
+            String accountType = args.getString(ACCOUNT_TYPE);
+            String accountName = args.getString(ACCOUNT_NAME);
+            BookmarksLoader bl = new BookmarksLoader(getActivity(),
+                    accountType, accountName);
+            return bl;
+        } else {
+            throw new UnsupportedOperationException("Unknown loader id " + id);
+        }
+    }
+
+    @Override
+    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
+        if (loader.getId() == LOADER_ACCOUNTS) {
+            LoaderManager lm = getLoaderManager();
+            int id = LOADER_BOOKMARKS;
+            while (cursor.moveToNext()) {
+                String accountName = cursor.getString(0);
+                String accountType = cursor.getString(1);
+                Bundle args = new Bundle();
+                args.putString(ACCOUNT_NAME, accountName);
+                args.putString(ACCOUNT_TYPE, accountType);
+                BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter(
+                        getActivity());
+                mBookmarkAdapters.put(id, adapter);
+                boolean expand = true;
+                try {
+                    expand = mState.getBoolean(accountName != null ? accountName
+                            : BookmarkExpandableView.LOCAL_ACCOUNT_NAME);
+                } catch (JSONException e) {} // no state for accountName
+                mGrid.addAccount(accountName, adapter, expand);
+                lm.restartLoader(id, args, this);
+                id++;
+            }
+            // TODO: Figure out what a reload of these means
+            // Currently, a reload is triggered whenever bookmarks change
+            // This is less than ideal
+            // It also causes UI flickering as a new adapter is created
+            // instead of re-using an existing one when the account_name is the
+            // same.
+            // For now, this is a one-shot load
+            getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
+        } else if (loader.getId() >= LOADER_BOOKMARKS) {
+            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
+            adapter.changeCursor(cursor);
+            if (adapter.getCount() != 0) {
+                mCurrentFolderId = adapter.getItem(0).getLong(BookmarksLoader.COLUMN_INDEX_PARENT);
+            }
+        }
+    }
+
+    @Override
+    public void onLoaderReset(Loader<Cursor> loader) {
+        if (loader.getId() >= LOADER_BOOKMARKS) {
+            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
+            adapter.changeCursor(null);
+        }
+    }
+
+    //add for carrier feature which adds new bookmark/folder function.
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.bookmark, menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final Activity activity = getActivity();
+        if (item.getItemId() == R.id.add_bookmark_menu_id) {
+            Intent intent = new Intent(activity, AddBookmarkPage.class);
+            intent.putExtra(BrowserContract.Bookmarks.URL, "http://");
+            intent.putExtra(BrowserContract.Bookmarks.TITLE, "");
+            intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
+            activity.startActivity(intent);
+        }
+        if (item.getItemId() == R.id.new_bmfolder_menu_id) {
+            Intent intent = new Intent(activity, AddBookmarkFolder.class);
+            intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
+            activity.startActivity(intent);
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        if (!(item.getMenuInfo() instanceof BookmarkContextMenuInfo)) {
+            return false;
+        }
+        BookmarkContextMenuInfo i = (BookmarkContextMenuInfo) item.getMenuInfo();
+        // If we have no menu info, we can't tell which item was selected.
+        if (i == null) {
+            return false;
+        }
+
+        if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) {
+            return true;
+        }
+        return super.onContextItemSelected(item);
+    }
+
+    public boolean handleContextItem(int itemId, int groupPosition,
+            int childPosition) {
+        final Activity activity = getActivity();
+        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
+
+        switch (itemId) {
+        case R.id.open_context_menu_id:
+            loadUrl(adapter, childPosition);
+            break;
+        case R.id.edit_context_menu_id:
+            editBookmark(adapter, childPosition);
+            break;
+        case R.id.shortcut_context_menu_id:
+            Cursor c = adapter.getItem(childPosition);
+            activity.sendBroadcast(createShortcutIntent(getActivity(), c));
+            break;
+        case R.id.delete_context_menu_id:
+            displayRemoveBookmarkDialog(adapter, childPosition);
+            break;
+        case R.id.new_window_context_menu_id:
+            openInNewWindow(adapter, childPosition);
+            break;
+        case R.id.share_link_context_menu_id: {
+            Cursor cursor = adapter.getItem(childPosition);
+            Controller.sharePage(activity,
+                    cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
+                    cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
+                    getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON),
+                    getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL));
+            break;
+        }
+        case R.id.copy_url_context_menu_id:
+            copy(getUrl(adapter, childPosition));
+            break;
+        case R.id.homepage_context_menu_id: {
+            BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition));
+            Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
+            break;
+        }
+        // Only for the Most visited page
+        case R.id.save_to_bookmarks_menu_id: {
+            Cursor cursor = adapter.getItem(childPosition);
+            String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
+            String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
+            // If the site is bookmarked, the item becomes remove from
+            // bookmarks.
+            Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name);
+            break;
+        }
+        default:
+            return false;
+        }
+        return true;
+    }
+
+    static Bitmap getBitmap(Cursor cursor, int columnIndex) {
+        return getBitmap(cursor, columnIndex, null);
+    }
+
+    static ThreadLocal<Options> sOptions = new ThreadLocal<Options>() {
+        @Override
+        protected Options initialValue() {
+            return new Options();
+        };
+    };
+    static Bitmap getBitmap(Cursor cursor, int columnIndex, Bitmap inBitmap) {
+        byte[] data = cursor.getBlob(columnIndex);
+        if (data == null) {
+            return null;
+        }
+        Options opts = sOptions.get();
+        opts.inBitmap = inBitmap;
+        opts.inSampleSize = 1;
+        opts.inScaled = false;
+        try {
+            return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
+        } catch (IllegalArgumentException ex) {
+            // Failed to re-use bitmap, create a new one
+            return BitmapFactory.decodeByteArray(data, 0, data.length);
+        }
+    }
+
+    private MenuItem.OnMenuItemClickListener mContextItemClickListener =
+            new MenuItem.OnMenuItemClickListener() {
+        @Override
+        public boolean onMenuItemClick(MenuItem item) {
+            return onContextItemSelected(item);
+        }
+    };
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo;
+        BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition);
+        Cursor cursor = adapter.getItem(info.childPosition);
+        if (!canEdit(cursor)) {
+            return;
+        }
+        boolean isFolder
+                = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+
+        final Activity activity = getActivity();
+        MenuInflater inflater = activity.getMenuInflater();
+        inflater.inflate(R.menu.bookmarkscontext, menu);
+        if (isFolder) {
+            menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true);
+        } else {
+            menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true);
+            if (mDisableNewWindow) {
+                menu.findItem(R.id.new_window_context_menu_id).setVisible(false);
+            }
+        }
+        BookmarkItem header = new BookmarkItem(activity);
+        header.setEnableScrolling(true);
+        populateBookmarkItem(cursor, header, isFolder);
+        menu.setHeaderView(header);
+
+        int count = menu.size();
+        for (int i = 0; i < count; i++) {
+            menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener);
+        }
+    }
+
+    boolean canEdit(Cursor c) {
+        int type = c.getInt(BookmarksLoader.COLUMN_INDEX_TYPE);
+        return type == BrowserContract.Bookmarks.BOOKMARK_TYPE_BOOKMARK
+                || type == BrowserContract.Bookmarks.BOOKMARK_TYPE_FOLDER;
+    }
+
+    private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) {
+        item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
+        if (isFolder) {
+            item.setUrl(null);
+            Bitmap bitmap =
+                BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark);
+            item.setFavicon(bitmap);
+            new LookupBookmarkCount(getActivity(), item)
+                    .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
+        } else {
+            String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
+            item.setUrl(url);
+            Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
+            item.setFavicon(bitmap);
+        }
+    }
+
+    /**
+     *  Create a new BrowserBookmarksPage.
+     */
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
+        try {
+            mState = new JSONObject(prefs.getString(PREF_GROUP_STATE, "{}"));
+        } catch (JSONException e) {
+            // Parse failed, clear preference and start with empty state
+            prefs.edit().remove(PREF_GROUP_STATE).apply();
+            mState = new JSONObject();
+        }
+        Bundle args = getArguments();
+        mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
+        setHasOptionsMenu(true);
+        if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) {
+            mCallbacks = new CombinedBookmarksCallbackWrapper(
+                    (CombinedBookmarksCallbacks) getActivity());
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        try {
+            mState = mGrid.saveGroupState();
+            // Save state
+            SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
+            prefs.edit()
+                    .putString(PREF_GROUP_STATE, mState.toString())
+                    .apply();
+        } catch (JSONException e) {
+            // Not critical, ignore
+        }
+    }
+
+    private static class CombinedBookmarksCallbackWrapper
+            implements BookmarksPageCallbacks {
+
+        private CombinedBookmarksCallbacks mCombinedCallback;
+
+        private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) {
+            mCombinedCallback = cb;
+        }
+
+        @Override
+        public boolean onOpenInNewWindow(String... urls) {
+            mCombinedCallback.openInNewTab(urls);
+            return true;
+        }
+
+        @Override
+        public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
+            if (isFolder) {
+                return false;
+            }
+            mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c));
+            return true;
+        }
+    };
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        mRoot = inflater.inflate(R.layout.bookmarks, container, false);
+        mEmptyView = mRoot.findViewById(android.R.id.empty);
+
+        mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid);
+        mGrid.setOnChildClickListener(this);
+        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
+        mGrid.setBreadcrumbController(this);
+        setEnableContextMenu(mEnableContextMenu);
+
+        // Start the loaders
+        LoaderManager lm = getLoaderManager();
+        lm.restartLoader(LOADER_ACCOUNTS, null, this);
+
+        return mRoot;
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        mGrid.setBreadcrumbController(null);
+        mGrid.clearAccounts();
+        LoaderManager lm = getLoaderManager();
+        lm.destroyLoader(LOADER_ACCOUNTS);
+        for (int id : mBookmarkAdapters.keySet()) {
+            lm.destroyLoader(id);
+        }
+        mBookmarkAdapters.clear();
+    }
+
+    private BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
+        return mGrid.getChildAdapter(groupPosition);
+    }
+
+    private BreadCrumbView getBreadCrumbs(int groupPosition) {
+        return mGrid.getBreadCrumbs(groupPosition);
+    }
+
+    @Override
+    public boolean onChildClick(ExpandableListView parent, View v,
+            int groupPosition, int childPosition, long id) {
+        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
+        Cursor cursor = adapter.getItem(childPosition);
+        boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+        if (mCallbacks != null &&
+                mCallbacks.onBookmarkSelected(cursor, isFolder)) {
+            return true;
+        }
+
+        if (isFolder) {
+            String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
+            Uri uri = ContentUris.withAppendedId(
+                    BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
+            BreadCrumbView crumbs = getBreadCrumbs(groupPosition);
+            if (crumbs != null) {
+                // update crumbs
+                crumbs.pushView(title, uri);
+                crumbs.setVisibility(View.VISIBLE);
+                Object data = crumbs.getTopData();
+                mCurrentFolderId = (data != null ? ContentUris.parseId((Uri) data)
+                        : DEFAULT_FOLDER_ID);
+            }
+            loadFolder(groupPosition, uri);
+        }
+        return true;
+    }
+
+    /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
+        String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
+        String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
+        Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
+        Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
+        return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
+    }
+
+    private void loadUrl(BrowserBookmarksAdapter adapter, int position) {
+        if (mCallbacks != null && adapter != null) {
+            mCallbacks.onBookmarkSelected(adapter.getItem(position), false);
+        }
+    }
+
+    private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) {
+        if (mCallbacks != null) {
+            Cursor c = adapter.getItem(position);
+            boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1;
+            if (isFolder) {
+                long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
+                new OpenAllInTabsTask(id).execute();
+            } else {
+                mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c));
+            }
+        }
+    }
+
+    class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> {
+        long mFolderId;
+        public OpenAllInTabsTask(long id) {
+            mFolderId = id;
+        }
+
+        @Override
+        protected Cursor doInBackground(Void... params) {
+            Context c = getActivity();
+            if (c == null) return null;
+            return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c),
+                    BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?",
+                    new String[] { Long.toString(mFolderId) }, null);
+        }
+
+        @Override
+        protected void onPostExecute(Cursor result) {
+            if (mCallbacks != null && result.getCount() > 0) {
+                String[] urls = new String[result.getCount()];
+                int i = 0;
+                while (result.moveToNext()) {
+                    urls[i++] = BrowserBookmarksPage.getUrl(result);
+                }
+                mCallbacks.onOpenInNewWindow(urls);
+            }
+        }
+
+    }
+
+    private void editBookmark(BrowserBookmarksAdapter adapter, int position) {
+        Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
+        Cursor cursor = adapter.getItem(position);
+        Bundle item = new Bundle();
+        item.putString(BrowserContract.Bookmarks.TITLE,
+                cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
+        item.putString(BrowserContract.Bookmarks.URL,
+                cursor.getString(BookmarksLoader.COLUMN_INDEX_URL));
+        byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
+        if (data != null) {
+            item.putParcelable(BrowserContract.Bookmarks.FAVICON,
+                    BitmapFactory.decodeByteArray(data, 0, data.length));
+        }
+        item.putLong(BrowserContract.Bookmarks._ID,
+                cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
+        item.putLong(BrowserContract.Bookmarks.PARENT,
+                cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT));
+        intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item);
+        intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER,
+                cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1);
+        startActivity(intent);
+    }
+
+    private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter,
+            int position) {
+        // Put up a dialog asking if the user really wants to
+        // delete the bookmark
+        Cursor cursor = adapter.getItem(position);
+        long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
+        String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
+        Context context = getActivity();
+        BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null);
+    }
+
+    private String getUrl(BrowserBookmarksAdapter adapter, int position) {
+        return getUrl(adapter.getItem(position));
+    }
+
+    /* package */ static String getUrl(Cursor c) {
+        return c.getString(BookmarksLoader.COLUMN_INDEX_URL);
+    }
+
+    private void copy(CharSequence text) {
+        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
+                Context.CLIPBOARD_SERVICE);
+        cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString())));
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        Resources res = getActivity().getResources();
+        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
+        int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop);
+        mRoot.setPadding(0, paddingTop, 0, 0);
+        getActivity().invalidateOptionsMenu();
+    }
+
+    /**
+     * BreadCrumb controller callback
+     */
+    @Override
+    public void onTop(BreadCrumbView view, int level, Object data) {
+        int groupPosition = (Integer) view.getTag(R.id.group_position);
+        Uri uri = (Uri) data;
+        if (uri == null) {
+            // top level
+            uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
+        }
+        loadFolder(groupPosition, uri);
+        if (level <= 1) {
+            view.setVisibility(View.GONE);
+        } else {
+            view.setVisibility(View.VISIBLE);
+        }
+    }
+
+    /**
+     * @param uri
+     */
+    private void loadFolder(int groupPosition, Uri uri) {
+        LoaderManager manager = getLoaderManager();
+        // This assumes groups are ordered the same as loaders
+        BookmarksLoader loader = (BookmarksLoader) ((Loader<?>)
+                manager.getLoader(LOADER_BOOKMARKS + groupPosition));
+        loader.setUri(uri);
+        loader.forceLoad();
+    }
+
+    public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
+        mCallbacks = callbackListener;
+    }
+
+    public void setEnableContextMenu(boolean enable) {
+        mEnableContextMenu = enable;
+        if (mGrid != null) {
+            if (mEnableContextMenu) {
+                registerForContextMenu(mGrid);
+            } else {
+                unregisterForContextMenu(mGrid);
+                mGrid.setLongClickable(false);
+            }
+        }
+    }
+
+    private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> {
+        Context mContext;
+        BookmarkItem mHeader;
+
+        public LookupBookmarkCount(Context context, BookmarkItem header) {
+            mContext = context.getApplicationContext();
+            mHeader = header;
+        }
+
+        @Override
+        protected Integer doInBackground(Long... params) {
+            if (params.length != 1) {
+                throw new IllegalArgumentException("Missing folder id!");
+            }
+            Uri uri = BookmarkUtils.getBookmarksUri(mContext);
+            Cursor c = mContext.getContentResolver().query(uri,
+                    null, BrowserContract.Bookmarks.PARENT + "=?",
+                    new String[] {params[0].toString()}, null);
+            return c.getCount();
+        }
+
+        @Override
+        protected void onPostExecute(Integer result) {
+            if (result > 0) {
+                mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount,
+                        result));
+            } else if (result == 0) {
+                mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty));
+            }
+        }
+    }
+
+    static class AccountsLoader extends CursorLoader {
+
+        static String[] ACCOUNTS_PROJECTION = new String[] {
+            Accounts.ACCOUNT_NAME,
+            Accounts.ACCOUNT_TYPE
+        };
+
+        public AccountsLoader(Context context) {
+            super(context, Accounts.CONTENT_URI
+                    .buildUpon()
+                    .appendQueryParameter(BrowserProvider2.PARAM_ALLOW_EMPTY_ACCOUNTS, "false")
+                    .build(),
+                    ACCOUNTS_PROJECTION, null, null, null);
+        }
+
+    }
+}