blob: 03e3e5d770608468cff3fa02fd13bb16738a7069 [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;
31import android.provider.Browser;
32import android.provider.Browser.BookmarkColumns;
33import android.view.KeyEvent;
Leon Scroggins892df312009-07-14 14:48:02 -040034import android.view.LayoutInflater;
The Android Open Source Project0c908882009-03-03 19:32:16 -080035import android.view.View;
36import android.view.ViewGroup;
37import android.webkit.WebIconDatabase;
Patrick Scott3918d442009-08-04 13:22:29 -040038import android.webkit.WebView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080039import android.widget.BaseAdapter;
Leon Scroggins892df312009-07-14 14:48:02 -040040import android.widget.ImageView;
41import android.widget.TextView;
The Android Open Source Project0c908882009-03-03 19:32:16 -080042
43import java.io.ByteArrayOutputStream;
44
45class BrowserBookmarksAdapter extends BaseAdapter {
46
The Android Open Source Project0c908882009-03-03 19:32:16 -080047 private String mCurrentPage;
Leon Scroggins89c6d362009-07-15 16:54:37 -040048 private String mCurrentTitle;
Ben Murdochdcc2b6f2009-09-21 14:29:20 +010049 private Bitmap mCurrentThumbnail;
The Android Open Source Project0c908882009-03-03 19:32:16 -080050 private Cursor mCursor;
51 private int mCount;
The Android Open Source Project0c908882009-03-03 19:32:16 -080052 private BrowserBookmarksPage mBookmarksPage;
53 private ContentResolver mContentResolver;
The Android Open Source Project0c908882009-03-03 19:32:16 -080054 private boolean mDataValid;
Ben Murdoch328ea872009-09-16 13:33:29 +010055 private BookmarkViewMode mViewMode;
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040056 private boolean mMostVisited;
57 private boolean mNeedsOffset;
58 private int mExtraOffset;
The Android Open Source Project0c908882009-03-03 19:32:16 -080059
The Android Open Source Project0c908882009-03-03 19:32:16 -080060 /**
61 * Create a new BrowserBookmarksAdapter.
The Android Open Source Project0c908882009-03-03 19:32:16 -080062 * @param b BrowserBookmarksPage that instantiated this.
63 * Necessary so it will adjust its focus
64 * appropriately after a search.
65 */
66 public BrowserBookmarksAdapter(BrowserBookmarksPage b, String curPage,
Ben Murdochdcc2b6f2009-09-21 14:29:20 +010067 String curTitle, Bitmap curThumbnail, boolean createShortcut,
68 boolean mostVisited) {
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040069 mNeedsOffset = !(createShortcut || mostVisited);
70 mMostVisited = mostVisited;
71 mExtraOffset = mNeedsOffset ? 1 : 0;
The Android Open Source Project0c908882009-03-03 19:32:16 -080072 mBookmarksPage = b;
Leon Scroggins89c6d362009-07-15 16:54:37 -040073 mCurrentPage = b.getResources().getString(R.string.current_page)
74 + curPage;
75 mCurrentTitle = curTitle;
Ben Murdochdcc2b6f2009-09-21 14:29:20 +010076 mCurrentThumbnail = curThumbnail;
The Android Open Source Project0c908882009-03-03 19:32:16 -080077 mContentResolver = b.getContentResolver();
Ben Murdoch328ea872009-09-16 13:33:29 +010078 mViewMode = BookmarkViewMode.LIST;
Leon Scroggins892df312009-07-14 14:48:02 -040079
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040080 String whereClause;
The Android Open Source Project0c908882009-03-03 19:32:16 -080081 // FIXME: Should have a default sort order that the user selects.
Leon Scroggins892df312009-07-14 14:48:02 -040082 String orderBy = Browser.BookmarkColumns.VISITS + " DESC";
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040083 if (mostVisited) {
84 whereClause = Browser.BookmarkColumns.VISITS + " != 0";
85 } else {
Patrick Scottc1cf63a2010-03-09 16:02:08 -050086 whereClause = Browser.BookmarkColumns.BOOKMARK + " = 1";
Leon Scrogginsa5d669e2009-08-05 14:07:58 -040087 }
Leon Scroggins892df312009-07-14 14:48:02 -040088 mCursor = b.managedQuery(Browser.BOOKMARKS_URI,
89 Browser.HISTORY_PROJECTION, whereClause, null, orderBy);
90 mCursor.registerContentObserver(new ChangeObserver());
91 mCursor.registerDataSetObserver(new MyDataSetObserver());
92
93 mDataValid = true;
94 notifyDataSetChanged();
95
96 mCount = mCursor.getCount() + mExtraOffset;
The Android Open Source Project0c908882009-03-03 19:32:16 -080097 }
98
99 /**
100 * Return a hashmap with one row's Title, Url, and favicon.
101 * @param position Position in the list.
102 * @return Bundle Stores title, url of row position, favicon, and id
103 * for the url. Return a blank map if position is out of
104 * range.
105 */
106 public Bundle getRow(int position) {
107 Bundle map = new Bundle();
108 if (position < mExtraOffset || position >= mCount) {
109 return map;
110 }
111 mCursor.moveToPosition(position- mExtraOffset);
112 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
113 map.putString(Browser.BookmarkColumns.TITLE,
114 mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
115 map.putString(Browser.BookmarkColumns.URL, url);
116 byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
117 if (data != null) {
118 map.putParcelable(Browser.BookmarkColumns.FAVICON,
119 BitmapFactory.decodeByteArray(data, 0, data.length));
120 }
121 map.putInt("id", mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
122 return map;
123 }
124
125 /**
126 * Update a row in the database with new information.
127 * Requeries the database if the information has changed.
128 * @param map Bundle storing id, title and url of new information
129 */
130 public void updateRow(Bundle map) {
131
132 // Find the record
133 int id = map.getInt("id");
134 int position = -1;
135 for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
136 if (mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX) == id) {
137 position = mCursor.getPosition();
138 break;
139 }
140 }
141 if (position < 0) {
142 return;
143 }
144
145 mCursor.moveToPosition(position);
146 ContentValues values = new ContentValues();
147 String title = map.getString(Browser.BookmarkColumns.TITLE);
148 if (!title.equals(mCursor
149 .getString(Browser.HISTORY_PROJECTION_TITLE_INDEX))) {
150 values.put(Browser.BookmarkColumns.TITLE, title);
151 }
152 String url = map.getString(Browser.BookmarkColumns.URL);
153 if (!url.equals(mCursor.
154 getString(Browser.HISTORY_PROJECTION_URL_INDEX))) {
155 values.put(Browser.BookmarkColumns.URL, url);
156 }
Ben Murdoch1794fe22009-09-29 18:14:30 +0100157
158 if (map.getBoolean("invalidateThumbnail") == true) {
159 values.put(Browser.BookmarkColumns.THUMBNAIL, new byte[0]);
160 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800161 if (values.size() > 0
162 && mContentResolver.update(Browser.BOOKMARKS_URI, values,
163 "_id = " + id, null) != -1) {
164 refreshList();
165 }
166 }
167
168 /**
169 * Delete a row from the database. Requeries the database.
170 * Does nothing if the provided position is out of range.
171 * @param position Position in the list.
172 */
173 public void deleteRow(int position) {
174 if (position < mExtraOffset || position >= getCount()) {
175 return;
176 }
177 mCursor.moveToPosition(position- mExtraOffset);
178 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
Andrei Popescuc9526192009-09-23 15:52:16 +0100179 String title = mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX);
180 Bookmarks.removeFromBookmarks(null, mContentResolver, url, title);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800181 refreshList();
182 }
183
184 /**
185 * Delete all bookmarks from the db. Requeries the database.
186 * All bookmarks with become visited URLs or if never visited
187 * are removed
188 */
189 public void deleteAllRows() {
190 StringBuilder deleteIds = null;
191 StringBuilder convertIds = null;
192
193 for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
194 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
195 WebIconDatabase.getInstance().releaseIconForPageUrl(url);
196 int id = mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX);
197 int numVisits = mCursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX);
198 if (0 == numVisits) {
199 if (deleteIds == null) {
200 deleteIds = new StringBuilder();
201 deleteIds.append("( ");
202 } else {
203 deleteIds.append(" OR ( ");
204 }
205 deleteIds.append(BookmarkColumns._ID);
206 deleteIds.append(" = ");
207 deleteIds.append(id);
208 deleteIds.append(" )");
209 } else {
210 // It is no longer a bookmark, but it is still a visited site.
211 if (convertIds == null) {
212 convertIds = new StringBuilder();
213 convertIds.append("( ");
214 } else {
215 convertIds.append(" OR ( ");
216 }
217 convertIds.append(BookmarkColumns._ID);
218 convertIds.append(" = ");
219 convertIds.append(id);
220 convertIds.append(" )");
221 }
222 }
223
224 if (deleteIds != null) {
225 mContentResolver.delete(Browser.BOOKMARKS_URI, deleteIds.toString(),
226 null);
227 }
228 if (convertIds != null) {
229 ContentValues values = new ContentValues();
230 values.put(Browser.BookmarkColumns.BOOKMARK, 0);
231 mContentResolver.update(Browser.BOOKMARKS_URI, values,
232 convertIds.toString(), null);
233 }
234 refreshList();
235 }
236
237 /**
238 * Refresh list to recognize a change in the database.
239 */
240 public void refreshList() {
Leon Scroggins892df312009-07-14 14:48:02 -0400241 mCursor.requery();
242 mCount = mCursor.getCount() + mExtraOffset;
243 notifyDataSetChanged();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800244 }
245
246 /**
Patrick Scott3918d442009-08-04 13:22:29 -0400247 * Update the bookmark's favicon. This is a convenience method for updating
248 * a bookmark favicon for the originalUrl and url of the passed in WebView.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800249 * @param cr The ContentResolver to use.
Patrick Scott15525d42009-09-21 13:39:37 -0400250 * @param originalUrl The original url before any redirects.
251 * @param url The current url.
The Android Open Source Project0c908882009-03-03 19:32:16 -0800252 * @param favicon The favicon bitmap to write to the db.
253 */
Patrick Scott63a45b82010-04-06 16:36:12 -0400254 /* package */ static void updateBookmarkFavicon(final ContentResolver cr,
255 final String originalUrl, final String url, final Bitmap favicon) {
256 new AsyncTask<Void, Void, Void>() {
257 protected Void doInBackground(Void... unused) {
258 final Cursor c =
259 queryBookmarksForUrl(cr, originalUrl, url, true);
260 if (c == null) {
261 return null;
262 }
263 if (c.moveToFirst()) {
264 ContentValues values = new ContentValues();
265 final ByteArrayOutputStream os =
266 new ByteArrayOutputStream();
267 favicon.compress(Bitmap.CompressFormat.PNG, 100, os);
268 values.put(Browser.BookmarkColumns.FAVICON,
269 os.toByteArray());
270 do {
271 cr.update(ContentUris.withAppendedId(
272 Browser.BOOKMARKS_URI, c.getInt(0)),
273 values, null, null);
274 } while (c.moveToNext());
275 }
276 c.close();
277 return null;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800278 }
Patrick Scott63a45b82010-04-06 16:36:12 -0400279 }.execute();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800280 }
281
Patrick Scott3918d442009-08-04 13:22:29 -0400282 /* package */ static Cursor queryBookmarksForUrl(ContentResolver cr,
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400283 String originalUrl, String url, boolean onlyBookmarks) {
Patrick Scott3918d442009-08-04 13:22:29 -0400284 if (cr == null || url == null) {
285 return null;
286 }
287
288 // If originalUrl is null, just set it to url.
289 if (originalUrl == null) {
290 originalUrl = url;
291 }
292
293 // Look for both the original url and the actual url. This takes in to
294 // account redirects.
295 String originalUrlNoQuery = removeQuery(originalUrl);
296 String urlNoQuery = removeQuery(url);
297 originalUrl = originalUrlNoQuery + '?';
298 url = urlNoQuery + '?';
299
300 // Use NoQuery to search for the base url (i.e. if the url is
301 // http://www.yahoo.com/?rs=1, search for http://www.yahoo.com)
302 // Use url to match the base url with other queries (i.e. if the url is
303 // http://www.google.com/m, search for
304 // http://www.google.com/m?some_query)
305 final String[] selArgs = new String[] {
306 originalUrlNoQuery, urlNoQuery, originalUrl, url };
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400307 String where = BookmarkColumns.URL + " == ? OR "
Patrick Scott3918d442009-08-04 13:22:29 -0400308 + BookmarkColumns.URL + " == ? OR "
Patrick Scott193def92010-01-07 15:01:09 -0500309 + BookmarkColumns.URL + " LIKE ? || '%' OR "
310 + BookmarkColumns.URL + " LIKE ? || '%'";
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400311 if (onlyBookmarks) {
312 where = "(" + where + ") AND " + BookmarkColumns.BOOKMARK + " == 1";
313 }
Patrick Scott3918d442009-08-04 13:22:29 -0400314 final String[] projection =
315 new String[] { Browser.BookmarkColumns._ID };
316 return cr.query(Browser.BOOKMARKS_URI, projection, where, selArgs,
317 null);
318 }
319
320 // Strip the query from the given url.
321 private static String removeQuery(String url) {
322 if (url == null) {
323 return null;
324 }
325 int query = url.indexOf('?');
326 String noQuery = url;
327 if (query != -1) {
328 noQuery = url.substring(0, query);
329 }
330 return noQuery;
331 }
332
The Android Open Source Project0c908882009-03-03 19:32:16 -0800333 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800334 * How many items should be displayed in the list.
335 * @return Count of items.
336 */
337 public int getCount() {
338 if (mDataValid) {
339 return mCount;
340 } else {
341 return 0;
342 }
343 }
344
345 public boolean areAllItemsEnabled() {
346 return true;
347 }
348
349 public boolean isEnabled(int position) {
350 return true;
351 }
352
353 /**
354 * Get the data associated with the specified position in the list.
355 * @param position Index of the item whose data we want.
356 * @return The data at the specified position.
357 */
358 public Object getItem(int position) {
359 return null;
360 }
361
362 /**
363 * Get the row id associated with the specified position in the list.
364 * @param position Index of the item whose row id we want.
365 * @return The id of the item at the specified position.
366 */
367 public long getItemId(int position) {
368 return position;
369 }
370
Ben Murdoch328ea872009-09-16 13:33:29 +0100371 /* package */ void switchViewMode(BookmarkViewMode viewMode) {
372 mViewMode = viewMode;
Leon Scroggins892df312009-07-14 14:48:02 -0400373 }
374
375 /* package */ void populateBookmarkItem(BookmarkItem b, int position) {
376 mCursor.moveToPosition(position - mExtraOffset);
Patrick Scott8f0076b2009-09-17 13:51:30 -0400377 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
378 b.setUrl(url);
Leon Scroggins892df312009-07-14 14:48:02 -0400379 b.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
380 byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
Patrick Scott8f0076b2009-09-17 13:51:30 -0400381 Bitmap bitmap = null;
382 if (data == null) {
383 bitmap = CombinedBookmarkHistoryActivity.getIconListenerSet()
384 .getFavicon(url);
385 } else {
386 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
387 }
Leon Scroggins892df312009-07-14 14:48:02 -0400388 b.setFavicon(bitmap);
389 }
390
The Android Open Source Project0c908882009-03-03 19:32:16 -0800391 /**
392 * Get a View that displays the data at the specified position
393 * in the list.
394 * @param position Index of the item whose view we want.
395 * @return A View corresponding to the data at the specified position.
396 */
397 public View getView(int position, View convertView, ViewGroup parent) {
398 if (!mDataValid) {
399 throw new IllegalStateException(
400 "this should only be called when the cursor is valid");
401 }
402 if (position < 0 || position > mCount) {
403 throw new AssertionError(
404 "BrowserBookmarksAdapter tried to get a view out of range");
405 }
Ben Murdoch328ea872009-09-16 13:33:29 +0100406 if (mViewMode == BookmarkViewMode.GRID) {
Leon Scroggins892df312009-07-14 14:48:02 -0400407 if (convertView == null || convertView instanceof AddNewBookmark
408 || convertView instanceof BookmarkItem) {
409 LayoutInflater factory = LayoutInflater.from(mBookmarksPage);
410 convertView
411 = factory.inflate(R.layout.bookmark_thumbnail, null);
412 }
Leon Scroggins89c6d362009-07-15 16:54:37 -0400413 View holder = convertView.findViewById(R.id.holder);
Leon Scroggins892df312009-07-14 14:48:02 -0400414 ImageView thumb = (ImageView) convertView.findViewById(R.id.thumb);
Leon Scroggins892df312009-07-14 14:48:02 -0400415 TextView tv = (TextView) convertView.findViewById(R.id.label);
416
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400417 if (0 == position && mNeedsOffset) {
Leon Scroggins892df312009-07-14 14:48:02 -0400418 // This is to create a bookmark for the current page.
Leon Scroggins89c6d362009-07-15 16:54:37 -0400419 holder.setVisibility(View.VISIBLE);
Leon Scroggins89c6d362009-07-15 16:54:37 -0400420 tv.setText(mCurrentTitle);
Ben Murdochdcc2b6f2009-09-21 14:29:20 +0100421
422 if (mCurrentThumbnail != null) {
423 thumb.setImageBitmap(mCurrentThumbnail);
424 } else {
425 thumb.setImageResource(
Leon Scrogginsf8551612009-09-24 16:06:02 -0400426 R.drawable.browser_thumbnail);
Ben Murdochdcc2b6f2009-09-21 14:29:20 +0100427 }
Leon Scroggins892df312009-07-14 14:48:02 -0400428 return convertView;
429 }
Leon Scroggins89c6d362009-07-15 16:54:37 -0400430 holder.setVisibility(View.GONE);
Leon Scroggins892df312009-07-14 14:48:02 -0400431 mCursor.moveToPosition(position - mExtraOffset);
432 tv.setText(mCursor.getString(
433 Browser.HISTORY_PROJECTION_TITLE_INDEX));
Leon Scroggins96afcb12009-12-10 12:35:56 -0500434 Bitmap thumbnail = getScreenshot(position);
Ben Murdochaac7aa62009-09-17 16:57:40 +0100435 if (thumbnail == null) {
Leon Scrogginsf8551612009-09-24 16:06:02 -0400436 thumb.setImageResource(R.drawable.browser_thumbnail);
Leon Scroggins892df312009-07-14 14:48:02 -0400437 } else {
Ben Murdochaac7aa62009-09-17 16:57:40 +0100438 thumb.setImageBitmap(thumbnail);
Leon Scroggins892df312009-07-14 14:48:02 -0400439 }
Leon Scroggins89c6d362009-07-15 16:54:37 -0400440
Leon Scroggins892df312009-07-14 14:48:02 -0400441 return convertView;
442
443 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400444 if (position == 0 && mNeedsOffset) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800445 AddNewBookmark b;
446 if (convertView instanceof AddNewBookmark) {
447 b = (AddNewBookmark) convertView;
448 } else {
449 b = new AddNewBookmark(mBookmarksPage);
450 }
451 b.setUrl(mCurrentPage);
452 return b;
453 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400454 if (mMostVisited) {
455 if (convertView == null || !(convertView instanceof HistoryItem)) {
456 convertView = new HistoryItem(mBookmarksPage);
457 }
458 } else {
459 if (convertView == null || !(convertView instanceof BookmarkItem)) {
460 convertView = new BookmarkItem(mBookmarksPage);
461 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800462 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400463 bind((BookmarkItem) convertView, position);
464 if (mMostVisited) {
465 ((HistoryItem) convertView).setIsBookmark(
466 getIsBookmark(position));
467 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800468 return convertView;
469 }
470
471 /**
472 * Return the title for this item in the list.
473 */
474 public String getTitle(int position) {
475 return getString(Browser.HISTORY_PROJECTION_TITLE_INDEX, position);
476 }
477
478 /**
479 * Return the Url for this item in the list.
480 */
481 public String getUrl(int position) {
482 return getString(Browser.HISTORY_PROJECTION_URL_INDEX, position);
483 }
484
485 /**
Leon Scroggins96afcb12009-12-10 12:35:56 -0500486 * Return the screenshot for this item in the list.
487 */
488 public Bitmap getScreenshot(int position) {
489 return getBitmap(Browser.HISTORY_PROJECTION_THUMBNAIL_INDEX, position);
490 }
491
492 /**
Patrick Scotte09761e2009-03-24 20:43:37 -0700493 * Return the favicon for this item in the list.
494 */
495 public Bitmap getFavicon(int position) {
Patrick Scott3918d442009-08-04 13:22:29 -0400496 return getBitmap(Browser.HISTORY_PROJECTION_FAVICON_INDEX, position);
497 }
498
499 public Bitmap getTouchIcon(int position) {
500 return getBitmap(Browser.HISTORY_PROJECTION_TOUCH_ICON_INDEX, position);
501 }
502
503 private Bitmap getBitmap(int cursorIndex, int position) {
Patrick Scotte09761e2009-03-24 20:43:37 -0700504 if (position < mExtraOffset || position > mCount) {
505 return null;
506 }
507 mCursor.moveToPosition(position - mExtraOffset);
Patrick Scott3918d442009-08-04 13:22:29 -0400508 byte[] data = mCursor.getBlob(cursorIndex);
Patrick Scotte09761e2009-03-24 20:43:37 -0700509 if (data == null) {
510 return null;
511 }
512 return BitmapFactory.decodeByteArray(data, 0, data.length);
513 }
514
515 /**
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400516 * Return whether or not this item represents a bookmarked site.
517 */
518 public boolean getIsBookmark(int position) {
519 if (position < mExtraOffset || position > mCount) {
520 return false;
521 }
522 mCursor.moveToPosition(position - mExtraOffset);
523 return (1 == mCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
524 }
525
526 /**
The Android Open Source Project0c908882009-03-03 19:32:16 -0800527 * Private helper function to return the title or url.
528 */
529 private String getString(int cursorIndex, int position) {
530 if (position < mExtraOffset || position > mCount) {
531 return "";
532 }
533 mCursor.moveToPosition(position- mExtraOffset);
534 return mCursor.getString(cursorIndex);
535 }
536
537 private void bind(BookmarkItem b, int position) {
538 mCursor.moveToPosition(position- mExtraOffset);
539
Ben Murdoch9907efc2009-10-28 13:22:46 +0000540 b.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800541 String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800542 b.setUrl(url);
543 byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
544 if (data != null) {
545 b.setFavicon(BitmapFactory.decodeByteArray(data, 0, data.length));
546 } else {
Patrick Scott8f0076b2009-09-17 13:51:30 -0400547 b.setFavicon(CombinedBookmarkHistoryActivity.getIconListenerSet()
548 .getFavicon(url));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800549 }
550 }
551
552 private class ChangeObserver extends ContentObserver {
553 public ChangeObserver() {
554 super(new Handler());
555 }
556
557 @Override
558 public boolean deliverSelfNotifications() {
559 return true;
560 }
561
562 @Override
563 public void onChange(boolean selfChange) {
564 refreshList();
565 }
566 }
567
568 private class MyDataSetObserver extends DataSetObserver {
569 @Override
570 public void onChanged() {
571 mDataValid = true;
572 notifyDataSetChanged();
573 }
574
575 @Override
576 public void onInvalidated() {
577 mDataValid = false;
578 notifyDataSetInvalidated();
579 }
580 }
581}