OSDN Git Service

Add a bulk request method for bookmark icons.
authorPatrick Scott <phanna@android.com>
Fri, 9 Apr 2010 16:42:03 +0000 (12:42 -0400)
committerPatrick Scott <phanna@android.com>
Mon, 12 Apr 2010 18:26:13 +0000 (14:26 -0400)
Rather than dispatch a message for every url in the db, send a message to the
WebCoreThread to handle the query and iteration.  Update the documentation for
requestAllIcons.

Bug: 2581894
Change-Id: I8af4f87570465dff3839db4ac492883e8805b007

core/java/android/provider/Browser.java
core/java/android/webkit/WebIconDatabase.java

index b466b40..2fba1d7 100644 (file)
@@ -574,7 +574,9 @@ public class Browser {
     }
     
     /**
-     *  Request all icons from the database.
+     *  Request all icons from the database.  This call must either be called
+     *  in the main thread or have had Looper.prepare() invoked in the calling
+     *  thread.
      *  Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
      *  @param  cr The ContentResolver used to access the database.
      *  @param  where Clause to be used to limit the query from the database.
@@ -584,25 +586,8 @@ public class Browser {
      */
     public static final void requestAllIcons(ContentResolver cr, String where,
             WebIconDatabase.IconListener listener) {
-        Cursor c = null;
-        try {
-            c = cr.query(
-                    BOOKMARKS_URI,
-                    new String[] { BookmarkColumns.URL },
-                    where, null, null);
-            if (c.moveToFirst()) {
-                final WebIconDatabase db = WebIconDatabase.getInstance();
-                do {
-                    db.requestIconForPageUrl(c.getString(0), listener);
-                } while (c.moveToNext());
-            }
-        } catch (IllegalStateException e) {
-            Log.e(LOGTAG, "requestAllIcons", e);
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
+        WebIconDatabase.getInstance()
+                .bulkRequestIconForPageUrl(cr, where, listener);
     }
 
     public static class BookmarkColumns implements BaseColumns {
index 6cc6bb4..bb9ec48 100644 (file)
 
 package android.webkit;
 
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.graphics.Bitmap;
 import android.os.Handler;
 import android.os.Message;
-import android.graphics.Bitmap;
+import android.provider.Browser;
+import android.util.Log;
 
+import java.util.HashMap;
 import java.util.Vector;
 
 /**
@@ -30,6 +35,7 @@ import java.util.Vector;
  * single object.
  */
 public final class WebIconDatabase {
+    private static final String LOGTAG = "WebIconDatabase";
     // Global instance of a WebIconDatabase
     private static WebIconDatabase sIconDatabase;
     // EventHandler for handling messages before and after the WebCore thread is
@@ -45,6 +51,7 @@ public final class WebIconDatabase {
         static final int REQUEST_ICON = 3;
         static final int RETAIN_ICON  = 4;
         static final int RELEASE_ICON = 5;
+        static final int BULK_REQUEST_ICON = 6;
         // Message for dispatching icon request results
         private static final int ICON_RESULT = 10;
         // Actual handler that runs in WebCore thread
@@ -100,12 +107,11 @@ public final class WebIconDatabase {
                             case REQUEST_ICON:
                                 IconListener l = (IconListener) msg.obj;
                                 String url = msg.getData().getString("url");
-                                Bitmap icon = nativeIconForPageUrl(url);
-                                if (icon != null) {
-                                    EventHandler.this.sendMessage(
-                                            Message.obtain(null, ICON_RESULT,
-                                                new IconResult(url, icon, l)));
-                                }
+                                requestIconAndSendResult(url, l);
+                                break;
+
+                            case BULK_REQUEST_ICON:
+                                bulkRequestIcons(msg);
                                 break;
 
                             case RETAIN_ICON:
@@ -126,6 +132,10 @@ public final class WebIconDatabase {
             }
         }
 
+        private synchronized boolean hasHandler() {
+            return mHandler != null;
+        }
+
         private synchronized void postMessage(Message msg) {
             if (mMessages != null) {
                 mMessages.add(msg);
@@ -133,6 +143,39 @@ public final class WebIconDatabase {
                 mHandler.sendMessage(msg);
             }
         }
+
+        private void bulkRequestIcons(Message msg) {
+            HashMap map = (HashMap) msg.obj;
+            IconListener listener = (IconListener) map.get("listener");
+            ContentResolver cr = (ContentResolver) map.get("contentResolver");
+            String where = (String) map.get("where");
+
+            Cursor c = null;
+            try {
+                c = cr.query(
+                        Browser.BOOKMARKS_URI,
+                        new String[] { Browser.BookmarkColumns.URL },
+                        where, null, null);
+                if (c.moveToFirst()) {
+                    do {
+                        String url = c.getString(0);
+                        requestIconAndSendResult(url, listener);
+                    } while (c.moveToNext());
+                }
+            } catch (IllegalStateException e) {
+                Log.e(LOGTAG, "BulkRequestIcons", e);
+            } finally {
+                if (c != null) c.close();
+            }
+        }
+
+        private void requestIconAndSendResult(String url, IconListener listener) {
+            Bitmap icon = nativeIconForPageUrl(url);
+            if (icon != null) {
+                sendMessage(obtainMessage(ICON_RESULT,
+                            new IconResult(url, icon, listener)));
+            }
+        }
     }
 
     /**
@@ -192,6 +235,30 @@ public final class WebIconDatabase {
         mEventHandler.postMessage(msg);
     }
 
+    /** {@hide}
+     */
+    public void bulkRequestIconForPageUrl(ContentResolver cr, String where,
+            IconListener listener) {
+        if (listener == null) {
+            return;
+        }
+
+        // Special case situation: we don't want to add this message to the
+        // queue if there is no handler because we may never have a real
+        // handler to service the messages and the cursor will never get
+        // closed.
+        if (mEventHandler.hasHandler()) {
+            // Don't use Bundle as it is parcelable.
+            HashMap<String, Object> map = new HashMap<String, Object>();
+            map.put("contentResolver", cr);
+            map.put("where", where);
+            map.put("listener", listener);
+            Message msg =
+                    Message.obtain(null, EventHandler.BULK_REQUEST_ICON, map);
+            mEventHandler.postMessage(msg);
+        }
+    }
+
     /**
      * Retain the icon for the given page url.
      * @param url The page's url.