/* * Copyright (C) 2006 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.os.Handler; import android.os.Message; import android.graphics.Bitmap; import java.util.Vector; /** * Functions for manipulating the icon database used by WebView. * These functions require that a WebView be constructed before being invoked * and WebView.getIconDatabase() will return a WebIconDatabase object. This * WebIconDatabase object is a single instance and all methods operate on that * single object. */ public final class WebIconDatabase { // Global instance of a WebIconDatabase private static WebIconDatabase 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 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; // 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"); Bitmap icon = nativeIconForPageUrl(url); if (icon != null) { EventHandler.this.sendMessage( Message.obtain(null, ICON_RESULT, new IconResult(url, icon, l))); } 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 void postMessage(Message msg) { if (mMessages != null) { mMessages.add(msg); } else { mHandler.sendMessage(msg); } } } /** * Interface for receiving icons from the database. */ public interface IconListener { /** * Called when the icon has been retrieved from the database and the * result is non-null. * @param url The url passed in the request. * @param icon The favicon for the given url. */ public void onReceivedIcon(String url, Bitmap icon); } /** * Open a the icon database and store the icons in the given path. * @param path The directory path where the icon database will be stored. * @return True if the database was successfully opened or created in * the given path. */ public void open(String path) { if (path != null) { mEventHandler.postMessage( Message.obtain(null, EventHandler.OPEN, path)); } } /** * Close the shared instance of the icon database. */ public void close() { mEventHandler.postMessage( Message.obtain(null, EventHandler.CLOSE)); } /** * Removes all the icons in the database. */ 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); } /** * Retain the icon for the given page url. * @param url The page's url. */ public void retainIconForPageUrl(String url) { if (url != null) { mEventHandler.postMessage( Message.obtain(null, EventHandler.RETAIN_ICON, url)); } } /** * Release the icon for the given page url. * @param url The page's url. */ 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 WebIconDatabase getInstance() { // XXX: Must be created in the UI thread. if (sIconDatabase == null) { sIconDatabase = new WebIconDatabase(); } 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 WebIconDatabase() {} // 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); }