summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/CallbackProxy.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/webkit/CallbackProxy.java')
-rw-r--r--core/java/android/webkit/CallbackProxy.java350
1 files changed, 314 insertions, 36 deletions
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 17d3f94..f760b61 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -65,50 +65,62 @@ class CallbackProxy extends Handler {
// Keep track of multiple progress updates.
private boolean mProgressUpdatePending;
// Keep track of the last progress amount.
- private volatile int mLatestProgress;
+ // Start with 100 to indicate it is not in load for the empty page.
+ private volatile int mLatestProgress = 100;
// Back/Forward list
private final WebBackForwardList mBackForwardList;
// Used to call startActivity during url override.
private final Context mContext;
// Message Ids
- private static final int PAGE_STARTED = 100;
- private static final int RECEIVED_ICON = 101;
- private static final int RECEIVED_TITLE = 102;
- private static final int OVERRIDE_URL = 103;
- private static final int AUTH_REQUEST = 104;
- private static final int SSL_ERROR = 105;
- private static final int PROGRESS = 106;
- private static final int UPDATE_VISITED = 107;
- private static final int LOAD_RESOURCE = 108;
- private static final int CREATE_WINDOW = 109;
- private static final int CLOSE_WINDOW = 110;
- private static final int SAVE_PASSWORD = 111;
- private static final int JS_ALERT = 112;
- private static final int JS_CONFIRM = 113;
- private static final int JS_PROMPT = 114;
- private static final int JS_UNLOAD = 115;
- private static final int ASYNC_KEYEVENTS = 116;
- private static final int TOO_MANY_REDIRECTS = 117;
- private static final int DOWNLOAD_FILE = 118;
- private static final int REPORT_ERROR = 119;
- private static final int RESEND_POST_DATA = 120;
- private static final int PAGE_FINISHED = 121;
- private static final int REQUEST_FOCUS = 122;
- private static final int SCALE_CHANGED = 123;
- private static final int RECEIVED_CERTIFICATE = 124;
- private static final int SWITCH_OUT_HISTORY = 125;
- private static final int JS_TIMEOUT = 126;
+ private static final int PAGE_STARTED = 100;
+ private static final int RECEIVED_ICON = 101;
+ private static final int RECEIVED_TITLE = 102;
+ private static final int OVERRIDE_URL = 103;
+ private static final int AUTH_REQUEST = 104;
+ private static final int SSL_ERROR = 105;
+ private static final int PROGRESS = 106;
+ private static final int UPDATE_VISITED = 107;
+ private static final int LOAD_RESOURCE = 108;
+ private static final int CREATE_WINDOW = 109;
+ private static final int CLOSE_WINDOW = 110;
+ private static final int SAVE_PASSWORD = 111;
+ private static final int JS_ALERT = 112;
+ private static final int JS_CONFIRM = 113;
+ private static final int JS_PROMPT = 114;
+ private static final int JS_UNLOAD = 115;
+ private static final int ASYNC_KEYEVENTS = 116;
+ private static final int TOO_MANY_REDIRECTS = 117;
+ private static final int DOWNLOAD_FILE = 118;
+ private static final int REPORT_ERROR = 119;
+ private static final int RESEND_POST_DATA = 120;
+ private static final int PAGE_FINISHED = 121;
+ private static final int REQUEST_FOCUS = 122;
+ private static final int SCALE_CHANGED = 123;
+ private static final int RECEIVED_CERTIFICATE = 124;
+ private static final int SWITCH_OUT_HISTORY = 125;
+ private static final int EXCEEDED_DATABASE_QUOTA = 126;
+ private static final int REACHED_APPCACHE_MAXSIZE = 127;
+ private static final int JS_TIMEOUT = 128;
+ private static final int ADD_MESSAGE_TO_CONSOLE = 129;
+ private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT = 130;
+ private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT = 131;
+ private static final int RECEIVED_TOUCH_ICON_URL = 132;
+ private static final int GET_VISITED_HISTORY = 133;
// Message triggered by the client to resume execution
- private static final int NOTIFY = 200;
+ private static final int NOTIFY = 200;
// Result transportation object for returning results across thread
// boundaries.
- private class ResultTransport<E> {
+ private static class ResultTransport<E> {
// Private result object
private E mResult;
+ public ResultTransport(E defaultResult) {
+ mResult = defaultResult;
+ }
+
public synchronized void setResult(E result) {
mResult = result;
}
@@ -145,6 +157,14 @@ class CallbackProxy extends Handler {
}
/**
+ * Get the WebChromeClient.
+ * @return the current WebChromeClient instance.
+ */
+ public WebChromeClient getWebChromeClient() {
+ return mWebChromeClient;
+ }
+
+ /**
* Set the client DownloadListener.
* @param client An implementation of DownloadListener.
*/
@@ -229,6 +249,13 @@ class CallbackProxy extends Handler {
}
break;
+ case RECEIVED_TOUCH_ICON_URL:
+ if (mWebChromeClient != null) {
+ mWebChromeClient.onReceivedTouchIconUrl(mWebView,
+ (String) msg.obj, msg.arg1 == 1);
+ }
+ break;
+
case RECEIVED_TITLE:
if (mWebChromeClient != null) {
mWebChromeClient.onReceivedTitle(mWebView,
@@ -389,6 +416,63 @@ class CallbackProxy extends Handler {
}
break;
+ case EXCEEDED_DATABASE_QUOTA:
+ if (mWebChromeClient != null) {
+ HashMap<String, Object> map =
+ (HashMap<String, Object>) msg.obj;
+ String databaseIdentifier =
+ (String) map.get("databaseIdentifier");
+ String url = (String) map.get("url");
+ long currentQuota =
+ ((Long) map.get("currentQuota")).longValue();
+ long totalUsedQuota =
+ ((Long) map.get("totalUsedQuota")).longValue();
+ long estimatedSize =
+ ((Long) map.get("estimatedSize")).longValue();
+ WebStorage.QuotaUpdater quotaUpdater =
+ (WebStorage.QuotaUpdater) map.get("quotaUpdater");
+
+ mWebChromeClient.onExceededDatabaseQuota(url,
+ databaseIdentifier, currentQuota, estimatedSize,
+ totalUsedQuota, quotaUpdater);
+ }
+ break;
+
+ case REACHED_APPCACHE_MAXSIZE:
+ if (mWebChromeClient != null) {
+ HashMap<String, Object> map =
+ (HashMap<String, Object>) msg.obj;
+ long spaceNeeded =
+ ((Long) map.get("spaceNeeded")).longValue();
+ long totalUsedQuota =
+ ((Long) map.get("totalUsedQuota")).longValue();
+ WebStorage.QuotaUpdater quotaUpdater =
+ (WebStorage.QuotaUpdater) map.get("quotaUpdater");
+
+ mWebChromeClient.onReachedMaxAppCacheSize(spaceNeeded,
+ totalUsedQuota, quotaUpdater);
+ }
+ break;
+
+ case GEOLOCATION_PERMISSIONS_SHOW_PROMPT:
+ if (mWebChromeClient != null) {
+ HashMap<String, Object> map =
+ (HashMap<String, Object>) msg.obj;
+ String origin = (String) map.get("origin");
+ GeolocationPermissions.Callback callback =
+ (GeolocationPermissions.Callback)
+ map.get("callback");
+ mWebChromeClient.onGeolocationPermissionsShowPrompt(origin,
+ callback);
+ }
+ break;
+
+ case GEOLOCATION_PERMISSIONS_HIDE_PROMPT:
+ if (mWebChromeClient != null) {
+ mWebChromeClient.onGeolocationPermissionsHidePrompt();
+ }
+ break;
+
case JS_ALERT:
if (mWebChromeClient != null) {
final JsResult res = (JsResult) msg.obj;
@@ -563,6 +647,19 @@ class CallbackProxy extends Handler {
case SWITCH_OUT_HISTORY:
mWebView.switchOutDrawHistory();
break;
+
+ case ADD_MESSAGE_TO_CONSOLE:
+ String message = msg.getData().getString("message");
+ String sourceID = msg.getData().getString("sourceID");
+ int lineNumber = msg.getData().getInt("lineNumber");
+ mWebChromeClient.addMessageToConsole(message, lineNumber, sourceID);
+ break;
+
+ case GET_VISITED_HISTORY:
+ if (mWebChromeClient != null) {
+ mWebChromeClient.getVisitedHistory((ValueCallback<String[]>)msg.obj);
+ }
+ break;
}
}
@@ -605,7 +702,40 @@ class CallbackProxy extends Handler {
//--------------------------------------------------------------------------
// Performance probe
+ private static final boolean PERF_PROBE = false;
private long mWebCoreThreadTime;
+ private long mWebCoreIdleTime;
+
+ /*
+ * If PERF_PROBE is true, this block needs to be added to MessageQueue.java.
+ * startWait() and finishWait() should be called before and after wait().
+
+ private WaitCallback mWaitCallback = null;
+ public static interface WaitCallback {
+ void startWait();
+ void finishWait();
+ }
+ public final void setWaitCallback(WaitCallback callback) {
+ mWaitCallback = callback;
+ }
+ */
+
+ // un-comment this block if PERF_PROBE is true
+ /*
+ private IdleCallback mIdleCallback = new IdleCallback();
+
+ private final class IdleCallback implements MessageQueue.WaitCallback {
+ private long mStartTime = 0;
+
+ public void finishWait() {
+ mWebCoreIdleTime += SystemClock.uptimeMillis() - mStartTime;
+ }
+
+ public void startWait() {
+ mStartTime = SystemClock.uptimeMillis();
+ }
+ }
+ */
public void onPageStarted(String url, Bitmap favicon) {
// Do an unsynchronized quick check to avoid posting if no callback has
@@ -614,9 +744,12 @@ class CallbackProxy extends Handler {
return;
}
// Performance probe
- if (false) {
+ if (PERF_PROBE) {
mWebCoreThreadTime = SystemClock.currentThreadTimeMillis();
+ mWebCoreIdleTime = 0;
Network.getInstance(mContext).startTiming();
+ // un-comment this if PERF_PROBE is true
+// Looper.myQueue().setWaitCallback(mIdleCallback);
}
Message msg = obtainMessage(PAGE_STARTED);
msg.obj = favicon;
@@ -631,10 +764,12 @@ class CallbackProxy extends Handler {
return;
}
// Performance probe
- if (false) {
+ if (PERF_PROBE) {
+ // un-comment this if PERF_PROBE is true
+// Looper.myQueue().setWaitCallback(null);
Log.d("WebCore", "WebCore thread used " +
(SystemClock.currentThreadTimeMillis() - mWebCoreThreadTime)
- + " ms");
+ + " ms and idled " + mWebCoreIdleTime + " ms");
Network.getInstance(mContext).stopTiming();
}
Message msg = obtainMessage(PAGE_FINISHED, url);
@@ -693,7 +828,7 @@ class CallbackProxy extends Handler {
public boolean shouldOverrideUrlLoading(String url) {
// We have a default behavior if no client exists so always send the
// message.
- ResultTransport<Boolean> res = new ResultTransport<Boolean>();
+ ResultTransport<Boolean> res = new ResultTransport<Boolean>(false);
Message msg = obtainMessage(OVERRIDE_URL);
msg.getData().putString("url", url);
msg.obj = res;
@@ -834,7 +969,7 @@ class CallbackProxy extends Handler {
String password, Message resumeMsg) {
// resumeMsg should be null at this point because we want to create it
// within the CallbackProxy.
- if (WebView.DEBUG) {
+ if (DebugFlags.CALLBACK_PROXY) {
junit.framework.Assert.assertNull(resumeMsg);
}
resumeMsg = obtainMessage(NOTIFY);
@@ -939,6 +1074,24 @@ class CallbackProxy extends Handler {
sendMessage(obtainMessage(RECEIVED_ICON, icon));
}
+ /* package */ void onReceivedTouchIconUrl(String url, boolean precomposed) {
+ // We should have a current item but we do not want to crash so check
+ // for null.
+ WebHistoryItem i = mBackForwardList.getCurrentItem();
+ if (i != null) {
+ if (precomposed || i.getTouchIconUrl() != null) {
+ i.setTouchIconUrl(url);
+ }
+ }
+ // Do an unsynchronized quick check to avoid posting if no callback has
+ // been set.
+ if (mWebChromeClient == null) {
+ return;
+ }
+ sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL,
+ precomposed ? 1 : 0, 0, url));
+ }
+
public void onReceivedTitle(String title) {
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
@@ -1037,8 +1190,124 @@ class CallbackProxy extends Handler {
}
/**
- * @hide pending API council approval
+ * Called by WebViewCore to inform the Java side that the current origin
+ * has overflowed it's database quota. Called in the WebCore thread so
+ * posts a message to the UI thread that will prompt the WebChromeClient
+ * for what to do. On return back to C++ side, the WebCore thread will
+ * sleep pending a new quota value.
+ * @param url The URL that caused the quota overflow.
+ * @param databaseIdentifier The identifier of the database that the
+ * transaction that caused the overflow was running on.
+ * @param currentQuota The current quota the origin is allowed.
+ * @param estimatedSize The estimated size of the database.
+ * @param totalUsedQuota is the sum of all origins' quota.
+ * @param quotaUpdater An instance of a class encapsulating a callback
+ * to WebViewCore to run when the decision to allow or deny more
+ * quota has been made.
+ */
+ public void onExceededDatabaseQuota(
+ String url, String databaseIdentifier, long currentQuota,
+ long estimatedSize, long totalUsedQuota,
+ WebStorage.QuotaUpdater quotaUpdater) {
+ if (mWebChromeClient == null) {
+ quotaUpdater.updateQuota(currentQuota);
+ return;
+ }
+
+ Message exceededQuota = obtainMessage(EXCEEDED_DATABASE_QUOTA);
+ HashMap<String, Object> map = new HashMap();
+ map.put("databaseIdentifier", databaseIdentifier);
+ map.put("url", url);
+ map.put("currentQuota", currentQuota);
+ map.put("estimatedSize", estimatedSize);
+ map.put("totalUsedQuota", totalUsedQuota);
+ map.put("quotaUpdater", quotaUpdater);
+ exceededQuota.obj = map;
+ sendMessage(exceededQuota);
+ }
+
+ /**
+ * Called by WebViewCore to inform the Java side that the appcache has
+ * exceeded its max size.
+ * @param spaceNeeded is the amount of disk space that would be needed
+ * in order for the last appcache operation to succeed.
+ * @param totalUsedQuota is the sum of all origins' quota.
+ * @param quotaUpdater An instance of a class encapsulating a callback
+ * to WebViewCore to run when the decision to allow or deny a bigger
+ * app cache size has been made.
+ */
+ public void onReachedMaxAppCacheSize(long spaceNeeded,
+ long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
+ if (mWebChromeClient == null) {
+ quotaUpdater.updateQuota(0);
+ return;
+ }
+
+ Message msg = obtainMessage(REACHED_APPCACHE_MAXSIZE);
+ HashMap<String, Object> map = new HashMap();
+ map.put("spaceNeeded", spaceNeeded);
+ map.put("totalUsedQuota", totalUsedQuota);
+ map.put("quotaUpdater", quotaUpdater);
+ msg.obj = map;
+ sendMessage(msg);
+ }
+
+ /**
+ * Called by WebViewCore to instruct the browser to display a prompt to ask
+ * the user to set the Geolocation permission state for the given origin.
+ * @param origin The origin requesting Geolocation permsissions.
+ * @param callback The callback to call once a permission state has been
+ * obtained.
+ */
+ public void onGeolocationPermissionsShowPrompt(String origin,
+ GeolocationPermissions.Callback callback) {
+ if (mWebChromeClient == null) {
+ return;
+ }
+
+ Message showMessage =
+ obtainMessage(GEOLOCATION_PERMISSIONS_SHOW_PROMPT);
+ HashMap<String, Object> map = new HashMap();
+ map.put("origin", origin);
+ map.put("callback", callback);
+ showMessage.obj = map;
+ sendMessage(showMessage);
+ }
+
+ /**
+ * Called by WebViewCore to instruct the browser to hide the Geolocation
+ * permissions prompt.
+ */
+ public void onGeolocationPermissionsHidePrompt() {
+ if (mWebChromeClient == null) {
+ return;
+ }
+
+ Message hideMessage = obtainMessage(GEOLOCATION_PERMISSIONS_HIDE_PROMPT);
+ sendMessage(hideMessage);
+ }
+
+ /**
+ * Called by WebViewCore when we have a message to be added to the JavaScript
+ * error console. Sends a message to the Java side with the details.
+ * @param message The message to add to the console.
+ * @param lineNumber The lineNumber of the source file on which the error
+ * occurred.
+ * @param sourceID The filename of the source file in which the error
+ * occurred.
*/
+ public void addMessageToConsole(String message, int lineNumber, String sourceID) {
+ if (mWebChromeClient == null) {
+ return;
+ }
+
+ Message msg = obtainMessage(ADD_MESSAGE_TO_CONSOLE);
+ msg.getData().putString("message", message);
+ msg.getData().putString("sourceID", sourceID);
+ msg.getData().putInt("lineNumber", lineNumber);
+ sendMessage(msg);
+ }
+
public boolean onJsTimeout() {
//always interrupt timedout JS by default
if (mWebChromeClient == null) {
@@ -1057,4 +1326,13 @@ class CallbackProxy extends Handler {
}
return result.getResult();
}
+
+ public void getVisitedHistory(ValueCallback<String[]> callback) {
+ if (mWebChromeClient == null) {
+ return;
+ }
+ Message msg = obtainMessage(GET_VISITED_HISTORY);
+ msg.obj = callback;
+ sendMessage(msg);
+ }
}