blob: c8aaee7001eb1b9e51cc086d40e541d69bc5cdd5 [file] [log] [blame]
Leon Scrogginse372c022009-06-12 17:07:29 -04001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.content.ContentResolver;
20import android.content.ContentUris;
21import android.content.ContentValues;
22import android.content.Context;
23import android.database.Cursor;
Ben Murdochaac7aa62009-09-17 16:57:40 +010024import android.graphics.Bitmap;
Leon Scrogginse372c022009-06-12 17:07:29 -040025import android.net.Uri;
26import android.provider.Browser;
27import android.util.Log;
28import android.webkit.WebIconDatabase;
29import android.widget.Toast;
30
Ben Murdochaac7aa62009-09-17 16:57:40 +010031import java.io.ByteArrayOutputStream;
Leon Scrogginse372c022009-06-12 17:07:29 -040032import java.util.Date;
33
34/**
35 * This class is purely to have a common place for adding/deleting bookmarks.
36 */
37/* package */ class Bookmarks {
38 private static final String WHERE_CLAUSE
39 = "url = ? OR url = ? OR url = ? OR url = ?";
40 private static final String WHERE_CLAUSE_SECURE = "url = ? OR url = ?";
41
42 private static String[] SELECTION_ARGS;
43
44 /**
45 * Add a bookmark to the database.
46 * @param context Context of the calling Activity. This is used to make
47 * Toast confirming that the bookmark has been added. If the
48 * caller provides null, the Toast will not be shown.
49 * @param cr The ContentResolver being used to add the bookmark to the db.
50 * @param url URL of the website to be bookmarked.
51 * @param name Provided name for the bookmark.
Ben Murdochaac7aa62009-09-17 16:57:40 +010052 * @param thumbnail A thumbnail for the bookmark.
Christopher Tate9c0dd8c2009-07-10 17:51:48 -070053 * @param retainIcon Whether to retain the page's icon in the icon database.
54 * This will usually be <code>true</code> except when bookmarks are
55 * added by a settings restore agent.
Leon Scrogginse372c022009-06-12 17:07:29 -040056 */
57 /* package */ static void addBookmark(Context context,
Christopher Tate9c0dd8c2009-07-10 17:51:48 -070058 ContentResolver cr, String url, String name,
Ben Murdochaac7aa62009-09-17 16:57:40 +010059 Bitmap thumbnail, boolean retainIcon) {
Leon Scrogginse372c022009-06-12 17:07:29 -040060 // Want to append to the beginning of the list
61 long creationTime = new Date().getTime();
62 // First we check to see if the user has already visited this
63 // site. They may have bookmarked it in a different way from
64 // how it's stored in the database, so allow different combos
65 // to map to the same url.
66 boolean secure = false;
67 String compareString = url;
68 if (compareString.startsWith("http://")) {
69 compareString = compareString.substring(7);
70 } else if (compareString.startsWith("https://")) {
71 compareString = compareString.substring(8);
72 secure = true;
73 }
74 if (compareString.startsWith("www.")) {
75 compareString = compareString.substring(4);
76 }
77 if (secure) {
78 SELECTION_ARGS = new String[2];
79 SELECTION_ARGS[0] = "https://" + compareString;
80 SELECTION_ARGS[1] = "https://www." + compareString;
81 } else {
82 SELECTION_ARGS = new String[4];
83 SELECTION_ARGS[0] = compareString;
84 SELECTION_ARGS[1] = "www." + compareString;
85 SELECTION_ARGS[2] = "http://" + compareString;
86 SELECTION_ARGS[3] = "http://" + SELECTION_ARGS[1];
87 }
88 Cursor cursor = cr.query(Browser.BOOKMARKS_URI,
89 Browser.HISTORY_PROJECTION,
90 secure ? WHERE_CLAUSE_SECURE : WHERE_CLAUSE,
91 SELECTION_ARGS,
92 null);
93 ContentValues map = new ContentValues();
94 if (cursor.moveToFirst() && cursor.getInt(
95 Browser.HISTORY_PROJECTION_BOOKMARK_INDEX) == 0) {
96 // This means we have been to this site but not bookmarked
97 // it, so convert the history item to a bookmark
98 map.put(Browser.BookmarkColumns.CREATED, creationTime);
99 map.put(Browser.BookmarkColumns.TITLE, name);
100 map.put(Browser.BookmarkColumns.BOOKMARK, 1);
Ben Murdochaac7aa62009-09-17 16:57:40 +0100101 map.put(Browser.BookmarkColumns.THUMBNAIL, bitmapToBytes(thumbnail));
Leon Scrogginse372c022009-06-12 17:07:29 -0400102 cr.update(Browser.BOOKMARKS_URI, map,
103 "_id = " + cursor.getInt(0), null);
104 } else {
105 int count = cursor.getCount();
106 boolean matchedTitle = false;
107 for (int i = 0; i < count; i++) {
108 // One or more bookmarks already exist for this site.
109 // Check the names of each
110 cursor.moveToPosition(i);
111 if (cursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX)
112 .equals(name)) {
113 // The old bookmark has the same name.
114 // Update its creation time.
115 map.put(Browser.BookmarkColumns.CREATED,
116 creationTime);
117 cr.update(Browser.BOOKMARKS_URI, map,
118 "_id = " + cursor.getInt(0), null);
119 matchedTitle = true;
120 break;
121 }
122 }
123 if (!matchedTitle) {
124 // Adding a bookmark for a site the user has visited,
125 // or a new bookmark (with a different name) for a site
126 // the user has visited
127 map.put(Browser.BookmarkColumns.TITLE, name);
128 map.put(Browser.BookmarkColumns.URL, url);
129 map.put(Browser.BookmarkColumns.CREATED, creationTime);
130 map.put(Browser.BookmarkColumns.BOOKMARK, 1);
131 map.put(Browser.BookmarkColumns.DATE, 0);
Ben Murdochaac7aa62009-09-17 16:57:40 +0100132 map.put(Browser.BookmarkColumns.THUMBNAIL, bitmapToBytes(thumbnail));
Leon Scrogginse372c022009-06-12 17:07:29 -0400133 int visits = 0;
134 if (count > 0) {
135 // The user has already bookmarked, and possibly
136 // visited this site. However, they are creating
137 // a new bookmark with the same url but a different
138 // name. The new bookmark should have the same
139 // number of visits as the already created bookmark.
140 visits = cursor.getInt(
141 Browser.HISTORY_PROJECTION_VISITS_INDEX);
142 }
143 // Bookmark starts with 3 extra visits so that it will
144 // bubble up in the most visited and goto search box
145 map.put(Browser.BookmarkColumns.VISITS, visits + 3);
146 cr.insert(Browser.BOOKMARKS_URI, map);
147 }
148 }
Christopher Tate9c0dd8c2009-07-10 17:51:48 -0700149 if (retainIcon) {
150 WebIconDatabase.getInstance().retainIconForPageUrl(url);
151 }
Leon Scrogginse372c022009-06-12 17:07:29 -0400152 cursor.deactivate();
153 if (context != null) {
154 Toast.makeText(context, R.string.added_to_bookmarks,
155 Toast.LENGTH_LONG).show();
156 }
157 }
158
159 /**
160 * Remove a bookmark from the database. If the url is a visited site, it
161 * will remain in the database, but only as a history item, and not as a
162 * bookmarked site.
163 * @param context Context of the calling Activity. This is used to make
164 * Toast confirming that the bookmark has been removed. If the
165 * caller provides null, the Toast will not be shown.
166 * @param cr The ContentResolver being used to remove the bookmark.
167 * @param url URL of the website to be removed.
168 */
169 /* package */ static void removeFromBookmarks(Context context,
Andrei Popescuc9526192009-09-23 15:52:16 +0100170 ContentResolver cr, String url, String title) {
Leon Scrogginse372c022009-06-12 17:07:29 -0400171 Cursor cursor = cr.query(
172 Browser.BOOKMARKS_URI,
173 Browser.HISTORY_PROJECTION,
Andrei Popescuc9526192009-09-23 15:52:16 +0100174 "url = ? AND title = ?",
175 new String[] { url, title },
Leon Scrogginse372c022009-06-12 17:07:29 -0400176 null);
177 boolean first = cursor.moveToFirst();
178 // Should be in the database no matter what
179 if (!first) {
Andrei Popescuc9526192009-09-23 15:52:16 +0100180 throw new AssertionError("URL is not in the database! " + url + " " + title);
Leon Scrogginse372c022009-06-12 17:07:29 -0400181 }
182 // Remove from bookmarks
183 WebIconDatabase.getInstance().releaseIconForPageUrl(url);
184 Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
185 cursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
186 int numVisits = cursor.getInt(
187 Browser.HISTORY_PROJECTION_VISITS_INDEX);
188 if (0 == numVisits) {
189 cr.delete(uri, null, null);
190 } else {
191 // It is no longer a bookmark, but it is still a visited
192 // site.
193 ContentValues values = new ContentValues();
194 values.put(Browser.BookmarkColumns.BOOKMARK, 0);
195 try {
196 cr.update(uri, values, null, null);
197 } catch (IllegalStateException e) {
198 Log.e("removeFromBookmarks", "no database!");
199 }
200 }
201 if (context != null) {
202 Toast.makeText(context, R.string.removed_from_bookmarks,
203 Toast.LENGTH_LONG).show();
204 }
205 cursor.deactivate();
206 }
Ben Murdochaac7aa62009-09-17 16:57:40 +0100207
208 private static byte[] bitmapToBytes(Bitmap bm) {
209 if (bm == null) {
210 return null;
211 }
212
213 final ByteArrayOutputStream os = new ByteArrayOutputStream();
214 bm.compress(Bitmap.CompressFormat.PNG, 100, os);
215 return os.toByteArray();
216 }
217}