blob: de4949c73724df3fdf78a914945057e8602ad66d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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 android.webkit;
18
Ben Murdochf7093be2010-11-01 10:27:33 +000019import android.app.ActivityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.Context;
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -050021import android.content.pm.PackageManager.NameNotFoundException;
Leon Scroggins70ca3c22009-10-02 15:58:55 -040022import android.database.Cursor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.graphics.Point;
24import android.graphics.Rect;
25import android.graphics.Region;
Shimeng (Simon) Wangbf013122010-10-05 16:59:05 -070026import android.media.MediaFile;
Kristian Monsen2032eee2011-05-23 14:25:27 +010027import android.net.ProxyProperties;
Leon Scroggins70ca3c22009-10-02 15:58:55 -040028import android.net.Uri;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.Handler;
30import android.os.Looper;
31import android.os.Message;
32import android.os.Process;
Ben Murdoch65b4cda2010-05-28 11:07:15 +010033import android.provider.MediaStore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.util.Log;
35import android.util.SparseBooleanArray;
36import android.view.KeyEvent;
Huahui Wu0904c0d2011-01-07 17:30:53 -080037import android.view.MotionEvent;
Patrick Scottfb6aecb2009-07-17 16:38:07 -040038import android.view.SurfaceView;
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -040039import android.view.View;
Steve Blockdc82a292010-10-06 14:34:15 +010040import android.webkit.DeviceMotionService;
Steve Block1be73392010-10-15 16:31:01 +010041import android.webkit.DeviceMotionAndOrientationManager;
Steve Blockc43565b2010-08-11 13:12:37 +010042import android.webkit.DeviceOrientationService;
Steve Block808751f2011-01-04 14:26:27 +000043import android.webkit.JniUtil;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
45import java.util.ArrayList;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010046import java.util.Collection;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010047import java.util.Map;
Andrei Popescu59e2ad92009-07-28 13:38:06 +010048import java.util.Set;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049
50import junit.framework.Assert;
51
Dounia Berrada940a1982011-04-27 13:53:13 -070052/**
53 * @hide
54 */
55public final class WebViewCore {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
57 private static final String LOGTAG = "webcore";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59 static {
Ben Murdoch492bbe32011-09-01 03:27:26 +010060 // Load libwebcore and libchromium_net during static initialization.
61 // This happens in the zygote process so they will be shared read-only
62 // across all app processes.
Jean-Baptiste Queruc0e95042011-01-31 15:43:19 -080063 try {
64 System.loadLibrary("webcore");
Ben Murdoch492bbe32011-09-01 03:27:26 +010065 System.loadLibrary("chromium_net");
Jean-Baptiste Queruc0e95042011-01-31 15:43:19 -080066 } catch (UnsatisfiedLinkError e) {
Ben Murdoch492bbe32011-09-01 03:27:26 +010067 Log.e(LOGTAG, "Unable to load native support libraries.");
Jean-Baptiste Queruc0e95042011-01-31 15:43:19 -080068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 }
70
71 /*
72 * WebViewCore always executes in the same thread as the native webkit.
73 */
74
75 // The WebView that corresponds to this WebViewCore.
76 private WebView mWebView;
77 // Proxy for handling callbacks from native code
78 private final CallbackProxy mCallbackProxy;
79 // Settings object for maintaining all settings
80 private final WebSettings mSettings;
81 // Context for initializing the BrowserFrame with the proper assets.
82 private final Context mContext;
83 // The pointer to a native view object.
84 private int mNativeClass;
85 // The BrowserFrame is an interface to the native Frame component.
86 private BrowserFrame mBrowserFrame;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010087 // Custom JS interfaces to add during the initialization.
88 private Map<String, Object> mJavascriptInterfaces;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 /*
90 * range is from 200 to 10,000. 0 is a special value means device-width. -1
91 * means undefined.
92 */
93 private int mViewportWidth = -1;
94
95 /*
96 * range is from 200 to 10,000. 0 is a special value means device-height. -1
97 * means undefined.
98 */
99 private int mViewportHeight = -1;
100
101 /*
102 * scale in percent, range is from 1 to 1000. 0 means undefined.
103 */
104 private int mViewportInitialScale = 0;
105
106 /*
107 * scale in percent, range is from 1 to 1000. 0 means undefined.
108 */
109 private int mViewportMinimumScale = 0;
110
111 /*
112 * scale in percent, range is from 1 to 1000. 0 means undefined.
113 */
114 private int mViewportMaximumScale = 0;
115
116 private boolean mViewportUserScalable = true;
Cary Clarkd6982c92009-05-29 11:02:22 -0400117
Grace Kloba408cf852009-09-20 16:34:44 -0700118 /*
119 * range is from 70 to 400.
120 * 0 is a special value means device-dpi. The default scale factor will be
121 * always 100.
122 * -1 means undefined. The default scale factor will be
123 * WebView.DEFAULT_SCALE_PERCENT.
124 */
125 private int mViewportDensityDpi = -1;
126
Mangesh Ghiwaref0e96d52011-10-26 17:23:54 -0700127 private boolean mIsRestored = false;
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -0800128 private float mRestoredScale = 0;
129 private float mRestoredTextWrapScale = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 private int mRestoredX = 0;
131 private int mRestoredY = 0;
132
Steve Block1be73392010-10-15 16:31:01 +0100133 private DeviceMotionAndOrientationManager mDeviceMotionAndOrientationManager =
134 new DeviceMotionAndOrientationManager(this);
Steve Blockdc82a292010-10-06 14:34:15 +0100135 private DeviceMotionService mDeviceMotionService;
Steve Blockc43565b2010-08-11 13:12:37 +0100136 private DeviceOrientationService mDeviceOrientationService;
Steve Blockf4a705f2010-08-11 13:08:24 +0100137
Ben Murdochf7093be2010-11-01 10:27:33 +0000138 private int mLowMemoryUsageThresholdMb;
139 private int mHighMemoryUsageThresholdMb;
Shimeng (Simon) Wang7c1bcfd2011-01-24 14:38:46 -0800140 private int mHighUsageDeltaMb;
Ben Murdochf7093be2010-11-01 10:27:33 +0000141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 // The thread name used to identify the WebCore thread and for use in
143 // debugging other classes that require operation within the WebCore thread.
144 /* package */ static final String THREAD_NAME = "WebViewCoreThread";
145
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100146 public WebViewCore(Context context, WebView w, CallbackProxy proxy,
147 Map<String, Object> javascriptInterfaces) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 // No need to assign this in the WebCore thread.
149 mCallbackProxy = proxy;
150 mWebView = w;
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100151 mJavascriptInterfaces = javascriptInterfaces;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 // This context object is used to initialize the WebViewCore during
153 // subwindow creation.
154 mContext = context;
155
156 // We need to wait for the initial thread creation before sending
157 // a message to the WebCore thread.
158 // XXX: This is the only time the UI thread will wait for the WebCore
159 // thread!
160 synchronized (WebViewCore.class) {
161 if (sWebCoreHandler == null) {
162 // Create a global thread and start it.
163 Thread t = new Thread(new WebCoreThread());
164 t.setName(THREAD_NAME);
165 t.start();
166 try {
167 WebViewCore.class.wait();
168 } catch (InterruptedException e) {
169 Log.e(LOGTAG, "Caught exception while waiting for thread " +
170 "creation.");
171 Log.e(LOGTAG, Log.getStackTraceString(e));
172 }
173 }
174 }
175 // Create an EventHub to handle messages before and after the thread is
176 // ready.
177 mEventHub = new EventHub();
178 // Create a WebSettings object for maintaining all settings
Grace Kloba0d8b77c2009-06-25 11:20:51 -0700179 mSettings = new WebSettings(mContext, mWebView);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 // The WebIconDatabase needs to be initialized within the UI thread so
181 // just request the instance here.
182 WebIconDatabase.getInstance();
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100183 // Create the WebStorage singleton and the UI handler
184 WebStorage.getInstance().createUIHandler();
185 // Create the UI handler for GeolocationPermissions
186 GeolocationPermissions.getInstance().createUIHandler();
Ben Murdochf7093be2010-11-01 10:27:33 +0000187
188 // Get the memory class of the current device. V8 will use these values
189 // to GC more effectively.
190 ActivityManager manager = (ActivityManager) mContext.getSystemService(
191 Context.ACTIVITY_SERVICE);
192 ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
193 manager.getMemoryInfo(memInfo);
194
195 // Allow us to use up to our memory class value before V8's GC kicks in.
196 // These values have been determined by experimentation.
Shimeng (Simon) Wang7c1bcfd2011-01-24 14:38:46 -0800197 mLowMemoryUsageThresholdMb = manager.getLargeMemoryClass();
Shimeng (Simon) Wang7114f3b2011-01-26 10:34:26 -0800198 mHighMemoryUsageThresholdMb = (int) (mLowMemoryUsageThresholdMb * 1.5);
Shimeng (Simon) Wang7c1bcfd2011-01-24 14:38:46 -0800199 // Avoid constant V8 GC when memory usage equals to working set estimate.
Shimeng (Simon) Wang7114f3b2011-01-26 10:34:26 -0800200 mHighUsageDeltaMb = mLowMemoryUsageThresholdMb / 32;
Ben Murdochf7093be2010-11-01 10:27:33 +0000201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 // Send a message to initialize the WebViewCore.
203 Message init = sWebCoreHandler.obtainMessage(
204 WebCoreThread.INITIALIZE, this);
205 sWebCoreHandler.sendMessage(init);
206 }
207
208 /* Initialize private data within the WebCore thread.
209 */
210 private void initialize() {
211 /* Initialize our private BrowserFrame class to handle all
212 * frame-related functions. We need to create a new view which
213 * in turn creates a C level FrameView and attaches it to the frame.
214 */
215 mBrowserFrame = new BrowserFrame(mContext, this, mCallbackProxy,
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100216 mSettings, mJavascriptInterfaces);
217 mJavascriptInterfaces = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 // Sync the native settings and also create the WebCore thread handler.
219 mSettings.syncSettingsAndCreateHandler(mBrowserFrame);
220 // Create the handler and transfer messages for the IconDatabase
221 WebIconDatabase.getInstance().createHandler();
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100222 // Create the handler for WebStorage
223 WebStorage.getInstance().createHandler();
Steve Block0ac031b2009-07-28 11:53:20 +0100224 // Create the handler for GeolocationPermissions.
225 GeolocationPermissions.getInstance().createHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 // The transferMessages call will transfer all pending messages to the
227 // WebCore thread handler.
228 mEventHub.transferMessages();
229
230 // Send a message back to WebView to tell it that we have set up the
231 // WebCore thread.
232 if (mWebView != null) {
233 Message.obtain(mWebView.mPrivateHandler,
234 WebView.WEBCORE_INITIALIZED_MSG_ID,
235 mNativeClass, 0).sendToTarget();
236 }
237
238 }
239
240 /* Handle the initialization of WebViewCore during subwindow creation. This
241 * method is called from the WebCore thread but it is called before the
242 * INITIALIZE message can be handled.
243 */
244 /* package */ void initializeSubwindow() {
245 // Go ahead and initialize the core components.
246 initialize();
247 // Remove the INITIALIZE method so we don't try to initialize twice.
248 sWebCoreHandler.removeMessages(WebCoreThread.INITIALIZE, this);
249 }
250
251 /* Get the BrowserFrame component. This is used for subwindow creation and
252 * is called only from BrowserFrame in the WebCore thread. */
Mathew Inwoode7821cd2011-07-08 17:26:46 +0100253 /* package */ synchronized BrowserFrame getBrowserFrame() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 return mBrowserFrame;
255 }
256
257 //-------------------------------------------------------------------------
258 // Common methods
259 //-------------------------------------------------------------------------
260
261 /**
262 * Causes all timers to pause. This applies to all WebViews in the current
263 * app process.
264 */
265 public static void pauseTimers() {
266 if (BrowserFrame.sJavaBridge == null) {
267 throw new IllegalStateException(
268 "No WebView has been created in this process!");
269 }
270 BrowserFrame.sJavaBridge.pause();
271 }
272
273 /**
274 * Resume all timers. This applies to all WebViews in the current process.
275 */
276 public static void resumeTimers() {
277 if (BrowserFrame.sJavaBridge == null) {
278 throw new IllegalStateException(
279 "No WebView has been created in this process!");
280 }
281 BrowserFrame.sJavaBridge.resume();
282 }
283
284 public WebSettings getSettings() {
285 return mSettings;
286 }
287
Shimeng (Simon) Wangbf013122010-10-05 16:59:05 -0700288 /*
289 * Given mimeType, check whether it's supported in Android media framework.
290 * mimeType could be such as "audio/ogg" and "video/mp4".
291 */
Iain Merrick4e7665d2010-10-27 10:15:14 +0100292 /* package */ static boolean isSupportedMediaMimeType(String mimeType) {
293 int fileType = MediaFile.getFileTypeForMimeType(mimeType);
Andreas Huber5dffd0e2010-11-15 08:54:40 -0800294 return MediaFile.isAudioFileType(fileType)
295 || MediaFile.isVideoFileType(fileType)
Shimeng (Simon) Wangb394d9a2010-11-17 17:55:06 -0800296 || MediaFile.isPlayListFileType(fileType)
297 // The following is not in Media framework, but it's supported.
298 || (mimeType != null && mimeType.startsWith("video/m4v"));
Shimeng (Simon) Wangbf013122010-10-05 16:59:05 -0700299 }
Iain Merrick4e7665d2010-10-27 10:15:14 +0100300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 /**
Ben Murdoch6262ae52009-04-17 13:21:53 +0100302 * Add an error message to the client's console.
303 * @param message The message to add
304 * @param lineNumber the line on which the error occurred
305 * @param sourceID the filename of the source that caused the error.
Ben Murdoch3141e0a2010-01-28 15:06:32 +0000306 * @param msgLevel the log level of this message. This is a value casted to int
307 * from WebCore::MessageLevel in WebCore/page/Console.h.
Ben Murdoch6262ae52009-04-17 13:21:53 +0100308 */
Ben Murdoch3141e0a2010-01-28 15:06:32 +0000309 protected void addMessageToConsole(String message, int lineNumber, String sourceID,
310 int msgLevel) {
311 mCallbackProxy.addMessageToConsole(message, lineNumber, sourceID, msgLevel);
Ben Murdoch6262ae52009-04-17 13:21:53 +0100312 }
313
314 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 * Invoke a javascript alert.
316 * @param message The message displayed in the alert.
317 */
318 protected void jsAlert(String url, String message) {
319 mCallbackProxy.onJsAlert(url, message);
320 }
321
Leon Scrogginsf2e17a82010-09-24 15:58:50 -0400322 /**
323 * Called by JNI. Send a message to the UI thread to hide the soft keyboard
324 * if the node pointed to by nodePointer is still in focus.
325 * @param nodePointer The node which just blurred.
326 */
327 private void formDidBlur(int nodePointer) {
328 if (mWebView == null) return;
329 Message.obtain(mWebView.mPrivateHandler, WebView.FORM_DID_BLUR,
330 nodePointer, 0).sendToTarget();
331 }
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400332
333 /**
334 * Called by JNI. Open a file chooser to upload a file.
Ben Murdoch4ae32f52010-05-18 14:30:39 +0100335 * @param acceptType The value of the 'accept' attribute of the
336 * input tag associated with this file picker.
Ben Murdochcc749de2010-05-18 12:37:00 +0100337 * @return String version of the URI.
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400338 */
Ben Murdoch4ae32f52010-05-18 14:30:39 +0100339 private String openFileChooser(String acceptType) {
340 Uri uri = mCallbackProxy.openFileChooser(acceptType);
Ben Murdochcc749de2010-05-18 12:37:00 +0100341 if (uri != null) {
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100342 String filePath = "";
343 // Note - querying for MediaStore.Images.Media.DATA
344 // seems to work for all content URIs, not just images
Ben Murdochcc749de2010-05-18 12:37:00 +0100345 Cursor cursor = mContext.getContentResolver().query(
346 uri,
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100347 new String[] { MediaStore.Images.Media.DATA },
Ben Murdochcc749de2010-05-18 12:37:00 +0100348 null, null, null);
349 if (cursor != null) {
350 try {
351 if (cursor.moveToNext()) {
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100352 filePath = cursor.getString(0);
Ben Murdochcc749de2010-05-18 12:37:00 +0100353 }
354 } finally {
355 cursor.close();
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400356 }
Ben Murdochcc749de2010-05-18 12:37:00 +0100357 } else {
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100358 filePath = uri.getLastPathSegment();
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400359 }
Ben Murdochcc749de2010-05-18 12:37:00 +0100360 String uriString = uri.toString();
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100361 BrowserFrame.sJavaBridge.storeFilePathForContentUri(filePath, uriString);
Ben Murdochcc749de2010-05-18 12:37:00 +0100362 return uriString;
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400363 }
Ben Murdochcc749de2010-05-18 12:37:00 +0100364 return "";
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400365 }
366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 /**
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100368 * Notify the browser that the origin has exceeded it's database quota.
Ben Murdoch7df19852009-04-22 13:07:58 +0100369 * @param url The URL that caused the overflow.
370 * @param databaseIdentifier The identifier of the database.
371 * @param currentQuota The current quota for the origin.
Ben Murdochd497d872009-08-25 19:32:54 +0100372 * @param estimatedSize The estimated size of the database.
Ben Murdoch7df19852009-04-22 13:07:58 +0100373 */
374 protected void exceededDatabaseQuota(String url,
375 String databaseIdentifier,
Ben Murdochd497d872009-08-25 19:32:54 +0100376 long currentQuota,
377 long estimatedSize) {
Ben Murdoch7df19852009-04-22 13:07:58 +0100378 // Inform the callback proxy of the quota overflow. Send an object
379 // that encapsulates a call to the nativeSetDatabaseQuota method to
380 // awaken the sleeping webcore thread when a decision from the
381 // client to allow or deny quota is available.
382 mCallbackProxy.onExceededDatabaseQuota(url, databaseIdentifier,
Ben Murdochd497d872009-08-25 19:32:54 +0100383 currentQuota, estimatedSize, getUsedQuota(),
384 new WebStorage.QuotaUpdater() {
385 public void updateQuota(long quota) {
386 nativeSetNewStorageLimit(quota);
387 }
388 });
Ben Murdoch7df19852009-04-22 13:07:58 +0100389 }
390
391 /**
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100392 * Notify the browser that the appcache has exceeded its max size.
393 * @param spaceNeeded is the amount of disk space that would be needed
394 * in order for the last appcache operation to succeed.
395 */
396 protected void reachedMaxAppCacheSize(long spaceNeeded) {
397 mCallbackProxy.onReachedMaxAppCacheSize(spaceNeeded, getUsedQuota(),
398 new WebStorage.QuotaUpdater() {
399 public void updateQuota(long quota) {
400 nativeSetNewStorageLimit(quota);
401 }
402 });
403 }
404
Leon Clarke194e3452009-09-28 11:42:12 +0100405 protected void populateVisitedLinks() {
406 ValueCallback callback = new ValueCallback<String[]>() {
407 public void onReceiveValue(String[] value) {
408 sendMessage(EventHub.POPULATE_VISITED_LINKS, (Object)value);
409 }
410 };
411 mCallbackProxy.getVisitedHistory(callback);
Leon Clarke9c8d8862009-09-24 15:20:10 +0100412 }
413
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100414 /**
Steve Block4faee092009-07-28 18:20:50 +0100415 * Shows a prompt to ask the user to set the Geolocation permission state
416 * for the given origin.
417 * @param origin The origin for which Geolocation permissions are
418 * requested.
419 */
420 protected void geolocationPermissionsShowPrompt(String origin) {
421 mCallbackProxy.onGeolocationPermissionsShowPrompt(origin,
422 new GeolocationPermissions.Callback() {
423 public void invoke(String origin, boolean allow, boolean remember) {
424 GeolocationPermissionsData data = new GeolocationPermissionsData();
425 data.mOrigin = origin;
426 data.mAllow = allow;
427 data.mRemember = remember;
428 // Marshall to WebCore thread.
429 sendMessage(EventHub.GEOLOCATION_PERMISSIONS_PROVIDE, data);
430 }
431 });
432 }
433
434 /**
435 * Hides the Geolocation permissions prompt.
436 */
437 protected void geolocationPermissionsHidePrompt() {
438 mCallbackProxy.onGeolocationPermissionsHidePrompt();
439 }
440
441 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 * Invoke a javascript confirm dialog.
443 * @param message The message displayed in the dialog.
444 * @return True if the user confirmed or false if the user cancelled.
445 */
446 protected boolean jsConfirm(String url, String message) {
447 return mCallbackProxy.onJsConfirm(url, message);
448 }
449
450 /**
451 * Invoke a javascript prompt dialog.
452 * @param message The message to be displayed in the dialog.
453 * @param defaultValue The default value in the prompt input.
454 * @return The input from the user or null to indicate the user cancelled
455 * the dialog.
456 */
457 protected String jsPrompt(String url, String message, String defaultValue) {
458 return mCallbackProxy.onJsPrompt(url, message, defaultValue);
459 }
460
461 /**
462 * Invoke a javascript before unload dialog.
463 * @param url The url that is requesting the dialog.
464 * @param message The message displayed in the dialog.
465 * @return True if the user confirmed or false if the user cancelled. False
466 * will cancel the navigation.
467 */
468 protected boolean jsUnload(String url, String message) {
469 return mCallbackProxy.onJsBeforeUnload(url, message);
470 }
471
Guang Zhu81e41432009-05-08 16:09:55 -0700472 /**
473 *
474 * Callback to notify that a JavaScript execution timeout has occured.
475 * @return True if the JavaScript execution should be interrupted. False
476 * will continue the execution.
477 */
478 protected boolean jsInterrupt() {
479 return mCallbackProxy.onJsTimeout();
480 }
481
Ben Murdoch6312de22010-06-29 19:20:11 +0100482 /**
483 * Notify the webview that this is an installable web app.
484 */
485 protected void setInstallableWebApp() {
486 mCallbackProxy.setInstallableWebApp();
487 }
488
Nicolas Roard0e778a12011-03-11 14:29:05 -0800489 /**
490 * Notify the webview that we want to display the video layer fullscreen.
491 */
Teng-Hui Zhu10ab6542011-03-16 16:42:32 -0700492 protected void enterFullscreenForVideoLayer(int layerId, String url) {
Nicolas Roard0e778a12011-03-11 14:29:05 -0800493 if (mWebView == null) return;
Teng-Hui Zhu10ab6542011-03-16 16:42:32 -0700494 Message message = Message.obtain(mWebView.mPrivateHandler,
495 WebView.ENTER_FULLSCREEN_VIDEO, layerId, 0);
496 message.obj = url;
497 message.sendToTarget();
Nicolas Roard0e778a12011-03-11 14:29:05 -0800498 }
499
Ben Murdocha62b9632011-12-05 14:51:00 +0000500 /**
501 * Clear the picture set. To be called only on the WebCore thread.
502 */
503 /* package */ void clearContent() {
504 nativeClearContent();
505 }
506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 //-------------------------------------------------------------------------
508 // JNI methods
509 //-------------------------------------------------------------------------
510
Cary Clark3e399de2009-06-17 10:00:57 -0400511 static native String nativeFindAddress(String addr, boolean caseInsensitive);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512
513 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 * Empty the picture set.
515 */
516 private native void nativeClearContent();
Cary Clarkd6982c92009-05-29 11:02:22 -0400517
Cary Clark75796bb2010-08-24 14:59:58 -0400518 private native void nativeContentInvalidateAll();
519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 * Redraw a portion of the picture set. The Point wh returns the
522 * width and height of the overall picture.
523 */
Grace Kloba8abd50b2010-07-08 15:02:14 -0700524 private native int nativeRecordContent(Region invalRegion, Point wh);
Cary Clarkd6982c92009-05-29 11:02:22 -0400525
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700526 /**
527 * Update the layers' content
528 */
Chris Craikd0051c02011-11-29 10:26:10 -0800529 private native boolean nativeUpdateLayers(int nativeClass, int baseLayer);
530
531 /**
532 * Notify webkit that animations have begun (on the hardware accelerated content)
533 */
534 private native void nativeNotifyAnimationStarted(int nativeClass);
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700535
Cary Clark5da9aeb2009-10-06 17:40:53 -0400536 private native boolean nativeFocusBoundsChanged();
537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 /**
Grace Kloba8abd50b2010-07-08 15:02:14 -0700539 * Splits slow parts of the picture set. Called from the webkit thread after
540 * WebView.nativeDraw() returns content to be split.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 */
Grace Kloba8abd50b2010-07-08 15:02:14 -0700542 private native void nativeSplitContent(int content);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543
544 private native boolean nativeKey(int keyCode, int unichar,
Cary Clark215b72c2009-06-26 14:38:43 -0400545 int repeatCount, boolean isShift, boolean isAlt, boolean isSym,
546 boolean isDown);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547
Leon Scrogginsb45a2632011-01-12 14:11:24 -0500548 private native void nativeClick(int framePtr, int nodePtr, boolean fake);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549
550 private native void nativeSendListBoxChoices(boolean[] choices, int size);
551
552 private native void nativeSendListBoxChoice(int choice);
553
Kristian Monsen64decc62011-08-25 20:32:24 +0100554 private native void nativeCloseIdleConnections();
555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 /* Tell webkit what its width and height are, for the purposes
557 of layout/line-breaking. These coordinates are in document space,
558 which is the same as View coords unless we have zoomed the document
559 (see nativeSetZoom).
Grace Klobae80cbcc2010-05-28 18:07:50 -0700560 textWrapWidth is used by layout to wrap column around. If viewport uses
561 fixed size, textWrapWidth can be different from width with zooming.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 should this be called nativeSetViewPortSize?
563 */
Grace Klobae80cbcc2010-05-28 18:07:50 -0700564 private native void nativeSetSize(int width, int height, int textWrapWidth,
565 float scale, int screenWidth, int screenHeight, int anchorX,
Grace Kloba3a0def22010-01-23 21:11:54 -0800566 int anchorY, boolean ignoreHeight);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567
568 private native int nativeGetContentMinPrefWidth();
Cary Clarkd6982c92009-05-29 11:02:22 -0400569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 // Start: functions that deal with text editing
Cary Clark2f1d60c2009-06-03 08:05:53 -0400571 private native void nativeReplaceTextfieldText(
Leon Scroggins43488fc2009-07-06 14:32:49 -0400572 int oldStart, int oldEnd, String replace, int newStart, int newEnd,
573 int textGeneration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574
Cary Clark2f1d60c2009-06-03 08:05:53 -0400575 private native void passToJs(int gen,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 String currentText, int keyCode, int keyValue, boolean down,
577 boolean cap, boolean fn, boolean sym);
578
Leon Scroggins8cdad882009-06-30 08:47:04 -0400579 private native void nativeSetFocusControllerActive(boolean active);
Leon Scroggins63dda1c2009-04-15 13:25:00 -0400580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 private native void nativeSaveDocumentState(int frame);
582
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500583 private native void nativeMoveFocus(int framePtr, int nodePointer);
Cary Clarked56eda2009-06-18 09:48:47 -0400584 private native void nativeMoveMouse(int framePtr, int x, int y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585
Cary Clarkd6982c92009-05-29 11:02:22 -0400586 private native void nativeMoveMouseIfLatest(int moveGeneration,
Cary Clarked56eda2009-06-18 09:48:47 -0400587 int framePtr, int x, int y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588
Cary Clarke41bb532010-11-30 15:59:59 -0500589 private native String nativeRetrieveHref(int x, int y);
590 private native String nativeRetrieveAnchorText(int x, int y);
Cary Clark861368a2010-12-15 11:24:37 -0500591 private native String nativeRetrieveImageSource(int x, int y);
Leon Scrogginsb6112132011-02-24 12:35:50 -0500592 private native void nativeStopPaintingCaret();
Cary Clarkd6982c92009-05-29 11:02:22 -0400593 private native void nativeTouchUp(int touchGeneration,
Leon Scroggins22e883d2011-01-31 10:54:19 -0500594 int framePtr, int nodePtr, int x, int y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595
Huahui Wue838a422011-01-13 16:03:43 -0800596 private native boolean nativeHandleTouchEvent(int action, int[] idArray,
Huahui Wu2d3ef372011-03-13 18:13:42 -0700597 int[] xArray, int[] yArray, int count, int actionIndex, int metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 private native void nativeUpdateFrameCache();
Cary Clarkd6982c92009-05-29 11:02:22 -0400600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 private native void nativeSetBackgroundColor(int color);
Cary Clarkd6982c92009-05-29 11:02:22 -0400602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 private native void nativeDumpDomTree(boolean useFile);
604
605 private native void nativeDumpRenderTree(boolean useFile);
606
607 private native void nativeDumpNavTree();
608
Feng Qianb3081372009-06-29 15:55:18 -0700609 private native void nativeSetJsFlags(String flags);
610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 /**
612 * Delete text from start to end in the focused textfield. If there is no
Cary Clarkd6982c92009-05-29 11:02:22 -0400613 * focus, or if start == end, silently fail. If start and end are out of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 * order, swap them.
615 * @param start Beginning of selection to delete.
616 * @param end End of selection to delete.
Leon Scroggins43488fc2009-07-06 14:32:49 -0400617 * @param textGeneration Text generation number when delete was pressed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 */
Leon Scroggins43488fc2009-07-06 14:32:49 -0400619 private native void nativeDeleteSelection(int start, int end,
620 int textGeneration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621
622 /**
623 * Set the selection to (start, end) in the focused textfield. If start and
624 * end are out of order, swap them.
625 * @param start Beginning of selection.
626 * @param end End of selection.
627 */
Cary Clark2f1d60c2009-06-03 08:05:53 -0400628 private native void nativeSetSelection(int start, int end);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 // Register a scheme to be treated as local scheme so that it can access
631 // local asset files for resources
632 private native void nativeRegisterURLSchemeAsLocal(String scheme);
633
Ben Murdoch7df19852009-04-22 13:07:58 +0100634 /*
635 * Inform webcore that the user has decided whether to allow or deny new
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100636 * quota for the current origin or more space for the app cache, and that
637 * the main thread should wake up now.
638 * @param limit Is the new quota for an origin or new app cache max size.
Ben Murdoch7df19852009-04-22 13:07:58 +0100639 */
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100640 private native void nativeSetNewStorageLimit(long limit);
Ben Murdoch7df19852009-04-22 13:07:58 +0100641
Steve Block4faee092009-07-28 18:20:50 +0100642 /**
643 * Provide WebCore with a Geolocation permission state for the specified
644 * origin.
645 * @param origin The origin for which Geolocation permissions are provided.
646 * @param allow Whether Geolocation permissions are allowed.
647 * @param remember Whether this decision should be remembered beyond the
648 * life of the current page.
649 */
650 private native void nativeGeolocationPermissionsProvide(String origin, boolean allow, boolean remember);
651
Leon Clarke194e3452009-09-28 11:42:12 +0100652 /**
653 * Provide WebCore with the previously visted links from the history database
654 */
Svetoslav Ganovda355512010-05-12 22:04:44 -0700655 private native void nativeProvideVisitedHistory(String[] history);
656
657 /**
658 * Modifies the current selection.
659 *
Svetoslav Ganovc93fb652011-01-05 18:52:05 -0800660 * Note: Accessibility support.
661 *
Svetoslav Ganovda355512010-05-12 22:04:44 -0700662 * @param direction The direction in which to alter the selection.
663 * @param granularity The granularity of the selection modification.
664 *
665 * @return The selection string.
666 */
Svetoslav Ganov585f13f8d2010-08-10 07:59:15 -0700667 private native String nativeModifySelection(int direction, int granularity);
Leon Clarke194e3452009-09-28 11:42:12 +0100668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669 // EventHub for processing messages
670 private final EventHub mEventHub;
671 // WebCore thread handler
672 private static Handler sWebCoreHandler;
673 // Class for providing Handler creation inside the WebCore thread.
674 private static class WebCoreThread implements Runnable {
675 // Message id for initializing a new WebViewCore.
676 private static final int INITIALIZE = 0;
677 private static final int REDUCE_PRIORITY = 1;
678 private static final int RESUME_PRIORITY = 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679
680 public void run() {
681 Looper.prepare();
682 Assert.assertNull(sWebCoreHandler);
683 synchronized (WebViewCore.class) {
684 sWebCoreHandler = new Handler() {
685 @Override
686 public void handleMessage(Message msg) {
687 switch (msg.what) {
688 case INITIALIZE:
689 WebViewCore core = (WebViewCore) msg.obj;
690 core.initialize();
691 break;
692
693 case REDUCE_PRIORITY:
694 // 3 is an adjustable number.
695 Process.setThreadPriority(
696 Process.THREAD_PRIORITY_DEFAULT + 3 *
697 Process.THREAD_PRIORITY_LESS_FAVORABLE);
698 break;
699
700 case RESUME_PRIORITY:
701 Process.setThreadPriority(
702 Process.THREAD_PRIORITY_DEFAULT);
703 break;
Kristian Monsen4190aab2010-12-16 18:39:21 +0000704
705 case EventHub.ADD_PACKAGE_NAME:
706 if (BrowserFrame.sJavaBridge == null) {
707 throw new IllegalStateException(
708 "No WebView has been created in this process!");
709 }
710 BrowserFrame.sJavaBridge.addPackageName((String) msg.obj);
711 break;
712
713 case EventHub.REMOVE_PACKAGE_NAME:
714 if (BrowserFrame.sJavaBridge == null) {
715 throw new IllegalStateException(
716 "No WebView has been created in this process!");
717 }
718 BrowserFrame.sJavaBridge.removePackageName((String) msg.obj);
719 break;
Kristian Monsen41e7e6f2010-12-21 12:51:11 +0000720
721 case EventHub.PROXY_CHANGED:
722 if (BrowserFrame.sJavaBridge == null) {
723 throw new IllegalStateException(
724 "No WebView has been created in this process!");
725 }
Kristian Monsen2032eee2011-05-23 14:25:27 +0100726 BrowserFrame.sJavaBridge.updateProxy((ProxyProperties)msg.obj);
Kristian Monsen41e7e6f2010-12-21 12:51:11 +0000727 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 }
729 }
730 };
731 WebViewCore.class.notify();
732 }
733 Looper.loop();
734 }
735 }
736
Cary Clarkded054c2009-06-15 10:26:08 -0400737 static class BaseUrlData {
738 String mBaseUrl;
739 String mData;
740 String mMimeType;
741 String mEncoding;
Leon Scroggins1bb1a912010-03-23 15:39:46 -0400742 String mHistoryUrl;
Cary Clarkded054c2009-06-15 10:26:08 -0400743 }
744
Cary Clarkd6982c92009-05-29 11:02:22 -0400745 static class CursorData {
746 CursorData() {}
747 CursorData(int frame, int node, int x, int y) {
748 mFrame = frame;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500749 mNode = node;
Cary Clarkd6982c92009-05-29 11:02:22 -0400750 mX = x;
751 mY = y;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 }
753 int mMoveGeneration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 int mFrame;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500755 int mNode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 int mX;
757 int mY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 }
759
Cary Clarkded054c2009-06-15 10:26:08 -0400760 static class JSInterfaceData {
761 Object mObject;
762 String mInterfaceName;
763 }
764
765 static class JSKeyData {
766 String mCurrentText;
767 KeyEvent mEvent;
768 }
769
Cary Clark1cb97ee2009-12-11 12:10:36 -0500770 static class MotionUpData {
771 int mFrame;
772 int mNode;
773 Rect mBounds;
774 int mX;
775 int mY;
776 }
777
Grace Klobad0d9bc22010-01-26 18:08:28 -0800778 static class GetUrlData {
779 String mUrl;
780 Map<String, String> mExtraHeaders;
781 }
782
Cary Clarkded054c2009-06-15 10:26:08 -0400783 static class PostUrlData {
784 String mUrl;
785 byte[] mPostData;
786 }
787
788 static class ReplaceTextData {
789 String mReplace;
790 int mNewStart;
791 int mNewEnd;
Leon Scroggins43488fc2009-07-06 14:32:49 -0400792 int mTextGeneration;
Cary Clarkded054c2009-06-15 10:26:08 -0400793 }
794
Leon Scroggins6679f2f2009-08-12 18:48:10 -0400795 static class TextSelectionData {
796 public TextSelectionData(int start, int end) {
797 mStart = start;
798 mEnd = end;
799 }
800 int mStart;
801 int mEnd;
802 }
803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 static class TouchUpData {
805 int mMoveGeneration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 int mFrame;
807 int mNode;
808 int mX;
809 int mY;
Patrick Scottcfa734a2011-02-22 11:19:02 -0500810 int mNativeLayer;
811 Rect mNativeLayerRect = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 }
813
Grace Kloba178db412010-05-18 22:22:23 -0700814 static class TouchHighlightData {
815 int mX;
816 int mY;
817 int mSlop;
John Reck335f4542011-08-25 18:25:09 -0700818 int mNativeLayer;
819 Rect mNativeLayerRect;
Grace Kloba178db412010-05-18 22:22:23 -0700820 }
821
Ben Murdochdb8d19c2010-10-29 11:44:17 +0100822 static class AutoFillData {
823 public AutoFillData() {
824 mQueryId = WebTextView.FORM_NOT_AUTOFILLABLE;
825 mPreview = "";
826 }
827
828 public AutoFillData(int queryId, String preview) {
829 mQueryId = queryId;
830 mPreview = preview;
831 }
832
833 public int getQueryId() {
834 return mQueryId;
835 }
836
837 public String getPreviewString() {
838 return mPreview;
839 }
840
841 private int mQueryId;
842 private String mPreview;
843 }
844
Grace Kloba5f68d6f2009-12-08 18:42:54 -0800845 // mAction of TouchEventData can be MotionEvent.getAction() which uses the
846 // last two bytes or one of the following values
847 static final int ACTION_LONGPRESS = 0x100;
848 static final int ACTION_DOUBLETAP = 0x200;
849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 static class TouchEventData {
Grace Kloba5f68d6f2009-12-08 18:42:54 -0800851 int mAction;
Huahui Wue838a422011-01-13 16:03:43 -0800852 int[] mIds; // Ids of the touch points
Huahui Wu41865f42010-09-02 13:41:41 -0700853 Point[] mPoints;
Huahui Wu88b869a2011-03-17 17:42:12 -0700854 Point[] mPointsInView; // the point coordinates in view axis.
Huahui Wu2d3ef372011-03-13 18:13:42 -0700855 int mActionIndex; // Associated pointer index for ACTION_POINTER_DOWN/UP
Ben Murdoch8a032a32010-02-02 18:20:11 +0000856 int mMetaState;
Grace Klobac2242f22010-03-05 14:00:26 -0800857 boolean mReprocess;
Huahui Wu0904c0d2011-01-07 17:30:53 -0800858 MotionEvent mMotionEvent;
Patrick Scottcfa734a2011-02-22 11:19:02 -0500859 int mNativeLayer;
860 Rect mNativeLayerRect = new Rect();
Adam Powell4fb35d42011-03-03 17:54:55 -0800861 long mSequence;
862 boolean mNativeResult;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 }
864
Steve Block4faee092009-07-28 18:20:50 +0100865 static class GeolocationPermissionsData {
866 String mOrigin;
867 boolean mAllow;
868 boolean mRemember;
869 }
870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 static final String[] HandlerDebugString = {
Leon Scroggins200c13d2010-05-14 15:35:42 -0400872 "REVEAL_SELECTION", // 96
Leon Scroggins3a503392010-01-06 17:04:38 -0500873 "REQUEST_LABEL", // 97
Cary Clark77d98f42009-07-31 09:40:38 -0400874 "UPDATE_FRAME_CACHE_IF_LOADING", // = 98
Leon Scroggins72543e12009-07-23 15:29:45 -0400875 "SCROLL_TEXT_INPUT", // = 99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 "LOAD_URL", // = 100;
877 "STOP_LOADING", // = 101;
878 "RELOAD", // = 102;
879 "KEY_DOWN", // = 103;
880 "KEY_UP", // = 104;
881 "VIEW_SIZE_CHANGED", // = 105;
882 "GO_BACK_FORWARD", // = 106;
883 "SET_SCROLL_OFFSET", // = 107;
884 "RESTORE_STATE", // = 108;
885 "PAUSE_TIMERS", // = 109;
886 "RESUME_TIMERS", // = 110;
887 "CLEAR_CACHE", // = 111;
888 "CLEAR_HISTORY", // = 112;
889 "SET_SELECTION", // = 113;
890 "REPLACE_TEXT", // = 114;
891 "PASS_TO_JS", // = 115;
892 "SET_GLOBAL_BOUNDS", // = 116;
893 "UPDATE_CACHE_AND_TEXT_ENTRY", // = 117;
894 "CLICK", // = 118;
Grace Klobaa72cc092009-04-02 08:50:17 -0700895 "SET_NETWORK_STATE", // = 119;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 "DOC_HAS_IMAGES", // = 120;
Leon Scrogginsb45a2632011-01-12 14:11:24 -0500897 "FAKE_CLICK", // = 121;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 "DELETE_SELECTION", // = 122;
899 "LISTBOX_CHOICES", // = 123;
900 "SINGLE_LISTBOX_CHOICE", // = 124;
Grace Klobab3230cb2009-04-13 14:04:23 -0700901 "MESSAGE_RELAY", // = 125;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 "SET_BACKGROUND_COLOR", // = 126;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500903 "SET_MOVE_FOCUS", // = 127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 "SAVE_DOCUMENT_STATE", // = 128;
Cary Clark57d2c3a2009-12-23 13:57:15 -0500905 "129", // = 129;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 "WEBKIT_DRAW", // = 130;
Patrick Scottfa8be1c2011-02-02 14:09:34 -0500907 "131", // = 131;
Grace Kloba57534302009-05-22 18:55:02 -0700908 "POST_URL", // = 132;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 "SPLIT_PICTURE_SET", // = 133;
910 "CLEAR_CONTENT", // = 134;
Cary Clarkd6982c92009-05-29 11:02:22 -0400911 "SET_MOVE_MOUSE", // = 135;
912 "SET_MOVE_MOUSE_IF_LATEST", // = 136;
Leon Scroggins1c7f8c52009-06-05 13:49:26 -0400913 "REQUEST_CURSOR_HREF", // = 137;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 "ADD_JS_INTERFACE", // = 138;
915 "LOAD_DATA", // = 139;
916 "TOUCH_UP", // = 140;
917 "TOUCH_EVENT", // = 141;
Leon Scroggins8cdad882009-06-30 08:47:04 -0400918 "SET_ACTIVE", // = 142;
Mike Reedd205d5b2009-05-27 11:02:29 -0400919 "ON_PAUSE", // = 143
920 "ON_RESUME", // = 144
Derek Sollenbergere0155e92009-06-10 15:35:45 -0400921 "FREE_MEMORY", // = 145
Cary Clark1cb97ee2009-12-11 12:10:36 -0500922 "VALID_NODE_BOUNDS", // = 146
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -0700923 "SAVE_WEBARCHIVE", // = 147
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700924 "WEBKIT_DRAW_LAYERS", // = 148;
Steve Block689a3422010-12-07 18:18:26 +0000925 "REMOVE_JS_INTERFACE", // = 149;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 };
927
Dounia Berrada940a1982011-04-27 13:53:13 -0700928 /**
929 * @hide
930 */
931 public class EventHub {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 // Message Ids
Leon Scroggins200c13d2010-05-14 15:35:42 -0400933 static final int REVEAL_SELECTION = 96;
Leon Scroggins3a503392010-01-06 17:04:38 -0500934 static final int REQUEST_LABEL = 97;
Cary Clark77d98f42009-07-31 09:40:38 -0400935 static final int UPDATE_FRAME_CACHE_IF_LOADING = 98;
Leon Scroggins72543e12009-07-23 15:29:45 -0400936 static final int SCROLL_TEXT_INPUT = 99;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 static final int LOAD_URL = 100;
938 static final int STOP_LOADING = 101;
939 static final int RELOAD = 102;
940 static final int KEY_DOWN = 103;
941 static final int KEY_UP = 104;
942 static final int VIEW_SIZE_CHANGED = 105;
943 static final int GO_BACK_FORWARD = 106;
944 static final int SET_SCROLL_OFFSET = 107;
945 static final int RESTORE_STATE = 108;
946 static final int PAUSE_TIMERS = 109;
947 static final int RESUME_TIMERS = 110;
948 static final int CLEAR_CACHE = 111;
949 static final int CLEAR_HISTORY = 112;
950 static final int SET_SELECTION = 113;
951 static final int REPLACE_TEXT = 114;
952 static final int PASS_TO_JS = 115;
953 static final int SET_GLOBAL_BOUNDS = 116;
954 static final int UPDATE_CACHE_AND_TEXT_ENTRY = 117;
955 static final int CLICK = 118;
Grace Klobaa72cc092009-04-02 08:50:17 -0700956 static final int SET_NETWORK_STATE = 119;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 static final int DOC_HAS_IMAGES = 120;
Leon Scrogginsb45a2632011-01-12 14:11:24 -0500958 static final int FAKE_CLICK = 121;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 static final int DELETE_SELECTION = 122;
960 static final int LISTBOX_CHOICES = 123;
961 static final int SINGLE_LISTBOX_CHOICE = 124;
Dounia Berrada940a1982011-04-27 13:53:13 -0700962 public static final int MESSAGE_RELAY = 125;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 static final int SET_BACKGROUND_COLOR = 126;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500964 static final int SET_MOVE_FOCUS = 127;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 static final int SAVE_DOCUMENT_STATE = 128;
Cary Clark57d2c3a2009-12-23 13:57:15 -0500966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 static final int WEBKIT_DRAW = 130;
Grace Kloba57534302009-05-22 18:55:02 -0700968 static final int POST_URL = 132;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 static final int SPLIT_PICTURE_SET = 133;
970 static final int CLEAR_CONTENT = 134;
Cary Clarkd6982c92009-05-29 11:02:22 -0400971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972 // UI nav messages
Cary Clarkd6982c92009-05-29 11:02:22 -0400973 static final int SET_MOVE_MOUSE = 135;
974 static final int SET_MOVE_MOUSE_IF_LATEST = 136;
Leon Scroggins1c7f8c52009-06-05 13:49:26 -0400975 static final int REQUEST_CURSOR_HREF = 137;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 static final int ADD_JS_INTERFACE = 138;
977 static final int LOAD_DATA = 139;
978
979 // motion
980 static final int TOUCH_UP = 140;
981 // message used to pass UI touch events to WebCore
982 static final int TOUCH_EVENT = 141;
983
Leon Scrogginsfa03cde2009-06-15 15:48:46 -0400984 // Used to tell the focus controller not to draw the blinking cursor,
985 // based on whether the WebView has focus and whether the WebView's
986 // cursor matches the webpage's focus.
Leon Scroggins8cdad882009-06-30 08:47:04 -0400987 static final int SET_ACTIVE = 142;
Leon Scroggins63dda1c2009-04-15 13:25:00 -0400988
Derek Sollenbergere0155e92009-06-10 15:35:45 -0400989 // lifecycle activities for just this DOM (unlike pauseTimers, which
Mike Reedd205d5b2009-05-27 11:02:29 -0400990 // is global)
991 static final int ON_PAUSE = 143;
992 static final int ON_RESUME = 144;
Derek Sollenbergere0155e92009-06-10 15:35:45 -0400993 static final int FREE_MEMORY = 145;
Cary Clark1cb97ee2009-12-11 12:10:36 -0500994 static final int VALID_NODE_BOUNDS = 146;
Mike Reedd205d5b2009-05-27 11:02:29 -0400995
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -0700996 // Load and save web archives
997 static final int SAVE_WEBARCHIVE = 147;
998
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700999 // Update layers
1000 static final int WEBKIT_DRAW_LAYERS = 148;
1001
Steve Block689a3422010-12-07 18:18:26 +00001002 static final int REMOVE_JS_INTERFACE = 149;
1003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 // Network-based messaging
1005 static final int CLEAR_SSL_PREF_TABLE = 150;
1006
1007 // Test harness messages
1008 static final int REQUEST_EXT_REPRESENTATION = 160;
1009 static final int REQUEST_DOC_AS_TEXT = 161;
1010
1011 // debugging
1012 static final int DUMP_DOMTREE = 170;
1013 static final int DUMP_RENDERTREE = 171;
1014 static final int DUMP_NAVTREE = 172;
1015
Andrei Popescu5e7bb0a2010-02-01 22:32:16 +00001016 static final int SET_JS_FLAGS = 174;
Chris Craik555c55e2011-07-28 15:39:43 -07001017 static final int CONTENT_INVALIDATE_ALL = 175;
Steve Block4faee092009-07-28 18:20:50 +01001018 // Geolocation
1019 static final int GEOLOCATION_PERMISSIONS_PROVIDE = 180;
Feng Qianb3081372009-06-29 15:55:18 -07001020
Leon Clarke194e3452009-09-28 11:42:12 +01001021 static final int POPULATE_VISITED_LINKS = 181;
1022
Grace Kloba11438c32009-12-16 11:39:12 -08001023 static final int HIDE_FULLSCREEN = 182;
1024
Andrei Popescuf5dba882010-01-12 22:42:41 +00001025 static final int SET_NETWORK_TYPE = 183;
1026
Andrei Popescua6d747d2010-02-11 13:19:21 +00001027 // navigator.isApplicationInstalled()
1028 static final int ADD_PACKAGE_NAMES = 184;
1029 static final int ADD_PACKAGE_NAME = 185;
1030 static final int REMOVE_PACKAGE_NAME = 186;
1031
Grace Kloba178db412010-05-18 22:22:23 -07001032 static final int GET_TOUCH_HIGHLIGHT_RECTS = 187;
Grace Kloba178db412010-05-18 22:22:23 -07001033
Svetoslav Ganovda355512010-05-12 22:04:44 -07001034 // accessibility support
1035 static final int MODIFY_SELECTION = 190;
1036
Steve Block68dede32010-08-04 10:28:46 +01001037 static final int USE_MOCK_DEVICE_ORIENTATION = 191;
1038
Ben Murdoch62275a42010-09-07 11:27:28 +01001039 static final int AUTOFILL_FORM = 192;
1040
Kristian Monsen41e7e6f2010-12-21 12:51:11 +00001041 static final int PROXY_CHANGED = 193;
1042
Narayan Kamath9497c5f2011-02-22 12:05:34 +00001043 static final int EXECUTE_JS = 194;
1044
Derek Sollenberger281432c2011-08-22 14:05:49 -04001045 static final int PLUGIN_SURFACE_READY = 195;
1046
Chris Craikd0051c02011-11-29 10:26:10 -08001047 static final int NOTIFY_ANIMATION_STARTED = 196;
1048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 // private message ids
1050 private static final int DESTROY = 200;
Cary Clarkd6982c92009-05-29 11:02:22 -04001051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 // Private handler for WebCore messages.
1053 private Handler mHandler;
1054 // Message queue for containing messages before the WebCore thread is
1055 // ready.
1056 private ArrayList<Message> mMessages = new ArrayList<Message>();
1057 // Flag for blocking messages. This is used during DESTROY to avoid
1058 // posting more messages to the EventHub or to WebView's event handler.
1059 private boolean mBlockMessages;
John Reck45576fa2011-09-01 11:45:35 -07001060 private boolean mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061
1062 private int mTid;
1063 private int mSavedPriority;
1064
1065 /**
1066 * Prevent other classes from creating an EventHub.
1067 */
1068 private EventHub() {}
1069
Leon Scroggins200c13d2010-05-14 15:35:42 -04001070 private static final int FIRST_PACKAGE_MSG_ID = REVEAL_SELECTION;
1071 private static final int LAST_PACKAGE_MSG_ID = VALID_NODE_BOUNDS;
1072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 /**
1074 * Transfer all messages to the newly created webcore thread handler.
1075 */
1076 private void transferMessages() {
1077 mTid = Process.myTid();
1078 mSavedPriority = Process.getThreadPriority(mTid);
1079
1080 mHandler = new Handler() {
1081 @Override
1082 public void handleMessage(Message msg) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001083 if (DebugFlags.WEB_VIEW_CORE) {
Leon Scroggins200c13d2010-05-14 15:35:42 -04001084 Log.v(LOGTAG, (msg.what < FIRST_PACKAGE_MSG_ID
1085 || msg.what > LAST_PACKAGE_MSG_ID
1086 ? Integer.toString(msg.what)
Leon Scroggins72543e12009-07-23 15:29:45 -04001087 : HandlerDebugString[msg.what
Leon Scroggins200c13d2010-05-14 15:35:42 -04001088 - FIRST_PACKAGE_MSG_ID])
Cary Clark243ea062009-06-25 10:49:32 -04001089 + " arg1=" + msg.arg1 + " arg2=" + msg.arg2
1090 + " obj=" + msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 }
John Reck45576fa2011-09-01 11:45:35 -07001092 if (mWebView == null || mNativeClass == 0) {
1093 if (DebugFlags.WEB_VIEW_CORE) {
1094 Log.w(LOGTAG, "Rejecting message " + msg.what
1095 + " because we are destroyed");
1096 }
1097 return;
1098 }
1099 if (mDestroying == true
John Reck00d5bf72011-07-21 09:46:17 -07001100 && msg.what != EventHub.RESUME_TIMERS
John Reck45576fa2011-09-01 11:45:35 -07001101 && msg.what != EventHub.PAUSE_TIMERS
1102 && msg.what != EventHub.DESTROY) {
John Reck00d5bf72011-07-21 09:46:17 -07001103 if (DebugFlags.WEB_VIEW_CORE) {
1104 Log.v(LOGTAG, "Rejecting message " + msg.what
John Reck45576fa2011-09-01 11:45:35 -07001105 + " because we are being destroyed");
John Reck00d5bf72011-07-21 09:46:17 -07001106 }
1107 return;
1108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 switch (msg.what) {
1110 case WEBKIT_DRAW:
1111 webkitDraw();
1112 break;
1113
Nicolas Roardfb7bc342010-11-01 15:08:03 -07001114 case WEBKIT_DRAW_LAYERS:
1115 webkitDrawLayers();
1116 break;
1117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 case DESTROY:
1119 // Time to take down the world. Cancel all pending
1120 // loads and destroy the native view and frame.
Cary Clark674a8442009-09-15 16:25:43 -04001121 synchronized (WebViewCore.this) {
1122 mBrowserFrame.destroy();
1123 mBrowserFrame = null;
Andrei Popescudee76be2009-09-22 18:28:21 +01001124 mSettings.onDestroyed();
Cary Clark674a8442009-09-15 16:25:43 -04001125 mNativeClass = 0;
Ben Murdoch3dba1e42009-09-22 15:50:30 +01001126 mWebView = null;
Cary Clark674a8442009-09-15 16:25:43 -04001127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 break;
1129
Leon Scroggins200c13d2010-05-14 15:35:42 -04001130 case REVEAL_SELECTION:
1131 nativeRevealSelection();
1132 break;
1133
Leon Scroggins3a503392010-01-06 17:04:38 -05001134 case REQUEST_LABEL:
1135 if (mWebView != null) {
1136 int nodePointer = msg.arg2;
1137 String label = nativeRequestLabel(msg.arg1,
1138 nodePointer);
1139 if (label != null && label.length() > 0) {
1140 Message.obtain(mWebView.mPrivateHandler,
1141 WebView.RETURN_LABEL, nodePointer,
1142 0, label).sendToTarget();
1143 }
1144 }
1145 break;
1146
Cary Clark77d98f42009-07-31 09:40:38 -04001147 case UPDATE_FRAME_CACHE_IF_LOADING:
1148 nativeUpdateFrameCacheIfLoading();
1149 break;
1150
Leon Scroggins72543e12009-07-23 15:29:45 -04001151 case SCROLL_TEXT_INPUT:
Leon Scroggins22e883d2011-01-31 10:54:19 -05001152 float xPercent;
1153 if (msg.obj == null) {
1154 xPercent = 0f;
1155 } else {
1156 xPercent = ((Float) msg.obj).floatValue();
1157 }
1158 nativeScrollFocusedTextInput(xPercent, msg.arg2);
Leon Scroggins72543e12009-07-23 15:29:45 -04001159 break;
1160
Grace Klobad0d9bc22010-01-26 18:08:28 -08001161 case LOAD_URL: {
Kristian Monsen85173052010-12-08 15:29:29 +00001162 CookieManager.getInstance().waitForCookieOperationsToComplete();
Grace Klobad0d9bc22010-01-26 18:08:28 -08001163 GetUrlData param = (GetUrlData) msg.obj;
1164 loadUrl(param.mUrl, param.mExtraHeaders);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 break;
Grace Klobad0d9bc22010-01-26 18:08:28 -08001166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167
Grace Kloba57534302009-05-22 18:55:02 -07001168 case POST_URL: {
Kristian Monsen85173052010-12-08 15:29:29 +00001169 CookieManager.getInstance().waitForCookieOperationsToComplete();
Cary Clarkded054c2009-06-15 10:26:08 -04001170 PostUrlData param = (PostUrlData) msg.obj;
1171 mBrowserFrame.postUrl(param.mUrl, param.mPostData);
Grace Kloba57534302009-05-22 18:55:02 -07001172 break;
1173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 case LOAD_DATA:
Kristian Monsen85173052010-12-08 15:29:29 +00001175 CookieManager.getInstance().waitForCookieOperationsToComplete();
Cary Clarkded054c2009-06-15 10:26:08 -04001176 BaseUrlData loadParams = (BaseUrlData) msg.obj;
1177 String baseUrl = loadParams.mBaseUrl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 if (baseUrl != null) {
1179 int i = baseUrl.indexOf(':');
1180 if (i > 0) {
Steve Blockae328572011-06-08 18:58:51 +01001181 // In 1.0, WebView.loadDataWithBaseURL() could access local
1182 // asset files using 'file' scheme URLs as long as the data is
1183 // valid. Later versions of WebKit have tightened the
1184 // restriction around when pages can access such local URLs.
1185 // To maintain compatibility with 1.0, we register the scheme of
1186 // the baseUrl to be considered local, as long as it is not
1187 // http(s)/ftp(s)/about/javascript.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 String scheme = baseUrl.substring(0, i);
1189 if (!scheme.startsWith("http") &&
1190 !scheme.startsWith("ftp") &&
1191 !scheme.startsWith("about") &&
1192 !scheme.startsWith("javascript")) {
1193 nativeRegisterURLSchemeAsLocal(scheme);
1194 }
1195 }
1196 }
1197 mBrowserFrame.loadData(baseUrl,
Cary Clarkded054c2009-06-15 10:26:08 -04001198 loadParams.mData,
1199 loadParams.mMimeType,
1200 loadParams.mEncoding,
Leon Scroggins1bb1a912010-03-23 15:39:46 -04001201 loadParams.mHistoryUrl);
John Reckfb2b9b22011-08-25 15:38:33 -07001202 nativeContentInvalidateAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 break;
1204
1205 case STOP_LOADING:
Cary Clarkd6982c92009-05-29 11:02:22 -04001206 // If the WebCore has committed the load, but not
1207 // finished the first layout yet, we need to set
1208 // first layout done to trigger the interpreted side sync
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 // up with native side
1210 if (mBrowserFrame.committed()
1211 && !mBrowserFrame.firstLayoutDone()) {
1212 mBrowserFrame.didFirstLayout();
1213 }
1214 // Do this after syncing up the layout state.
1215 stopLoading();
1216 break;
1217
1218 case RELOAD:
1219 mBrowserFrame.reload(false);
1220 break;
1221
1222 case KEY_DOWN:
1223 key((KeyEvent) msg.obj, true);
1224 break;
1225
1226 case KEY_UP:
1227 key((KeyEvent) msg.obj, false);
1228 break;
1229
Leon Scrogginsb45a2632011-01-12 14:11:24 -05001230 case FAKE_CLICK:
1231 nativeClick(msg.arg1, msg.arg2, true);
1232 break;
1233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 case CLICK:
Leon Scrogginsb45a2632011-01-12 14:11:24 -05001235 nativeClick(msg.arg1, msg.arg2, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 break;
1237
Grace Klobaef347ef2009-07-30 11:20:32 -07001238 case VIEW_SIZE_CHANGED: {
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001239 viewSizeChanged((WebView.ViewSizeData) msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 break;
Grace Klobaef347ef2009-07-30 11:20:32 -07001241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 case SET_SCROLL_OFFSET:
1243 // note: these are in document coordinates
1244 // (inv-zoom)
Cary Clarked56eda2009-06-18 09:48:47 -04001245 Point pt = (Point) msg.obj;
Patrick Scottfa8be1c2011-02-02 14:09:34 -05001246 nativeSetScrollOffset(msg.arg1, msg.arg2 == 1,
1247 pt.x, pt.y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 case SET_GLOBAL_BOUNDS:
1251 Rect r = (Rect) msg.obj;
1252 nativeSetGlobalBounds(r.left, r.top, r.width(),
1253 r.height());
1254 break;
1255
1256 case GO_BACK_FORWARD:
1257 // If it is a standard load and the load is not
1258 // committed yet, we interpret BACK as RELOAD
1259 if (!mBrowserFrame.committed() && msg.arg1 == -1 &&
Cary Clarkd6982c92009-05-29 11:02:22 -04001260 (mBrowserFrame.loadType() ==
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 BrowserFrame.FRAME_LOADTYPE_STANDARD)) {
1262 mBrowserFrame.reload(true);
1263 } else {
1264 mBrowserFrame.goBackOrForward(msg.arg1);
1265 }
1266 break;
1267
1268 case RESTORE_STATE:
1269 stopLoading();
1270 restoreState(msg.arg1);
1271 break;
1272
1273 case PAUSE_TIMERS:
1274 mSavedPriority = Process.getThreadPriority(mTid);
1275 Process.setThreadPriority(mTid,
1276 Process.THREAD_PRIORITY_BACKGROUND);
1277 pauseTimers();
Steve Block808751f2011-01-04 14:26:27 +00001278 if (!JniUtil.useChromiumHttpStack()) {
1279 WebViewWorker.getHandler().sendEmptyMessage(
1280 WebViewWorker.MSG_PAUSE_CACHE_TRANSACTION);
Kristian Monsen64decc62011-08-25 20:32:24 +01001281 } else {
1282 nativeCloseIdleConnections();
Steve Block808751f2011-01-04 14:26:27 +00001283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 break;
1285
1286 case RESUME_TIMERS:
1287 Process.setThreadPriority(mTid, mSavedPriority);
1288 resumeTimers();
Steve Block808751f2011-01-04 14:26:27 +00001289 if (!JniUtil.useChromiumHttpStack()) {
1290 WebViewWorker.getHandler().sendEmptyMessage(
1291 WebViewWorker.MSG_RESUME_CACHE_TRANSACTION);
1292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 break;
1294
Mike Reedd205d5b2009-05-27 11:02:29 -04001295 case ON_PAUSE:
1296 nativePause();
1297 break;
1298
1299 case ON_RESUME:
1300 nativeResume();
1301 break;
1302
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001303 case FREE_MEMORY:
1304 clearCache(false);
1305 nativeFreeMemory();
1306 break;
1307
Grace Klobaa72cc092009-04-02 08:50:17 -07001308 case SET_NETWORK_STATE:
1309 if (BrowserFrame.sJavaBridge == null) {
1310 throw new IllegalStateException("No WebView " +
1311 "has been created in this process!");
1312 }
1313 BrowserFrame.sJavaBridge
1314 .setNetworkOnLine(msg.arg1 == 1);
1315 break;
1316
Andrei Popescuf5dba882010-01-12 22:42:41 +00001317 case SET_NETWORK_TYPE:
1318 if (BrowserFrame.sJavaBridge == null) {
1319 throw new IllegalStateException("No WebView " +
1320 "has been created in this process!");
1321 }
1322 Map<String, String> map = (Map<String, String>) msg.obj;
1323 BrowserFrame.sJavaBridge
1324 .setNetworkType(map.get("type"), map.get("subtype"));
1325 break;
1326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 case CLEAR_CACHE:
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001328 clearCache(msg.arg1 == 1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 break;
1330
1331 case CLEAR_HISTORY:
1332 mCallbackProxy.getBackForwardList().
1333 close(mBrowserFrame.mNativeFrame);
1334 break;
1335
Cary Clarkd6982c92009-05-29 11:02:22 -04001336 case REPLACE_TEXT:
Cary Clarkded054c2009-06-15 10:26:08 -04001337 ReplaceTextData rep = (ReplaceTextData) msg.obj;
1338 nativeReplaceTextfieldText(msg.arg1, msg.arg2,
Leon Scroggins43488fc2009-07-06 14:32:49 -04001339 rep.mReplace, rep.mNewStart, rep.mNewEnd,
1340 rep.mTextGeneration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 break;
1342
1343 case PASS_TO_JS: {
Cary Clarkded054c2009-06-15 10:26:08 -04001344 JSKeyData jsData = (JSKeyData) msg.obj;
1345 KeyEvent evt = jsData.mEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 int keyCode = evt.getKeyCode();
1347 int keyValue = evt.getUnicodeChar();
1348 int generation = msg.arg1;
Cary Clark2f1d60c2009-06-03 08:05:53 -04001349 passToJs(generation,
Cary Clarkded054c2009-06-15 10:26:08 -04001350 jsData.mCurrentText,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 keyCode,
1352 keyValue,
1353 evt.isDown(),
1354 evt.isShiftPressed(), evt.isAltPressed(),
1355 evt.isSymPressed());
1356 break;
1357 }
1358
1359 case SAVE_DOCUMENT_STATE: {
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001360 CursorData cDat = (CursorData) msg.obj;
1361 nativeSaveDocumentState(cDat.mFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 break;
1363 }
1364
1365 case CLEAR_SSL_PREF_TABLE:
Kristian Monsend9151bf2011-09-14 16:29:23 +01001366 if (JniUtil.useChromiumHttpStack()) {
1367 // FIXME: This will not work for connections currently in use, as
1368 // they cache the certificate responses. See http://b/5324235.
1369 SslCertLookupTable.getInstance().clear();
1370 nativeCloseIdleConnections();
1371 } else {
1372 Network.getInstance(mContext).clearUserSslPrefTable();
1373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 break;
1375
1376 case TOUCH_UP:
1377 TouchUpData touchUpData = (TouchUpData) msg.obj;
Patrick Scottcfa734a2011-02-22 11:19:02 -05001378 if (touchUpData.mNativeLayer != 0) {
1379 nativeScrollLayer(touchUpData.mNativeLayer,
1380 touchUpData.mNativeLayerRect);
1381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 nativeTouchUp(touchUpData.mMoveGeneration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 touchUpData.mFrame, touchUpData.mNode,
Leon Scroggins22e883d2011-01-31 10:54:19 -05001384 touchUpData.mX, touchUpData.mY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 break;
1386
1387 case TOUCH_EVENT: {
1388 TouchEventData ted = (TouchEventData) msg.obj;
Huahui Wu41865f42010-09-02 13:41:41 -07001389 final int count = ted.mPoints.length;
1390 int[] xArray = new int[count];
1391 int[] yArray = new int[count];
1392 for (int c = 0; c < count; c++) {
1393 xArray[c] = ted.mPoints[c].x;
1394 yArray[c] = ted.mPoints[c].y;
1395 }
Patrick Scottcfa734a2011-02-22 11:19:02 -05001396 if (ted.mNativeLayer != 0) {
1397 nativeScrollLayer(ted.mNativeLayer,
1398 ted.mNativeLayerRect);
1399 }
Adam Powell4fb35d42011-03-03 17:54:55 -08001400 ted.mNativeResult = nativeHandleTouchEvent(ted.mAction, ted.mIds,
Huahui Wu2d3ef372011-03-13 18:13:42 -07001401 xArray, yArray, count, ted.mActionIndex, ted.mMetaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 Message.obtain(
1403 mWebView.mPrivateHandler,
Grace Klobac2242f22010-03-05 14:00:26 -08001404 WebView.PREVENT_TOUCH_ID,
1405 ted.mAction,
Adam Powell4fb35d42011-03-03 17:54:55 -08001406 ted.mNativeResult ? 1 : 0,
1407 ted).sendToTarget();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 break;
1409 }
1410
Leon Scroggins8cdad882009-06-30 08:47:04 -04001411 case SET_ACTIVE:
1412 nativeSetFocusControllerActive(msg.arg1 == 1);
Leon Scroggins63dda1c2009-04-15 13:25:00 -04001413 break;
1414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 case ADD_JS_INTERFACE:
Cary Clarkded054c2009-06-15 10:26:08 -04001416 JSInterfaceData jsData = (JSInterfaceData) msg.obj;
1417 mBrowserFrame.addJavascriptInterface(jsData.mObject,
1418 jsData.mInterfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 break;
1420
Steve Block689a3422010-12-07 18:18:26 +00001421 case REMOVE_JS_INTERFACE:
1422 jsData = (JSInterfaceData) msg.obj;
1423 mBrowserFrame.removeJavascriptInterface(
1424 jsData.mInterfaceName);
1425 break;
1426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 case REQUEST_EXT_REPRESENTATION:
1428 mBrowserFrame.externalRepresentation(
1429 (Message) msg.obj);
1430 break;
1431
1432 case REQUEST_DOC_AS_TEXT:
1433 mBrowserFrame.documentAsText((Message) msg.obj);
1434 break;
1435
Leon Scroggins47fabbf2009-12-08 16:57:26 -05001436 case SET_MOVE_FOCUS:
1437 CursorData focusData = (CursorData) msg.obj;
1438 nativeMoveFocus(focusData.mFrame, focusData.mNode);
1439 break;
1440
Cary Clarkd6982c92009-05-29 11:02:22 -04001441 case SET_MOVE_MOUSE:
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001442 CursorData cursorData = (CursorData) msg.obj;
1443 nativeMoveMouse(cursorData.mFrame,
Cary Clarked56eda2009-06-18 09:48:47 -04001444 cursorData.mX, cursorData.mY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 break;
1446
Cary Clarkd6982c92009-05-29 11:02:22 -04001447 case SET_MOVE_MOUSE_IF_LATEST:
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001448 CursorData cData = (CursorData) msg.obj;
1449 nativeMoveMouseIfLatest(cData.mMoveGeneration,
Cary Clarked56eda2009-06-18 09:48:47 -04001450 cData.mFrame,
1451 cData.mX, cData.mY);
Leon Scrogginsb6112132011-02-24 12:35:50 -05001452 if (msg.arg1 == 1) {
1453 nativeStopPaintingCaret();
1454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 break;
1456
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001457 case REQUEST_CURSOR_HREF: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 Message hrefMsg = (Message) msg.obj;
Ben Murdoch0a784a52009-11-17 18:13:02 +00001459 hrefMsg.getData().putString("url",
1460 nativeRetrieveHref(msg.arg1, msg.arg2));
1461 hrefMsg.getData().putString("title",
1462 nativeRetrieveAnchorText(msg.arg1, msg.arg2));
Cary Clark861368a2010-12-15 11:24:37 -05001463 hrefMsg.getData().putString("src",
1464 nativeRetrieveImageSource(msg.arg1, msg.arg2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 hrefMsg.sendToTarget();
1466 break;
1467 }
Cary Clarkd6982c92009-05-29 11:02:22 -04001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 case UPDATE_CACHE_AND_TEXT_ENTRY:
1470 nativeUpdateFrameCache();
1471 // FIXME: this should provide a minimal rectangle
1472 if (mWebView != null) {
1473 mWebView.postInvalidate();
1474 }
1475 sendUpdateTextEntry();
1476 break;
1477
1478 case DOC_HAS_IMAGES:
1479 Message imageResult = (Message) msg.obj;
1480 imageResult.arg1 =
1481 mBrowserFrame.documentHasImages() ? 1 : 0;
1482 imageResult.sendToTarget();
1483 break;
1484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 case DELETE_SELECTION:
Leon Scroggins6679f2f2009-08-12 18:48:10 -04001486 TextSelectionData deleteSelectionData
1487 = (TextSelectionData) msg.obj;
Leon Scroggins43488fc2009-07-06 14:32:49 -04001488 nativeDeleteSelection(deleteSelectionData.mStart,
Leon Scroggins6679f2f2009-08-12 18:48:10 -04001489 deleteSelectionData.mEnd, msg.arg1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 break;
1491
1492 case SET_SELECTION:
Cary Clark2f1d60c2009-06-03 08:05:53 -04001493 nativeSetSelection(msg.arg1, msg.arg2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001495
Svetoslav Ganovda355512010-05-12 22:04:44 -07001496 case MODIFY_SELECTION:
Svetoslav Ganovc93fb652011-01-05 18:52:05 -08001497 String modifiedSelectionString = nativeModifySelection(msg.arg1,
1498 msg.arg2);
Svetoslav Ganov585f13f8d2010-08-10 07:59:15 -07001499 mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED,
Svetoslav Ganovc93fb652011-01-05 18:52:05 -08001500 modifiedSelectionString).sendToTarget();
1501 break;
1502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 case LISTBOX_CHOICES:
1504 SparseBooleanArray choices = (SparseBooleanArray)
1505 msg.obj;
1506 int choicesSize = msg.arg1;
1507 boolean[] choicesArray = new boolean[choicesSize];
1508 for (int c = 0; c < choicesSize; c++) {
1509 choicesArray[c] = choices.get(c);
1510 }
Cary Clarkd6982c92009-05-29 11:02:22 -04001511 nativeSendListBoxChoices(choicesArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 choicesSize);
1513 break;
1514
1515 case SINGLE_LISTBOX_CHOICE:
1516 nativeSendListBoxChoice(msg.arg1);
1517 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 case SET_BACKGROUND_COLOR:
1520 nativeSetBackgroundColor(msg.arg1);
1521 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 case DUMP_DOMTREE:
1524 nativeDumpDomTree(msg.arg1 == 1);
1525 break;
1526
1527 case DUMP_RENDERTREE:
1528 nativeDumpRenderTree(msg.arg1 == 1);
1529 break;
1530
1531 case DUMP_NAVTREE:
1532 nativeDumpNavTree();
1533 break;
1534
Feng Qianb3081372009-06-29 15:55:18 -07001535 case SET_JS_FLAGS:
1536 nativeSetJsFlags((String)msg.obj);
Feng Qian706cee42009-08-03 16:01:42 -07001537 break;
Steve Block4faee092009-07-28 18:20:50 +01001538
Chris Craik555c55e2011-07-28 15:39:43 -07001539 case CONTENT_INVALIDATE_ALL:
1540 nativeContentInvalidateAll();
1541 break;
1542
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -07001543 case SAVE_WEBARCHIVE:
1544 WebView.SaveWebArchiveMessage saveMessage =
1545 (WebView.SaveWebArchiveMessage)msg.obj;
1546 saveMessage.mResultFile =
1547 saveWebArchive(saveMessage.mBasename, saveMessage.mAutoname);
1548 mWebView.mPrivateHandler.obtainMessage(
1549 WebView.SAVE_WEBARCHIVE_FINISHED, saveMessage).sendToTarget();
1550 break;
1551
Steve Block4faee092009-07-28 18:20:50 +01001552 case GEOLOCATION_PERMISSIONS_PROVIDE:
1553 GeolocationPermissionsData data =
1554 (GeolocationPermissionsData) msg.obj;
1555 nativeGeolocationPermissionsProvide(data.mOrigin,
1556 data.mAllow, data.mRemember);
Feng Qianb3081372009-06-29 15:55:18 -07001557 break;
1558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 case SPLIT_PICTURE_SET:
Grace Kloba8abd50b2010-07-08 15:02:14 -07001560 nativeSplitContent(msg.arg1);
1561 mWebView.mPrivateHandler.obtainMessage(
1562 WebView.REPLACE_BASE_CONTENT, msg.arg1, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 mSplitPictureIsScheduled = false;
1564 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 case CLEAR_CONTENT:
1567 // Clear the view so that onDraw() will draw nothing
1568 // but white background
1569 // (See public method WebView.clearView)
Ben Murdocha62b9632011-12-05 14:51:00 +00001570 clearContent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 break;
Grace Klobab3230cb2009-04-13 14:04:23 -07001572
1573 case MESSAGE_RELAY:
Patrick Scottfa8be1c2011-02-02 14:09:34 -05001574 ((Message) msg.obj).sendToTarget();
Grace Klobab3230cb2009-04-13 14:04:23 -07001575 break;
Leon Clarke194e3452009-09-28 11:42:12 +01001576
1577 case POPULATE_VISITED_LINKS:
1578 nativeProvideVisitedHistory((String[])msg.obj);
1579 break;
Cary Clark1cb97ee2009-12-11 12:10:36 -05001580
1581 case VALID_NODE_BOUNDS: {
1582 MotionUpData motionUpData = (MotionUpData) msg.obj;
Cary Clarkbad0c542010-01-11 14:58:21 -05001583 if (!nativeValidNodeAndBounds(
Cary Clark1cb97ee2009-12-11 12:10:36 -05001584 motionUpData.mFrame, motionUpData.mNode,
Cary Clarkbad0c542010-01-11 14:58:21 -05001585 motionUpData.mBounds)) {
1586 nativeUpdateFrameCache();
1587 }
Cary Clark1cb97ee2009-12-11 12:10:36 -05001588 Message message = mWebView.mPrivateHandler
1589 .obtainMessage(WebView.DO_MOTION_UP,
Cary Clarkbad0c542010-01-11 14:58:21 -05001590 motionUpData.mX, motionUpData.mY);
Cary Clark1cb97ee2009-12-11 12:10:36 -05001591 mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(
1592 message);
1593 break;
1594 }
Grace Kloba11438c32009-12-16 11:39:12 -08001595
1596 case HIDE_FULLSCREEN:
1597 nativeFullScreenPluginHidden(msg.arg1);
1598 break;
Andrei Popescua6d747d2010-02-11 13:19:21 +00001599
Derek Sollenberger281432c2011-08-22 14:05:49 -04001600 case PLUGIN_SURFACE_READY:
1601 nativePluginSurfaceReady();
1602 break;
1603
Chris Craikd0051c02011-11-29 10:26:10 -08001604 case NOTIFY_ANIMATION_STARTED:
1605 nativeNotifyAnimationStarted(mNativeClass);
1606 break;
1607
Andrei Popescua6d747d2010-02-11 13:19:21 +00001608 case ADD_PACKAGE_NAMES:
1609 if (BrowserFrame.sJavaBridge == null) {
1610 throw new IllegalStateException("No WebView " +
1611 "has been created in this process!");
1612 }
1613 BrowserFrame.sJavaBridge.addPackageNames(
1614 (Set<String>) msg.obj);
1615 break;
1616
Grace Kloba178db412010-05-18 22:22:23 -07001617 case GET_TOUCH_HIGHLIGHT_RECTS:
1618 TouchHighlightData d = (TouchHighlightData) msg.obj;
John Reck335f4542011-08-25 18:25:09 -07001619 if (d.mNativeLayer != 0) {
1620 nativeScrollLayer(d.mNativeLayer,
1621 d.mNativeLayerRect);
1622 }
Grace Kloba178db412010-05-18 22:22:23 -07001623 ArrayList<Rect> rects = nativeGetTouchHighlightRects
1624 (d.mX, d.mY, d.mSlop);
1625 mWebView.mPrivateHandler.obtainMessage(
1626 WebView.SET_TOUCH_HIGHLIGHT_RECTS, rects)
1627 .sendToTarget();
1628 break;
1629
Steve Block68dede32010-08-04 10:28:46 +01001630 case USE_MOCK_DEVICE_ORIENTATION:
1631 useMockDeviceOrientation();
1632 break;
Ben Murdoch62275a42010-09-07 11:27:28 +01001633
1634 case AUTOFILL_FORM:
1635 nativeAutoFillForm(msg.arg1);
Ben Murdoch961d55f2010-12-02 13:58:24 +00001636 mWebView.mPrivateHandler.obtainMessage(WebView.AUTOFILL_COMPLETE, null)
1637 .sendToTarget();
Ben Murdoch62275a42010-09-07 11:27:28 +01001638 break;
Narayan Kamath9497c5f2011-02-22 12:05:34 +00001639
1640 case EXECUTE_JS:
1641 if (msg.obj instanceof String) {
1642 if (DebugFlags.WEB_VIEW_CORE) {
1643 Log.d(LOGTAG, "Executing JS : " + msg.obj);
1644 }
1645 mBrowserFrame.stringByEvaluatingJavaScriptFromString((String) msg.obj);
1646 }
1647 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 }
1649 }
1650 };
1651 // Take all queued messages and resend them to the new handler.
1652 synchronized (this) {
1653 int size = mMessages.size();
1654 for (int i = 0; i < size; i++) {
1655 mHandler.sendMessage(mMessages.get(i));
1656 }
1657 mMessages = null;
1658 }
1659 }
1660
1661 /**
1662 * Send a message internally to the queue or to the handler
1663 */
1664 private synchronized void sendMessage(Message msg) {
1665 if (mBlockMessages) {
1666 return;
1667 }
1668 if (mMessages != null) {
1669 mMessages.add(msg);
1670 } else {
1671 mHandler.sendMessage(msg);
1672 }
1673 }
1674
1675 private synchronized void removeMessages(int what) {
1676 if (mBlockMessages) {
1677 return;
1678 }
1679 if (what == EventHub.WEBKIT_DRAW) {
1680 mDrawIsScheduled = false;
1681 }
1682 if (mMessages != null) {
Steve Block7b65a3e2011-08-30 13:52:51 +01001683 Throwable throwable = new Throwable(
1684 "EventHub.removeMessages(int what = " + what + ") is not supported " +
1685 "before the WebViewCore is set up.");
1686 Log.w(LOGTAG, Log.getStackTraceString(throwable));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 } else {
1688 mHandler.removeMessages(what);
1689 }
1690 }
1691
1692 private synchronized void sendMessageDelayed(Message msg, long delay) {
1693 if (mBlockMessages) {
1694 return;
1695 }
1696 mHandler.sendMessageDelayed(msg, delay);
1697 }
1698
1699 /**
1700 * Send a message internally to the front of the queue.
1701 */
1702 private synchronized void sendMessageAtFrontOfQueue(Message msg) {
1703 if (mBlockMessages) {
1704 return;
1705 }
1706 if (mMessages != null) {
1707 mMessages.add(0, msg);
1708 } else {
1709 mHandler.sendMessageAtFrontOfQueue(msg);
1710 }
1711 }
1712
1713 /**
1714 * Remove all the messages.
1715 */
1716 private synchronized void removeMessages() {
1717 // reset mDrawIsScheduled flag as WEBKIT_DRAW may be removed
1718 mDrawIsScheduled = false;
1719 mSplitPictureIsScheduled = false;
1720 if (mMessages != null) {
1721 mMessages.clear();
1722 } else {
1723 mHandler.removeCallbacksAndMessages(null);
1724 }
1725 }
1726
1727 /**
1728 * Block sending messages to the EventHub.
1729 */
1730 private synchronized void blockMessages() {
1731 mBlockMessages = true;
1732 }
1733 }
1734
1735 //-------------------------------------------------------------------------
1736 // Methods called by host activity (in the same thread)
1737 //-------------------------------------------------------------------------
1738
1739 void stopLoading() {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001740 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "CORE stopLoading");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001741 if (mBrowserFrame != null) {
1742 mBrowserFrame.stopLoading();
1743 }
1744 }
1745
1746 //-------------------------------------------------------------------------
1747 // Methods called by WebView
1748 // If it refers to local variable, it needs synchronized().
1749 // If it needs WebCore, it has to send message.
1750 //-------------------------------------------------------------------------
1751
Dounia Berrada940a1982011-04-27 13:53:13 -07001752 /**
1753 * @hide
1754 */
1755 public void sendMessage(Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 mEventHub.sendMessage(msg);
1757 }
1758
1759 void sendMessage(int what) {
1760 mEventHub.sendMessage(Message.obtain(null, what));
1761 }
1762
1763 void sendMessage(int what, Object obj) {
1764 mEventHub.sendMessage(Message.obtain(null, what, obj));
1765 }
1766
1767 void sendMessage(int what, int arg1) {
1768 // just ignore the second argument (make it 0)
1769 mEventHub.sendMessage(Message.obtain(null, what, arg1, 0));
1770 }
1771
1772 void sendMessage(int what, int arg1, int arg2) {
1773 mEventHub.sendMessage(Message.obtain(null, what, arg1, arg2));
1774 }
1775
1776 void sendMessage(int what, int arg1, Object obj) {
1777 // just ignore the second argument (make it 0)
1778 mEventHub.sendMessage(Message.obtain(null, what, arg1, 0, obj));
1779 }
1780
1781 void sendMessage(int what, int arg1, int arg2, Object obj) {
1782 mEventHub.sendMessage(Message.obtain(null, what, arg1, arg2, obj));
1783 }
1784
Cary Clark1cb97ee2009-12-11 12:10:36 -05001785 void sendMessageAtFrontOfQueue(int what, Object obj) {
1786 mEventHub.sendMessageAtFrontOfQueue(Message.obtain(
1787 null, what, obj));
1788 }
1789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 void sendMessageDelayed(int what, Object obj, long delay) {
1791 mEventHub.sendMessageDelayed(Message.obtain(null, what, obj), delay);
1792 }
1793
1794 void removeMessages(int what) {
1795 mEventHub.removeMessages(what);
1796 }
1797
1798 void removeMessages() {
1799 mEventHub.removeMessages();
1800 }
1801
1802 /**
John Reck00d5bf72011-07-21 09:46:17 -07001803 * Sends a DESTROY message to WebCore.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 * Called from UI thread.
1805 */
1806 void destroy() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 synchronized (mEventHub) {
John Reck00d5bf72011-07-21 09:46:17 -07001808 // Do not call removeMessages as then we risk removing PAUSE_TIMERS
1809 // or RESUME_TIMERS messages, which we must still handle as they
1810 // are per process. DESTROY will instead trigger a white list in
1811 // mEventHub, skipping any remaining messages in the queue
John Reck45576fa2011-09-01 11:45:35 -07001812 mEventHub.mDestroying = true;
1813 mEventHub.sendMessage(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 Message.obtain(null, EventHub.DESTROY));
1815 mEventHub.blockMessages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
1817 }
1818
1819 //-------------------------------------------------------------------------
1820 // WebViewCore private methods
1821 //-------------------------------------------------------------------------
1822
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001823 private void clearCache(boolean includeDiskFiles) {
1824 mBrowserFrame.clearCache();
Kristian Monsencedb3a72011-01-20 12:42:16 +00001825 if (includeDiskFiles) {
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001826 CacheManager.removeAllCacheFiles();
1827 }
1828 }
1829
Grace Klobad0d9bc22010-01-26 18:08:28 -08001830 private void loadUrl(String url, Map<String, String> extraHeaders) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001831 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, " CORE loadUrl " + url);
Grace Klobad0d9bc22010-01-26 18:08:28 -08001832 mBrowserFrame.loadUrl(url, extraHeaders);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 }
1834
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -07001835 private String saveWebArchive(String filename, boolean autoname) {
1836 if (DebugFlags.WEB_VIEW_CORE) {
1837 Log.v(LOGTAG, " CORE saveWebArchive " + filename + " " + autoname);
1838 }
1839 return mBrowserFrame.saveWebArchive(filename, autoname);
1840 }
1841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 private void key(KeyEvent evt, boolean isDown) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001843 if (DebugFlags.WEB_VIEW_CORE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844 Log.v(LOGTAG, "CORE key at " + System.currentTimeMillis() + ", "
1845 + evt);
1846 }
Leon Scrogginse3225672009-06-03 15:53:13 -04001847 int keyCode = evt.getKeyCode();
Derek Sollenbergerff0f9732010-08-06 11:50:49 -04001848 int unicodeChar = evt.getUnicodeChar();
1849
1850 if (keyCode == KeyEvent.KEYCODE_UNKNOWN && evt.getCharacters() != null
1851 && evt.getCharacters().length() > 0) {
1852 // we should only receive individual complex characters
1853 unicodeChar = evt.getCharacters().codePointAt(0);
1854 }
1855
1856 if (!nativeKey(keyCode, unicodeChar, evt.getRepeatCount(), evt.isShiftPressed(),
1857 evt.isAltPressed(), evt.isSymPressed(),
Leon Scrogginse3225672009-06-03 15:53:13 -04001858 isDown) && keyCode != KeyEvent.KEYCODE_ENTER) {
Cary Clark215b72c2009-06-26 14:38:43 -04001859 if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
1860 && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
1861 if (DebugFlags.WEB_VIEW_CORE) {
Leon Scroggins9ab32b62010-05-03 14:19:50 +01001862 Log.v(LOGTAG, "key: arrow unused by page: " + keyCode);
Cary Clark215b72c2009-06-26 14:38:43 -04001863 }
1864 if (mWebView != null && evt.isDown()) {
1865 Message.obtain(mWebView.mPrivateHandler,
Leon Scroggins9ab32b62010-05-03 14:19:50 +01001866 WebView.UNHANDLED_NAV_KEY, keyCode,
1867 0).sendToTarget();
Cary Clark215b72c2009-06-26 14:38:43 -04001868 }
1869 return;
1870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 // bubble up the event handling
Leon Scrogginse3225672009-06-03 15:53:13 -04001872 // but do not bubble up the ENTER key, which would open the search
1873 // bar without any text.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874 mCallbackProxy.onUnhandledKeyEvent(evt);
1875 }
1876 }
1877
1878 // These values are used to avoid requesting a layout based on old values
1879 private int mCurrentViewWidth = 0;
1880 private int mCurrentViewHeight = 0;
Grace Klobaef347ef2009-07-30 11:20:32 -07001881 private float mCurrentViewScale = 1.0f;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 // notify webkit that our virtual view size changed size (after inv-zoom)
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001884 private void viewSizeChanged(WebView.ViewSizeData data) {
1885 int w = data.mWidth;
1886 int h = data.mHeight;
1887 int textwrapWidth = data.mTextWrapWidth;
1888 float scale = data.mScale;
Grace Klobaef347ef2009-07-30 11:20:32 -07001889 if (DebugFlags.WEB_VIEW_CORE) {
1890 Log.v(LOGTAG, "viewSizeChanged w=" + w + "; h=" + h
1891 + "; textwrapWidth=" + textwrapWidth + "; scale=" + scale);
1892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 if (w == 0) {
1894 Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
1895 return;
1896 }
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07001897 int width = calculateWindowWidth(w);
Shimeng (Simon) Wanga0cc8642011-02-03 10:24:03 -08001898 int height = h;
1899 if (width != w) {
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001900 float heightWidthRatio = data.mHeightWidthRatio;
Shimeng (Simon) Wanga0cc8642011-02-03 10:24:03 -08001901 float ratio = (heightWidthRatio > 0) ? heightWidthRatio : (float) h / w;
1902 height = Math.round(ratio * width);
1903 }
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001904 nativeSetSize(width, height, textwrapWidth, scale, w,
1905 data.mActualViewHeight > 0 ? data.mActualViewHeight : h,
1906 data.mAnchorX, data.mAnchorY, data.mIgnoreHeight);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 // Remember the current width and height
1908 boolean needInvalidate = (mCurrentViewWidth == 0);
1909 mCurrentViewWidth = w;
1910 mCurrentViewHeight = h;
Grace Klobaef347ef2009-07-30 11:20:32 -07001911 mCurrentViewScale = scale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 if (needInvalidate) {
1913 // ensure {@link #webkitDraw} is called as we were blocking in
1914 // {@link #contentDraw} when mCurrentViewWidth is 0
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001915 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "viewSizeChanged");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 contentDraw();
1917 }
1918 mEventHub.sendMessage(Message.obtain(null,
1919 EventHub.UPDATE_CACHE_AND_TEXT_ENTRY));
1920 }
1921
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001922 // Calculate width to be used in webkit window.
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07001923 private int calculateWindowWidth(int viewWidth) {
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001924 int width = viewWidth;
1925 if (mSettings.getUseWideViewPort()) {
1926 if (mViewportWidth == -1) {
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07001927 // Fixed viewport width.
1928 width = WebView.DEFAULT_VIEWPORT_WIDTH;
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001929 } else if (mViewportWidth > 0) {
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07001930 // Use website specified or desired fixed viewport width.
1931 width = mViewportWidth;
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001932 } else {
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07001933 // For mobile web site.
Shimeng (Simon) Wang82a07702011-06-09 15:57:11 -07001934 width = Math.round(mWebView.getViewWidth() / mWebView.getDefaultZoomScale());
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001935 }
1936 }
1937 return width;
1938 }
1939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 private void sendUpdateTextEntry() {
1941 if (mWebView != null) {
1942 Message.obtain(mWebView.mPrivateHandler,
1943 WebView.UPDATE_TEXT_ENTRY_MSG_ID).sendToTarget();
1944 }
1945 }
1946
Andrei Popescu59e2ad92009-07-28 13:38:06 +01001947 // Utility method for exceededDatabaseQuota and reachedMaxAppCacheSize
1948 // callbacks. Computes the sum of database quota for all origins.
1949 private long getUsedQuota() {
1950 WebStorage webStorage = WebStorage.getInstance();
Nicolas Roard6c24b4d2009-09-22 18:44:52 +01001951 Collection<WebStorage.Origin> origins = webStorage.getOriginsSync();
1952
Andrei Popescu59e2ad92009-07-28 13:38:06 +01001953 if (origins == null) {
1954 return 0;
1955 }
1956 long usedQuota = 0;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +01001957 for (WebStorage.Origin website : origins) {
1958 usedQuota += website.getQuota();
Andrei Popescu59e2ad92009-07-28 13:38:06 +01001959 }
1960 return usedQuota;
1961 }
1962
Grace Kloba8abd50b2010-07-08 15:02:14 -07001963 // called from UI thread
1964 void splitContent(int content) {
1965 if (!mSplitPictureIsScheduled) {
1966 mSplitPictureIsScheduled = true;
1967 sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
1968 }
1969 }
1970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 // Used to avoid posting more than one draw message.
1972 private boolean mDrawIsScheduled;
Nicolas Roardfb7bc342010-11-01 15:08:03 -07001973 private boolean mDrawLayersIsScheduled;
Cary Clarkd6982c92009-05-29 11:02:22 -04001974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001975 // Used to avoid posting more than one split picture message.
1976 private boolean mSplitPictureIsScheduled;
1977
Grace Klobaa7bc87c2010-01-29 14:56:25 -08001978 // Used to suspend drawing.
1979 private boolean mDrawIsPaused;
1980
Derek Sollenbergerb983c892010-06-28 08:38:28 -04001981 // mInitialViewState is set by didFirstLayout() and then reset in the
1982 // next webkitDraw after passing the state to the UI thread.
1983 private ViewState mInitialViewState = null;
Shimeng (Simon) Wang72a1d2e2011-06-30 13:36:53 -07001984 private boolean mFirstLayoutForNonStandardLoad;
Grace Klobaef347ef2009-07-30 11:20:32 -07001985
Derek Sollenbergerb983c892010-06-28 08:38:28 -04001986 static class ViewState {
Grace Klobaef347ef2009-07-30 11:20:32 -07001987 float mMinScale;
1988 float mMaxScale;
1989 float mViewScale;
1990 float mTextWrapScale;
Grace Kloba408cf852009-09-20 16:34:44 -07001991 float mDefaultScale;
Grace Klobaef347ef2009-07-30 11:20:32 -07001992 int mScrollX;
1993 int mScrollY;
Leon Scrogginsb2359262009-08-19 16:19:26 -04001994 boolean mMobileSite;
Shimeng (Simon) Wang96fcb872010-11-24 16:01:12 -08001995 boolean mIsRestored;
George Mounte263bc12011-10-31 13:49:03 -07001996 boolean mShouldStartScrolledRight;
Grace Klobaef347ef2009-07-30 11:20:32 -07001997 }
1998
1999 static class DrawData {
2000 DrawData() {
Grace Kloba8abd50b2010-07-08 15:02:14 -07002001 mBaseLayer = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002002 mInvalRegion = new Region();
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04002003 mContentSize = new Point();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 }
Grace Kloba8abd50b2010-07-08 15:02:14 -07002005 int mBaseLayer;
Grace Klobaef347ef2009-07-30 11:20:32 -07002006 Region mInvalRegion;
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04002007 // view size that was used by webkit during the most recent layout
2008 Point mViewSize;
2009 Point mContentSize;
Grace Kloba188bf8d2010-04-07 11:30:19 -07002010 int mMinPrefWidth;
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002011 // only non-null if it is for the first picture set after the first layout
2012 ViewState mViewState;
Shimeng (Simon) Wang72a1d2e2011-06-30 13:36:53 -07002013 boolean mFirstLayoutForNonStandardLoad;
Cary Clark5da9aeb2009-10-06 17:40:53 -04002014 boolean mFocusSizeChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 }
Cary Clarkd6982c92009-05-29 11:02:22 -04002016
Nicolas Roarddc221e02011-10-04 17:57:59 -07002017 DrawData mLastDrawData = null;
2018
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002019 // Only update the layers' content, not the base surface
2020 // PictureSet.
2021 private void webkitDrawLayers() {
2022 mDrawLayersIsScheduled = false;
Nicolas Roarddc221e02011-10-04 17:57:59 -07002023 if (mDrawIsScheduled || mLastDrawData == null) {
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002024 removeMessages(EventHub.WEBKIT_DRAW);
2025 webkitDraw();
2026 return;
2027 }
Nicolas Roarddc221e02011-10-04 17:57:59 -07002028 // Directly update the layers we last passed to the UI side
Chris Craikd0051c02011-11-29 10:26:10 -08002029 if (nativeUpdateLayers(mNativeClass, mLastDrawData.mBaseLayer)) {
Nicolas Roarddc221e02011-10-04 17:57:59 -07002030 // If anything more complex than position has been touched, let's do a full draw
2031 webkitDraw();
Nicolas Roarddc221e02011-10-04 17:57:59 -07002032 }
Nicolas Roarddee7b1b2011-10-06 17:12:40 -07002033 mWebView.mPrivateHandler.removeMessages(WebView.INVAL_RECT_MSG_ID);
2034 mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(mWebView.mPrivateHandler
2035 .obtainMessage(WebView.INVAL_RECT_MSG_ID));
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002036 }
2037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 private void webkitDraw() {
2039 mDrawIsScheduled = false;
2040 DrawData draw = new DrawData();
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04002041 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start");
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04002042 draw.mBaseLayer = nativeRecordContent(draw.mInvalRegion, draw.mContentSize);
Grace Kloba8abd50b2010-07-08 15:02:14 -07002043 if (draw.mBaseLayer == 0) {
John Reck1c1e6df2011-06-24 11:07:09 -07002044 if (mWebView != null && !mWebView.isPaused()) {
2045 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort, resending draw message");
2046 mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
2047 } else {
2048 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort, webview paused");
2049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002050 return;
2051 }
Nicolas Roarddc221e02011-10-04 17:57:59 -07002052 mLastDrawData = draw;
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002053 webkitDraw(draw);
2054 }
2055
2056 private void webkitDraw(DrawData draw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002057 if (mWebView != null) {
Cary Clark5da9aeb2009-10-06 17:40:53 -04002058 draw.mFocusSizeChanged = nativeFocusBoundsChanged();
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04002059 draw.mViewSize = new Point(mCurrentViewWidth, mCurrentViewHeight);
Grace Kloba188bf8d2010-04-07 11:30:19 -07002060 if (mSettings.getUseWideViewPort()) {
2061 draw.mMinPrefWidth = Math.max(
2062 mViewportWidth == -1 ? WebView.DEFAULT_VIEWPORT_WIDTH
2063 : (mViewportWidth == 0 ? mCurrentViewWidth
2064 : mViewportWidth),
2065 nativeGetContentMinPrefWidth());
2066 }
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002067 if (mInitialViewState != null) {
2068 draw.mViewState = mInitialViewState;
2069 mInitialViewState = null;
Grace Klobaef347ef2009-07-30 11:20:32 -07002070 }
Shimeng (Simon) Wang72a1d2e2011-06-30 13:36:53 -07002071 if (mFirstLayoutForNonStandardLoad) {
2072 draw.mFirstLayoutForNonStandardLoad = true;
2073 mFirstLayoutForNonStandardLoad = false;
2074 }
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04002075 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 Message.obtain(mWebView.mPrivateHandler,
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -07002077 WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 }
2079 }
2080
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002081 static void reducePriority() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002082 // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
2083 sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);
2084 sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY);
2085 sWebCoreHandler.sendMessageAtFrontOfQueue(sWebCoreHandler
2086 .obtainMessage(WebCoreThread.REDUCE_PRIORITY));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 }
2088
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002089 static void resumePriority() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
2091 sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);
2092 sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY);
2093 sWebCoreHandler.sendMessageAtFrontOfQueue(sWebCoreHandler
2094 .obtainMessage(WebCoreThread.RESUME_PRIORITY));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002095 }
2096
Kristian Monsend4819a72010-12-16 17:42:57 +00002097 static void sendStaticMessage(int messageType, Object argument) {
2098 if (sWebCoreHandler == null)
2099 return;
2100
2101 sWebCoreHandler.sendMessage(sWebCoreHandler.obtainMessage(messageType, argument));
2102 }
2103
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002104 static void pauseUpdatePicture(WebViewCore core) {
2105 // Note: there is one possible failure mode. If pauseUpdatePicture() is
2106 // called from UI thread while WEBKIT_DRAW is just pulled out of the
2107 // queue in WebCore thread to be executed. Then update won't be blocked.
2108 if (core != null) {
Grace Klobaf9b731d2010-06-21 19:23:57 -07002109 if (!core.getSettings().enableSmoothTransition()) return;
2110
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002111 synchronized (core) {
John Reck2f4d30a2011-09-13 15:50:41 -07002112 if (core.mNativeClass == 0) {
2113 Log.w(LOGTAG, "Cannot pauseUpdatePicture, core destroyed or not initialized!");
2114 return;
2115 }
Chris Craik58d94af2011-08-18 11:42:13 -07002116 core.nativeSetIsPaused(true);
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002117 core.mDrawIsPaused = true;
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002118 }
2119 }
2120
2121 }
2122
2123 static void resumeUpdatePicture(WebViewCore core) {
2124 if (core != null) {
Grace Klobaf9b731d2010-06-21 19:23:57 -07002125 // if mDrawIsPaused is true, ignore the setting, continue to resume
Chris Craik58d94af2011-08-18 11:42:13 -07002126 if (!core.mDrawIsPaused)
2127 return;
Grace Klobaf9b731d2010-06-21 19:23:57 -07002128
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002129 synchronized (core) {
John Reck2f4d30a2011-09-13 15:50:41 -07002130 if (core.mNativeClass == 0) {
2131 Log.w(LOGTAG, "Cannot resumeUpdatePicture, core destroyed!");
2132 return;
2133 }
Chris Craik58d94af2011-08-18 11:42:13 -07002134 core.nativeSetIsPaused(false);
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002135 core.mDrawIsPaused = false;
Cary Clark75796bb2010-08-24 14:59:58 -04002136 // always redraw on resume to reenable gif animations
2137 core.mDrawIsScheduled = false;
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002138 }
2139 }
2140 }
2141
Adam Powelle00e8a782011-09-11 17:48:42 -07002142 static boolean isUpdatePicturePaused(WebViewCore core) {
2143 return core != null ? core.mDrawIsPaused : false;
2144 }
2145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 //////////////////////////////////////////////////////////////////////////
2147
2148 private void restoreState(int index) {
2149 WebBackForwardList list = mCallbackProxy.getBackForwardList();
2150 int size = list.getSize();
2151 for (int i = 0; i < size; i++) {
2152 list.getItemAtIndex(i).inflate(mBrowserFrame.mNativeFrame);
2153 }
2154 mBrowserFrame.mLoadInitFromJava = true;
2155 list.restoreIndex(mBrowserFrame.mNativeFrame, index);
2156 mBrowserFrame.mLoadInitFromJava = false;
2157 }
2158
2159 //-------------------------------------------------------------------------
2160 // Implement abstract methods in WebViewCore, native WebKit callback part
2161 //-------------------------------------------------------------------------
2162
2163 // called from JNI or WebView thread
2164 /* package */ void contentDraw() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 synchronized (this) {
John Reck00d5bf72011-07-21 09:46:17 -07002166 if (mWebView == null || mBrowserFrame == null) {
2167 // We were destroyed
2168 return;
2169 }
2170 // don't update the Picture until we have an initial width and finish
2171 // the first layout
2172 if (mCurrentViewWidth == 0 || !mBrowserFrame.firstLayoutDone()) {
2173 return;
2174 }
2175 // only fire an event if this is our first request
Grace Kloba3f40bd42009-12-07 14:47:28 -08002176 if (mDrawIsScheduled) return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177 mDrawIsScheduled = true;
2178 mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
2179 }
2180 }
Cary Clarkd6982c92009-05-29 11:02:22 -04002181
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002182 // called from JNI
2183 void layersDraw() {
2184 synchronized (this) {
2185 if (mDrawLayersIsScheduled) return;
2186 mDrawLayersIsScheduled = true;
2187 mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW_LAYERS));
2188 }
2189 }
2190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002191 // called by JNI
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002192 private void contentScrollTo(int x, int y, boolean animate,
2193 boolean onlyIfImeIsShowing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002194 if (!mBrowserFrame.firstLayoutDone()) {
2195 /*
2196 * WebKit restore state will be called before didFirstLayout(),
2197 * remember the position as it has to be applied after restoring
2198 * zoom factor which is controlled by screenWidth.
2199 */
2200 mRestoredX = x;
2201 mRestoredY = y;
2202 return;
2203 }
2204 if (mWebView != null) {
Grace Klobab3230cb2009-04-13 14:04:23 -07002205 Message msg = Message.obtain(mWebView.mPrivateHandler,
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002206 WebView.SCROLL_TO_MSG_ID, animate ? 1 : 0,
2207 onlyIfImeIsShowing ? 1 : 0, new Point(x, y));
Grace Klobab3230cb2009-04-13 14:04:23 -07002208 if (mDrawIsScheduled) {
2209 mEventHub.sendMessage(Message.obtain(null,
2210 EventHub.MESSAGE_RELAY, msg));
2211 } else {
2212 msg.sendToTarget();
2213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 }
2215 }
2216
2217 // called by JNI
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 private void sendNotifyProgressFinished() {
2219 sendUpdateTextEntry();
Steve Block808751f2011-01-04 14:26:27 +00002220 if (!JniUtil.useChromiumHttpStack()) {
2221 // as CacheManager can behave based on database transaction, we need to
2222 // call tick() to trigger endTransaction
2223 WebViewWorker.getHandler().removeMessages(
2224 WebViewWorker.MSG_CACHE_TRANSACTION_TICKER);
2225 WebViewWorker.getHandler().sendEmptyMessage(
2226 WebViewWorker.MSG_CACHE_TRANSACTION_TICKER);
2227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 contentDraw();
2229 }
2230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 /* Called by JNI. The coordinates are in doc coordinates, so they need to
2232 be scaled before they can be used by the view system, which happens
2233 in WebView since it (and its thread) know the current scale factor.
2234 */
2235 private void sendViewInvalidate(int left, int top, int right, int bottom) {
2236 if (mWebView != null) {
2237 Message.obtain(mWebView.mPrivateHandler,
2238 WebView.INVAL_RECT_MSG_ID,
2239 new Rect(left, top, right, bottom)).sendToTarget();
2240 }
2241 }
2242
Nicolas Roard38863332010-01-04 19:30:55 +00002243 private static boolean mRepaintScheduled = false;
2244
2245 /*
2246 * Called by the WebView thread
2247 */
2248 /* package */ void signalRepaintDone() {
2249 mRepaintScheduled = false;
2250 }
2251
Steve Block85aa9442011-09-28 12:20:12 +01002252 // Gets the WebView corresponding to this WebViewCore. Note that the
2253 // WebView object must only be used on the UI thread.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 /* package */ WebView getWebView() {
2255 return mWebView;
2256 }
2257
2258 private native void setViewportSettingsFromNative();
Cary Clarkd6982c92009-05-29 11:02:22 -04002259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 // called by JNI
Grace Kloba45dee412009-04-06 10:47:26 -07002261 private void didFirstLayout(boolean standardLoad) {
Grace Klobaef347ef2009-07-30 11:20:32 -07002262 if (DebugFlags.WEB_VIEW_CORE) {
2263 Log.v(LOGTAG, "didFirstLayout standardLoad =" + standardLoad);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 }
2265
2266 mBrowserFrame.didFirstLayout();
2267
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002268 if (mWebView == null) return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269
Mangesh Ghiwaref0e96d52011-10-26 17:23:54 -07002270 boolean updateViewState = standardLoad || mIsRestored;
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002271 setupViewport(updateViewState);
Grace Kloba9a67c822009-12-20 11:33:58 -08002272 // if updateRestoreState is true, ViewManager.postReadyToDrawAll() will
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002273 // be called after the WebView updates its state. If updateRestoreState
Grace Kloba9a67c822009-12-20 11:33:58 -08002274 // is false, start to draw now as it is ready.
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002275 if (!updateViewState) {
Grace Kloba9a67c822009-12-20 11:33:58 -08002276 mWebView.mViewManager.postReadyToDrawAll();
2277 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002278
Grace Kloba178db412010-05-18 22:22:23 -07002279 // remove the touch highlight when moving to a new page
John Reck335f4542011-08-25 18:25:09 -07002280 if (WebView.USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
2281 mWebView.mPrivateHandler.sendEmptyMessage(
2282 WebView.SET_TOUCH_HIGHLIGHT_RECTS);
Grace Kloba178db412010-05-18 22:22:23 -07002283 }
2284
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002285 // reset the scroll position, the restored offset and scales
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002286 mRestoredX = mRestoredY = 0;
Mangesh Ghiwaref0e96d52011-10-26 17:23:54 -07002287 mIsRestored = false;
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002288 mRestoredScale = mRestoredTextWrapScale = 0;
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002289 }
2290
2291 // called by JNI
2292 private void updateViewport() {
Shimeng (Simon) Wang56bd4342011-07-07 15:26:22 -07002293 // Update viewport asap to make sure we get correct one.
2294 setupViewport(true);
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002295 }
2296
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002297 private void setupViewport(boolean updateViewState) {
John Reckd4324aa2011-07-08 11:22:38 -07002298 if (mWebView == null || mSettings == null) {
2299 // We've been destroyed or are being destroyed, return early
2300 return;
2301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 // set the viewport settings from WebKit
2303 setViewportSettingsFromNative();
2304
Mangesh Ghiwareca4d54c2011-10-31 14:41:38 -07002305 // clamp initial scale
2306 if (mViewportInitialScale > 0) {
2307 if (mViewportMinimumScale > 0) {
2308 mViewportInitialScale = Math.max(mViewportInitialScale,
2309 mViewportMinimumScale);
2310 }
2311 if (mViewportMaximumScale > 0) {
2312 mViewportInitialScale = Math.min(mViewportInitialScale,
2313 mViewportMaximumScale);
2314 }
2315 }
2316
John Reck7818aaa2011-04-26 16:57:46 -07002317 if (mSettings.forceUserScalable()) {
2318 mViewportUserScalable = true;
2319 if (mViewportInitialScale > 0) {
2320 if (mViewportMinimumScale > 0) {
2321 mViewportMinimumScale = Math.min(mViewportMinimumScale,
2322 mViewportInitialScale / 2);
2323 }
2324 if (mViewportMaximumScale > 0) {
2325 mViewportMaximumScale = Math.max(mViewportMaximumScale,
2326 mViewportInitialScale * 2);
2327 }
2328 } else {
2329 if (mViewportMinimumScale > 0) {
2330 mViewportMinimumScale = Math.min(mViewportMinimumScale, 50);
2331 }
2332 if (mViewportMaximumScale > 0) {
2333 mViewportMaximumScale = Math.max(mViewportMaximumScale, 200);
2334 }
2335 }
2336 }
2337
Grace Kloba408cf852009-09-20 16:34:44 -07002338 // adjust the default scale to match the densityDpi
2339 float adjust = 1.0f;
2340 if (mViewportDensityDpi == -1) {
Derek Sollenberger03e48912010-05-18 17:03:42 -04002341 // convert default zoom scale to a integer (percentage) to avoid any
2342 // issues with floating point comparisons
2343 if (mWebView != null && (int)(mWebView.getDefaultZoomScale() * 100) != 100) {
2344 adjust = mWebView.getDefaultZoomScale();
Grace Kloba0d8b77c2009-06-25 11:20:51 -07002345 }
Grace Kloba408cf852009-09-20 16:34:44 -07002346 } else if (mViewportDensityDpi > 0) {
2347 adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
2348 / mViewportDensityDpi;
2349 }
Mangesh Ghiwaree832b632011-11-16 11:46:39 -08002350 if (adjust != mWebView.getDefaultZoomScale()) {
Mangesh Ghiware31f263d2011-11-21 16:54:20 -08002351 Message.obtain(mWebView.mPrivateHandler,
2352 WebView.UPDATE_ZOOM_DENSITY, adjust).sendToTarget();
Mangesh Ghiwaree832b632011-11-16 11:46:39 -08002353 }
Grace Kloba408cf852009-09-20 16:34:44 -07002354 int defaultScale = (int) (adjust * 100);
2355
2356 if (mViewportInitialScale > 0) {
2357 mViewportInitialScale *= adjust;
2358 }
2359 if (mViewportMinimumScale > 0) {
2360 mViewportMinimumScale *= adjust;
2361 }
2362 if (mViewportMaximumScale > 0) {
2363 mViewportMaximumScale *= adjust;
Grace Kloba0d8b77c2009-06-25 11:20:51 -07002364 }
2365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 // infer the values if they are not defined.
2367 if (mViewportWidth == 0) {
2368 if (mViewportInitialScale == 0) {
Grace Kloba408cf852009-09-20 16:34:44 -07002369 mViewportInitialScale = defaultScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 }
2372 if (mViewportUserScalable == false) {
Grace Kloba408cf852009-09-20 16:34:44 -07002373 mViewportInitialScale = defaultScale;
2374 mViewportMinimumScale = defaultScale;
2375 mViewportMaximumScale = defaultScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 }
Grace Klobaf53c1862009-09-21 16:26:11 -07002377 if (mViewportMinimumScale > mViewportInitialScale
2378 && mViewportInitialScale != 0) {
2379 mViewportMinimumScale = mViewportInitialScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 }
Grace Klobaf53c1862009-09-21 16:26:11 -07002381 if (mViewportMaximumScale > 0
2382 && mViewportMaximumScale < mViewportInitialScale) {
2383 mViewportMaximumScale = mViewportInitialScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 }
Grace Kloba408cf852009-09-20 16:34:44 -07002385 if (mViewportWidth < 0 && mViewportInitialScale == defaultScale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 mViewportWidth = 0;
2387 }
2388
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002389 // if mViewportWidth is 0, it means device-width, always update.
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002390 if (mViewportWidth != 0 && !updateViewState) {
Shimeng (Simon) Wang72a1d2e2011-06-30 13:36:53 -07002391 // For non standard load, since updateViewState will be false.
2392 mFirstLayoutForNonStandardLoad = true;
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002393 ViewState viewState = new ViewState();
2394 viewState.mMinScale = mViewportMinimumScale / 100.0f;
2395 viewState.mMaxScale = mViewportMaximumScale / 100.0f;
2396 viewState.mDefaultScale = adjust;
Grace Kloba769ed212010-01-27 10:52:47 -08002397 // as mViewportWidth is not 0, it is not mobile site.
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002398 viewState.mMobileSite = false;
Grace Kloba188bf8d2010-04-07 11:30:19 -07002399 // for non-mobile site, we don't need minPrefWidth, set it as 0
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002400 viewState.mScrollX = 0;
George Mounte263bc12011-10-31 13:49:03 -07002401 viewState.mShouldStartScrolledRight = false;
Grace Kloba769ed212010-01-27 10:52:47 -08002402 Message.obtain(mWebView.mPrivateHandler,
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002403 WebView.UPDATE_ZOOM_RANGE, viewState).sendToTarget();
Grace Kloba769ed212010-01-27 10:52:47 -08002404 return;
2405 }
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 // now notify webview
Grace Kloba6ed525e2009-09-17 15:31:12 -07002408 // webViewWidth refers to the width in the view system
2409 int webViewWidth;
2410 // viewportWidth refers to the width in the document system
2411 int viewportWidth = mCurrentViewWidth;
2412 if (viewportWidth == 0) {
2413 // this may happen when WebView just starts. This is not perfect as
2414 // we call WebView method from WebCore thread. But not perfect
2415 // reference is better than no reference.
2416 webViewWidth = mWebView.getViewWidth();
Grace Kloba408cf852009-09-20 16:34:44 -07002417 viewportWidth = (int) (webViewWidth / adjust);
Grace Kloba6ed525e2009-09-17 15:31:12 -07002418 if (viewportWidth == 0) {
Shimeng (Simon) Wanga6c5d382011-07-19 11:06:06 -07002419 if (DebugFlags.WEB_VIEW_CORE) {
2420 Log.v(LOGTAG, "Can't get the viewWidth yet");
2421 }
Grace Kloba6ed525e2009-09-17 15:31:12 -07002422 }
2423 } else {
2424 webViewWidth = Math.round(viewportWidth * mCurrentViewScale);
2425 }
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002426 mInitialViewState = new ViewState();
2427 mInitialViewState.mMinScale = mViewportMinimumScale / 100.0f;
2428 mInitialViewState.mMaxScale = mViewportMaximumScale / 100.0f;
2429 mInitialViewState.mDefaultScale = adjust;
2430 mInitialViewState.mScrollX = mRestoredX;
2431 mInitialViewState.mScrollY = mRestoredY;
George Mounte263bc12011-10-31 13:49:03 -07002432 mInitialViewState.mShouldStartScrolledRight = (mRestoredX == 0)
2433 && (mRestoredY == 0)
2434 && (mBrowserFrame != null)
2435 && mBrowserFrame.getShouldStartScrolledRight();
2436
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002437 mInitialViewState.mMobileSite = (0 == mViewportWidth);
Mangesh Ghiwaref0e96d52011-10-26 17:23:54 -07002438 if (mIsRestored) {
Shimeng (Simon) Wang96fcb872010-11-24 16:01:12 -08002439 mInitialViewState.mIsRestored = true;
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002440 mInitialViewState.mViewScale = mRestoredScale;
Mangesh Ghiwaree59e3012011-11-03 13:21:18 -07002441 if (mRestoredTextWrapScale > 0) {
2442 mInitialViewState.mTextWrapScale = mRestoredTextWrapScale;
2443 } else {
2444 mInitialViewState.mTextWrapScale = mInitialViewState.mViewScale;
2445 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002446 } else {
2447 if (mViewportInitialScale > 0) {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002448 mInitialViewState.mViewScale = mInitialViewState.mTextWrapScale =
Grace Klobaef347ef2009-07-30 11:20:32 -07002449 mViewportInitialScale / 100.0f;
Shimeng (Simon) Wang9c64bae2010-10-22 10:52:57 -07002450 } else if (mViewportWidth > 0 && mViewportWidth < webViewWidth &&
Shimeng (Simon) Wangb30381d2011-06-22 17:44:27 -07002451 !getSettings().getUseFixedViewport()) {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002452 mInitialViewState.mViewScale = mInitialViewState.mTextWrapScale =
Grace Klobaef347ef2009-07-30 11:20:32 -07002453 (float) webViewWidth / mViewportWidth;
2454 } else {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002455 mInitialViewState.mTextWrapScale = adjust;
Shimeng (Simon) Wang56bd4342011-07-07 15:26:22 -07002456 if (mSettings.getUseWideViewPort()) {
2457 // 0 will trigger WebView to turn on zoom overview mode
2458 mInitialViewState.mViewScale = 0;
2459 } else {
2460 mInitialViewState.mViewScale = adjust;
2461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002464
2465 if (mWebView.mHeightCanMeasure) {
2466 // Trick to ensure that the Picture has the exact height for the
2467 // content by forcing to layout with 0 height after the page is
2468 // ready, which is indicated by didFirstLayout. This is essential to
2469 // get rid of the white space in the GMail which uses WebView for
2470 // message view.
2471 mWebView.mLastHeightSent = 0;
2472 // Send a negative scale to indicate that WebCore should reuse
2473 // the current scale
2474 WebView.ViewSizeData data = new WebView.ViewSizeData();
2475 data.mWidth = mWebView.mLastWidthSent;
2476 data.mHeight = 0;
2477 // if mHeightCanMeasure is true, getUseWideViewPort() can't be
2478 // true. It is safe to use mWidth for mTextWrapWidth.
2479 data.mTextWrapWidth = data.mWidth;
2480 data.mScale = -1.0f;
Cary Clark6d45acc2009-08-27 15:42:57 -04002481 data.mIgnoreHeight = false;
Grace Kloba3a0def22010-01-23 21:11:54 -08002482 data.mAnchorX = data.mAnchorY = 0;
Grace Kloba0d03b912009-09-27 17:46:31 -07002483 // send VIEW_SIZE_CHANGED to the front of the queue so that we can
2484 // avoid pushing the wrong picture to the WebView side. If there is
2485 // a VIEW_SIZE_CHANGED in the queue, probably from WebView side,
2486 // ignore it as we have a new size. If we leave VIEW_SIZE_CHANGED
2487 // in the queue, as mLastHeightSent has been updated here, we may
2488 // miss the requestLayout in WebView side after the new picture.
2489 mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED);
Grace Klobaef347ef2009-07-30 11:20:32 -07002490 mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
2491 EventHub.VIEW_SIZE_CHANGED, data));
Shimeng (Simon) Wang56bd4342011-07-07 15:26:22 -07002492 } else {
Grace Kloba6ed525e2009-09-17 15:31:12 -07002493 if (viewportWidth == 0) {
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002494 // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView
2495 // to WebViewCore
2496 mWebView.mLastWidthSent = 0;
2497 } else {
2498 WebView.ViewSizeData data = new WebView.ViewSizeData();
2499 // mViewScale as 0 means it is in zoom overview mode. So we don't
2500 // know the exact scale. If mRestoredScale is non-zero, use it;
2501 // otherwise just use mTextWrapScale as the initial scale.
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002502 float tentativeScale = mInitialViewState.mViewScale;
2503 if (tentativeScale == 0) {
2504 // The following tries to figure out more correct view scale
2505 // and text wrap scale to be sent to webkit, by using some
2506 // knowledge from web settings and zoom manager.
2507
2508 // Calculated window width will be used to guess the scale
2509 // in zoom overview mode.
2510 tentativeScale = mInitialViewState.mTextWrapScale;
2511 int tentativeViewWidth = Math.round(webViewWidth / tentativeScale);
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07002512 int windowWidth = calculateWindowWidth(tentativeViewWidth);
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002513 // In viewport setup time, since no content width is known, we assume
2514 // the windowWidth will be the content width, to get a more likely
2515 // zoom overview scale.
2516 data.mScale = (float) webViewWidth / windowWidth;
2517 if (!mSettings.getLoadWithOverviewMode()) {
2518 // If user choose non-overview mode.
2519 data.mScale = Math.max(data.mScale, tentativeScale);
2520 }
Shimeng (Simon) Wang24a252e2011-05-24 15:00:52 -07002521 if (mSettings.isNarrowColumnLayout()) {
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002522 // In case of automatic text reflow in fixed view port mode.
2523 mInitialViewState.mTextWrapScale =
Mangesh Ghiware66b2ff82011-12-08 13:43:55 -08002524 mWebView.computeReadingLevelScale(data.mScale);
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002525 }
2526 } else {
2527 // Scale is given such as when page is restored, use it.
2528 data.mScale = tentativeScale;
2529 }
Cary Clark35155c12009-10-29 15:34:00 -04002530 if (DebugFlags.WEB_VIEW_CORE) {
2531 Log.v(LOGTAG, "setupViewport"
2532 + " mRestoredScale=" + mRestoredScale
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002533 + " mViewScale=" + mInitialViewState.mViewScale
2534 + " mTextWrapScale=" + mInitialViewState.mTextWrapScale
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002535 + " data.mScale= " + data.mScale
Cary Clark35155c12009-10-29 15:34:00 -04002536 );
2537 }
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002538 data.mWidth = Math.round(webViewWidth / data.mScale);
Ben Murdochd1bee052010-03-05 11:30:07 +00002539 // We may get a call here when mCurrentViewHeight == 0 if webcore completes the
2540 // first layout before we sync our webview dimensions to it. In that case, we
2541 // request the real height of the webview. This is not a perfect solution as we
2542 // are calling a WebView method from the WebCore thread. But this is preferable
2543 // to syncing an incorrect height.
2544 data.mHeight = mCurrentViewHeight == 0 ?
2545 Math.round(mWebView.getViewHeight() / data.mScale)
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08002546 : Math.round((float) mCurrentViewHeight * data.mWidth / viewportWidth);
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002547 data.mTextWrapWidth = Math.round(webViewWidth
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002548 / mInitialViewState.mTextWrapScale);
Cary Clark6d45acc2009-08-27 15:42:57 -04002549 data.mIgnoreHeight = false;
Grace Kloba3a0def22010-01-23 21:11:54 -08002550 data.mAnchorX = data.mAnchorY = 0;
Grace Kloba0d03b912009-09-27 17:46:31 -07002551 // send VIEW_SIZE_CHANGED to the front of the queue so that we
2552 // can avoid pushing the wrong picture to the WebView side.
2553 mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED);
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002554 // Let webkit know the scale and inner width/height immediately
2555 // in viewport setup time to avoid wrong information.
2556 viewSizeChanged(data);
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002557 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 }
2560
2561 // called by JNI
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002562 private void restoreScale(float scale, float textWrapScale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 if (mBrowserFrame.firstLayoutDone() == false) {
Mangesh Ghiwaree832b632011-11-16 11:46:39 -08002564 mIsRestored = true;
Mangesh Ghiwaref0e96d52011-10-26 17:23:54 -07002565 mRestoredScale = scale;
Mangesh Ghiwaree59e3012011-11-03 13:21:18 -07002566 if (mSettings.getUseWideViewPort()) {
2567 mRestoredTextWrapScale = textWrapScale;
2568 }
Grace Kloba8b97e4b2009-07-28 13:11:38 -07002569 }
2570 }
2571
2572 // called by JNI
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002573 private void needTouchEvents(boolean need) {
2574 if (mWebView != null) {
2575 Message.obtain(mWebView.mPrivateHandler,
2576 WebView.WEBCORE_NEED_TOUCH_EVENTS, need ? 1 : 0, 0)
2577 .sendToTarget();
2578 }
2579 }
2580
2581 // called by JNI
2582 private void updateTextfield(int ptr, boolean changeToPassword,
2583 String text, int textGeneration) {
2584 if (mWebView != null) {
2585 Message msg = Message.obtain(mWebView.mPrivateHandler,
Cary Clarkd6982c92009-05-29 11:02:22 -04002586 WebView.UPDATE_TEXTFIELD_TEXT_MSG_ID, ptr,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 textGeneration, text);
2588 msg.getData().putBoolean("password", changeToPassword);
2589 msg.sendToTarget();
2590 }
2591 }
2592
Cary Clark243ea062009-06-25 10:49:32 -04002593 // called by JNI
Leon Scroggins6679f2f2009-08-12 18:48:10 -04002594 private void updateTextSelection(int pointer, int start, int end,
2595 int textGeneration) {
2596 if (mWebView != null) {
2597 Message.obtain(mWebView.mPrivateHandler,
2598 WebView.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration,
2599 new TextSelectionData(start, end)).sendToTarget();
2600 }
2601 }
2602
2603 // called by JNI
Cary Clark243ea062009-06-25 10:49:32 -04002604 private void clearTextEntry() {
2605 if (mWebView == null) return;
2606 Message.obtain(mWebView.mPrivateHandler,
2607 WebView.CLEAR_TEXT_ENTRY).sendToTarget();
2608 }
2609
Leon Scroggins5de63892009-10-29 09:48:43 -04002610 // called by JNI
2611 private void sendFindAgain() {
2612 if (mWebView == null) return;
2613 Message.obtain(mWebView.mPrivateHandler,
2614 WebView.FIND_AGAIN).sendToTarget();
2615 }
2616
Cary Clark77d98f42009-07-31 09:40:38 -04002617 private native void nativeUpdateFrameCacheIfLoading();
Leon Scroggins200c13d2010-05-14 15:35:42 -04002618 private native void nativeRevealSelection();
Leon Scroggins3a503392010-01-06 17:04:38 -05002619 private native String nativeRequestLabel(int framePtr, int nodePtr);
Leon Scroggins72543e12009-07-23 15:29:45 -04002620 /**
Cary Clarkeaa18de2009-09-28 12:50:42 -04002621 * Scroll the focused textfield to (xPercent, y) in document space
Leon Scroggins72543e12009-07-23 15:29:45 -04002622 */
Cary Clarkeaa18de2009-09-28 12:50:42 -04002623 private native void nativeScrollFocusedTextInput(float xPercent, int y);
Leon Scroggins72543e12009-07-23 15:29:45 -04002624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 // these must be in document space (i.e. not scaled/zoomed).
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002626 private native void nativeSetScrollOffset(int gen, boolean sendScrollEvent, int dx, int dy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627
2628 private native void nativeSetGlobalBounds(int x, int y, int w, int h);
2629
2630 // called by JNI
Leon Scrogginsa8da1732009-10-19 19:04:30 -04002631 private void requestListBox(String[] array, int[] enabledArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 int[] selectedArray) {
2633 if (mWebView != null) {
2634 mWebView.requestListBox(array, enabledArray, selectedArray);
2635 }
2636 }
2637
2638 // called by JNI
Leon Scrogginsa8da1732009-10-19 19:04:30 -04002639 private void requestListBox(String[] array, int[] enabledArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002640 int selection) {
2641 if (mWebView != null) {
2642 mWebView.requestListBox(array, enabledArray, selection);
2643 }
Cary Clarkd6982c92009-05-29 11:02:22 -04002644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 }
Mike Reedd205d5b2009-05-27 11:02:29 -04002646
Derek Sollenberger4c41e8d2009-06-29 13:49:27 -04002647 // called by JNI
Leon Scrogginsb4157792010-03-18 12:42:33 -04002648 private void requestKeyboardWithSelection(int pointer, int selStart,
2649 int selEnd, int textGeneration) {
Derek Sollenberger4c41e8d2009-06-29 13:49:27 -04002650 if (mWebView != null) {
2651 Message.obtain(mWebView.mPrivateHandler,
Leon Scrogginsb4157792010-03-18 12:42:33 -04002652 WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
2653 textGeneration, new TextSelectionData(selStart, selEnd))
2654 .sendToTarget();
2655 }
2656 }
2657
2658 // called by JNI
2659 private void requestKeyboard(boolean showKeyboard) {
2660 if (mWebView != null) {
2661 Message.obtain(mWebView.mPrivateHandler,
2662 WebView.REQUEST_KEYBOARD, showKeyboard ? 1 : 0, 0)
Derek Sollenberger4c41e8d2009-06-29 13:49:27 -04002663 .sendToTarget();
2664 }
2665 }
2666
Ben Murdochdb8d19c2010-10-29 11:44:17 +01002667 private void setWebTextViewAutoFillable(int queryId, String preview) {
Ben Murdoch62275a42010-09-07 11:27:28 +01002668 if (mWebView != null) {
Ben Murdochdb8d19c2010-10-29 11:44:17 +01002669 Message.obtain(mWebView.mPrivateHandler, WebView.SET_AUTOFILLABLE,
2670 new AutoFillData(queryId, preview))
2671 .sendToTarget();
Ben Murdoch62275a42010-09-07 11:27:28 +01002672 }
2673 }
2674
Steve Block85aa9442011-09-28 12:20:12 +01002675 Context getContext() {
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002676 return mContext;
2677 }
2678
2679 // called by JNI
Derek Sollenbergerf3196cd2011-01-27 17:33:14 -05002680 private void keepScreenOn(boolean screenOn) {
2681 if (mWebView != null) {
2682 Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SCREEN_ON);
2683 message.arg1 = screenOn ? 1 : 0;
2684 message.sendToTarget();
2685 }
2686 }
2687
2688 // called by JNI
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002689 private Class<?> getPluginClass(String libName, String clsName) {
John Reck7818aaa2011-04-26 16:57:46 -07002690
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002691 if (mWebView == null) {
2692 return null;
2693 }
John Reck7818aaa2011-04-26 16:57:46 -07002694
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002695 PluginManager pluginManager = PluginManager.getInstance(null);
2696
2697 String pkgName = pluginManager.getPluginsAPKName(libName);
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002698 if (pkgName == null) {
2699 Log.w(LOGTAG, "Unable to resolve " + libName + " to a plugin APK");
2700 return null;
2701 }
John Reck7818aaa2011-04-26 16:57:46 -07002702
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002703 try {
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002704 return pluginManager.getPluginClass(pkgName, clsName);
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002705 } catch (NameNotFoundException e) {
2706 Log.e(LOGTAG, "Unable to find plugin classloader for the apk (" + pkgName + ")");
2707 } catch (ClassNotFoundException e) {
2708 Log.e(LOGTAG, "Unable to find plugin class (" + clsName +
2709 ") in the apk (" + pkgName + ")");
2710 }
2711
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002712 return null;
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002713 }
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002714
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002715 // called by JNI. PluginWidget function to launch a full-screen view using a
2716 // View object provided by the plugin class.
Derek Sollenberger7ab3d672011-06-01 14:45:05 -04002717 private void showFullScreenPlugin(ViewManager.ChildView childView, int orientation, int npp) {
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002718 if (mWebView == null) {
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002719 return;
2720 }
2721
Derek Sollenbergerc28ff442010-03-09 17:38:49 -05002722 Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN);
2723 message.obj = childView.mView;
Derek Sollenberger7ab3d672011-06-01 14:45:05 -04002724 message.arg1 = orientation;
2725 message.arg2 = npp;
Derek Sollenbergerc28ff442010-03-09 17:38:49 -05002726 message.sendToTarget();
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002727 }
2728
Grace Kloba11438c32009-12-16 11:39:12 -08002729 // called by JNI
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002730 private void hideFullScreenPlugin() {
2731 if (mWebView == null) {
2732 return;
2733 }
Grace Kloba11438c32009-12-16 11:39:12 -08002734 mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN)
2735 .sendToTarget();
2736 }
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002737
Derek Sollenberger36a4f232011-01-04 16:05:43 -05002738 private ViewManager.ChildView createSurface(View pluginView) {
Patrick Scottfb6aecb2009-07-17 16:38:07 -04002739 if (mWebView == null) {
2740 return null;
2741 }
Derek Sollenbergerc0b8a962009-09-22 14:08:09 -04002742
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002743 if (pluginView == null) {
2744 Log.e(LOGTAG, "Attempted to add an empty plugin view to the view hierarchy");
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002745 return null;
2746 }
Derek Sollenbergerc0b8a962009-09-22 14:08:09 -04002747
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002748 // ensures the view system knows the view can redraw itself
Derek Sollenberger42d00fb2009-12-01 15:19:42 -05002749 pluginView.setWillNotDraw(false);
Derek Sollenbergerc0b8a962009-09-22 14:08:09 -04002750
Derek Sollenberger2120cd62010-02-23 16:52:45 -05002751 if(pluginView instanceof SurfaceView)
2752 ((SurfaceView)pluginView).setZOrderOnTop(true);
2753
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002754 ViewManager.ChildView view = mWebView.mViewManager.createView();
2755 view.mView = pluginView;
Derek Sollenberger36a4f232011-01-04 16:05:43 -05002756 return view;
2757 }
John Reck7818aaa2011-04-26 16:57:46 -07002758
Derek Sollenberger36a4f232011-01-04 16:05:43 -05002759 // called by JNI. PluginWidget functions for creating an embedded View for
2760 // the surface drawing model.
2761 private ViewManager.ChildView addSurface(View pluginView, int x, int y,
2762 int width, int height) {
2763 ViewManager.ChildView view = createSurface(pluginView);
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002764 view.attachView(x, y, width, height);
2765 return view;
Patrick Scottfb6aecb2009-07-17 16:38:07 -04002766 }
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002767
Derek Sollenberger3dafca12009-10-13 11:38:25 -04002768 private void updateSurface(ViewManager.ChildView childView, int x, int y,
2769 int width, int height) {
2770 childView.attachView(x, y, width, height);
2771 }
2772
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002773 private void destroySurface(ViewManager.ChildView childView) {
2774 childView.removeView();
Patrick Scottfb6aecb2009-07-17 16:38:07 -04002775 }
2776
Grace Kloba3a0def22010-01-23 21:11:54 -08002777 // called by JNI
2778 static class ShowRectData {
2779 int mLeft;
2780 int mTop;
2781 int mWidth;
2782 int mHeight;
2783 int mContentWidth;
2784 int mContentHeight;
2785 float mXPercentInDoc;
2786 float mXPercentInView;
2787 float mYPercentInDoc;
2788 float mYPercentInView;
2789 }
2790
2791 private void showRect(int left, int top, int width, int height,
2792 int contentWidth, int contentHeight, float xPercentInDoc,
2793 float xPercentInView, float yPercentInDoc, float yPercentInView) {
2794 if (mWebView != null) {
2795 ShowRectData data = new ShowRectData();
2796 data.mLeft = left;
2797 data.mTop = top;
2798 data.mWidth = width;
2799 data.mHeight = height;
2800 data.mContentWidth = contentWidth;
2801 data.mContentHeight = contentHeight;
2802 data.mXPercentInDoc = xPercentInDoc;
2803 data.mXPercentInView = xPercentInView;
2804 data.mYPercentInDoc = yPercentInDoc;
2805 data.mYPercentInView = yPercentInView;
2806 Message.obtain(mWebView.mPrivateHandler, WebView.SHOW_RECT_MSG_ID,
2807 data).sendToTarget();
2808 }
2809 }
2810
Grace Klobae8300a12010-03-12 13:32:55 -08002811 // called by JNI
2812 private void centerFitRect(int x, int y, int width, int height) {
2813 if (mWebView == null) {
2814 return;
2815 }
2816 mWebView.mPrivateHandler.obtainMessage(WebView.CENTER_FIT_RECT,
2817 new Rect(x, y, x + width, y + height)).sendToTarget();
2818 }
2819
Grace Kloba50004bc2010-04-13 22:58:51 -07002820 // called by JNI
2821 private void setScrollbarModes(int hMode, int vMode) {
2822 if (mWebView == null) {
2823 return;
2824 }
2825 mWebView.mPrivateHandler.obtainMessage(WebView.SET_SCROLLBAR_MODES,
2826 hMode, vMode).sendToTarget();
2827 }
2828
Svetoslav Ganov9504f572011-01-14 11:38:17 -08002829 // called by JNI
2830 @SuppressWarnings("unused")
2831 private void selectAt(int x, int y) {
2832 if (mWebView != null) {
2833 mWebView.mPrivateHandler.obtainMessage(WebView.SELECT_AT, x, y).sendToTarget();
2834 }
2835 }
2836
Steve Block68dede32010-08-04 10:28:46 +01002837 private void useMockDeviceOrientation() {
Steve Block1be73392010-10-15 16:31:01 +01002838 mDeviceMotionAndOrientationManager.useMock();
Steve Blockf4a705f2010-08-11 13:08:24 +01002839 }
2840
2841 public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
2842 boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
Steve Block1be73392010-10-15 16:31:01 +01002843 mDeviceMotionAndOrientationManager.setMockOrientation(canProvideAlpha, alpha,
2844 canProvideBeta, beta, canProvideGamma, gamma);
Steve Block68dede32010-08-04 10:28:46 +01002845 }
2846
Steve Blockdc82a292010-10-06 14:34:15 +01002847 protected DeviceMotionService getDeviceMotionService() {
2848 if (mDeviceMotionService == null) {
2849 mDeviceMotionService =
Steve Block1be73392010-10-15 16:31:01 +01002850 new DeviceMotionService(mDeviceMotionAndOrientationManager, mContext);
Steve Blockdc82a292010-10-06 14:34:15 +01002851 }
2852 return mDeviceMotionService;
2853 }
2854
Steve Blockc43565b2010-08-11 13:12:37 +01002855 protected DeviceOrientationService getDeviceOrientationService() {
2856 if (mDeviceOrientationService == null) {
Steve Blockbb9db222010-08-18 11:12:07 +01002857 mDeviceOrientationService =
Steve Block1be73392010-10-15 16:31:01 +01002858 new DeviceOrientationService(mDeviceMotionAndOrientationManager, mContext);
Steve Blockc43565b2010-08-11 13:12:37 +01002859 }
2860 return mDeviceOrientationService;
2861 }
2862
Chris Craik58d94af2011-08-18 11:42:13 -07002863 private native void nativeSetIsPaused(boolean isPaused);
Mike Reedd205d5b2009-05-27 11:02:29 -04002864 private native void nativePause();
2865 private native void nativeResume();
Derek Sollenbergere0155e92009-06-10 15:35:45 -04002866 private native void nativeFreeMemory();
Derek Sollenbergerb6ddc7a2009-12-08 15:41:46 -05002867 private native void nativeFullScreenPluginHidden(int npp);
Derek Sollenberger281432c2011-08-22 14:05:49 -04002868 private native void nativePluginSurfaceReady();
Cary Clark1cb97ee2009-12-11 12:10:36 -05002869 private native boolean nativeValidNodeAndBounds(int frame, int node,
2870 Rect bounds);
2871
Grace Kloba178db412010-05-18 22:22:23 -07002872 private native ArrayList<Rect> nativeGetTouchHighlightRects(int x, int y,
2873 int slop);
Ben Murdoch62275a42010-09-07 11:27:28 +01002874
2875 private native void nativeAutoFillForm(int queryId);
Patrick Scottcfa734a2011-02-22 11:19:02 -05002876 private native void nativeScrollLayer(int layer, Rect rect);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002877}