Bookmarks.java revision 568467e18d8b4d8bb143b6d3abf41bd4f70349bf
1e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins/*
2e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Copyright (C) 2009 The Android Open Source Project
3e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins *
4e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Licensed under the Apache License, Version 2.0 (the "License");
5e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * you may not use this file except in compliance with the License.
6e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * You may obtain a copy of the License at
7e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins *
8e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins *      http://www.apache.org/licenses/LICENSE-2.0
9e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins *
10e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Unless required by applicable law or agreed to in writing, software
11e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * distributed under the License is distributed on an "AS IS" BASIS,
12e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * See the License for the specific language governing permissions and
14e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * limitations under the License.
15e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins */
16e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins
17e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginspackage com.android.browser;
18e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins
19e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.content.ContentResolver;
20e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.content.ContentUris;
21e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.content.ContentValues;
22e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.content.Context;
237f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamiltonimport android.content.SharedPreferences;
24e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.database.Cursor;
25aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdochimport android.graphics.Bitmap;
26e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.net.Uri;
278402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamiltonimport android.os.AsyncTask;
287f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamiltonimport android.preference.PreferenceManager;
2969bd7077becb42438513fa80c98d0b48c8a23a41Jeff Hamiltonimport android.provider.BrowserContract;
301a805652e389d9404ee0fda7c993a6202332e92bJeff Hamiltonimport android.provider.BrowserContract.Combined;
311a805652e389d9404ee0fda7c993a6202332e92bJeff Hamiltonimport android.provider.BrowserContract.Images;
32568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reckimport android.text.TextUtils;
33e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.util.Log;
34e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.webkit.WebIconDatabase;
35e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.widget.Toast;
36e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins
37aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdochimport java.io.ByteArrayOutputStream;
38e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins
39e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins/**
40e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins *  This class is purely to have a common place for adding/deleting bookmarks.
41e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins */
42e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins/* package */ class Bookmarks {
43de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch    // We only want the user to be able to bookmark content that
44de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch    // the browser can handle directly.
45de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch    private static final String acceptableBookmarkSchemes[] = {
46de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "http:",
47de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "https:",
48de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "about:",
49de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "data:",
50de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "javascript:",
51de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "file:",
52de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            "content:"
53de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch    };
54de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch
552c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins    private final static String LOGTAG = "Bookmarks";
56e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins    /**
57e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  Add a bookmark to the database.
58e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  @param context Context of the calling Activity.  This is used to make
59e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *          Toast confirming that the bookmark has been added.  If the
60e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *          caller provides null, the Toast will not be shown.
61e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  @param url URL of the website to be bookmarked.
62e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  @param name Provided name for the bookmark.
63aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch     *  @param thumbnail A thumbnail for the bookmark.
649c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate     *  @param retainIcon Whether to retain the page's icon in the icon database.
659c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate     *          This will usually be <code>true</code> except when bookmarks are
669c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate     *          added by a settings restore agent.
67052ce667ce77c4fb3208c0b0dacba7be79c072d9Leon Scroggins III     *  @param parent ID of the parent folder.
68e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     */
697f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton    /* package */ static void addBookmark(Context context, boolean showToast, String url,
70052ce667ce77c4fb3208c0b0dacba7be79c072d9Leon Scroggins III            String name, Bitmap thumbnail, boolean retainIcon, long parent) {
71e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins        // Want to append to the beginning of the list
728402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        ContentValues values = new ContentValues();
732c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        try {
747f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
757f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton            String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
767f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton            String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
777f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton            values.put(BrowserContract.Bookmarks.ACCOUNT_TYPE, accountType);
787f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton            values.put(BrowserContract.Bookmarks.ACCOUNT_NAME, accountName);
798402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            values.put(BrowserContract.Bookmarks.TITLE, name);
808402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            values.put(BrowserContract.Bookmarks.URL, url);
818402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            values.put(BrowserContract.Bookmarks.IS_FOLDER, 0);
828402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            values.put(BrowserContract.Bookmarks.THUMBNAIL,
838402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    bitmapToBytes(thumbnail));
84052ce667ce77c4fb3208c0b0dacba7be79c072d9Leon Scroggins III            values.put(BrowserContract.Bookmarks.PARENT, parent);
857f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton            context.getContentResolver().insert(BrowserContract.Bookmarks.CONTENT_URI, values);
862c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } catch (IllegalStateException e) {
872c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            Log.e(LOGTAG, "addBookmark", e);
88e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins        }
899c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate        if (retainIcon) {
909c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate            WebIconDatabase.getInstance().retainIconForPageUrl(url);
919c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate        }
927f6cf3e4109426164c6fdd11aba0c69622e2353cJeff Hamilton        if (showToast) {
93e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins            Toast.makeText(context, R.string.added_to_bookmarks,
94e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins                    Toast.LENGTH_LONG).show();
95e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins        }
96e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins    }
97e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins
98e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins    /**
99e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  Remove a bookmark from the database.  If the url is a visited site, it
100e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  will remain in the database, but only as a history item, and not as a
101e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  bookmarked site.
102e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  @param context Context of the calling Activity.  This is used to make
103e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *          Toast confirming that the bookmark has been removed.  If the
104e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *          caller provides null, the Toast will not be shown.
105e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  @param cr The ContentResolver being used to remove the bookmark.
106e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     *  @param url URL of the website to be removed.
107e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins     */
108e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins    /* package */ static void removeFromBookmarks(Context context,
109c95261955cf08f30b484b6a229c4bcff42c645ceAndrei Popescu            ContentResolver cr, String url, String title) {
1102c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor cursor = null;
1112c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        try {
1124b59db8bc6b609307dfcb346283378c5ea993d7cJohn Reck            Uri uri = BookmarkUtils.getBookmarksUri(context);
1134b59db8bc6b609307dfcb346283378c5ea993d7cJohn Reck            cursor = cr.query(uri,
1148ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                    new String[] { BrowserContract.Bookmarks._ID },
1158ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                    BrowserContract.Bookmarks.URL + " = ? AND " +
1168ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                            BrowserContract.Bookmarks.TITLE + " = ?",
1172c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    new String[] { url, title },
1182c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    null);
1198ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton
1208ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton            if (!cursor.moveToFirst()) {
1214b59db8bc6b609307dfcb346283378c5ea993d7cJohn Reck                return;
122e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins            }
1238ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton
1242c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            // Remove from bookmarks
1252c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            WebIconDatabase.getInstance().releaseIconForPageUrl(url);
1264b59db8bc6b609307dfcb346283378c5ea993d7cJohn Reck            uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
1278ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                    cursor.getLong(0));
1288ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton            cr.delete(uri, null, null);
1292c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (context != null) {
1308ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                Toast.makeText(context, R.string.removed_from_bookmarks, Toast.LENGTH_LONG).show();
1312c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            }
1322c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } catch (IllegalStateException e) {
1332c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            Log.e(LOGTAG, "removeFromBookmarks", e);
1342c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
1352c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (cursor != null) cursor.close();
136e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins        }
137e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins    }
138aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
139aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch    private static byte[] bitmapToBytes(Bitmap bm) {
140aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch        if (bm == null) {
141aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch            return null;
142aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch        }
143aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
144aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch        final ByteArrayOutputStream os = new ByteArrayOutputStream();
145aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch        bm.compress(Bitmap.CompressFormat.PNG, 100, os);
146aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch        return os.toByteArray();
147aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch    }
148de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch
149de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch    /* package */ static boolean urlHasAcceptableScheme(String url) {
150de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch        if (url == null) {
151de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            return false;
152de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch        }
153de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch
154de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch        for (int i = 0; i < acceptableBookmarkSchemes.length; i++) {
155de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            if (url.startsWith(acceptableBookmarkSchemes[i])) {
156de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                return true;
157de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch            }
158de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch        }
159de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch        return false;
160de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch    }
1618402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1628ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton    static final String QUERY_BOOKMARKS_WHERE =
1631a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton            Combined.URL + " == ? OR " +
1641a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton            Combined.URL + " == ? OR " +
1651a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton            Combined.URL + " LIKE ? || '%' OR " +
1661a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton            Combined.URL + " LIKE ? || '%'";
1678ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton
1681a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton    /* package */ static Cursor queryCombinedForUrl(ContentResolver cr,
1698ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton            String originalUrl, String url) {
1708402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        if (cr == null || url == null) {
1718402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            return null;
1728402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
1738402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1748402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // If originalUrl is null, just set it to url.
1758402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        if (originalUrl == null) {
1768402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            originalUrl = url;
1778402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
1788402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1798402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // Look for both the original url and the actual url. This takes in to
1808402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // account redirects.
1811a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton        String originalUrlNoQuery = removeQuery(originalUrl);
1821a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton        String urlNoQuery = removeQuery(url);
1838402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        originalUrl = originalUrlNoQuery + '?';
1848402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        url = urlNoQuery + '?';
1858402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1868402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // Use NoQuery to search for the base url (i.e. if the url is
1878402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // http://www.yahoo.com/?rs=1, search for http://www.yahoo.com)
1888402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // Use url to match the base url with other queries (i.e. if the url is
1898402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // http://www.google.com/m, search for
1908402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        // http://www.google.com/m?some_query)
1911a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton        final String[] selArgs = new String[] { originalUrlNoQuery, urlNoQuery, originalUrl, url };
1921a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton        final String[] projection = new String[] { Combined.URL };
1931a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton        return cr.query(Combined.CONTENT_URI, projection, QUERY_BOOKMARKS_WHERE, selArgs, null);
1948402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
1958402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
1968402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    // Strip the query from the given url.
1978402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    static String removeQuery(String url) {
1988402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        if (url == null) {
1998402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            return null;
2008402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
2018402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        int query = url.indexOf('?');
2028402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        String noQuery = url;
2038402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        if (query != -1) {
2048402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            noQuery = url.substring(0, query);
2058402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }
2068402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        return noQuery;
2078402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
2088402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton
2098402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    /**
2108402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     * Update the bookmark's favicon. This is a convenience method for updating
2118402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     * a bookmark favicon for the originalUrl and url of the passed in WebView.
2128402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     * @param cr The ContentResolver to use.
2138402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     * @param originalUrl The original url before any redirects.
2148402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     * @param url The current url.
2158402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     * @param favicon The favicon bitmap to write to the db.
2168402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton     */
2171a805652e389d9404ee0fda7c993a6202332e92bJeff Hamilton    /* package */ static void updateFavicon(final ContentResolver cr,
2188402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            final String originalUrl, final String url, final Bitmap favicon) {
2198402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        new AsyncTask<Void, Void, Void>() {
2208402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            @Override
2218402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            protected Void doInBackground(Void... unused) {
222568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                final ByteArrayOutputStream os = new ByteArrayOutputStream();
223568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                favicon.compress(Bitmap.CompressFormat.PNG, 100, os);
224568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck
225568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                // The Images update will insert if it doesn't exist
226568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                ContentValues values = new ContentValues();
227568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                values.put(Images.FAVICON, os.toByteArray());
228568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                updateImages(cr, originalUrl, values);
229568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                updateImages(cr, url, values);
2308402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                return null;
2318402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton            }
232568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck
233568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck            private void updateImages(final ContentResolver cr,
234568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                    final String url, ContentValues values) {
235568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                String iurl = removeQuery(url);
236568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                if (!TextUtils.isEmpty(iurl)) {
237568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                    values.put(Images.URL, iurl);
238568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                    cr.update(BrowserContract.Images.CONTENT_URI, values, null, null);
239568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck                }
240568467e18d8b4d8bb143b6d3abf41bd4f70349bfJohn Reck            }
2418402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton        }.execute();
2428402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton    }
243aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch}
244