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; 23e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.database.Cursor; 24aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdochimport android.graphics.Bitmap; 25e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.net.Uri; 26e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.provider.Browser; 27e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.util.Log; 28e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.webkit.WebIconDatabase; 29e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport android.widget.Toast; 30e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins 31aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdochimport java.io.ByteArrayOutputStream; 32e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scrogginsimport java.util.Date; 33e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins 34e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins/** 35e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * This class is purely to have a common place for adding/deleting bookmarks. 36e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins */ 37e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins/* package */ class Bookmarks { 38de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch // We only want the user to be able to bookmark content that 39de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch // the browser can handle directly. 40de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch private static final String acceptableBookmarkSchemes[] = { 41de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "http:", 42de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "https:", 43de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "about:", 44de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "data:", 45de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "javascript:", 46de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "file:", 47de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch "content:" 48de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch }; 49de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch 502c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins private final static String LOGTAG = "Bookmarks"; 51e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins /** 52e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Add a bookmark to the database. 53e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param context Context of the calling Activity. This is used to make 54e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Toast confirming that the bookmark has been added. If the 55e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * caller provides null, the Toast will not be shown. 56e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param cr The ContentResolver being used to add the bookmark to the db. 57e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param url URL of the website to be bookmarked. 58e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param name Provided name for the bookmark. 59aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch * @param thumbnail A thumbnail for the bookmark. 609c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate * @param retainIcon Whether to retain the page's icon in the icon database. 619c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate * This will usually be <code>true</code> except when bookmarks are 629c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate * added by a settings restore agent. 63e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins */ 64e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins /* package */ static void addBookmark(Context context, 659c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate ContentResolver cr, String url, String name, 66aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch Bitmap thumbnail, boolean retainIcon) { 67e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins // Want to append to the beginning of the list 68e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins long creationTime = new Date().getTime(); 69e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins ContentValues map = new ContentValues(); 702c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Cursor cursor = null; 712c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins try { 722c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cursor = Browser.getVisitedLike(cr, url); 732c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (cursor.moveToFirst() && cursor.getInt( 742c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Browser.HISTORY_PROJECTION_BOOKMARK_INDEX) == 0) { 752c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // This means we have been to this site but not bookmarked 762c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // it, so convert the history item to a bookmark 77e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins map.put(Browser.BookmarkColumns.CREATED, creationTime); 782c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.TITLE, name); 79e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins map.put(Browser.BookmarkColumns.BOOKMARK, 1); 802c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.THUMBNAIL, 812c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins bitmapToBytes(thumbnail)); 822c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cr.update(Browser.BOOKMARKS_URI, map, 832c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins "_id = " + cursor.getInt(0), null); 842c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } else { 852c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins int count = cursor.getCount(); 862c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins boolean matchedTitle = false; 872c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins for (int i = 0; i < count; i++) { 882c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // One or more bookmarks already exist for this site. 892c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // Check the names of each 902c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cursor.moveToPosition(i); 912c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (cursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX) 922c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins .equals(name)) { 932c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // The old bookmark has the same name. 942c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // Update its creation time. 952c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.CREATED, 962c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins creationTime); 972c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cr.update(Browser.BOOKMARKS_URI, map, 982c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins "_id = " + cursor.getInt(0), null); 992c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins matchedTitle = true; 1002c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins break; 1012c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } 1022c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } 1032c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (!matchedTitle) { 1042c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // Adding a bookmark for a site the user has visited, 1052c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // or a new bookmark (with a different name) for a site 1062c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // the user has visited 1072c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.TITLE, name); 1082c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.URL, url); 1092c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.CREATED, creationTime); 1102c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.BOOKMARK, 1); 1112c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.DATE, 0); 1122c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.THUMBNAIL, 1132c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins bitmapToBytes(thumbnail)); 1142c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins int visits = 0; 1152c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (count > 0) { 1162c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // The user has already bookmarked, and possibly 1172c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // visited this site. However, they are creating 1182c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // a new bookmark with the same url but a different 1192c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // name. The new bookmark should have the same 1202c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // number of visits as the already created bookmark. 1212c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins visits = cursor.getInt( 1222c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Browser.HISTORY_PROJECTION_VISITS_INDEX); 1232c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } 1242c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // Bookmark starts with 3 extra visits so that it will 1252c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // bubble up in the most visited and goto search box 1262c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins map.put(Browser.BookmarkColumns.VISITS, visits + 3); 1272c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cr.insert(Browser.BOOKMARKS_URI, map); 128e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 129e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 1302c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } catch (IllegalStateException e) { 1312c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Log.e(LOGTAG, "addBookmark", e); 1322c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } finally { 1332c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (cursor != null) cursor.close(); 134e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 1359c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate if (retainIcon) { 1369c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate WebIconDatabase.getInstance().retainIconForPageUrl(url); 1379c0dd8caacff99ba76bbb9dc2cab156cded505a8Christopher Tate } 138e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins if (context != null) { 139e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins Toast.makeText(context, R.string.added_to_bookmarks, 140e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins Toast.LENGTH_LONG).show(); 141e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 142e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 143e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins 144e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins /** 145e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Remove a bookmark from the database. If the url is a visited site, it 146e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * will remain in the database, but only as a history item, and not as a 147e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * bookmarked site. 148e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param context Context of the calling Activity. This is used to make 149e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * Toast confirming that the bookmark has been removed. If the 150e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * caller provides null, the Toast will not be shown. 151e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param cr The ContentResolver being used to remove the bookmark. 152e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins * @param url URL of the website to be removed. 153e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins */ 154e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins /* package */ static void removeFromBookmarks(Context context, 155c95261955cf08f30b484b6a229c4bcff42c645ceAndrei Popescu ContentResolver cr, String url, String title) { 1562c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Cursor cursor = null; 1572c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins try { 1582c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cursor = cr.query( 1592c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Browser.BOOKMARKS_URI, 1602c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Browser.HISTORY_PROJECTION, 1612c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins "url = ? AND title = ?", 1622c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins new String[] { url, title }, 1632c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins null); 1642c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins boolean first = cursor.moveToFirst(); 1652c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // Should be in the database no matter what 1662c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (!first) { 1672c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins throw new AssertionError("URL is not in the database! " + url 1682c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins + " " + title); 169e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 1702c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // Remove from bookmarks 1712c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins WebIconDatabase.getInstance().releaseIconForPageUrl(url); 1722c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI, 1732c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX)); 1742c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins int numVisits = cursor.getInt( 1752c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Browser.HISTORY_PROJECTION_VISITS_INDEX); 1762c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (0 == numVisits) { 1772c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cr.delete(uri, null, null); 1782c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } else { 1792c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // It is no longer a bookmark, but it is still a visited 1802c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins // site. 1812c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins ContentValues values = new ContentValues(); 1822c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins values.put(Browser.BookmarkColumns.BOOKMARK, 0); 1832c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins try { 1842c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins cr.update(uri, values, null, null); 1852c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } catch (IllegalStateException e) { 1862c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Log.e("removeFromBookmarks", "no database!"); 1872c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } 1882c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } 1892c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (context != null) { 1902c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Toast.makeText(context, R.string.removed_from_bookmarks, 1912c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Toast.LENGTH_LONG).show(); 1922c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } 1932c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } catch (IllegalStateException e) { 1942c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins Log.e(LOGTAG, "removeFromBookmarks", e); 1952c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins } finally { 1962c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins if (cursor != null) cursor.close(); 197e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 198e372c02c732cf0881c21eb8423454a555e8fc75cLeon Scroggins } 199aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch 200aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch private static byte[] bitmapToBytes(Bitmap bm) { 201aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch if (bm == null) { 202aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch return null; 203aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch } 204aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch 205aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch final ByteArrayOutputStream os = new ByteArrayOutputStream(); 206aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch bm.compress(Bitmap.CompressFormat.PNG, 100, os); 207aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch return os.toByteArray(); 208aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch } 209de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch 210de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch /* package */ static boolean urlHasAcceptableScheme(String url) { 211de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch if (url == null) { 212de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch return false; 213de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch } 214de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch 215de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch for (int i = 0; i < acceptableBookmarkSchemes.length; i++) { 216de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch if (url.startsWith(acceptableBookmarkSchemes[i])) { 217de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch return true; 218de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch } 219de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch } 220de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch return false; 221de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch } 222aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch} 223