summaryrefslogtreecommitdiff
path: root/core/java/android/webkit/WebIconDatabaseClassic.java
diff options
context:
space:
mode:
authorJonathan Dixon <joth@google.com>2012-04-12 20:51:51 +0100
committerJonathan Dixon <joth@google.com>2012-04-23 12:43:02 +0100
commitd3101b1d300f5942fdb7dfa323dc8830c4edc007 (patch)
tree4140cbc09c362fd7584fec4f87dff13a79b22388 /core/java/android/webkit/WebIconDatabaseClassic.java
parenteb65757d24a97450fed160d66e86a4a62c392c5c (diff)
Seperate interface and implementation of 4 WebView classes
GeolocationPermissionsClassic CookieManagerClassic WebIconDatabaseClassic WebStorageClassic Also creats a WebViewFactory top level class - this remains hidden for now, as it's currently only used implicitly by the other public WebView classes to create the provider instances. Bug: 5626244 Change-Id: Id0ca1c16d8058f31a86414bbc0e8a55db4b907ba
Diffstat (limited to 'core/java/android/webkit/WebIconDatabaseClassic.java')
-rw-r--r--core/java/android/webkit/WebIconDatabaseClassic.java289
1 files changed, 289 insertions, 0 deletions
diff --git a/core/java/android/webkit/WebIconDatabaseClassic.java b/core/java/android/webkit/WebIconDatabaseClassic.java
new file mode 100644
index 000000000000..d6c4c3374893
--- /dev/null
+++ b/core/java/android/webkit/WebIconDatabaseClassic.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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.provider.Browser;
+import android.util.Log;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+class WebIconDatabaseClassic extends WebIconDatabase {
+ private static final String LOGTAG = "WebIconDatabase";
+ // Global instance of a WebIconDatabase
+ private static WebIconDatabaseClassic sIconDatabase;
+ // EventHandler for handling messages before and after the WebCore thread is
+ // ready.
+ private final EventHandler mEventHandler = new EventHandler();
+
+ // Class to handle messages before WebCore is ready
+ private static class EventHandler extends Handler {
+ // Message ids
+ static final int OPEN = 0;
+ static final int CLOSE = 1;
+ static final int REMOVE_ALL = 2;
+ 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
+ private Handler mHandler;
+ // Vector of messages before the WebCore thread is ready
+ private Vector<Message> mMessages = new Vector<Message>();
+ // Class to handle a result dispatch
+ private class IconResult {
+ private final String mUrl;
+ private final Bitmap mIcon;
+ private final IconListener mListener;
+ IconResult(String url, Bitmap icon, IconListener l) {
+ mUrl = url;
+ mIcon = icon;
+ mListener = l;
+ }
+ void dispatch() {
+ mListener.onReceivedIcon(mUrl, mIcon);
+ }
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ // Note: This is the message handler for the UI thread.
+ switch (msg.what) {
+ case ICON_RESULT:
+ ((IconResult) msg.obj).dispatch();
+ break;
+ }
+ }
+
+ // Called by WebCore thread to create the actual handler
+ private synchronized void createHandler() {
+ if (mHandler == null) {
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Note: This is the message handler for the WebCore
+ // thread.
+ switch (msg.what) {
+ case OPEN:
+ nativeOpen((String) msg.obj);
+ break;
+
+ case CLOSE:
+ nativeClose();
+ break;
+
+ case REMOVE_ALL:
+ nativeRemoveAllIcons();
+ break;
+
+ case REQUEST_ICON:
+ IconListener l = (IconListener) msg.obj;
+ String url = msg.getData().getString("url");
+ requestIconAndSendResult(url, l);
+ break;
+
+ case BULK_REQUEST_ICON:
+ bulkRequestIcons(msg);
+ break;
+
+ case RETAIN_ICON:
+ nativeRetainIconForPageUrl((String) msg.obj);
+ break;
+
+ case RELEASE_ICON:
+ nativeReleaseIconForPageUrl((String) msg.obj);
+ break;
+ }
+ }
+ };
+ // Transfer all pending messages
+ for (int size = mMessages.size(); size > 0; size--) {
+ mHandler.sendMessage(mMessages.remove(0));
+ }
+ mMessages = null;
+ }
+ }
+
+ private synchronized boolean hasHandler() {
+ return mHandler != null;
+ }
+
+ private synchronized void postMessage(Message msg) {
+ if (mMessages != null) {
+ mMessages.add(msg);
+ } else {
+ 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)));
+ }
+ }
+ }
+
+ @Override
+ public void open(String path) {
+ if (path != null) {
+ // Make the directories and parents if they don't exist
+ File db = new File(path);
+ if (!db.exists()) {
+ db.mkdirs();
+ }
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.OPEN, db.getAbsolutePath()));
+ }
+ }
+
+ @Override
+ public void close() {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.CLOSE));
+ }
+
+ @Override
+ public void removeAllIcons() {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.REMOVE_ALL));
+ }
+
+ /**
+ * Request the Bitmap representing the icon for the given page
+ * url. If the icon exists, the listener will be called with the result.
+ * @param url The page's url.
+ * @param listener An implementation on IconListener to receive the result.
+ */
+ public void requestIconForPageUrl(String url, IconListener listener) {
+ if (listener == null || url == null) {
+ return;
+ }
+ Message msg = Message.obtain(null, EventHandler.REQUEST_ICON, listener);
+ msg.getData().putString("url", url);
+ 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);
+ }
+ }
+
+ @Override
+ public void retainIconForPageUrl(String url) {
+ if (url != null) {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.RETAIN_ICON, url));
+ }
+ }
+
+ @Override
+ public void releaseIconForPageUrl(String url) {
+ if (url != null) {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.RELEASE_ICON, url));
+ }
+ }
+
+ /**
+ * Get the global instance of WebIconDatabase.
+ * @return A single instance of WebIconDatabase. It will be the same
+ * instance for the current process each time this method is
+ * called.
+ */
+ public static WebIconDatabaseClassic getInstance() {
+ // XXX: Must be created in the UI thread.
+ if (sIconDatabase == null) {
+ sIconDatabase = new WebIconDatabaseClassic();
+ }
+ return sIconDatabase;
+ }
+
+ /**
+ * Create the internal handler and transfer all pending messages.
+ * XXX: Called by WebCore thread only!
+ */
+ /*package*/ void createHandler() {
+ mEventHandler.createHandler();
+ }
+
+ /**
+ * Private constructor to avoid anyone else creating an instance.
+ */
+ private WebIconDatabaseClassic() {}
+
+ // Native functions
+ private static native void nativeOpen(String path);
+ private static native void nativeClose();
+ private static native void nativeRemoveAllIcons();
+ private static native Bitmap nativeIconForPageUrl(String url);
+ private static native void nativeRetainIconForPageUrl(String url);
+ private static native void nativeReleaseIconForPageUrl(String url);
+}