blob: 40aaa63dc91c27d77d5f48186be96222b50295d9 [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;
24import android.net.Uri;
25import android.provider.Browser;
26import android.util.Log;
27import android.webkit.WebIconDatabase;
28import android.widget.Toast;
29
30import java.util.Date;
31
32/**
33 * This class is purely to have a common place for adding/deleting bookmarks.
34 */
35/* package */ class Bookmarks {
36 private static final String WHERE_CLAUSE
37 = "url = ? OR url = ? OR url = ? OR url = ?";
38 private static final String WHERE_CLAUSE_SECURE = "url = ? OR url = ?";
39
40 private static String[] SELECTION_ARGS;
41
42 /**
43 * Add a bookmark to the database.
44 * @param context Context of the calling Activity. This is used to make
45 * Toast confirming that the bookmark has been added. If the
46 * caller provides null, the Toast will not be shown.
47 * @param cr The ContentResolver being used to add the bookmark to the db.
48 * @param url URL of the website to be bookmarked.
49 * @param name Provided name for the bookmark.
Christopher Tate9c0dd8c2009-07-10 17:51:48 -070050 * @param retainIcon Whether to retain the page's icon in the icon database.
51 * This will usually be <code>true</code> except when bookmarks are
52 * added by a settings restore agent.
Leon Scrogginse372c022009-06-12 17:07:29 -040053 */
54 /* package */ static void addBookmark(Context context,
Christopher Tate9c0dd8c2009-07-10 17:51:48 -070055 ContentResolver cr, String url, String name,
56 boolean retainIcon) {
Leon Scrogginse372c022009-06-12 17:07:29 -040057 // Want to append to the beginning of the list
58 long creationTime = new Date().getTime();
59 // First we check to see if the user has already visited this
60 // site. They may have bookmarked it in a different way from
61 // how it's stored in the database, so allow different combos
62 // to map to the same url.
63 boolean secure = false;
64 String compareString = url;
65 if (compareString.startsWith("http://")) {
66 compareString = compareString.substring(7);
67 } else if (compareString.startsWith("https://")) {
68 compareString = compareString.substring(8);
69 secure = true;
70 }
71 if (compareString.startsWith("www.")) {
72 compareString = compareString.substring(4);
73 }
74 if (secure) {
75 SELECTION_ARGS = new String[2];
76 SELECTION_ARGS[0] = "https://" + compareString;
77 SELECTION_ARGS[1] = "https://www." + compareString;
78 } else {
79 SELECTION_ARGS = new String[4];
80 SELECTION_ARGS[0] = compareString;
81 SELECTION_ARGS[1] = "www." + compareString;
82 SELECTION_ARGS[2] = "http://" + compareString;
83 SELECTION_ARGS[3] = "http://" + SELECTION_ARGS[1];
84 }
85 Cursor cursor = cr.query(Browser.BOOKMARKS_URI,
86 Browser.HISTORY_PROJECTION,
87 secure ? WHERE_CLAUSE_SECURE : WHERE_CLAUSE,
88 SELECTION_ARGS,
89 null);
90 ContentValues map = new ContentValues();
91 if (cursor.moveToFirst() && cursor.getInt(
92 Browser.HISTORY_PROJECTION_BOOKMARK_INDEX) == 0) {
93 // This means we have been to this site but not bookmarked
94 // it, so convert the history item to a bookmark
95 map.put(Browser.BookmarkColumns.CREATED, creationTime);
96 map.put(Browser.BookmarkColumns.TITLE, name);
97 map.put(Browser.BookmarkColumns.BOOKMARK, 1);
98 cr.update(Browser.BOOKMARKS_URI, map,
99 "_id = " + cursor.getInt(0), null);
100 } else {
101 int count = cursor.getCount();
102 boolean matchedTitle = false;
103 for (int i = 0; i < count; i++) {
104 // One or more bookmarks already exist for this site.
105 // Check the names of each
106 cursor.moveToPosition(i);
107 if (cursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX)
108 .equals(name)) {
109 // The old bookmark has the same name.
110 // Update its creation time.
111 map.put(Browser.BookmarkColumns.CREATED,
112 creationTime);
113 cr.update(Browser.BOOKMARKS_URI, map,
114 "_id = " + cursor.getInt(0), null);
115 matchedTitle = true;
116 break;
117 }
118 }
119 if (!matchedTitle) {
120 // Adding a bookmark for a site the user has visited,
121 // or a new bookmark (with a different name) for a site
122 // the user has visited
123 map.put(Browser.BookmarkColumns.TITLE, name);
124 map.put(Browser.BookmarkColumns.URL, url);
125 map.put(Browser.BookmarkColumns.CREATED, creationTime);
126 map.put(Browser.BookmarkColumns.BOOKMARK, 1);
127 map.put(Browser.BookmarkColumns.DATE, 0);
128 int visits = 0;
129 if (count > 0) {
130 // The user has already bookmarked, and possibly
131 // visited this site. However, they are creating
132 // a new bookmark with the same url but a different
133 // name. The new bookmark should have the same
134 // number of visits as the already created bookmark.
135 visits = cursor.getInt(
136 Browser.HISTORY_PROJECTION_VISITS_INDEX);
137 }
138 // Bookmark starts with 3 extra visits so that it will
139 // bubble up in the most visited and goto search box
140 map.put(Browser.BookmarkColumns.VISITS, visits + 3);
141 cr.insert(Browser.BOOKMARKS_URI, map);
142 }
143 }
Christopher Tate9c0dd8c2009-07-10 17:51:48 -0700144 if (retainIcon) {
145 WebIconDatabase.getInstance().retainIconForPageUrl(url);
146 }
Leon Scrogginse372c022009-06-12 17:07:29 -0400147 cursor.deactivate();
148 if (context != null) {
149 Toast.makeText(context, R.string.added_to_bookmarks,
150 Toast.LENGTH_LONG).show();
151 }
152 }
153
154 /**
155 * Remove a bookmark from the database. If the url is a visited site, it
156 * will remain in the database, but only as a history item, and not as a
157 * bookmarked site.
158 * @param context Context of the calling Activity. This is used to make
159 * Toast confirming that the bookmark has been removed. If the
160 * caller provides null, the Toast will not be shown.
161 * @param cr The ContentResolver being used to remove the bookmark.
162 * @param url URL of the website to be removed.
163 */
164 /* package */ static void removeFromBookmarks(Context context,
Andrei Popescuc9526192009-09-23 15:52:16 +0100165 ContentResolver cr, String url, String title) {
Leon Scrogginse372c022009-06-12 17:07:29 -0400166 Cursor cursor = cr.query(
167 Browser.BOOKMARKS_URI,
168 Browser.HISTORY_PROJECTION,
Andrei Popescuc9526192009-09-23 15:52:16 +0100169 "url = ? AND title = ?",
170 new String[] { url, title },
Leon Scrogginse372c022009-06-12 17:07:29 -0400171 null);
172 boolean first = cursor.moveToFirst();
173 // Should be in the database no matter what
174 if (!first) {
Andrei Popescuc9526192009-09-23 15:52:16 +0100175 throw new AssertionError("URL is not in the database! " + url + " " + title);
Leon Scrogginse372c022009-06-12 17:07:29 -0400176 }
177 // Remove from bookmarks
178 WebIconDatabase.getInstance().releaseIconForPageUrl(url);
179 Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
180 cursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
181 int numVisits = cursor.getInt(
182 Browser.HISTORY_PROJECTION_VISITS_INDEX);
183 if (0 == numVisits) {
184 cr.delete(uri, null, null);
185 } else {
186 // It is no longer a bookmark, but it is still a visited
187 // site.
188 ContentValues values = new ContentValues();
189 values.put(Browser.BookmarkColumns.BOOKMARK, 0);
190 try {
191 cr.update(uri, values, null, null);
192 } catch (IllegalStateException e) {
193 Log.e("removeFromBookmarks", "no database!");
194 }
195 }
196 if (context != null) {
197 Toast.makeText(context, R.string.removed_from_bookmarks,
198 Toast.LENGTH_LONG).show();
199 }
200 cursor.deactivate();
201 }
202}