blob: 241b33b75a2e17337f6581a142199c4036afa2c0 [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
2 * Copyright (C) 2006 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.database.ContentObserver;
23import android.database.Cursor;
24import android.database.DataSetObserver;
25import android.graphics.Bitmap;
26import android.graphics.BitmapFactory;
27import android.net.Uri;
Patrick Scott63a45b82010-04-06 16:36:12 -040028import android.os.AsyncTask;
The Android Open Source Project0c908882009-03-03 19:32:16 -080029import android.os.Bundle;
30import android.os.Handler;
Patrick Scottf49ecd62010-04-09 12:43:26 -040031import android.os.Looper;
The Android Open Source Project0c908882009-03-03 19:32:16 -080032import android.provider.Browser;
33import android.provider.Browser.BookmarkColumns;
34import android.view.KeyEvent;
Leon Scroggins892df312009-07-14 14:48:02 -040035import android.view.LayoutInflater;
The Android Open Source Project0c908882009-03-03 19:32:16 -080036import android.view.View;
37import android.view.ViewGroup;
38import android.webkit.WebIconDatabase;
Patrick Scott3918d442009-08-04 13:22:29 -040039import android.webkit.WebView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080040import android.widget.BaseAdapter;
Leon Scroggins892df312009-07-14 14:48:02 -040041import android.widget.ImageView;
42import android.widget.TextView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080043
44import java.io.ByteArrayOutputStream;
45
46class BrowserBookmarksAdapter extends BaseAdapter {
47
The Android Open Source Project0c908882009-03-03 19:32:16 -080048 private String mCurrentPage;
Leon Scroggins89c6d362009-07-15 16:54:37 -040049 private String mCurrentTitle;
Ben Murdochdcc2b6f2009-09-21 14:29:20 +010050 private Bitmap mCurrentThumbnail;
The Android Open Source Project0c908882009-03-03 19:32:16 -080051 private Cursor mCursor;
52 private int mCount;
The Android Open Source Project0c908882009-03-03 19:32:16 -080053 private BrowserBookmarksPage mBookmarksPage;
54 private ContentResolver mContentResolver;
The Android Open Source Project0c908882009-03-03 19:32:16 -080055 private boolean mDataValid;
Ben Murdoch328ea872009-09-16 13:33:29 +010056 private BookmarkViewMode mViewMode;
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040057 private boolean mMostVisited;
58 private boolean mNeedsOffset;
59 private int mExtraOffset;
The Android Open Source Project0c908882009-03-03 19:32:16 -080060
The Android Open Source Project0c908882009-03-03 19:32:16 -080061 /**
62 * Create a new BrowserBookmarksAdapter.
The Android Open Source Project0c908882009-03-03 19:32:16 -080063 * @param b BrowserBookmarksPage that instantiated this.
64 * Necessary so it will adjust its focus
65 * appropriately after a search.
66 */
67 public BrowserBookmarksAdapter(BrowserBookmarksPage b, String curPage,
Ben Murdochdcc2b6f2009-09-21 14:29:20 +010068 String curTitle, Bitmap curThumbnail, boolean createShortcut,
69 boolean mostVisited) {
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040070 mNeedsOffset = !(createShortcut || mostVisited);
71 mMostVisited = mostVisited;
72 mExtraOffset = mNeedsOffset ? 1 : 0;
The Android Open Source Project0c908882009-03-03 19:32:16 -080073 mBookmarksPage = b;
Leon Scroggins89c6d362009-07-15 16:54:37 -040074 mCurrentPage = b.getResources().getString(R.string.current_page)
75 + curPage;
76 mCurrentTitle = curTitle;
Ben Murdochdcc2b6f2009-09-21 14:29:20 +010077 mCurrentThumbnail = curThumbnail;
The Android Open Source Project0c908882009-03-03 19:32:16 -080078 mContentResolver = b.getContentResolver();
Ben Murdoch328ea872009-09-16 13:33:29 +010079 mViewMode = BookmarkViewMode.LIST;
Leon Scroggins892df312009-07-14 14:48:02 -040080
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040081 String whereClause;
The Android Open Source Project0c908882009-03-03 19:32:16 -080082 // FIXME: Should have a default sort order that the user selects.
Leon Scroggins892df312009-07-14 14:48:02 -040083 String orderBy = Browser.BookmarkColumns.VISITS + " DESC";
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040084 if (mostVisited) {
85 whereClause = Browser.BookmarkColumns.VISITS + " != 0";
86 } else {
Patrick Scottc1cf63a2010-03-09 16:02:08 -050087 whereClause = Browser.BookmarkColumns.BOOKMARK + " = 1";
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040088 }
Leon Scroggins892df312009-07-14 14:48:02 -040089 mCursor = b.managedQuery(Browser.BOOKMARKS_URI,
90 Browser.HISTORY_PROJECTION, whereClause, null, orderBy);
91 mCursor.registerContentObserver(new ChangeObserver());
92 mCursor.registerDataSetObserver(new MyDataSetObserver());
93
94 mDataValid = true;
95 notifyDataSetChanged();
96
97 mCount = mCursor.getCount() + mExtraOffset;
The Android Open Source Project0c908882009-03-03 19:32:16 -080098 }
99
100 /**
101 * Return a hashmap with one row's Title, Url, and favicon.
102 * @param position Position in the list.
103 * @return Bundle Stores title, url of row position, favicon, and id
104 * for the url. Return a blank map if position is out of
105 * range.
106 */
107 public Bundle getRow(int position) {
108 Bundle map = new Bundle();
109 if (position < mExtraOffset || position >= mCount) {
110 return map;
111 }
112 mCursor.moveToPosition(position- mExtraOffset);
113 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
114 map.putString(Browser.BookmarkColumns.TITLE,
115 mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
116 map.putString(Browser.BookmarkColumns.URL, url);
117 byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
118 if (data != null) {
119 map.putParcelable(Browser.BookmarkColumns.FAVICON,
120 BitmapFactory.decodeByteArray(data, 0, data.length));
121 }
122 map.putInt("id", mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
123 return map;
124 }
125
126 /**
127 * Update a row in the database with new information.
128 * Requeries the database if the information has changed.
129 * @param map Bundle storing id, title and url of new information
130 */
131 public void updateRow(Bundle map) {
132
133 // Find the record
134 int id = map.getInt("id");
135 int position = -1;
136 for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
137 if (mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX) == id) {
138 position = mCursor.getPosition();
139 break;
140 }
141 }
142 if (position < 0) {
143 return;
144 }
145
146 mCursor.moveToPosition(position);
147 ContentValues values = new ContentValues();
148 String title = map.getString(Browser.BookmarkColumns.TITLE);
149 if (!title.equals(mCursor
150 .getString(Browser.HISTORY_PROJECTION_TITLE_INDEX))) {
151 values.put(Browser.BookmarkColumns.TITLE, title);
152 }
153 String url = map.getString(Browser.BookmarkColumns.URL);
154 if (!url.equals(mCursor.
155 getString(Browser.HISTORY_PROJECTION_URL_INDEX))) {
156 values.put(Browser.BookmarkColumns.URL, url);
157 }
Ben Murdoch1794fe22009-09-29 18:14:30 +0100158
159 if (map.getBoolean("invalidateThumbnail") == true) {
160 values.put(Browser.BookmarkColumns.THUMBNAIL, new byte[0]);
161 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800162 if (values.size() > 0
163 && mContentResolver.update(Browser.BOOKMARKS_URI, values,
164 "_id = " + id, null) != -1) {
165 refreshList();
166 }
167 }
168
169 /**
170 * Delete a row from the database. Requeries the database.
171 * Does nothing if the provided position is out of range.
172 * @param position Position in the list.
173 */
174 public void deleteRow(int position) {
175 if (position < mExtraOffset || position >= getCount()) {
176 return;
177 }
178 mCursor.moveToPosition(position- mExtraOffset);
179 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
Andrei Popescuc9526192009-09-23 15:52:16 +0100180 String title = mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX);
181 Bookmarks.removeFromBookmarks(null, mContentResolver, url, title);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800182 refreshList();
183 }
184
185 /**
186 * Delete all bookmarks from the db. Requeries the database.
187 * All bookmarks with become visited URLs or if never visited
188 * are removed
189 */
190 public void deleteAllRows() {
191 StringBuilder deleteIds = null;
192 StringBuilder convertIds = null;
193
194 for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
195 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
196 WebIconDatabase.getInstance().releaseIconForPageUrl(url);
197 int id = mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX);
198 int numVisits = mCursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX);
199 if (0 == numVisits) {
200 if (deleteIds == null) {
201 deleteIds = new StringBuilder();
202 deleteIds.append("( ");
203 } else {
204 deleteIds.append(" OR ( ");
205 }
206 deleteIds.append(BookmarkColumns._ID);
207 deleteIds.append(" = ");
208 deleteIds.append(id);
209 deleteIds.append(" )");
210 } else {
211 // It is no longer a bookmark, but it is still a visited site.
212 if (convertIds == null) {
213 convertIds = new StringBuilder();
214 convertIds.append("( ");
215 } else {
216 convertIds.append(" OR ( ");
217 }
218 convertIds.append(BookmarkColumns._ID);
219 convertIds.append(" = ");
220 convertIds.append(id);
221 convertIds.append(" )");
222 }
223 }
224
225 if (deleteIds != null) {
226 mContentResolver.delete(Browser.BOOKMARKS_URI, deleteIds.toString(),
227 null);
228 }
229 if (convertIds != null) {
230 ContentValues values = new ContentValues();
231 values.put(Browser.BookmarkColumns.BOOKMARK, 0);
232 mContentResolver.update(Browser.BOOKMARKS_URI, values,
233 convertIds.toString(), null);
234 }
235 refreshList();
236 }
237
238 /**
239 * Refresh list to recognize a change in the database.
240 */
241 public void refreshList() {
Leon Scroggins892df312009-07-14 14:48:02 -0400242 mCursor.requery();
243 mCount = mCursor.getCount() + mExtraOffset;
244 notifyDataSetChanged();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800245 }
246
247 /**
Patrick Scott3918d442009-08-04 13:22:29 -0400248 * Update the bookmark's favicon. This is a convenience method for updating
249 * a bookmark favicon for the originalUrl and url of the passed in WebView.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800250 * @param cr The ContentResolver to use.
Patrick Scott15525d42009-09-21 13:39:37 -0400251 * @param originalUrl The original url before any redirects.
252 * @param url The current url.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800253 * @param favicon The favicon bitmap to write to the db.
254 */
Patrick Scott63a45b82010-04-06 16:36:12 -0400255 /* package */ static void updateBookmarkFavicon(final ContentResolver cr,
256 final String originalUrl, final String url, final Bitmap favicon) {
257 new AsyncTask<Void, Void, Void>() {
258 protected Void doInBackground(Void... unused) {
259 final Cursor c =
260 queryBookmarksForUrl(cr, originalUrl, url, true);
261 if (c == null) {
262 return null;
263 }
264 if (c.moveToFirst()) {
265 ContentValues values = new ContentValues();
266 final ByteArrayOutputStream os =
267 new ByteArrayOutputStream();
268 favicon.compress(Bitmap.CompressFormat.PNG, 100, os);
269 values.put(Browser.BookmarkColumns.FAVICON,
270 os.toByteArray());
271 do {
272 cr.update(ContentUris.withAppendedId(
273 Browser.BOOKMARKS_URI, c.getInt(0)),
274 values, null, null);
275 } while (c.moveToNext());
276 }
277 c.close();
278 return null;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800279 }
Patrick Scott63a45b82010-04-06 16:36:12 -0400280 }.execute();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800281 }
282
Patrick Scott3918d442009-08-04 13:22:29 -0400283 /* package */ static Cursor queryBookmarksForUrl(ContentResolver cr,
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400284 String originalUrl, String url, boolean onlyBookmarks) {
Patrick Scott3918d442009-08-04 13:22:29 -0400285 if (cr == null || url == null) {
286 return null;
287 }
288
289 // If originalUrl is null, just set it to url.
290 if (originalUrl == null) {
291 originalUrl = url;
292 }
293
294 // Look for both the original url and the actual url. This takes in to
295 // account redirects.
296 String originalUrlNoQuery = removeQuery(originalUrl);
297 String urlNoQuery = removeQuery(url);
298 originalUrl = originalUrlNoQuery + '?';
299 url = urlNoQuery + '?';
300
301 // Use NoQuery to search for the base url (i.e. if the url is
302 // http://www.yahoo.com/?rs=1, search for http://www.yahoo.com)
303 // Use url to match the base url with other queries (i.e. if the url is
304 // http://www.google.com/m, search for
305 // http://www.google.com/m?some_query)
306 final String[] selArgs = new String[] {
307 originalUrlNoQuery, urlNoQuery, originalUrl, url };
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400308 String where = BookmarkColumns.URL + " == ? OR "
Patrick Scott3918d442009-08-04 13:22:29 -0400309 + BookmarkColumns.URL + " == ? OR "
Patrick Scott193def92010-01-07 15:01:09 -0500310 + BookmarkColumns.URL + " LIKE ? || '%' OR "
311 + BookmarkColumns.URL + " LIKE ? || '%'";
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400312 if (onlyBookmarks) {
313 where = "(" + where + ") AND " + BookmarkColumns.BOOKMARK + " == 1";
314 }
Patrick Scott3918d442009-08-04 13:22:29 -0400315 final String[] projection =
316 new String[] { Browser.BookmarkColumns._ID };
317 return cr.query(Browser.BOOKMARKS_URI, projection, where, selArgs,
318 null);
319 }
320
321 // Strip the query from the given url.
322 private static String removeQuery(String url) {
323 if (url == null) {
324 return null;
325 }
326 int query = url.indexOf('?');
327 String noQuery = url;
328 if (query != -1) {
329 noQuery = url.substring(0, query);
330 }
331 return noQuery;
332 }
333
The Android Open Source Project0c908882009-03-03 19:32:16 -0800334 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800335 * How many items should be displayed in the list.
336 * @return Count of items.
337 */
338 public int getCount() {
339 if (mDataValid) {
340 return mCount;
341 } else {
342 return 0;
343 }
344 }
345
346 public boolean areAllItemsEnabled() {
347 return true;
348 }
349
350 public boolean isEnabled(int position) {
351 return true;
352 }
353
354 /**
355 * Get the data associated with the specified position in the list.
356 * @param position Index of the item whose data we want.
357 * @return The data at the specified position.
358 */
359 public Object getItem(int position) {
360 return null;
361 }
362
363 /**
364 * Get the row id associated with the specified position in the list.
365 * @param position Index of the item whose row id we want.
366 * @return The id of the item at the specified position.
367 */
368 public long getItemId(int position) {
369 return position;
370 }
371
Ben Murdoch328ea872009-09-16 13:33:29 +0100372 /* package */ void switchViewMode(BookmarkViewMode viewMode) {
373 mViewMode = viewMode;
Leon Scroggins892df312009-07-14 14:48:02 -0400374 }
375
376 /* package */ void populateBookmarkItem(BookmarkItem b, int position) {
377 mCursor.moveToPosition(position - mExtraOffset);
Patrick Scott8f0076b2009-09-17 13:51:30 -0400378 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
379 b.setUrl(url);
Leon Scroggins892df312009-07-14 14:48:02 -0400380 b.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
381 byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
Patrick Scott8f0076b2009-09-17 13:51:30 -0400382 Bitmap bitmap = null;
383 if (data == null) {
384 bitmap = CombinedBookmarkHistoryActivity.getIconListenerSet()
385 .getFavicon(url);
386 } else {
387 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
388 }
Leon Scroggins892df312009-07-14 14:48:02 -0400389 b.setFavicon(bitmap);
390 }
391
The Android Open Source Project0c908882009-03-03 19:32:16 -0800392 /**
393 * Get a View that displays the data at the specified position
394 * in the list.
395 * @param position Index of the item whose view we want.
396 * @return A View corresponding to the data at the specified position.
397 */
398 public View getView(int position, View convertView, ViewGroup parent) {
399 if (!mDataValid) {
400 throw new IllegalStateException(
401 "this should only be called when the cursor is valid");
402 }
403 if (position < 0 || position > mCount) {
404 throw new AssertionError(
405 "BrowserBookmarksAdapter tried to get a view out of range");
406 }
Ben Murdoch328ea872009-09-16 13:33:29 +0100407 if (mViewMode == BookmarkViewMode.GRID) {
Leon Scroggins892df312009-07-14 14:48:02 -0400408 if (convertView == null || convertView instanceof AddNewBookmark
409 || convertView instanceof BookmarkItem) {
410 LayoutInflater factory = LayoutInflater.from(mBookmarksPage);
411 convertView
412 = factory.inflate(R.layout.bookmark_thumbnail, null);
413 }
Leon Scroggins89c6d362009-07-15 16:54:37 -0400414 View holder = convertView.findViewById(R.id.holder);
Leon Scroggins892df312009-07-14 14:48:02 -0400415 ImageView thumb = (ImageView) convertView.findViewById(R.id.thumb);
Leon Scroggins892df312009-07-14 14:48:02 -0400416 TextView tv = (TextView) convertView.findViewById(R.id.label);
417
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400418 if (0 == position && mNeedsOffset) {
Leon Scroggins892df312009-07-14 14:48:02 -0400419 // This is to create a bookmark for the current page.
Leon Scroggins89c6d362009-07-15 16:54:37 -0400420 holder.setVisibility(View.VISIBLE);
Leon Scroggins89c6d362009-07-15 16:54:37 -0400421 tv.setText(mCurrentTitle);
Ben Murdochdcc2b6f2009-09-21 14:29:20 +0100422
423 if (mCurrentThumbnail != null) {
424 thumb.setImageBitmap(mCurrentThumbnail);
425 } else {
426 thumb.setImageResource(
Leon Scrogginsf8551612009-09-24 16:06:02 -0400427 R.drawable.browser_thumbnail);
Ben Murdochdcc2b6f2009-09-21 14:29:20 +0100428 }
Leon Scroggins892df312009-07-14 14:48:02 -0400429 return convertView;
430 }
Leon Scroggins89c6d362009-07-15 16:54:37 -0400431 holder.setVisibility(View.GONE);
Leon Scroggins892df312009-07-14 14:48:02 -0400432 mCursor.moveToPosition(position - mExtraOffset);
433 tv.setText(mCursor.getString(
434 Browser.HISTORY_PROJECTION_TITLE_INDEX));
Leon Scroggins96afcb12009-12-10 12:35:56 -0500435 Bitmap thumbnail = getScreenshot(position);
Ben Murdochaac7aa62009-09-17 16:57:40 +0100436 if (thumbnail == null) {
Leon Scrogginsf8551612009-09-24 16:06:02 -0400437 thumb.setImageResource(R.drawable.browser_thumbnail);
Leon Scroggins892df312009-07-14 14:48:02 -0400438 } else {
Ben Murdochaac7aa62009-09-17 16:57:40 +0100439 thumb.setImageBitmap(thumbnail);
Leon Scroggins892df312009-07-14 14:48:02 -0400440 }
Leon Scroggins89c6d362009-07-15 16:54:37 -0400441
Leon Scroggins892df312009-07-14 14:48:02 -0400442 return convertView;
443
444 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400445 if (position == 0 && mNeedsOffset) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800446 AddNewBookmark b;
447 if (convertView instanceof AddNewBookmark) {
448 b = (AddNewBookmark) convertView;
449 } else {
450 b = new AddNewBookmark(mBookmarksPage);
451 }
452 b.setUrl(mCurrentPage);
453 return b;
454 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400455 if (mMostVisited) {
456 if (convertView == null || !(convertView instanceof HistoryItem)) {
457 convertView = new HistoryItem(mBookmarksPage);
458 }
459 } else {
460 if (convertView == null || !(convertView instanceof BookmarkItem)) {
461 convertView = new BookmarkItem(mBookmarksPage);
462 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800463 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400464 bind((BookmarkItem) convertView, position);
465 if (mMostVisited) {
466 ((HistoryItem) convertView).setIsBookmark(
467 getIsBookmark(position));
468 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800469 return convertView;
470 }
471
472 /**
473 * Return the title for this item in the list.
474 */
475 public String getTitle(int position) {
476 return getString(Browser.HISTORY_PROJECTION_TITLE_INDEX, position);
477 }
478
479 /**
480 * Return the Url for this item in the list.
481 */
482 public String getUrl(int position) {
483 return getString(Browser.HISTORY_PROJECTION_URL_INDEX, position);
484 }
485
486 /**
Leon Scroggins96afcb12009-12-10 12:35:56 -0500487 * Return the screenshot for this item in the list.
488 */
489 public Bitmap getScreenshot(int position) {
490 return getBitmap(Browser.HISTORY_PROJECTION_THUMBNAIL_INDEX, position);
491 }
492
493 /**
Patrick Scotte09761e2009-03-24 20:43:37 -0700494 * Return the favicon for this item in the list.
495 */
496 public Bitmap getFavicon(int position) {
Patrick Scott3918d442009-08-04 13:22:29 -0400497 return getBitmap(Browser.HISTORY_PROJECTION_FAVICON_INDEX, position);
498 }
499
500 public Bitmap getTouchIcon(int position) {
501 return getBitmap(Browser.HISTORY_PROJECTION_TOUCH_ICON_INDEX, position);
502 }
503
504 private Bitmap getBitmap(int cursorIndex, int position) {
Patrick Scotte09761e2009-03-24 20:43:37 -0700505 if (position < mExtraOffset || position > mCount) {
506 return null;
507 }
508 mCursor.moveToPosition(position - mExtraOffset);
Patrick Scott3918d442009-08-04 13:22:29 -0400509 byte[] data = mCursor.getBlob(cursorIndex);
Patrick Scotte09761e2009-03-24 20:43:37 -0700510 if (data == null) {
511 return null;
512 }
513 return BitmapFactory.decodeByteArray(data, 0, data.length);
514 }
515
516 /**
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400517 * Return whether or not this item represents a bookmarked site.
518 */
519 public boolean getIsBookmark(int position) {
520 if (position < mExtraOffset || position > mCount) {
521 return false;
522 }
523 mCursor.moveToPosition(position - mExtraOffset);
524 return (1 == mCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
525 }
526
527 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800528 * Private helper function to return the title or url.
529 */
530 private String getString(int cursorIndex, int position) {
531 if (position < mExtraOffset || position > mCount) {
532 return "";
533 }
534 mCursor.moveToPosition(position- mExtraOffset);
535 return mCursor.getString(cursorIndex);
536 }
537
538 private void bind(BookmarkItem b, int position) {
539 mCursor.moveToPosition(position- mExtraOffset);
540
Ben Murdoch9907efc2009-10-28 13:22:46 +0000541 b.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800542 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800543 b.setUrl(url);
544 byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
545 if (data != null) {
546 b.setFavicon(BitmapFactory.decodeByteArray(data, 0, data.length));
547 } else {
Patrick Scott8f0076b2009-09-17 13:51:30 -0400548 b.setFavicon(CombinedBookmarkHistoryActivity.getIconListenerSet()
549 .getFavicon(url));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800550 }
551 }
552
553 private class ChangeObserver extends ContentObserver {
554 public ChangeObserver() {
Patrick Scottf49ecd62010-04-09 12:43:26 -0400555 super(new Handler(Looper.getMainLooper()));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800556 }
557
558 @Override
559 public boolean deliverSelfNotifications() {
560 return true;
561 }
562
563 @Override
564 public void onChange(boolean selfChange) {
565 refreshList();
566 }
567 }
568
569 private class MyDataSetObserver extends DataSetObserver {
570 @Override
571 public void onChanged() {
572 mDataValid = true;
573 notifyDataSetChanged();
574 }
575
576 @Override
577 public void onInvalidated() {
578 mDataValid = false;
579 notifyDataSetInvalidated();
580 }
581 }
582}