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