blob: 027169597921ddbc4d1f85b2594ef7dde351a56c [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;
Leon Scroggins70ca3c22009-10-02 15:58:55 -040027import android.net.Uri;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Handler;
29import android.os.Looper;
30import android.os.Message;
31import android.os.Process;
Ben Murdoch65b4cda2010-05-28 11:07:15 +010032import android.provider.MediaStore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.util.Log;
34import android.util.SparseBooleanArray;
35import android.view.KeyEvent;
Huahui Wu0904c0d2011-01-07 17:30:53 -080036import android.view.MotionEvent;
Patrick Scottfb6aecb2009-07-17 16:38:07 -040037import android.view.SurfaceView;
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -040038import android.view.View;
Steve Blockdc82a292010-10-06 14:34:15 +010039import android.webkit.DeviceMotionService;
Steve Block1be73392010-10-15 16:31:01 +010040import android.webkit.DeviceMotionAndOrientationManager;
Steve Blockc43565b2010-08-11 13:12:37 +010041import android.webkit.DeviceOrientationService;
Steve Block808751f2011-01-04 14:26:27 +000042import android.webkit.JniUtil;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043
44import java.util.ArrayList;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010045import java.util.Collection;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010046import java.util.Map;
Andrei Popescu59e2ad92009-07-28 13:38:06 +010047import java.util.Set;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048
49import junit.framework.Assert;
50
51final class WebViewCore {
52
53 private static final String LOGTAG = "webcore";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
55 static {
56 // Load libwebcore during static initialization. This happens in the
57 // zygote process so it will be shared read-only across all app
58 // processes.
Jean-Baptiste Queruc0e95042011-01-31 15:43:19 -080059 try {
60 System.loadLibrary("webcore");
61 } catch (UnsatisfiedLinkError e) {
62 Log.e(LOGTAG, "Unable to load webcore library");
63 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 }
65
66 /*
67 * WebViewCore always executes in the same thread as the native webkit.
68 */
69
70 // The WebView that corresponds to this WebViewCore.
71 private WebView mWebView;
72 // Proxy for handling callbacks from native code
73 private final CallbackProxy mCallbackProxy;
74 // Settings object for maintaining all settings
75 private final WebSettings mSettings;
76 // Context for initializing the BrowserFrame with the proper assets.
77 private final Context mContext;
78 // The pointer to a native view object.
79 private int mNativeClass;
80 // The BrowserFrame is an interface to the native Frame component.
81 private BrowserFrame mBrowserFrame;
Andrei Popescu4950b2b2009-09-03 13:56:07 +010082 // Custom JS interfaces to add during the initialization.
83 private Map<String, Object> mJavascriptInterfaces;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 /*
85 * range is from 200 to 10,000. 0 is a special value means device-width. -1
86 * means undefined.
87 */
88 private int mViewportWidth = -1;
89
90 /*
91 * range is from 200 to 10,000. 0 is a special value means device-height. -1
92 * means undefined.
93 */
94 private int mViewportHeight = -1;
95
96 /*
97 * scale in percent, range is from 1 to 1000. 0 means undefined.
98 */
99 private int mViewportInitialScale = 0;
100
101 /*
102 * scale in percent, range is from 1 to 1000. 0 means undefined.
103 */
104 private int mViewportMinimumScale = 0;
105
106 /*
107 * scale in percent, range is from 1 to 1000. 0 means undefined.
108 */
109 private int mViewportMaximumScale = 0;
110
111 private boolean mViewportUserScalable = true;
Cary Clarkd6982c92009-05-29 11:02:22 -0400112
Grace Kloba408cf852009-09-20 16:34:44 -0700113 /*
114 * range is from 70 to 400.
115 * 0 is a special value means device-dpi. The default scale factor will be
116 * always 100.
117 * -1 means undefined. The default scale factor will be
118 * WebView.DEFAULT_SCALE_PERCENT.
119 */
120 private int mViewportDensityDpi = -1;
121
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -0800122 private float mRestoredScale = 0;
123 private float mRestoredTextWrapScale = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 private int mRestoredX = 0;
125 private int mRestoredY = 0;
126
Steve Block1be73392010-10-15 16:31:01 +0100127 private DeviceMotionAndOrientationManager mDeviceMotionAndOrientationManager =
128 new DeviceMotionAndOrientationManager(this);
Steve Blockdc82a292010-10-06 14:34:15 +0100129 private DeviceMotionService mDeviceMotionService;
Steve Blockc43565b2010-08-11 13:12:37 +0100130 private DeviceOrientationService mDeviceOrientationService;
Steve Blockf4a705f2010-08-11 13:08:24 +0100131
Ben Murdochf7093be2010-11-01 10:27:33 +0000132 private int mLowMemoryUsageThresholdMb;
133 private int mHighMemoryUsageThresholdMb;
Shimeng (Simon) Wang7c1bcfd2011-01-24 14:38:46 -0800134 private int mHighUsageDeltaMb;
Ben Murdochf7093be2010-11-01 10:27:33 +0000135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 // The thread name used to identify the WebCore thread and for use in
137 // debugging other classes that require operation within the WebCore thread.
138 /* package */ static final String THREAD_NAME = "WebViewCoreThread";
139
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100140 public WebViewCore(Context context, WebView w, CallbackProxy proxy,
141 Map<String, Object> javascriptInterfaces) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 // No need to assign this in the WebCore thread.
143 mCallbackProxy = proxy;
144 mWebView = w;
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100145 mJavascriptInterfaces = javascriptInterfaces;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 // This context object is used to initialize the WebViewCore during
147 // subwindow creation.
148 mContext = context;
149
150 // We need to wait for the initial thread creation before sending
151 // a message to the WebCore thread.
152 // XXX: This is the only time the UI thread will wait for the WebCore
153 // thread!
154 synchronized (WebViewCore.class) {
155 if (sWebCoreHandler == null) {
156 // Create a global thread and start it.
157 Thread t = new Thread(new WebCoreThread());
158 t.setName(THREAD_NAME);
159 t.start();
160 try {
161 WebViewCore.class.wait();
162 } catch (InterruptedException e) {
163 Log.e(LOGTAG, "Caught exception while waiting for thread " +
164 "creation.");
165 Log.e(LOGTAG, Log.getStackTraceString(e));
166 }
167 }
168 }
169 // Create an EventHub to handle messages before and after the thread is
170 // ready.
171 mEventHub = new EventHub();
172 // Create a WebSettings object for maintaining all settings
Grace Kloba0d8b77c2009-06-25 11:20:51 -0700173 mSettings = new WebSettings(mContext, mWebView);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 // The WebIconDatabase needs to be initialized within the UI thread so
175 // just request the instance here.
176 WebIconDatabase.getInstance();
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100177 // Create the WebStorage singleton and the UI handler
178 WebStorage.getInstance().createUIHandler();
179 // Create the UI handler for GeolocationPermissions
180 GeolocationPermissions.getInstance().createUIHandler();
Ben Murdochf7093be2010-11-01 10:27:33 +0000181
182 // Get the memory class of the current device. V8 will use these values
183 // to GC more effectively.
184 ActivityManager manager = (ActivityManager) mContext.getSystemService(
185 Context.ACTIVITY_SERVICE);
186 ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
187 manager.getMemoryInfo(memInfo);
188
189 // Allow us to use up to our memory class value before V8's GC kicks in.
190 // These values have been determined by experimentation.
Shimeng (Simon) Wang7c1bcfd2011-01-24 14:38:46 -0800191 mLowMemoryUsageThresholdMb = manager.getLargeMemoryClass();
Shimeng (Simon) Wang7114f3b2011-01-26 10:34:26 -0800192 mHighMemoryUsageThresholdMb = (int) (mLowMemoryUsageThresholdMb * 1.5);
Shimeng (Simon) Wang7c1bcfd2011-01-24 14:38:46 -0800193 // Avoid constant V8 GC when memory usage equals to working set estimate.
Shimeng (Simon) Wang7114f3b2011-01-26 10:34:26 -0800194 mHighUsageDeltaMb = mLowMemoryUsageThresholdMb / 32;
Ben Murdochf7093be2010-11-01 10:27:33 +0000195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 // Send a message to initialize the WebViewCore.
197 Message init = sWebCoreHandler.obtainMessage(
198 WebCoreThread.INITIALIZE, this);
199 sWebCoreHandler.sendMessage(init);
200 }
201
202 /* Initialize private data within the WebCore thread.
203 */
204 private void initialize() {
205 /* Initialize our private BrowserFrame class to handle all
206 * frame-related functions. We need to create a new view which
207 * in turn creates a C level FrameView and attaches it to the frame.
208 */
209 mBrowserFrame = new BrowserFrame(mContext, this, mCallbackProxy,
Andrei Popescu4950b2b2009-09-03 13:56:07 +0100210 mSettings, mJavascriptInterfaces);
211 mJavascriptInterfaces = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 // Sync the native settings and also create the WebCore thread handler.
213 mSettings.syncSettingsAndCreateHandler(mBrowserFrame);
214 // Create the handler and transfer messages for the IconDatabase
215 WebIconDatabase.getInstance().createHandler();
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100216 // Create the handler for WebStorage
217 WebStorage.getInstance().createHandler();
Steve Block0ac031b2009-07-28 11:53:20 +0100218 // Create the handler for GeolocationPermissions.
219 GeolocationPermissions.getInstance().createHandler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 // The transferMessages call will transfer all pending messages to the
221 // WebCore thread handler.
222 mEventHub.transferMessages();
223
224 // Send a message back to WebView to tell it that we have set up the
225 // WebCore thread.
226 if (mWebView != null) {
227 Message.obtain(mWebView.mPrivateHandler,
228 WebView.WEBCORE_INITIALIZED_MSG_ID,
229 mNativeClass, 0).sendToTarget();
230 }
231
232 }
233
234 /* Handle the initialization of WebViewCore during subwindow creation. This
235 * method is called from the WebCore thread but it is called before the
236 * INITIALIZE message can be handled.
237 */
238 /* package */ void initializeSubwindow() {
239 // Go ahead and initialize the core components.
240 initialize();
241 // Remove the INITIALIZE method so we don't try to initialize twice.
242 sWebCoreHandler.removeMessages(WebCoreThread.INITIALIZE, this);
243 }
244
245 /* Get the BrowserFrame component. This is used for subwindow creation and
246 * is called only from BrowserFrame in the WebCore thread. */
247 /* package */ BrowserFrame getBrowserFrame() {
248 return mBrowserFrame;
249 }
250
251 //-------------------------------------------------------------------------
252 // Common methods
253 //-------------------------------------------------------------------------
254
255 /**
256 * Causes all timers to pause. This applies to all WebViews in the current
257 * app process.
258 */
259 public static void pauseTimers() {
260 if (BrowserFrame.sJavaBridge == null) {
261 throw new IllegalStateException(
262 "No WebView has been created in this process!");
263 }
264 BrowserFrame.sJavaBridge.pause();
265 }
266
267 /**
268 * Resume all timers. This applies to all WebViews in the current process.
269 */
270 public static void resumeTimers() {
271 if (BrowserFrame.sJavaBridge == null) {
272 throw new IllegalStateException(
273 "No WebView has been created in this process!");
274 }
275 BrowserFrame.sJavaBridge.resume();
276 }
277
278 public WebSettings getSettings() {
279 return mSettings;
280 }
281
Shimeng (Simon) Wangbf013122010-10-05 16:59:05 -0700282 /*
283 * Given mimeType, check whether it's supported in Android media framework.
284 * mimeType could be such as "audio/ogg" and "video/mp4".
285 */
Iain Merrick4e7665d2010-10-27 10:15:14 +0100286 /* package */ static boolean isSupportedMediaMimeType(String mimeType) {
287 int fileType = MediaFile.getFileTypeForMimeType(mimeType);
Andreas Huber5dffd0e2010-11-15 08:54:40 -0800288 return MediaFile.isAudioFileType(fileType)
289 || MediaFile.isVideoFileType(fileType)
Shimeng (Simon) Wangb394d9a2010-11-17 17:55:06 -0800290 || MediaFile.isPlayListFileType(fileType)
291 // The following is not in Media framework, but it's supported.
292 || (mimeType != null && mimeType.startsWith("video/m4v"));
Shimeng (Simon) Wangbf013122010-10-05 16:59:05 -0700293 }
Iain Merrick4e7665d2010-10-27 10:15:14 +0100294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 /**
Ben Murdoch6262ae52009-04-17 13:21:53 +0100296 * Add an error message to the client's console.
297 * @param message The message to add
298 * @param lineNumber the line on which the error occurred
299 * @param sourceID the filename of the source that caused the error.
Ben Murdoch3141e0a2010-01-28 15:06:32 +0000300 * @param msgLevel the log level of this message. This is a value casted to int
301 * from WebCore::MessageLevel in WebCore/page/Console.h.
Ben Murdoch6262ae52009-04-17 13:21:53 +0100302 */
Ben Murdoch3141e0a2010-01-28 15:06:32 +0000303 protected void addMessageToConsole(String message, int lineNumber, String sourceID,
304 int msgLevel) {
305 mCallbackProxy.addMessageToConsole(message, lineNumber, sourceID, msgLevel);
Ben Murdoch6262ae52009-04-17 13:21:53 +0100306 }
307
308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * Invoke a javascript alert.
310 * @param message The message displayed in the alert.
311 */
312 protected void jsAlert(String url, String message) {
313 mCallbackProxy.onJsAlert(url, message);
314 }
315
Leon Scrogginsf2e17a82010-09-24 15:58:50 -0400316 /**
317 * Called by JNI. Send a message to the UI thread to hide the soft keyboard
318 * if the node pointed to by nodePointer is still in focus.
319 * @param nodePointer The node which just blurred.
320 */
321 private void formDidBlur(int nodePointer) {
322 if (mWebView == null) return;
323 Message.obtain(mWebView.mPrivateHandler, WebView.FORM_DID_BLUR,
324 nodePointer, 0).sendToTarget();
325 }
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400326
327 /**
328 * Called by JNI. Open a file chooser to upload a file.
Ben Murdoch4ae32f52010-05-18 14:30:39 +0100329 * @param acceptType The value of the 'accept' attribute of the
330 * input tag associated with this file picker.
Ben Murdochcc749de2010-05-18 12:37:00 +0100331 * @return String version of the URI.
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400332 */
Ben Murdoch4ae32f52010-05-18 14:30:39 +0100333 private String openFileChooser(String acceptType) {
334 Uri uri = mCallbackProxy.openFileChooser(acceptType);
Ben Murdochcc749de2010-05-18 12:37:00 +0100335 if (uri != null) {
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100336 String filePath = "";
337 // Note - querying for MediaStore.Images.Media.DATA
338 // seems to work for all content URIs, not just images
Ben Murdochcc749de2010-05-18 12:37:00 +0100339 Cursor cursor = mContext.getContentResolver().query(
340 uri,
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100341 new String[] { MediaStore.Images.Media.DATA },
Ben Murdochcc749de2010-05-18 12:37:00 +0100342 null, null, null);
343 if (cursor != null) {
344 try {
345 if (cursor.moveToNext()) {
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100346 filePath = cursor.getString(0);
Ben Murdochcc749de2010-05-18 12:37:00 +0100347 }
348 } finally {
349 cursor.close();
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400350 }
Ben Murdochcc749de2010-05-18 12:37:00 +0100351 } else {
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100352 filePath = uri.getLastPathSegment();
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400353 }
Ben Murdochcc749de2010-05-18 12:37:00 +0100354 String uriString = uri.toString();
Ben Murdoch65b4cda2010-05-28 11:07:15 +0100355 BrowserFrame.sJavaBridge.storeFilePathForContentUri(filePath, uriString);
Ben Murdochcc749de2010-05-18 12:37:00 +0100356 return uriString;
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400357 }
Ben Murdochcc749de2010-05-18 12:37:00 +0100358 return "";
Leon Scroggins70ca3c22009-10-02 15:58:55 -0400359 }
360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 /**
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100362 * Notify the browser that the origin has exceeded it's database quota.
Ben Murdoch7df19852009-04-22 13:07:58 +0100363 * @param url The URL that caused the overflow.
364 * @param databaseIdentifier The identifier of the database.
365 * @param currentQuota The current quota for the origin.
Ben Murdochd497d872009-08-25 19:32:54 +0100366 * @param estimatedSize The estimated size of the database.
Ben Murdoch7df19852009-04-22 13:07:58 +0100367 */
368 protected void exceededDatabaseQuota(String url,
369 String databaseIdentifier,
Ben Murdochd497d872009-08-25 19:32:54 +0100370 long currentQuota,
371 long estimatedSize) {
Ben Murdoch7df19852009-04-22 13:07:58 +0100372 // Inform the callback proxy of the quota overflow. Send an object
373 // that encapsulates a call to the nativeSetDatabaseQuota method to
374 // awaken the sleeping webcore thread when a decision from the
375 // client to allow or deny quota is available.
376 mCallbackProxy.onExceededDatabaseQuota(url, databaseIdentifier,
Ben Murdochd497d872009-08-25 19:32:54 +0100377 currentQuota, estimatedSize, getUsedQuota(),
378 new WebStorage.QuotaUpdater() {
379 public void updateQuota(long quota) {
380 nativeSetNewStorageLimit(quota);
381 }
382 });
Ben Murdoch7df19852009-04-22 13:07:58 +0100383 }
384
385 /**
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100386 * Notify the browser that the appcache has exceeded its max size.
387 * @param spaceNeeded is the amount of disk space that would be needed
388 * in order for the last appcache operation to succeed.
389 */
390 protected void reachedMaxAppCacheSize(long spaceNeeded) {
391 mCallbackProxy.onReachedMaxAppCacheSize(spaceNeeded, getUsedQuota(),
392 new WebStorage.QuotaUpdater() {
393 public void updateQuota(long quota) {
394 nativeSetNewStorageLimit(quota);
395 }
396 });
397 }
398
Leon Clarke194e3452009-09-28 11:42:12 +0100399 protected void populateVisitedLinks() {
400 ValueCallback callback = new ValueCallback<String[]>() {
401 public void onReceiveValue(String[] value) {
402 sendMessage(EventHub.POPULATE_VISITED_LINKS, (Object)value);
403 }
404 };
405 mCallbackProxy.getVisitedHistory(callback);
Leon Clarke9c8d8862009-09-24 15:20:10 +0100406 }
407
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100408 /**
Steve Block4faee092009-07-28 18:20:50 +0100409 * Shows a prompt to ask the user to set the Geolocation permission state
410 * for the given origin.
411 * @param origin The origin for which Geolocation permissions are
412 * requested.
413 */
414 protected void geolocationPermissionsShowPrompt(String origin) {
415 mCallbackProxy.onGeolocationPermissionsShowPrompt(origin,
416 new GeolocationPermissions.Callback() {
417 public void invoke(String origin, boolean allow, boolean remember) {
418 GeolocationPermissionsData data = new GeolocationPermissionsData();
419 data.mOrigin = origin;
420 data.mAllow = allow;
421 data.mRemember = remember;
422 // Marshall to WebCore thread.
423 sendMessage(EventHub.GEOLOCATION_PERMISSIONS_PROVIDE, data);
424 }
425 });
426 }
427
428 /**
429 * Hides the Geolocation permissions prompt.
430 */
431 protected void geolocationPermissionsHidePrompt() {
432 mCallbackProxy.onGeolocationPermissionsHidePrompt();
433 }
434
435 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 * Invoke a javascript confirm dialog.
437 * @param message The message displayed in the dialog.
438 * @return True if the user confirmed or false if the user cancelled.
439 */
440 protected boolean jsConfirm(String url, String message) {
441 return mCallbackProxy.onJsConfirm(url, message);
442 }
443
444 /**
445 * Invoke a javascript prompt dialog.
446 * @param message The message to be displayed in the dialog.
447 * @param defaultValue The default value in the prompt input.
448 * @return The input from the user or null to indicate the user cancelled
449 * the dialog.
450 */
451 protected String jsPrompt(String url, String message, String defaultValue) {
452 return mCallbackProxy.onJsPrompt(url, message, defaultValue);
453 }
454
455 /**
456 * Invoke a javascript before unload dialog.
457 * @param url The url that is requesting the dialog.
458 * @param message The message displayed in the dialog.
459 * @return True if the user confirmed or false if the user cancelled. False
460 * will cancel the navigation.
461 */
462 protected boolean jsUnload(String url, String message) {
463 return mCallbackProxy.onJsBeforeUnload(url, message);
464 }
465
Guang Zhu81e41432009-05-08 16:09:55 -0700466 /**
467 *
468 * Callback to notify that a JavaScript execution timeout has occured.
469 * @return True if the JavaScript execution should be interrupted. False
470 * will continue the execution.
471 */
472 protected boolean jsInterrupt() {
473 return mCallbackProxy.onJsTimeout();
474 }
475
Ben Murdoch6312de22010-06-29 19:20:11 +0100476 /**
477 * Notify the webview that this is an installable web app.
478 */
479 protected void setInstallableWebApp() {
480 mCallbackProxy.setInstallableWebApp();
481 }
482
Nicolas Roard0e778a12011-03-11 14:29:05 -0800483 /**
484 * Notify the webview that we want to display the video layer fullscreen.
485 */
Teng-Hui Zhu10ab6542011-03-16 16:42:32 -0700486 protected void enterFullscreenForVideoLayer(int layerId, String url) {
Nicolas Roard0e778a12011-03-11 14:29:05 -0800487 if (mWebView == null) return;
Teng-Hui Zhu10ab6542011-03-16 16:42:32 -0700488 Message message = Message.obtain(mWebView.mPrivateHandler,
489 WebView.ENTER_FULLSCREEN_VIDEO, layerId, 0);
490 message.obj = url;
491 message.sendToTarget();
Nicolas Roard0e778a12011-03-11 14:29:05 -0800492 }
493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 //-------------------------------------------------------------------------
495 // JNI methods
496 //-------------------------------------------------------------------------
497
Cary Clark3e399de2009-06-17 10:00:57 -0400498 static native String nativeFindAddress(String addr, boolean caseInsensitive);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499
500 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 * Empty the picture set.
502 */
503 private native void nativeClearContent();
Cary Clarkd6982c92009-05-29 11:02:22 -0400504
Cary Clark75796bb2010-08-24 14:59:58 -0400505 private native void nativeContentInvalidateAll();
506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 * Redraw a portion of the picture set. The Point wh returns the
509 * width and height of the overall picture.
510 */
Grace Kloba8abd50b2010-07-08 15:02:14 -0700511 private native int nativeRecordContent(Region invalRegion, Point wh);
Cary Clarkd6982c92009-05-29 11:02:22 -0400512
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700513 /**
514 * Update the layers' content
515 */
Patrick Scott2f492272010-12-03 09:52:35 -0500516 private native int nativeUpdateLayers(Region invalRegion);
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700517
Cary Clark5da9aeb2009-10-06 17:40:53 -0400518 private native boolean nativeFocusBoundsChanged();
519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 /**
Grace Kloba8abd50b2010-07-08 15:02:14 -0700521 * Splits slow parts of the picture set. Called from the webkit thread after
522 * WebView.nativeDraw() returns content to be split.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 */
Grace Kloba8abd50b2010-07-08 15:02:14 -0700524 private native void nativeSplitContent(int content);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525
526 private native boolean nativeKey(int keyCode, int unichar,
Cary Clark215b72c2009-06-26 14:38:43 -0400527 int repeatCount, boolean isShift, boolean isAlt, boolean isSym,
528 boolean isDown);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529
Leon Scrogginsb45a2632011-01-12 14:11:24 -0500530 private native void nativeClick(int framePtr, int nodePtr, boolean fake);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531
532 private native void nativeSendListBoxChoices(boolean[] choices, int size);
533
534 private native void nativeSendListBoxChoice(int choice);
535
536 /* Tell webkit what its width and height are, for the purposes
537 of layout/line-breaking. These coordinates are in document space,
538 which is the same as View coords unless we have zoomed the document
539 (see nativeSetZoom).
Grace Klobae80cbcc2010-05-28 18:07:50 -0700540 textWrapWidth is used by layout to wrap column around. If viewport uses
541 fixed size, textWrapWidth can be different from width with zooming.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 should this be called nativeSetViewPortSize?
543 */
Grace Klobae80cbcc2010-05-28 18:07:50 -0700544 private native void nativeSetSize(int width, int height, int textWrapWidth,
545 float scale, int screenWidth, int screenHeight, int anchorX,
Grace Kloba3a0def22010-01-23 21:11:54 -0800546 int anchorY, boolean ignoreHeight);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547
548 private native int nativeGetContentMinPrefWidth();
Cary Clarkd6982c92009-05-29 11:02:22 -0400549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 // Start: functions that deal with text editing
Cary Clark2f1d60c2009-06-03 08:05:53 -0400551 private native void nativeReplaceTextfieldText(
Leon Scroggins43488fc2009-07-06 14:32:49 -0400552 int oldStart, int oldEnd, String replace, int newStart, int newEnd,
553 int textGeneration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554
Cary Clark2f1d60c2009-06-03 08:05:53 -0400555 private native void passToJs(int gen,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 String currentText, int keyCode, int keyValue, boolean down,
557 boolean cap, boolean fn, boolean sym);
558
Leon Scroggins8cdad882009-06-30 08:47:04 -0400559 private native void nativeSetFocusControllerActive(boolean active);
Leon Scroggins63dda1c2009-04-15 13:25:00 -0400560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 private native void nativeSaveDocumentState(int frame);
562
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500563 private native void nativeMoveFocus(int framePtr, int nodePointer);
Cary Clarked56eda2009-06-18 09:48:47 -0400564 private native void nativeMoveMouse(int framePtr, int x, int y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565
Cary Clarkd6982c92009-05-29 11:02:22 -0400566 private native void nativeMoveMouseIfLatest(int moveGeneration,
Cary Clarked56eda2009-06-18 09:48:47 -0400567 int framePtr, int x, int y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568
Cary Clarke41bb532010-11-30 15:59:59 -0500569 private native String nativeRetrieveHref(int x, int y);
570 private native String nativeRetrieveAnchorText(int x, int y);
Cary Clark861368a2010-12-15 11:24:37 -0500571 private native String nativeRetrieveImageSource(int x, int y);
Leon Scrogginsb6112132011-02-24 12:35:50 -0500572 private native void nativeStopPaintingCaret();
Cary Clarkd6982c92009-05-29 11:02:22 -0400573 private native void nativeTouchUp(int touchGeneration,
Leon Scroggins22e883d2011-01-31 10:54:19 -0500574 int framePtr, int nodePtr, int x, int y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575
Huahui Wue838a422011-01-13 16:03:43 -0800576 private native boolean nativeHandleTouchEvent(int action, int[] idArray,
Huahui Wu2d3ef372011-03-13 18:13:42 -0700577 int[] xArray, int[] yArray, int count, int actionIndex, int metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 private native void nativeUpdateFrameCache();
Cary Clarkd6982c92009-05-29 11:02:22 -0400580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 private native void nativeSetBackgroundColor(int color);
Cary Clarkd6982c92009-05-29 11:02:22 -0400582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 private native void nativeDumpDomTree(boolean useFile);
584
585 private native void nativeDumpRenderTree(boolean useFile);
586
587 private native void nativeDumpNavTree();
588
Andrei Popescu5e7bb0a2010-02-01 22:32:16 +0000589 private native void nativeDumpV8Counters();
590
Feng Qianb3081372009-06-29 15:55:18 -0700591 private native void nativeSetJsFlags(String flags);
592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 /**
594 * Delete text from start to end in the focused textfield. If there is no
Cary Clarkd6982c92009-05-29 11:02:22 -0400595 * focus, or if start == end, silently fail. If start and end are out of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 * order, swap them.
597 * @param start Beginning of selection to delete.
598 * @param end End of selection to delete.
Leon Scroggins43488fc2009-07-06 14:32:49 -0400599 * @param textGeneration Text generation number when delete was pressed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 */
Leon Scroggins43488fc2009-07-06 14:32:49 -0400601 private native void nativeDeleteSelection(int start, int end,
602 int textGeneration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603
604 /**
605 * Set the selection to (start, end) in the focused textfield. If start and
606 * end are out of order, swap them.
607 * @param start Beginning of selection.
608 * @param end End of selection.
609 */
Cary Clark2f1d60c2009-06-03 08:05:53 -0400610 private native void nativeSetSelection(int start, int end);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 // Register a scheme to be treated as local scheme so that it can access
613 // local asset files for resources
614 private native void nativeRegisterURLSchemeAsLocal(String scheme);
615
Ben Murdoch7df19852009-04-22 13:07:58 +0100616 /*
617 * Inform webcore that the user has decided whether to allow or deny new
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100618 * quota for the current origin or more space for the app cache, and that
619 * the main thread should wake up now.
620 * @param limit Is the new quota for an origin or new app cache max size.
Ben Murdoch7df19852009-04-22 13:07:58 +0100621 */
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100622 private native void nativeSetNewStorageLimit(long limit);
Ben Murdoch7df19852009-04-22 13:07:58 +0100623
Steve Block4faee092009-07-28 18:20:50 +0100624 /**
625 * Provide WebCore with a Geolocation permission state for the specified
626 * origin.
627 * @param origin The origin for which Geolocation permissions are provided.
628 * @param allow Whether Geolocation permissions are allowed.
629 * @param remember Whether this decision should be remembered beyond the
630 * life of the current page.
631 */
632 private native void nativeGeolocationPermissionsProvide(String origin, boolean allow, boolean remember);
633
Leon Clarke194e3452009-09-28 11:42:12 +0100634 /**
635 * Provide WebCore with the previously visted links from the history database
636 */
Svetoslav Ganovda355512010-05-12 22:04:44 -0700637 private native void nativeProvideVisitedHistory(String[] history);
638
639 /**
640 * Modifies the current selection.
641 *
Svetoslav Ganovc93fb652011-01-05 18:52:05 -0800642 * Note: Accessibility support.
643 *
Svetoslav Ganovda355512010-05-12 22:04:44 -0700644 * @param direction The direction in which to alter the selection.
645 * @param granularity The granularity of the selection modification.
646 *
647 * @return The selection string.
648 */
Svetoslav Ganov585f13f8d2010-08-10 07:59:15 -0700649 private native String nativeModifySelection(int direction, int granularity);
Leon Clarke194e3452009-09-28 11:42:12 +0100650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 // EventHub for processing messages
652 private final EventHub mEventHub;
653 // WebCore thread handler
654 private static Handler sWebCoreHandler;
655 // Class for providing Handler creation inside the WebCore thread.
656 private static class WebCoreThread implements Runnable {
657 // Message id for initializing a new WebViewCore.
658 private static final int INITIALIZE = 0;
659 private static final int REDUCE_PRIORITY = 1;
660 private static final int RESUME_PRIORITY = 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661
662 public void run() {
663 Looper.prepare();
664 Assert.assertNull(sWebCoreHandler);
665 synchronized (WebViewCore.class) {
666 sWebCoreHandler = new Handler() {
667 @Override
668 public void handleMessage(Message msg) {
669 switch (msg.what) {
670 case INITIALIZE:
671 WebViewCore core = (WebViewCore) msg.obj;
672 core.initialize();
673 break;
674
675 case REDUCE_PRIORITY:
676 // 3 is an adjustable number.
677 Process.setThreadPriority(
678 Process.THREAD_PRIORITY_DEFAULT + 3 *
679 Process.THREAD_PRIORITY_LESS_FAVORABLE);
680 break;
681
682 case RESUME_PRIORITY:
683 Process.setThreadPriority(
684 Process.THREAD_PRIORITY_DEFAULT);
685 break;
Kristian Monsen4190aab2010-12-16 18:39:21 +0000686
687 case EventHub.ADD_PACKAGE_NAME:
688 if (BrowserFrame.sJavaBridge == null) {
689 throw new IllegalStateException(
690 "No WebView has been created in this process!");
691 }
692 BrowserFrame.sJavaBridge.addPackageName((String) msg.obj);
693 break;
694
695 case EventHub.REMOVE_PACKAGE_NAME:
696 if (BrowserFrame.sJavaBridge == null) {
697 throw new IllegalStateException(
698 "No WebView has been created in this process!");
699 }
700 BrowserFrame.sJavaBridge.removePackageName((String) msg.obj);
701 break;
Kristian Monsen41e7e6f2010-12-21 12:51:11 +0000702
703 case EventHub.PROXY_CHANGED:
704 if (BrowserFrame.sJavaBridge == null) {
705 throw new IllegalStateException(
706 "No WebView has been created in this process!");
707 }
708 BrowserFrame.sJavaBridge.updateProxy((String) msg.obj);
709 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 }
711 }
712 };
713 WebViewCore.class.notify();
714 }
715 Looper.loop();
716 }
717 }
718
Cary Clarkded054c2009-06-15 10:26:08 -0400719 static class BaseUrlData {
720 String mBaseUrl;
721 String mData;
722 String mMimeType;
723 String mEncoding;
Leon Scroggins1bb1a912010-03-23 15:39:46 -0400724 String mHistoryUrl;
Cary Clarkded054c2009-06-15 10:26:08 -0400725 }
726
Cary Clarkd6982c92009-05-29 11:02:22 -0400727 static class CursorData {
728 CursorData() {}
729 CursorData(int frame, int node, int x, int y) {
730 mFrame = frame;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500731 mNode = node;
Cary Clarkd6982c92009-05-29 11:02:22 -0400732 mX = x;
733 mY = y;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 }
735 int mMoveGeneration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 int mFrame;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500737 int mNode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 int mX;
739 int mY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 }
741
Cary Clarkded054c2009-06-15 10:26:08 -0400742 static class JSInterfaceData {
743 Object mObject;
744 String mInterfaceName;
745 }
746
747 static class JSKeyData {
748 String mCurrentText;
749 KeyEvent mEvent;
750 }
751
Cary Clark1cb97ee2009-12-11 12:10:36 -0500752 static class MotionUpData {
753 int mFrame;
754 int mNode;
755 Rect mBounds;
756 int mX;
757 int mY;
758 }
759
Grace Klobad0d9bc22010-01-26 18:08:28 -0800760 static class GetUrlData {
761 String mUrl;
762 Map<String, String> mExtraHeaders;
763 }
764
Cary Clarkded054c2009-06-15 10:26:08 -0400765 static class PostUrlData {
766 String mUrl;
767 byte[] mPostData;
768 }
769
770 static class ReplaceTextData {
771 String mReplace;
772 int mNewStart;
773 int mNewEnd;
Leon Scroggins43488fc2009-07-06 14:32:49 -0400774 int mTextGeneration;
Cary Clarkded054c2009-06-15 10:26:08 -0400775 }
776
Leon Scroggins6679f2f2009-08-12 18:48:10 -0400777 static class TextSelectionData {
778 public TextSelectionData(int start, int end) {
779 mStart = start;
780 mEnd = end;
781 }
782 int mStart;
783 int mEnd;
784 }
785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 static class TouchUpData {
787 int mMoveGeneration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 int mFrame;
789 int mNode;
790 int mX;
791 int mY;
Patrick Scottcfa734a2011-02-22 11:19:02 -0500792 int mNativeLayer;
793 Rect mNativeLayerRect = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 }
795
Grace Kloba178db412010-05-18 22:22:23 -0700796 static class TouchHighlightData {
797 int mX;
798 int mY;
799 int mSlop;
800 }
801
Ben Murdochdb8d19c2010-10-29 11:44:17 +0100802 static class AutoFillData {
803 public AutoFillData() {
804 mQueryId = WebTextView.FORM_NOT_AUTOFILLABLE;
805 mPreview = "";
806 }
807
808 public AutoFillData(int queryId, String preview) {
809 mQueryId = queryId;
810 mPreview = preview;
811 }
812
813 public int getQueryId() {
814 return mQueryId;
815 }
816
817 public String getPreviewString() {
818 return mPreview;
819 }
820
821 private int mQueryId;
822 private String mPreview;
823 }
824
Grace Kloba5f68d6f2009-12-08 18:42:54 -0800825 // mAction of TouchEventData can be MotionEvent.getAction() which uses the
826 // last two bytes or one of the following values
827 static final int ACTION_LONGPRESS = 0x100;
828 static final int ACTION_DOUBLETAP = 0x200;
829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static class TouchEventData {
Grace Kloba5f68d6f2009-12-08 18:42:54 -0800831 int mAction;
Huahui Wue838a422011-01-13 16:03:43 -0800832 int[] mIds; // Ids of the touch points
Huahui Wu41865f42010-09-02 13:41:41 -0700833 Point[] mPoints;
Huahui Wu88b869a2011-03-17 17:42:12 -0700834 Point[] mPointsInView; // the point coordinates in view axis.
Huahui Wu2d3ef372011-03-13 18:13:42 -0700835 int mActionIndex; // Associated pointer index for ACTION_POINTER_DOWN/UP
Ben Murdoch8a032a32010-02-02 18:20:11 +0000836 int mMetaState;
Grace Klobac2242f22010-03-05 14:00:26 -0800837 boolean mReprocess;
Huahui Wu0904c0d2011-01-07 17:30:53 -0800838 MotionEvent mMotionEvent;
Patrick Scottcfa734a2011-02-22 11:19:02 -0500839 int mNativeLayer;
840 Rect mNativeLayerRect = new Rect();
Adam Powell4fb35d42011-03-03 17:54:55 -0800841 long mSequence;
842 boolean mNativeResult;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 }
844
Steve Block4faee092009-07-28 18:20:50 +0100845 static class GeolocationPermissionsData {
846 String mOrigin;
847 boolean mAllow;
848 boolean mRemember;
849 }
850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 static final String[] HandlerDebugString = {
Leon Scroggins200c13d2010-05-14 15:35:42 -0400852 "REVEAL_SELECTION", // 96
Leon Scroggins3a503392010-01-06 17:04:38 -0500853 "REQUEST_LABEL", // 97
Cary Clark77d98f42009-07-31 09:40:38 -0400854 "UPDATE_FRAME_CACHE_IF_LOADING", // = 98
Leon Scroggins72543e12009-07-23 15:29:45 -0400855 "SCROLL_TEXT_INPUT", // = 99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 "LOAD_URL", // = 100;
857 "STOP_LOADING", // = 101;
858 "RELOAD", // = 102;
859 "KEY_DOWN", // = 103;
860 "KEY_UP", // = 104;
861 "VIEW_SIZE_CHANGED", // = 105;
862 "GO_BACK_FORWARD", // = 106;
863 "SET_SCROLL_OFFSET", // = 107;
864 "RESTORE_STATE", // = 108;
865 "PAUSE_TIMERS", // = 109;
866 "RESUME_TIMERS", // = 110;
867 "CLEAR_CACHE", // = 111;
868 "CLEAR_HISTORY", // = 112;
869 "SET_SELECTION", // = 113;
870 "REPLACE_TEXT", // = 114;
871 "PASS_TO_JS", // = 115;
872 "SET_GLOBAL_BOUNDS", // = 116;
873 "UPDATE_CACHE_AND_TEXT_ENTRY", // = 117;
874 "CLICK", // = 118;
Grace Klobaa72cc092009-04-02 08:50:17 -0700875 "SET_NETWORK_STATE", // = 119;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 "DOC_HAS_IMAGES", // = 120;
Leon Scrogginsb45a2632011-01-12 14:11:24 -0500877 "FAKE_CLICK", // = 121;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 "DELETE_SELECTION", // = 122;
879 "LISTBOX_CHOICES", // = 123;
880 "SINGLE_LISTBOX_CHOICE", // = 124;
Grace Klobab3230cb2009-04-13 14:04:23 -0700881 "MESSAGE_RELAY", // = 125;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 "SET_BACKGROUND_COLOR", // = 126;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500883 "SET_MOVE_FOCUS", // = 127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 "SAVE_DOCUMENT_STATE", // = 128;
Cary Clark57d2c3a2009-12-23 13:57:15 -0500885 "129", // = 129;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 "WEBKIT_DRAW", // = 130;
Patrick Scottfa8be1c2011-02-02 14:09:34 -0500887 "131", // = 131;
Grace Kloba57534302009-05-22 18:55:02 -0700888 "POST_URL", // = 132;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 "SPLIT_PICTURE_SET", // = 133;
890 "CLEAR_CONTENT", // = 134;
Cary Clarkd6982c92009-05-29 11:02:22 -0400891 "SET_MOVE_MOUSE", // = 135;
892 "SET_MOVE_MOUSE_IF_LATEST", // = 136;
Leon Scroggins1c7f8c52009-06-05 13:49:26 -0400893 "REQUEST_CURSOR_HREF", // = 137;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 "ADD_JS_INTERFACE", // = 138;
895 "LOAD_DATA", // = 139;
896 "TOUCH_UP", // = 140;
897 "TOUCH_EVENT", // = 141;
Leon Scroggins8cdad882009-06-30 08:47:04 -0400898 "SET_ACTIVE", // = 142;
Mike Reedd205d5b2009-05-27 11:02:29 -0400899 "ON_PAUSE", // = 143
900 "ON_RESUME", // = 144
Derek Sollenbergere0155e92009-06-10 15:35:45 -0400901 "FREE_MEMORY", // = 145
Cary Clark1cb97ee2009-12-11 12:10:36 -0500902 "VALID_NODE_BOUNDS", // = 146
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -0700903 "SAVE_WEBARCHIVE", // = 147
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700904 "WEBKIT_DRAW_LAYERS", // = 148;
Steve Block689a3422010-12-07 18:18:26 +0000905 "REMOVE_JS_INTERFACE", // = 149;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 };
907
908 class EventHub {
909 // Message Ids
Leon Scroggins200c13d2010-05-14 15:35:42 -0400910 static final int REVEAL_SELECTION = 96;
Leon Scroggins3a503392010-01-06 17:04:38 -0500911 static final int REQUEST_LABEL = 97;
Cary Clark77d98f42009-07-31 09:40:38 -0400912 static final int UPDATE_FRAME_CACHE_IF_LOADING = 98;
Leon Scroggins72543e12009-07-23 15:29:45 -0400913 static final int SCROLL_TEXT_INPUT = 99;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 static final int LOAD_URL = 100;
915 static final int STOP_LOADING = 101;
916 static final int RELOAD = 102;
917 static final int KEY_DOWN = 103;
918 static final int KEY_UP = 104;
919 static final int VIEW_SIZE_CHANGED = 105;
920 static final int GO_BACK_FORWARD = 106;
921 static final int SET_SCROLL_OFFSET = 107;
922 static final int RESTORE_STATE = 108;
923 static final int PAUSE_TIMERS = 109;
924 static final int RESUME_TIMERS = 110;
925 static final int CLEAR_CACHE = 111;
926 static final int CLEAR_HISTORY = 112;
927 static final int SET_SELECTION = 113;
928 static final int REPLACE_TEXT = 114;
929 static final int PASS_TO_JS = 115;
930 static final int SET_GLOBAL_BOUNDS = 116;
931 static final int UPDATE_CACHE_AND_TEXT_ENTRY = 117;
932 static final int CLICK = 118;
Grace Klobaa72cc092009-04-02 08:50:17 -0700933 static final int SET_NETWORK_STATE = 119;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 static final int DOC_HAS_IMAGES = 120;
Leon Scrogginsb45a2632011-01-12 14:11:24 -0500935 static final int FAKE_CLICK = 121;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 static final int DELETE_SELECTION = 122;
937 static final int LISTBOX_CHOICES = 123;
938 static final int SINGLE_LISTBOX_CHOICE = 124;
Grace Klobab3230cb2009-04-13 14:04:23 -0700939 static final int MESSAGE_RELAY = 125;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 static final int SET_BACKGROUND_COLOR = 126;
Leon Scroggins47fabbf2009-12-08 16:57:26 -0500941 static final int SET_MOVE_FOCUS = 127;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 static final int SAVE_DOCUMENT_STATE = 128;
Cary Clark57d2c3a2009-12-23 13:57:15 -0500943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 static final int WEBKIT_DRAW = 130;
Grace Kloba57534302009-05-22 18:55:02 -0700945 static final int POST_URL = 132;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 static final int SPLIT_PICTURE_SET = 133;
947 static final int CLEAR_CONTENT = 134;
Cary Clarkd6982c92009-05-29 11:02:22 -0400948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 // UI nav messages
Cary Clarkd6982c92009-05-29 11:02:22 -0400950 static final int SET_MOVE_MOUSE = 135;
951 static final int SET_MOVE_MOUSE_IF_LATEST = 136;
Leon Scroggins1c7f8c52009-06-05 13:49:26 -0400952 static final int REQUEST_CURSOR_HREF = 137;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 static final int ADD_JS_INTERFACE = 138;
954 static final int LOAD_DATA = 139;
955
956 // motion
957 static final int TOUCH_UP = 140;
958 // message used to pass UI touch events to WebCore
959 static final int TOUCH_EVENT = 141;
960
Leon Scrogginsfa03cde2009-06-15 15:48:46 -0400961 // Used to tell the focus controller not to draw the blinking cursor,
962 // based on whether the WebView has focus and whether the WebView's
963 // cursor matches the webpage's focus.
Leon Scroggins8cdad882009-06-30 08:47:04 -0400964 static final int SET_ACTIVE = 142;
Leon Scroggins63dda1c2009-04-15 13:25:00 -0400965
Derek Sollenbergere0155e92009-06-10 15:35:45 -0400966 // lifecycle activities for just this DOM (unlike pauseTimers, which
Mike Reedd205d5b2009-05-27 11:02:29 -0400967 // is global)
968 static final int ON_PAUSE = 143;
969 static final int ON_RESUME = 144;
Derek Sollenbergere0155e92009-06-10 15:35:45 -0400970 static final int FREE_MEMORY = 145;
Cary Clark1cb97ee2009-12-11 12:10:36 -0500971 static final int VALID_NODE_BOUNDS = 146;
Mike Reedd205d5b2009-05-27 11:02:29 -0400972
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -0700973 // Load and save web archives
974 static final int SAVE_WEBARCHIVE = 147;
975
Nicolas Roardfb7bc342010-11-01 15:08:03 -0700976 // Update layers
977 static final int WEBKIT_DRAW_LAYERS = 148;
978
Steve Block689a3422010-12-07 18:18:26 +0000979 static final int REMOVE_JS_INTERFACE = 149;
980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 // Network-based messaging
982 static final int CLEAR_SSL_PREF_TABLE = 150;
983
984 // Test harness messages
985 static final int REQUEST_EXT_REPRESENTATION = 160;
986 static final int REQUEST_DOC_AS_TEXT = 161;
987
988 // debugging
989 static final int DUMP_DOMTREE = 170;
990 static final int DUMP_RENDERTREE = 171;
991 static final int DUMP_NAVTREE = 172;
Andrei Popescu5e7bb0a2010-02-01 22:32:16 +0000992 static final int DUMP_V8COUNTERS = 173;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993
Andrei Popescu5e7bb0a2010-02-01 22:32:16 +0000994 static final int SET_JS_FLAGS = 174;
Steve Block4faee092009-07-28 18:20:50 +0100995 // Geolocation
996 static final int GEOLOCATION_PERMISSIONS_PROVIDE = 180;
Feng Qianb3081372009-06-29 15:55:18 -0700997
Leon Clarke194e3452009-09-28 11:42:12 +0100998 static final int POPULATE_VISITED_LINKS = 181;
999
Grace Kloba11438c32009-12-16 11:39:12 -08001000 static final int HIDE_FULLSCREEN = 182;
1001
Andrei Popescuf5dba882010-01-12 22:42:41 +00001002 static final int SET_NETWORK_TYPE = 183;
1003
Andrei Popescua6d747d2010-02-11 13:19:21 +00001004 // navigator.isApplicationInstalled()
1005 static final int ADD_PACKAGE_NAMES = 184;
1006 static final int ADD_PACKAGE_NAME = 185;
1007 static final int REMOVE_PACKAGE_NAME = 186;
1008
Grace Kloba178db412010-05-18 22:22:23 -07001009 static final int GET_TOUCH_HIGHLIGHT_RECTS = 187;
1010 static final int REMOVE_TOUCH_HIGHLIGHT_RECTS = 188;
1011
Svetoslav Ganovda355512010-05-12 22:04:44 -07001012 // accessibility support
1013 static final int MODIFY_SELECTION = 190;
1014
Steve Block68dede32010-08-04 10:28:46 +01001015 static final int USE_MOCK_DEVICE_ORIENTATION = 191;
1016
Ben Murdoch62275a42010-09-07 11:27:28 +01001017 static final int AUTOFILL_FORM = 192;
1018
Kristian Monsen41e7e6f2010-12-21 12:51:11 +00001019 static final int PROXY_CHANGED = 193;
1020
Narayan Kamath9497c5f2011-02-22 12:05:34 +00001021 static final int EXECUTE_JS = 194;
1022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 // private message ids
1024 private static final int DESTROY = 200;
Cary Clarkd6982c92009-05-29 11:02:22 -04001025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001026 // Private handler for WebCore messages.
1027 private Handler mHandler;
1028 // Message queue for containing messages before the WebCore thread is
1029 // ready.
1030 private ArrayList<Message> mMessages = new ArrayList<Message>();
1031 // Flag for blocking messages. This is used during DESTROY to avoid
1032 // posting more messages to the EventHub or to WebView's event handler.
1033 private boolean mBlockMessages;
1034
1035 private int mTid;
1036 private int mSavedPriority;
1037
1038 /**
1039 * Prevent other classes from creating an EventHub.
1040 */
1041 private EventHub() {}
1042
Leon Scroggins200c13d2010-05-14 15:35:42 -04001043 private static final int FIRST_PACKAGE_MSG_ID = REVEAL_SELECTION;
1044 private static final int LAST_PACKAGE_MSG_ID = VALID_NODE_BOUNDS;
1045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 /**
1047 * Transfer all messages to the newly created webcore thread handler.
1048 */
1049 private void transferMessages() {
1050 mTid = Process.myTid();
1051 mSavedPriority = Process.getThreadPriority(mTid);
1052
1053 mHandler = new Handler() {
1054 @Override
1055 public void handleMessage(Message msg) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001056 if (DebugFlags.WEB_VIEW_CORE) {
Leon Scroggins200c13d2010-05-14 15:35:42 -04001057 Log.v(LOGTAG, (msg.what < FIRST_PACKAGE_MSG_ID
1058 || msg.what > LAST_PACKAGE_MSG_ID
1059 ? Integer.toString(msg.what)
Leon Scroggins72543e12009-07-23 15:29:45 -04001060 : HandlerDebugString[msg.what
Leon Scroggins200c13d2010-05-14 15:35:42 -04001061 - FIRST_PACKAGE_MSG_ID])
Cary Clark243ea062009-06-25 10:49:32 -04001062 + " arg1=" + msg.arg1 + " arg2=" + msg.arg2
1063 + " obj=" + msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 }
1065 switch (msg.what) {
1066 case WEBKIT_DRAW:
1067 webkitDraw();
1068 break;
1069
Nicolas Roardfb7bc342010-11-01 15:08:03 -07001070 case WEBKIT_DRAW_LAYERS:
1071 webkitDrawLayers();
1072 break;
1073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 case DESTROY:
1075 // Time to take down the world. Cancel all pending
1076 // loads and destroy the native view and frame.
Cary Clark674a8442009-09-15 16:25:43 -04001077 synchronized (WebViewCore.this) {
1078 mBrowserFrame.destroy();
1079 mBrowserFrame = null;
Andrei Popescudee76be2009-09-22 18:28:21 +01001080 mSettings.onDestroyed();
Cary Clark674a8442009-09-15 16:25:43 -04001081 mNativeClass = 0;
Ben Murdoch3dba1e42009-09-22 15:50:30 +01001082 mWebView = null;
Cary Clark674a8442009-09-15 16:25:43 -04001083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 break;
1085
Leon Scroggins200c13d2010-05-14 15:35:42 -04001086 case REVEAL_SELECTION:
1087 nativeRevealSelection();
1088 break;
1089
Leon Scroggins3a503392010-01-06 17:04:38 -05001090 case REQUEST_LABEL:
1091 if (mWebView != null) {
1092 int nodePointer = msg.arg2;
1093 String label = nativeRequestLabel(msg.arg1,
1094 nodePointer);
1095 if (label != null && label.length() > 0) {
1096 Message.obtain(mWebView.mPrivateHandler,
1097 WebView.RETURN_LABEL, nodePointer,
1098 0, label).sendToTarget();
1099 }
1100 }
1101 break;
1102
Cary Clark77d98f42009-07-31 09:40:38 -04001103 case UPDATE_FRAME_CACHE_IF_LOADING:
1104 nativeUpdateFrameCacheIfLoading();
1105 break;
1106
Leon Scroggins72543e12009-07-23 15:29:45 -04001107 case SCROLL_TEXT_INPUT:
Leon Scroggins22e883d2011-01-31 10:54:19 -05001108 float xPercent;
1109 if (msg.obj == null) {
1110 xPercent = 0f;
1111 } else {
1112 xPercent = ((Float) msg.obj).floatValue();
1113 }
1114 nativeScrollFocusedTextInput(xPercent, msg.arg2);
Leon Scroggins72543e12009-07-23 15:29:45 -04001115 break;
1116
Grace Klobad0d9bc22010-01-26 18:08:28 -08001117 case LOAD_URL: {
Kristian Monsen85173052010-12-08 15:29:29 +00001118 CookieManager.getInstance().waitForCookieOperationsToComplete();
Grace Klobad0d9bc22010-01-26 18:08:28 -08001119 GetUrlData param = (GetUrlData) msg.obj;
1120 loadUrl(param.mUrl, param.mExtraHeaders);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 break;
Grace Klobad0d9bc22010-01-26 18:08:28 -08001122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123
Grace Kloba57534302009-05-22 18:55:02 -07001124 case POST_URL: {
Kristian Monsen85173052010-12-08 15:29:29 +00001125 CookieManager.getInstance().waitForCookieOperationsToComplete();
Cary Clarkded054c2009-06-15 10:26:08 -04001126 PostUrlData param = (PostUrlData) msg.obj;
1127 mBrowserFrame.postUrl(param.mUrl, param.mPostData);
Grace Kloba57534302009-05-22 18:55:02 -07001128 break;
1129 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 case LOAD_DATA:
Kristian Monsen85173052010-12-08 15:29:29 +00001131 CookieManager.getInstance().waitForCookieOperationsToComplete();
Cary Clarkded054c2009-06-15 10:26:08 -04001132 BaseUrlData loadParams = (BaseUrlData) msg.obj;
1133 String baseUrl = loadParams.mBaseUrl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 if (baseUrl != null) {
1135 int i = baseUrl.indexOf(':');
1136 if (i > 0) {
1137 /*
1138 * In 1.0, {@link
1139 * WebView#loadDataWithBaseURL} can access
1140 * local asset files as long as the data is
1141 * valid. In the new WebKit, the restriction
1142 * is tightened. To be compatible with 1.0,
1143 * we automatically add the scheme of the
1144 * baseUrl for local access as long as it is
1145 * not http(s)/ftp(s)/about/javascript
Cary Clarkd6982c92009-05-29 11:02:22 -04001146 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 String scheme = baseUrl.substring(0, i);
1148 if (!scheme.startsWith("http") &&
1149 !scheme.startsWith("ftp") &&
1150 !scheme.startsWith("about") &&
1151 !scheme.startsWith("javascript")) {
1152 nativeRegisterURLSchemeAsLocal(scheme);
1153 }
1154 }
1155 }
1156 mBrowserFrame.loadData(baseUrl,
Cary Clarkded054c2009-06-15 10:26:08 -04001157 loadParams.mData,
1158 loadParams.mMimeType,
1159 loadParams.mEncoding,
Leon Scroggins1bb1a912010-03-23 15:39:46 -04001160 loadParams.mHistoryUrl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001161 break;
1162
1163 case STOP_LOADING:
Cary Clarkd6982c92009-05-29 11:02:22 -04001164 // If the WebCore has committed the load, but not
1165 // finished the first layout yet, we need to set
1166 // first layout done to trigger the interpreted side sync
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 // up with native side
1168 if (mBrowserFrame.committed()
1169 && !mBrowserFrame.firstLayoutDone()) {
1170 mBrowserFrame.didFirstLayout();
1171 }
1172 // Do this after syncing up the layout state.
1173 stopLoading();
1174 break;
1175
1176 case RELOAD:
1177 mBrowserFrame.reload(false);
1178 break;
1179
1180 case KEY_DOWN:
1181 key((KeyEvent) msg.obj, true);
1182 break;
1183
1184 case KEY_UP:
1185 key((KeyEvent) msg.obj, false);
1186 break;
1187
Leon Scrogginsb45a2632011-01-12 14:11:24 -05001188 case FAKE_CLICK:
1189 nativeClick(msg.arg1, msg.arg2, true);
1190 break;
1191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 case CLICK:
Leon Scrogginsb45a2632011-01-12 14:11:24 -05001193 nativeClick(msg.arg1, msg.arg2, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 break;
1195
Grace Klobaef347ef2009-07-30 11:20:32 -07001196 case VIEW_SIZE_CHANGED: {
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001197 viewSizeChanged((WebView.ViewSizeData) msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198 break;
Grace Klobaef347ef2009-07-30 11:20:32 -07001199 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 case SET_SCROLL_OFFSET:
1201 // note: these are in document coordinates
1202 // (inv-zoom)
Cary Clarked56eda2009-06-18 09:48:47 -04001203 Point pt = (Point) msg.obj;
Patrick Scottfa8be1c2011-02-02 14:09:34 -05001204 nativeSetScrollOffset(msg.arg1, msg.arg2 == 1,
1205 pt.x, pt.y);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001206 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 case SET_GLOBAL_BOUNDS:
1209 Rect r = (Rect) msg.obj;
1210 nativeSetGlobalBounds(r.left, r.top, r.width(),
1211 r.height());
1212 break;
1213
1214 case GO_BACK_FORWARD:
1215 // If it is a standard load and the load is not
1216 // committed yet, we interpret BACK as RELOAD
1217 if (!mBrowserFrame.committed() && msg.arg1 == -1 &&
Cary Clarkd6982c92009-05-29 11:02:22 -04001218 (mBrowserFrame.loadType() ==
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001219 BrowserFrame.FRAME_LOADTYPE_STANDARD)) {
1220 mBrowserFrame.reload(true);
1221 } else {
1222 mBrowserFrame.goBackOrForward(msg.arg1);
1223 }
1224 break;
1225
1226 case RESTORE_STATE:
1227 stopLoading();
1228 restoreState(msg.arg1);
1229 break;
1230
1231 case PAUSE_TIMERS:
1232 mSavedPriority = Process.getThreadPriority(mTid);
1233 Process.setThreadPriority(mTid,
1234 Process.THREAD_PRIORITY_BACKGROUND);
1235 pauseTimers();
Steve Block808751f2011-01-04 14:26:27 +00001236 if (!JniUtil.useChromiumHttpStack()) {
1237 WebViewWorker.getHandler().sendEmptyMessage(
1238 WebViewWorker.MSG_PAUSE_CACHE_TRANSACTION);
1239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 break;
1241
1242 case RESUME_TIMERS:
1243 Process.setThreadPriority(mTid, mSavedPriority);
1244 resumeTimers();
Steve Block808751f2011-01-04 14:26:27 +00001245 if (!JniUtil.useChromiumHttpStack()) {
1246 WebViewWorker.getHandler().sendEmptyMessage(
1247 WebViewWorker.MSG_RESUME_CACHE_TRANSACTION);
1248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 break;
1250
Mike Reedd205d5b2009-05-27 11:02:29 -04001251 case ON_PAUSE:
1252 nativePause();
1253 break;
1254
1255 case ON_RESUME:
1256 nativeResume();
1257 break;
1258
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001259 case FREE_MEMORY:
1260 clearCache(false);
1261 nativeFreeMemory();
1262 break;
1263
Grace Klobaa72cc092009-04-02 08:50:17 -07001264 case SET_NETWORK_STATE:
1265 if (BrowserFrame.sJavaBridge == null) {
1266 throw new IllegalStateException("No WebView " +
1267 "has been created in this process!");
1268 }
1269 BrowserFrame.sJavaBridge
1270 .setNetworkOnLine(msg.arg1 == 1);
1271 break;
1272
Andrei Popescuf5dba882010-01-12 22:42:41 +00001273 case SET_NETWORK_TYPE:
1274 if (BrowserFrame.sJavaBridge == null) {
1275 throw new IllegalStateException("No WebView " +
1276 "has been created in this process!");
1277 }
1278 Map<String, String> map = (Map<String, String>) msg.obj;
1279 BrowserFrame.sJavaBridge
1280 .setNetworkType(map.get("type"), map.get("subtype"));
1281 break;
1282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 case CLEAR_CACHE:
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001284 clearCache(msg.arg1 == 1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 break;
1286
1287 case CLEAR_HISTORY:
1288 mCallbackProxy.getBackForwardList().
1289 close(mBrowserFrame.mNativeFrame);
1290 break;
1291
Cary Clarkd6982c92009-05-29 11:02:22 -04001292 case REPLACE_TEXT:
Cary Clarkded054c2009-06-15 10:26:08 -04001293 ReplaceTextData rep = (ReplaceTextData) msg.obj;
1294 nativeReplaceTextfieldText(msg.arg1, msg.arg2,
Leon Scroggins43488fc2009-07-06 14:32:49 -04001295 rep.mReplace, rep.mNewStart, rep.mNewEnd,
1296 rep.mTextGeneration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 break;
1298
1299 case PASS_TO_JS: {
Cary Clarkded054c2009-06-15 10:26:08 -04001300 JSKeyData jsData = (JSKeyData) msg.obj;
1301 KeyEvent evt = jsData.mEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 int keyCode = evt.getKeyCode();
1303 int keyValue = evt.getUnicodeChar();
1304 int generation = msg.arg1;
Cary Clark2f1d60c2009-06-03 08:05:53 -04001305 passToJs(generation,
Cary Clarkded054c2009-06-15 10:26:08 -04001306 jsData.mCurrentText,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 keyCode,
1308 keyValue,
1309 evt.isDown(),
1310 evt.isShiftPressed(), evt.isAltPressed(),
1311 evt.isSymPressed());
1312 break;
1313 }
1314
1315 case SAVE_DOCUMENT_STATE: {
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001316 CursorData cDat = (CursorData) msg.obj;
1317 nativeSaveDocumentState(cDat.mFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 break;
1319 }
1320
1321 case CLEAR_SSL_PREF_TABLE:
1322 Network.getInstance(mContext)
1323 .clearUserSslPrefTable();
1324 break;
1325
1326 case TOUCH_UP:
1327 TouchUpData touchUpData = (TouchUpData) msg.obj;
Patrick Scottcfa734a2011-02-22 11:19:02 -05001328 if (touchUpData.mNativeLayer != 0) {
1329 nativeScrollLayer(touchUpData.mNativeLayer,
1330 touchUpData.mNativeLayerRect);
1331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 nativeTouchUp(touchUpData.mMoveGeneration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 touchUpData.mFrame, touchUpData.mNode,
Leon Scroggins22e883d2011-01-31 10:54:19 -05001334 touchUpData.mX, touchUpData.mY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 break;
1336
1337 case TOUCH_EVENT: {
1338 TouchEventData ted = (TouchEventData) msg.obj;
Huahui Wu41865f42010-09-02 13:41:41 -07001339 final int count = ted.mPoints.length;
1340 int[] xArray = new int[count];
1341 int[] yArray = new int[count];
1342 for (int c = 0; c < count; c++) {
1343 xArray[c] = ted.mPoints[c].x;
1344 yArray[c] = ted.mPoints[c].y;
1345 }
Patrick Scottcfa734a2011-02-22 11:19:02 -05001346 if (ted.mNativeLayer != 0) {
1347 nativeScrollLayer(ted.mNativeLayer,
1348 ted.mNativeLayerRect);
1349 }
Adam Powell4fb35d42011-03-03 17:54:55 -08001350 ted.mNativeResult = nativeHandleTouchEvent(ted.mAction, ted.mIds,
Huahui Wu2d3ef372011-03-13 18:13:42 -07001351 xArray, yArray, count, ted.mActionIndex, ted.mMetaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 Message.obtain(
1353 mWebView.mPrivateHandler,
Grace Klobac2242f22010-03-05 14:00:26 -08001354 WebView.PREVENT_TOUCH_ID,
1355 ted.mAction,
Adam Powell4fb35d42011-03-03 17:54:55 -08001356 ted.mNativeResult ? 1 : 0,
1357 ted).sendToTarget();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 break;
1359 }
1360
Leon Scroggins8cdad882009-06-30 08:47:04 -04001361 case SET_ACTIVE:
1362 nativeSetFocusControllerActive(msg.arg1 == 1);
Leon Scroggins63dda1c2009-04-15 13:25:00 -04001363 break;
1364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 case ADD_JS_INTERFACE:
Cary Clarkded054c2009-06-15 10:26:08 -04001366 JSInterfaceData jsData = (JSInterfaceData) msg.obj;
1367 mBrowserFrame.addJavascriptInterface(jsData.mObject,
1368 jsData.mInterfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 break;
1370
Steve Block689a3422010-12-07 18:18:26 +00001371 case REMOVE_JS_INTERFACE:
1372 jsData = (JSInterfaceData) msg.obj;
1373 mBrowserFrame.removeJavascriptInterface(
1374 jsData.mInterfaceName);
1375 break;
1376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 case REQUEST_EXT_REPRESENTATION:
1378 mBrowserFrame.externalRepresentation(
1379 (Message) msg.obj);
1380 break;
1381
1382 case REQUEST_DOC_AS_TEXT:
1383 mBrowserFrame.documentAsText((Message) msg.obj);
1384 break;
1385
Leon Scroggins47fabbf2009-12-08 16:57:26 -05001386 case SET_MOVE_FOCUS:
1387 CursorData focusData = (CursorData) msg.obj;
1388 nativeMoveFocus(focusData.mFrame, focusData.mNode);
1389 break;
1390
Cary Clarkd6982c92009-05-29 11:02:22 -04001391 case SET_MOVE_MOUSE:
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001392 CursorData cursorData = (CursorData) msg.obj;
1393 nativeMoveMouse(cursorData.mFrame,
Cary Clarked56eda2009-06-18 09:48:47 -04001394 cursorData.mX, cursorData.mY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 break;
1396
Cary Clarkd6982c92009-05-29 11:02:22 -04001397 case SET_MOVE_MOUSE_IF_LATEST:
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001398 CursorData cData = (CursorData) msg.obj;
1399 nativeMoveMouseIfLatest(cData.mMoveGeneration,
Cary Clarked56eda2009-06-18 09:48:47 -04001400 cData.mFrame,
1401 cData.mX, cData.mY);
Leon Scrogginsb6112132011-02-24 12:35:50 -05001402 if (msg.arg1 == 1) {
1403 nativeStopPaintingCaret();
1404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 break;
1406
Leon Scroggins1c7f8c52009-06-05 13:49:26 -04001407 case REQUEST_CURSOR_HREF: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 Message hrefMsg = (Message) msg.obj;
Ben Murdoch0a784a52009-11-17 18:13:02 +00001409 hrefMsg.getData().putString("url",
1410 nativeRetrieveHref(msg.arg1, msg.arg2));
1411 hrefMsg.getData().putString("title",
1412 nativeRetrieveAnchorText(msg.arg1, msg.arg2));
Cary Clark861368a2010-12-15 11:24:37 -05001413 hrefMsg.getData().putString("src",
1414 nativeRetrieveImageSource(msg.arg1, msg.arg2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 hrefMsg.sendToTarget();
1416 break;
1417 }
Cary Clarkd6982c92009-05-29 11:02:22 -04001418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 case UPDATE_CACHE_AND_TEXT_ENTRY:
1420 nativeUpdateFrameCache();
1421 // FIXME: this should provide a minimal rectangle
1422 if (mWebView != null) {
1423 mWebView.postInvalidate();
1424 }
1425 sendUpdateTextEntry();
1426 break;
1427
1428 case DOC_HAS_IMAGES:
1429 Message imageResult = (Message) msg.obj;
1430 imageResult.arg1 =
1431 mBrowserFrame.documentHasImages() ? 1 : 0;
1432 imageResult.sendToTarget();
1433 break;
1434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 case DELETE_SELECTION:
Leon Scroggins6679f2f2009-08-12 18:48:10 -04001436 TextSelectionData deleteSelectionData
1437 = (TextSelectionData) msg.obj;
Leon Scroggins43488fc2009-07-06 14:32:49 -04001438 nativeDeleteSelection(deleteSelectionData.mStart,
Leon Scroggins6679f2f2009-08-12 18:48:10 -04001439 deleteSelectionData.mEnd, msg.arg1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 break;
1441
1442 case SET_SELECTION:
Cary Clark2f1d60c2009-06-03 08:05:53 -04001443 nativeSetSelection(msg.arg1, msg.arg2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001445
Svetoslav Ganovda355512010-05-12 22:04:44 -07001446 case MODIFY_SELECTION:
Svetoslav Ganovc93fb652011-01-05 18:52:05 -08001447 String modifiedSelectionString = nativeModifySelection(msg.arg1,
1448 msg.arg2);
Svetoslav Ganov585f13f8d2010-08-10 07:59:15 -07001449 mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED,
Svetoslav Ganovc93fb652011-01-05 18:52:05 -08001450 modifiedSelectionString).sendToTarget();
1451 break;
1452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 case LISTBOX_CHOICES:
1454 SparseBooleanArray choices = (SparseBooleanArray)
1455 msg.obj;
1456 int choicesSize = msg.arg1;
1457 boolean[] choicesArray = new boolean[choicesSize];
1458 for (int c = 0; c < choicesSize; c++) {
1459 choicesArray[c] = choices.get(c);
1460 }
Cary Clarkd6982c92009-05-29 11:02:22 -04001461 nativeSendListBoxChoices(choicesArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 choicesSize);
1463 break;
1464
1465 case SINGLE_LISTBOX_CHOICE:
1466 nativeSendListBoxChoice(msg.arg1);
1467 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 case SET_BACKGROUND_COLOR:
1470 nativeSetBackgroundColor(msg.arg1);
1471 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 case DUMP_DOMTREE:
1474 nativeDumpDomTree(msg.arg1 == 1);
1475 break;
1476
1477 case DUMP_RENDERTREE:
1478 nativeDumpRenderTree(msg.arg1 == 1);
1479 break;
1480
1481 case DUMP_NAVTREE:
1482 nativeDumpNavTree();
1483 break;
1484
Andrei Popescu5e7bb0a2010-02-01 22:32:16 +00001485 case DUMP_V8COUNTERS:
1486 nativeDumpV8Counters();
1487 break;
1488
Feng Qianb3081372009-06-29 15:55:18 -07001489 case SET_JS_FLAGS:
1490 nativeSetJsFlags((String)msg.obj);
Feng Qian706cee42009-08-03 16:01:42 -07001491 break;
Steve Block4faee092009-07-28 18:20:50 +01001492
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -07001493 case SAVE_WEBARCHIVE:
1494 WebView.SaveWebArchiveMessage saveMessage =
1495 (WebView.SaveWebArchiveMessage)msg.obj;
1496 saveMessage.mResultFile =
1497 saveWebArchive(saveMessage.mBasename, saveMessage.mAutoname);
1498 mWebView.mPrivateHandler.obtainMessage(
1499 WebView.SAVE_WEBARCHIVE_FINISHED, saveMessage).sendToTarget();
1500 break;
1501
Steve Block4faee092009-07-28 18:20:50 +01001502 case GEOLOCATION_PERMISSIONS_PROVIDE:
1503 GeolocationPermissionsData data =
1504 (GeolocationPermissionsData) msg.obj;
1505 nativeGeolocationPermissionsProvide(data.mOrigin,
1506 data.mAllow, data.mRemember);
Feng Qianb3081372009-06-29 15:55:18 -07001507 break;
1508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 case SPLIT_PICTURE_SET:
Grace Kloba8abd50b2010-07-08 15:02:14 -07001510 nativeSplitContent(msg.arg1);
1511 mWebView.mPrivateHandler.obtainMessage(
1512 WebView.REPLACE_BASE_CONTENT, msg.arg1, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 mSplitPictureIsScheduled = false;
1514 break;
Cary Clarkd6982c92009-05-29 11:02:22 -04001515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 case CLEAR_CONTENT:
1517 // Clear the view so that onDraw() will draw nothing
1518 // but white background
1519 // (See public method WebView.clearView)
1520 nativeClearContent();
1521 break;
Grace Klobab3230cb2009-04-13 14:04:23 -07001522
1523 case MESSAGE_RELAY:
Patrick Scottfa8be1c2011-02-02 14:09:34 -05001524 ((Message) msg.obj).sendToTarget();
Grace Klobab3230cb2009-04-13 14:04:23 -07001525 break;
Leon Clarke194e3452009-09-28 11:42:12 +01001526
1527 case POPULATE_VISITED_LINKS:
1528 nativeProvideVisitedHistory((String[])msg.obj);
1529 break;
Cary Clark1cb97ee2009-12-11 12:10:36 -05001530
1531 case VALID_NODE_BOUNDS: {
1532 MotionUpData motionUpData = (MotionUpData) msg.obj;
Cary Clarkbad0c542010-01-11 14:58:21 -05001533 if (!nativeValidNodeAndBounds(
Cary Clark1cb97ee2009-12-11 12:10:36 -05001534 motionUpData.mFrame, motionUpData.mNode,
Cary Clarkbad0c542010-01-11 14:58:21 -05001535 motionUpData.mBounds)) {
1536 nativeUpdateFrameCache();
1537 }
Cary Clark1cb97ee2009-12-11 12:10:36 -05001538 Message message = mWebView.mPrivateHandler
1539 .obtainMessage(WebView.DO_MOTION_UP,
Cary Clarkbad0c542010-01-11 14:58:21 -05001540 motionUpData.mX, motionUpData.mY);
Cary Clark1cb97ee2009-12-11 12:10:36 -05001541 mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(
1542 message);
1543 break;
1544 }
Grace Kloba11438c32009-12-16 11:39:12 -08001545
1546 case HIDE_FULLSCREEN:
1547 nativeFullScreenPluginHidden(msg.arg1);
1548 break;
Andrei Popescua6d747d2010-02-11 13:19:21 +00001549
1550 case ADD_PACKAGE_NAMES:
1551 if (BrowserFrame.sJavaBridge == null) {
1552 throw new IllegalStateException("No WebView " +
1553 "has been created in this process!");
1554 }
1555 BrowserFrame.sJavaBridge.addPackageNames(
1556 (Set<String>) msg.obj);
1557 break;
1558
Grace Kloba178db412010-05-18 22:22:23 -07001559 case GET_TOUCH_HIGHLIGHT_RECTS:
1560 TouchHighlightData d = (TouchHighlightData) msg.obj;
1561 ArrayList<Rect> rects = nativeGetTouchHighlightRects
1562 (d.mX, d.mY, d.mSlop);
1563 mWebView.mPrivateHandler.obtainMessage(
1564 WebView.SET_TOUCH_HIGHLIGHT_RECTS, rects)
1565 .sendToTarget();
1566 break;
1567
1568 case REMOVE_TOUCH_HIGHLIGHT_RECTS:
1569 mWebView.mPrivateHandler.obtainMessage(
1570 WebView.SET_TOUCH_HIGHLIGHT_RECTS, null)
1571 .sendToTarget();
1572 break;
Steve Block68dede32010-08-04 10:28:46 +01001573
1574 case USE_MOCK_DEVICE_ORIENTATION:
1575 useMockDeviceOrientation();
1576 break;
Ben Murdoch62275a42010-09-07 11:27:28 +01001577
1578 case AUTOFILL_FORM:
1579 nativeAutoFillForm(msg.arg1);
Ben Murdoch961d55f2010-12-02 13:58:24 +00001580 mWebView.mPrivateHandler.obtainMessage(WebView.AUTOFILL_COMPLETE, null)
1581 .sendToTarget();
Ben Murdoch62275a42010-09-07 11:27:28 +01001582 break;
Narayan Kamath9497c5f2011-02-22 12:05:34 +00001583
1584 case EXECUTE_JS:
1585 if (msg.obj instanceof String) {
1586 if (DebugFlags.WEB_VIEW_CORE) {
1587 Log.d(LOGTAG, "Executing JS : " + msg.obj);
1588 }
1589 mBrowserFrame.stringByEvaluatingJavaScriptFromString((String) msg.obj);
1590 }
1591 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 }
1593 }
1594 };
1595 // Take all queued messages and resend them to the new handler.
1596 synchronized (this) {
1597 int size = mMessages.size();
1598 for (int i = 0; i < size; i++) {
1599 mHandler.sendMessage(mMessages.get(i));
1600 }
1601 mMessages = null;
1602 }
1603 }
1604
1605 /**
1606 * Send a message internally to the queue or to the handler
1607 */
1608 private synchronized void sendMessage(Message msg) {
1609 if (mBlockMessages) {
1610 return;
1611 }
1612 if (mMessages != null) {
1613 mMessages.add(msg);
1614 } else {
1615 mHandler.sendMessage(msg);
1616 }
1617 }
1618
1619 private synchronized void removeMessages(int what) {
1620 if (mBlockMessages) {
1621 return;
1622 }
1623 if (what == EventHub.WEBKIT_DRAW) {
1624 mDrawIsScheduled = false;
1625 }
1626 if (mMessages != null) {
1627 Log.w(LOGTAG, "Not supported in this case.");
1628 } else {
1629 mHandler.removeMessages(what);
1630 }
1631 }
1632
Grace Kloba9217c452009-09-01 00:59:27 -07001633 private synchronized boolean hasMessages(int what) {
1634 if (mBlockMessages) {
1635 return false;
1636 }
1637 if (mMessages != null) {
1638 Log.w(LOGTAG, "hasMessages() is not supported in this case.");
1639 return false;
1640 } else {
1641 return mHandler.hasMessages(what);
1642 }
1643 }
1644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 private synchronized void sendMessageDelayed(Message msg, long delay) {
1646 if (mBlockMessages) {
1647 return;
1648 }
1649 mHandler.sendMessageDelayed(msg, delay);
1650 }
1651
1652 /**
1653 * Send a message internally to the front of the queue.
1654 */
1655 private synchronized void sendMessageAtFrontOfQueue(Message msg) {
1656 if (mBlockMessages) {
1657 return;
1658 }
1659 if (mMessages != null) {
1660 mMessages.add(0, msg);
1661 } else {
1662 mHandler.sendMessageAtFrontOfQueue(msg);
1663 }
1664 }
1665
1666 /**
1667 * Remove all the messages.
1668 */
1669 private synchronized void removeMessages() {
1670 // reset mDrawIsScheduled flag as WEBKIT_DRAW may be removed
1671 mDrawIsScheduled = false;
1672 mSplitPictureIsScheduled = false;
1673 if (mMessages != null) {
1674 mMessages.clear();
1675 } else {
1676 mHandler.removeCallbacksAndMessages(null);
1677 }
1678 }
1679
1680 /**
1681 * Block sending messages to the EventHub.
1682 */
1683 private synchronized void blockMessages() {
1684 mBlockMessages = true;
1685 }
1686 }
1687
1688 //-------------------------------------------------------------------------
1689 // Methods called by host activity (in the same thread)
1690 //-------------------------------------------------------------------------
1691
1692 void stopLoading() {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001693 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "CORE stopLoading");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 if (mBrowserFrame != null) {
1695 mBrowserFrame.stopLoading();
1696 }
1697 }
1698
1699 //-------------------------------------------------------------------------
1700 // Methods called by WebView
1701 // If it refers to local variable, it needs synchronized().
1702 // If it needs WebCore, it has to send message.
1703 //-------------------------------------------------------------------------
1704
1705 void sendMessage(Message msg) {
1706 mEventHub.sendMessage(msg);
1707 }
1708
1709 void sendMessage(int what) {
1710 mEventHub.sendMessage(Message.obtain(null, what));
1711 }
1712
1713 void sendMessage(int what, Object obj) {
1714 mEventHub.sendMessage(Message.obtain(null, what, obj));
1715 }
1716
1717 void sendMessage(int what, int arg1) {
1718 // just ignore the second argument (make it 0)
1719 mEventHub.sendMessage(Message.obtain(null, what, arg1, 0));
1720 }
1721
1722 void sendMessage(int what, int arg1, int arg2) {
1723 mEventHub.sendMessage(Message.obtain(null, what, arg1, arg2));
1724 }
1725
1726 void sendMessage(int what, int arg1, Object obj) {
1727 // just ignore the second argument (make it 0)
1728 mEventHub.sendMessage(Message.obtain(null, what, arg1, 0, obj));
1729 }
1730
1731 void sendMessage(int what, int arg1, int arg2, Object obj) {
1732 mEventHub.sendMessage(Message.obtain(null, what, arg1, arg2, obj));
1733 }
1734
Cary Clark1cb97ee2009-12-11 12:10:36 -05001735 void sendMessageAtFrontOfQueue(int what, Object obj) {
1736 mEventHub.sendMessageAtFrontOfQueue(Message.obtain(
1737 null, what, obj));
1738 }
1739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740 void sendMessageDelayed(int what, Object obj, long delay) {
1741 mEventHub.sendMessageDelayed(Message.obtain(null, what, obj), delay);
1742 }
1743
1744 void removeMessages(int what) {
1745 mEventHub.removeMessages(what);
1746 }
1747
1748 void removeMessages() {
1749 mEventHub.removeMessages();
1750 }
1751
1752 /**
1753 * Removes pending messages and trigger a DESTROY message to send to
1754 * WebCore.
1755 * Called from UI thread.
1756 */
1757 void destroy() {
1758 // We don't want anyone to post a message between removing pending
1759 // messages and sending the destroy message.
1760 synchronized (mEventHub) {
Grace Kloba9217c452009-09-01 00:59:27 -07001761 // RESUME_TIMERS and PAUSE_TIMERS are per process base. They need to
1762 // be preserved even the WebView is destroyed.
1763 // Note: we should not have more than one RESUME_TIMERS/PAUSE_TIMERS
1764 boolean hasResume = mEventHub.hasMessages(EventHub.RESUME_TIMERS);
1765 boolean hasPause = mEventHub.hasMessages(EventHub.PAUSE_TIMERS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 mEventHub.removeMessages();
1767 mEventHub.sendMessageAtFrontOfQueue(
1768 Message.obtain(null, EventHub.DESTROY));
Grace Kloba9217c452009-09-01 00:59:27 -07001769 if (hasPause) {
1770 mEventHub.sendMessageAtFrontOfQueue(
1771 Message.obtain(null, EventHub.PAUSE_TIMERS));
1772 }
1773 if (hasResume) {
1774 mEventHub.sendMessageAtFrontOfQueue(
1775 Message.obtain(null, EventHub.RESUME_TIMERS));
1776 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 mEventHub.blockMessages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001778 }
1779 }
1780
1781 //-------------------------------------------------------------------------
1782 // WebViewCore private methods
1783 //-------------------------------------------------------------------------
1784
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001785 private void clearCache(boolean includeDiskFiles) {
1786 mBrowserFrame.clearCache();
Kristian Monsencedb3a72011-01-20 12:42:16 +00001787 if (includeDiskFiles) {
Derek Sollenbergere0155e92009-06-10 15:35:45 -04001788 CacheManager.removeAllCacheFiles();
1789 }
1790 }
1791
Grace Klobad0d9bc22010-01-26 18:08:28 -08001792 private void loadUrl(String url, Map<String, String> extraHeaders) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001793 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, " CORE loadUrl " + url);
Grace Klobad0d9bc22010-01-26 18:08:28 -08001794 mBrowserFrame.loadUrl(url, extraHeaders);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 }
1796
Elliott Slaughterb48fdbe2010-06-30 11:39:52 -07001797 private String saveWebArchive(String filename, boolean autoname) {
1798 if (DebugFlags.WEB_VIEW_CORE) {
1799 Log.v(LOGTAG, " CORE saveWebArchive " + filename + " " + autoname);
1800 }
1801 return mBrowserFrame.saveWebArchive(filename, autoname);
1802 }
1803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 private void key(KeyEvent evt, boolean isDown) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001805 if (DebugFlags.WEB_VIEW_CORE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 Log.v(LOGTAG, "CORE key at " + System.currentTimeMillis() + ", "
1807 + evt);
1808 }
Leon Scrogginse3225672009-06-03 15:53:13 -04001809 int keyCode = evt.getKeyCode();
Derek Sollenbergerff0f9732010-08-06 11:50:49 -04001810 int unicodeChar = evt.getUnicodeChar();
1811
1812 if (keyCode == KeyEvent.KEYCODE_UNKNOWN && evt.getCharacters() != null
1813 && evt.getCharacters().length() > 0) {
1814 // we should only receive individual complex characters
1815 unicodeChar = evt.getCharacters().codePointAt(0);
1816 }
1817
1818 if (!nativeKey(keyCode, unicodeChar, evt.getRepeatCount(), evt.isShiftPressed(),
1819 evt.isAltPressed(), evt.isSymPressed(),
Leon Scrogginse3225672009-06-03 15:53:13 -04001820 isDown) && keyCode != KeyEvent.KEYCODE_ENTER) {
Cary Clark215b72c2009-06-26 14:38:43 -04001821 if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
1822 && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
1823 if (DebugFlags.WEB_VIEW_CORE) {
Leon Scroggins9ab32b62010-05-03 14:19:50 +01001824 Log.v(LOGTAG, "key: arrow unused by page: " + keyCode);
Cary Clark215b72c2009-06-26 14:38:43 -04001825 }
1826 if (mWebView != null && evt.isDown()) {
1827 Message.obtain(mWebView.mPrivateHandler,
Leon Scroggins9ab32b62010-05-03 14:19:50 +01001828 WebView.UNHANDLED_NAV_KEY, keyCode,
1829 0).sendToTarget();
Cary Clark215b72c2009-06-26 14:38:43 -04001830 }
1831 return;
1832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 // bubble up the event handling
Leon Scrogginse3225672009-06-03 15:53:13 -04001834 // but do not bubble up the ENTER key, which would open the search
1835 // bar without any text.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836 mCallbackProxy.onUnhandledKeyEvent(evt);
1837 }
1838 }
1839
1840 // These values are used to avoid requesting a layout based on old values
1841 private int mCurrentViewWidth = 0;
1842 private int mCurrentViewHeight = 0;
Grace Klobaef347ef2009-07-30 11:20:32 -07001843 private float mCurrentViewScale = 1.0f;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 // notify webkit that our virtual view size changed size (after inv-zoom)
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001846 private void viewSizeChanged(WebView.ViewSizeData data) {
1847 int w = data.mWidth;
1848 int h = data.mHeight;
1849 int textwrapWidth = data.mTextWrapWidth;
1850 float scale = data.mScale;
Grace Klobaef347ef2009-07-30 11:20:32 -07001851 if (DebugFlags.WEB_VIEW_CORE) {
1852 Log.v(LOGTAG, "viewSizeChanged w=" + w + "; h=" + h
1853 + "; textwrapWidth=" + textwrapWidth + "; scale=" + scale);
1854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 if (w == 0) {
1856 Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
1857 return;
1858 }
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001859 int width = calculateWindowWidth(w, textwrapWidth);
Shimeng (Simon) Wanga0cc8642011-02-03 10:24:03 -08001860 int height = h;
1861 if (width != w) {
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001862 float heightWidthRatio = data.mHeightWidthRatio;
Shimeng (Simon) Wanga0cc8642011-02-03 10:24:03 -08001863 float ratio = (heightWidthRatio > 0) ? heightWidthRatio : (float) h / w;
1864 height = Math.round(ratio * width);
1865 }
Shimeng (Simon) Wang48fc9092011-02-03 14:29:54 -08001866 nativeSetSize(width, height, textwrapWidth, scale, w,
1867 data.mActualViewHeight > 0 ? data.mActualViewHeight : h,
1868 data.mAnchorX, data.mAnchorY, data.mIgnoreHeight);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 // Remember the current width and height
1870 boolean needInvalidate = (mCurrentViewWidth == 0);
1871 mCurrentViewWidth = w;
1872 mCurrentViewHeight = h;
Grace Klobaef347ef2009-07-30 11:20:32 -07001873 mCurrentViewScale = scale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874 if (needInvalidate) {
1875 // ensure {@link #webkitDraw} is called as we were blocking in
1876 // {@link #contentDraw} when mCurrentViewWidth is 0
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04001877 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "viewSizeChanged");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 contentDraw();
1879 }
1880 mEventHub.sendMessage(Message.obtain(null,
1881 EventHub.UPDATE_CACHE_AND_TEXT_ENTRY));
1882 }
1883
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08001884 // Calculate width to be used in webkit window.
1885 private int calculateWindowWidth(int viewWidth, int textwrapWidth) {
1886 int width = viewWidth;
1887 if (mSettings.getUseWideViewPort()) {
1888 if (mViewportWidth == -1) {
1889 if (mSettings.getLayoutAlgorithm() ==
1890 WebSettings.LayoutAlgorithm.NORMAL || mSettings.getUseFixedViewport()) {
1891 width = WebView.DEFAULT_VIEWPORT_WIDTH;
1892 } else {
1893 /*
1894 * if a page's minimum preferred width is wider than the
1895 * given "w", use it instead to get better layout result. If
1896 * we start a page with MAX_ZOOM_WIDTH, "w" will be always
1897 * wider. If we start a page with screen width, due to the
1898 * delay between {@link #didFirstLayout} and
1899 * {@link #viewSizeChanged},
1900 * {@link #nativeGetContentMinPrefWidth} will return a more
1901 * accurate value than initial 0 to result a better layout.
1902 * In the worse case, the native width will be adjusted when
1903 * next zoom or screen orientation change happens.
1904 */
1905 width = Math.min(WebView.sMaxViewportWidth, Math.max(viewWidth,
1906 Math.max(WebView.DEFAULT_VIEWPORT_WIDTH,
1907 nativeGetContentMinPrefWidth())));
1908 }
1909 } else if (mViewportWidth > 0) {
1910 if (mSettings.getUseFixedViewport()) {
1911 // Use website specified or desired fixed viewport width.
1912 width = mViewportWidth;
1913 } else {
1914 width = Math.max(viewWidth, mViewportWidth);
1915 }
1916 } else if (mSettings.getUseFixedViewport()) {
1917 width = mWebView.getViewWidth();
1918 } else {
1919 width = textwrapWidth;
1920 }
1921 }
1922 return width;
1923 }
1924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 private void sendUpdateTextEntry() {
1926 if (mWebView != null) {
1927 Message.obtain(mWebView.mPrivateHandler,
1928 WebView.UPDATE_TEXT_ENTRY_MSG_ID).sendToTarget();
1929 }
1930 }
1931
Andrei Popescu59e2ad92009-07-28 13:38:06 +01001932 // Utility method for exceededDatabaseQuota and reachedMaxAppCacheSize
1933 // callbacks. Computes the sum of database quota for all origins.
1934 private long getUsedQuota() {
1935 WebStorage webStorage = WebStorage.getInstance();
Nicolas Roard6c24b4d2009-09-22 18:44:52 +01001936 Collection<WebStorage.Origin> origins = webStorage.getOriginsSync();
1937
Andrei Popescu59e2ad92009-07-28 13:38:06 +01001938 if (origins == null) {
1939 return 0;
1940 }
1941 long usedQuota = 0;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +01001942 for (WebStorage.Origin website : origins) {
1943 usedQuota += website.getQuota();
Andrei Popescu59e2ad92009-07-28 13:38:06 +01001944 }
1945 return usedQuota;
1946 }
1947
Grace Kloba8abd50b2010-07-08 15:02:14 -07001948 // called from UI thread
1949 void splitContent(int content) {
1950 if (!mSplitPictureIsScheduled) {
1951 mSplitPictureIsScheduled = true;
1952 sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
1953 }
1954 }
1955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 // Used to avoid posting more than one draw message.
1957 private boolean mDrawIsScheduled;
Nicolas Roardfb7bc342010-11-01 15:08:03 -07001958 private boolean mDrawLayersIsScheduled;
Cary Clarkd6982c92009-05-29 11:02:22 -04001959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 // Used to avoid posting more than one split picture message.
1961 private boolean mSplitPictureIsScheduled;
1962
Grace Klobaa7bc87c2010-01-29 14:56:25 -08001963 // Used to suspend drawing.
1964 private boolean mDrawIsPaused;
1965
Derek Sollenbergerb983c892010-06-28 08:38:28 -04001966 // mInitialViewState is set by didFirstLayout() and then reset in the
1967 // next webkitDraw after passing the state to the UI thread.
1968 private ViewState mInitialViewState = null;
Grace Klobaef347ef2009-07-30 11:20:32 -07001969
Derek Sollenbergerb983c892010-06-28 08:38:28 -04001970 static class ViewState {
Grace Klobaef347ef2009-07-30 11:20:32 -07001971 float mMinScale;
1972 float mMaxScale;
1973 float mViewScale;
1974 float mTextWrapScale;
Grace Kloba408cf852009-09-20 16:34:44 -07001975 float mDefaultScale;
Grace Klobaef347ef2009-07-30 11:20:32 -07001976 int mScrollX;
1977 int mScrollY;
Leon Scrogginsb2359262009-08-19 16:19:26 -04001978 boolean mMobileSite;
Shimeng (Simon) Wang96fcb872010-11-24 16:01:12 -08001979 boolean mIsRestored;
Grace Klobaef347ef2009-07-30 11:20:32 -07001980 }
1981
1982 static class DrawData {
1983 DrawData() {
Grace Kloba8abd50b2010-07-08 15:02:14 -07001984 mBaseLayer = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 mInvalRegion = new Region();
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04001986 mContentSize = new Point();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 }
Grace Kloba8abd50b2010-07-08 15:02:14 -07001988 int mBaseLayer;
Grace Klobaef347ef2009-07-30 11:20:32 -07001989 Region mInvalRegion;
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04001990 // view size that was used by webkit during the most recent layout
1991 Point mViewSize;
1992 Point mContentSize;
Grace Kloba188bf8d2010-04-07 11:30:19 -07001993 int mMinPrefWidth;
Derek Sollenbergerb983c892010-06-28 08:38:28 -04001994 // only non-null if it is for the first picture set after the first layout
1995 ViewState mViewState;
Cary Clark5da9aeb2009-10-06 17:40:53 -04001996 boolean mFocusSizeChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001997 }
Cary Clarkd6982c92009-05-29 11:02:22 -04001998
Nicolas Roardfb7bc342010-11-01 15:08:03 -07001999 // Only update the layers' content, not the base surface
2000 // PictureSet.
2001 private void webkitDrawLayers() {
2002 mDrawLayersIsScheduled = false;
2003 if (mDrawIsScheduled) {
2004 removeMessages(EventHub.WEBKIT_DRAW);
2005 webkitDraw();
2006 return;
2007 }
2008 DrawData draw = new DrawData();
Patrick Scott2f492272010-12-03 09:52:35 -05002009 draw.mBaseLayer = nativeUpdateLayers(draw.mInvalRegion);
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002010 webkitDraw(draw);
2011 }
2012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 private void webkitDraw() {
2014 mDrawIsScheduled = false;
2015 DrawData draw = new DrawData();
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04002016 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start");
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04002017 draw.mBaseLayer = nativeRecordContent(draw.mInvalRegion, draw.mContentSize);
Grace Kloba8abd50b2010-07-08 15:02:14 -07002018 if (draw.mBaseLayer == 0) {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04002019 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 return;
2021 }
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002022 webkitDraw(draw);
2023 }
2024
2025 private void webkitDraw(DrawData draw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002026 if (mWebView != null) {
Cary Clark5da9aeb2009-10-06 17:40:53 -04002027 draw.mFocusSizeChanged = nativeFocusBoundsChanged();
Derek Sollenberger7e6bf6f2010-10-28 09:33:47 -04002028 draw.mViewSize = new Point(mCurrentViewWidth, mCurrentViewHeight);
Grace Kloba188bf8d2010-04-07 11:30:19 -07002029 if (mSettings.getUseWideViewPort()) {
2030 draw.mMinPrefWidth = Math.max(
2031 mViewportWidth == -1 ? WebView.DEFAULT_VIEWPORT_WIDTH
2032 : (mViewportWidth == 0 ? mCurrentViewWidth
2033 : mViewportWidth),
2034 nativeGetContentMinPrefWidth());
2035 }
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002036 if (mInitialViewState != null) {
2037 draw.mViewState = mInitialViewState;
2038 mInitialViewState = null;
Grace Klobaef347ef2009-07-30 11:20:32 -07002039 }
Derek Sollenberger2e5c1502009-06-03 10:44:42 -04002040 if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 Message.obtain(mWebView.mPrivateHandler,
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -07002042 WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 }
2044 }
2045
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002046 static void reducePriority() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
2048 sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);
2049 sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY);
2050 sWebCoreHandler.sendMessageAtFrontOfQueue(sWebCoreHandler
2051 .obtainMessage(WebCoreThread.REDUCE_PRIORITY));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 }
2053
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002054 static void resumePriority() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002055 // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
2056 sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);
2057 sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY);
2058 sWebCoreHandler.sendMessageAtFrontOfQueue(sWebCoreHandler
2059 .obtainMessage(WebCoreThread.RESUME_PRIORITY));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002060 }
2061
Kristian Monsend4819a72010-12-16 17:42:57 +00002062 static void sendStaticMessage(int messageType, Object argument) {
2063 if (sWebCoreHandler == null)
2064 return;
2065
2066 sWebCoreHandler.sendMessage(sWebCoreHandler.obtainMessage(messageType, argument));
2067 }
2068
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002069 static void pauseUpdatePicture(WebViewCore core) {
2070 // Note: there is one possible failure mode. If pauseUpdatePicture() is
2071 // called from UI thread while WEBKIT_DRAW is just pulled out of the
2072 // queue in WebCore thread to be executed. Then update won't be blocked.
2073 if (core != null) {
Grace Klobaf9b731d2010-06-21 19:23:57 -07002074 if (!core.getSettings().enableSmoothTransition()) return;
2075
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002076 synchronized (core) {
2077 core.mDrawIsPaused = true;
2078 if (core.mDrawIsScheduled) {
2079 core.mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
2080 }
2081 }
2082 }
2083
2084 }
2085
2086 static void resumeUpdatePicture(WebViewCore core) {
2087 if (core != null) {
Grace Klobaf9b731d2010-06-21 19:23:57 -07002088 // if mDrawIsPaused is true, ignore the setting, continue to resume
2089 if (!core.mDrawIsPaused
2090 && !core.getSettings().enableSmoothTransition()) return;
2091
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002092 synchronized (core) {
2093 core.mDrawIsPaused = false;
Cary Clark75796bb2010-08-24 14:59:58 -04002094 // always redraw on resume to reenable gif animations
2095 core.mDrawIsScheduled = false;
2096 core.nativeContentInvalidateAll();
2097 core.contentDraw();
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002098 }
2099 }
2100 }
2101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 //////////////////////////////////////////////////////////////////////////
2103
2104 private void restoreState(int index) {
2105 WebBackForwardList list = mCallbackProxy.getBackForwardList();
2106 int size = list.getSize();
2107 for (int i = 0; i < size; i++) {
2108 list.getItemAtIndex(i).inflate(mBrowserFrame.mNativeFrame);
2109 }
2110 mBrowserFrame.mLoadInitFromJava = true;
2111 list.restoreIndex(mBrowserFrame.mNativeFrame, index);
2112 mBrowserFrame.mLoadInitFromJava = false;
2113 }
2114
2115 //-------------------------------------------------------------------------
2116 // Implement abstract methods in WebViewCore, native WebKit callback part
2117 //-------------------------------------------------------------------------
2118
2119 // called from JNI or WebView thread
2120 /* package */ void contentDraw() {
2121 // don't update the Picture until we have an initial width and finish
2122 // the first layout
2123 if (mCurrentViewWidth == 0 || !mBrowserFrame.firstLayoutDone()) {
2124 return;
2125 }
2126 // only fire an event if this is our first request
2127 synchronized (this) {
Grace Kloba3f40bd42009-12-07 14:47:28 -08002128 if (mDrawIsScheduled) return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 mDrawIsScheduled = true;
Grace Klobaa7bc87c2010-01-29 14:56:25 -08002130 if (mDrawIsPaused) return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
2132 }
2133 }
Cary Clarkd6982c92009-05-29 11:02:22 -04002134
Nicolas Roardfb7bc342010-11-01 15:08:03 -07002135 // called from JNI
2136 void layersDraw() {
2137 synchronized (this) {
2138 if (mDrawLayersIsScheduled) return;
2139 mDrawLayersIsScheduled = true;
2140 mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW_LAYERS));
2141 }
2142 }
2143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 // called by JNI
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002145 private void contentScrollTo(int x, int y, boolean animate,
2146 boolean onlyIfImeIsShowing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 if (!mBrowserFrame.firstLayoutDone()) {
2148 /*
2149 * WebKit restore state will be called before didFirstLayout(),
2150 * remember the position as it has to be applied after restoring
2151 * zoom factor which is controlled by screenWidth.
2152 */
2153 mRestoredX = x;
2154 mRestoredY = y;
2155 return;
2156 }
2157 if (mWebView != null) {
Grace Klobab3230cb2009-04-13 14:04:23 -07002158 Message msg = Message.obtain(mWebView.mPrivateHandler,
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002159 WebView.SCROLL_TO_MSG_ID, animate ? 1 : 0,
2160 onlyIfImeIsShowing ? 1 : 0, new Point(x, y));
Grace Klobab3230cb2009-04-13 14:04:23 -07002161 if (mDrawIsScheduled) {
2162 mEventHub.sendMessage(Message.obtain(null,
2163 EventHub.MESSAGE_RELAY, msg));
2164 } else {
2165 msg.sendToTarget();
2166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 }
2168 }
2169
2170 // called by JNI
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 private void sendNotifyProgressFinished() {
2172 sendUpdateTextEntry();
Steve Block808751f2011-01-04 14:26:27 +00002173 if (!JniUtil.useChromiumHttpStack()) {
2174 // as CacheManager can behave based on database transaction, we need to
2175 // call tick() to trigger endTransaction
2176 WebViewWorker.getHandler().removeMessages(
2177 WebViewWorker.MSG_CACHE_TRANSACTION_TICKER);
2178 WebViewWorker.getHandler().sendEmptyMessage(
2179 WebViewWorker.MSG_CACHE_TRANSACTION_TICKER);
2180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 contentDraw();
2182 }
2183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 /* Called by JNI. The coordinates are in doc coordinates, so they need to
2185 be scaled before they can be used by the view system, which happens
2186 in WebView since it (and its thread) know the current scale factor.
2187 */
2188 private void sendViewInvalidate(int left, int top, int right, int bottom) {
2189 if (mWebView != null) {
2190 Message.obtain(mWebView.mPrivateHandler,
2191 WebView.INVAL_RECT_MSG_ID,
2192 new Rect(left, top, right, bottom)).sendToTarget();
2193 }
2194 }
2195
Nicolas Roard38863332010-01-04 19:30:55 +00002196 private static boolean mRepaintScheduled = false;
2197
2198 /*
2199 * Called by the WebView thread
2200 */
2201 /* package */ void signalRepaintDone() {
2202 mRepaintScheduled = false;
2203 }
2204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002205 /* package */ WebView getWebView() {
2206 return mWebView;
2207 }
2208
2209 private native void setViewportSettingsFromNative();
Cary Clarkd6982c92009-05-29 11:02:22 -04002210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 // called by JNI
Grace Kloba45dee412009-04-06 10:47:26 -07002212 private void didFirstLayout(boolean standardLoad) {
Grace Klobaef347ef2009-07-30 11:20:32 -07002213 if (DebugFlags.WEB_VIEW_CORE) {
2214 Log.v(LOGTAG, "didFirstLayout standardLoad =" + standardLoad);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 }
2216
2217 mBrowserFrame.didFirstLayout();
2218
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002219 if (mWebView == null) return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002221 boolean updateViewState = standardLoad || mRestoredScale > 0;
2222 setupViewport(updateViewState);
Grace Kloba9a67c822009-12-20 11:33:58 -08002223 // if updateRestoreState is true, ViewManager.postReadyToDrawAll() will
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002224 // be called after the WebView updates its state. If updateRestoreState
Grace Kloba9a67c822009-12-20 11:33:58 -08002225 // is false, start to draw now as it is ready.
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002226 if (!updateViewState) {
Grace Kloba9a67c822009-12-20 11:33:58 -08002227 mWebView.mViewManager.postReadyToDrawAll();
2228 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002229
Grace Kloba178db412010-05-18 22:22:23 -07002230 // remove the touch highlight when moving to a new page
2231 if (getSettings().supportTouchOnly()) {
2232 mEventHub.sendMessage(Message.obtain(null,
2233 EventHub.REMOVE_TOUCH_HIGHLIGHT_RECTS));
2234 }
2235
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002236 // reset the scroll position, the restored offset and scales
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002237 mRestoredX = mRestoredY = 0;
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002238 mRestoredScale = mRestoredTextWrapScale = 0;
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002239 }
2240
2241 // called by JNI
2242 private void updateViewport() {
2243 // if updateViewport is called before first layout, wait until first
2244 // layout to update the viewport. In the rare case, this is called after
2245 // first layout, force an update as we have just parsed the viewport
2246 // meta tag.
2247 if (mBrowserFrame.firstLayoutDone()) {
2248 setupViewport(true);
2249 }
2250 }
2251
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002252 private void setupViewport(boolean updateViewState) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 // set the viewport settings from WebKit
2254 setViewportSettingsFromNative();
2255
Grace Kloba408cf852009-09-20 16:34:44 -07002256 // adjust the default scale to match the densityDpi
2257 float adjust = 1.0f;
2258 if (mViewportDensityDpi == -1) {
Derek Sollenberger03e48912010-05-18 17:03:42 -04002259 // convert default zoom scale to a integer (percentage) to avoid any
2260 // issues with floating point comparisons
2261 if (mWebView != null && (int)(mWebView.getDefaultZoomScale() * 100) != 100) {
2262 adjust = mWebView.getDefaultZoomScale();
Grace Kloba0d8b77c2009-06-25 11:20:51 -07002263 }
Grace Kloba408cf852009-09-20 16:34:44 -07002264 } else if (mViewportDensityDpi > 0) {
2265 adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
2266 / mViewportDensityDpi;
2267 }
2268 int defaultScale = (int) (adjust * 100);
2269
2270 if (mViewportInitialScale > 0) {
2271 mViewportInitialScale *= adjust;
2272 }
2273 if (mViewportMinimumScale > 0) {
2274 mViewportMinimumScale *= adjust;
2275 }
2276 if (mViewportMaximumScale > 0) {
2277 mViewportMaximumScale *= adjust;
Grace Kloba0d8b77c2009-06-25 11:20:51 -07002278 }
2279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 // infer the values if they are not defined.
2281 if (mViewportWidth == 0) {
2282 if (mViewportInitialScale == 0) {
Grace Kloba408cf852009-09-20 16:34:44 -07002283 mViewportInitialScale = defaultScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286 if (mViewportUserScalable == false) {
Grace Kloba408cf852009-09-20 16:34:44 -07002287 mViewportInitialScale = defaultScale;
2288 mViewportMinimumScale = defaultScale;
2289 mViewportMaximumScale = defaultScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 }
Grace Klobaf53c1862009-09-21 16:26:11 -07002291 if (mViewportMinimumScale > mViewportInitialScale
2292 && mViewportInitialScale != 0) {
2293 mViewportMinimumScale = mViewportInitialScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 }
Grace Klobaf53c1862009-09-21 16:26:11 -07002295 if (mViewportMaximumScale > 0
2296 && mViewportMaximumScale < mViewportInitialScale) {
2297 mViewportMaximumScale = mViewportInitialScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 }
Grace Kloba408cf852009-09-20 16:34:44 -07002299 if (mViewportWidth < 0 && mViewportInitialScale == defaultScale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 mViewportWidth = 0;
2301 }
2302
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002303 // if mViewportWidth is 0, it means device-width, always update.
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002304 if (mViewportWidth != 0 && !updateViewState) {
2305 ViewState viewState = new ViewState();
2306 viewState.mMinScale = mViewportMinimumScale / 100.0f;
2307 viewState.mMaxScale = mViewportMaximumScale / 100.0f;
2308 viewState.mDefaultScale = adjust;
Grace Kloba769ed212010-01-27 10:52:47 -08002309 // as mViewportWidth is not 0, it is not mobile site.
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002310 viewState.mMobileSite = false;
Grace Kloba188bf8d2010-04-07 11:30:19 -07002311 // for non-mobile site, we don't need minPrefWidth, set it as 0
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002312 viewState.mScrollX = 0;
Grace Kloba769ed212010-01-27 10:52:47 -08002313 Message.obtain(mWebView.mPrivateHandler,
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002314 WebView.UPDATE_ZOOM_RANGE, viewState).sendToTarget();
Grace Kloba769ed212010-01-27 10:52:47 -08002315 return;
2316 }
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 // now notify webview
Grace Kloba6ed525e2009-09-17 15:31:12 -07002319 // webViewWidth refers to the width in the view system
2320 int webViewWidth;
2321 // viewportWidth refers to the width in the document system
2322 int viewportWidth = mCurrentViewWidth;
2323 if (viewportWidth == 0) {
2324 // this may happen when WebView just starts. This is not perfect as
2325 // we call WebView method from WebCore thread. But not perfect
2326 // reference is better than no reference.
2327 webViewWidth = mWebView.getViewWidth();
Grace Kloba408cf852009-09-20 16:34:44 -07002328 viewportWidth = (int) (webViewWidth / adjust);
Grace Kloba6ed525e2009-09-17 15:31:12 -07002329 if (viewportWidth == 0) {
2330 Log.w(LOGTAG, "Can't get the viewWidth after the first layout");
2331 }
2332 } else {
2333 webViewWidth = Math.round(viewportWidth * mCurrentViewScale);
2334 }
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002335 mInitialViewState = new ViewState();
2336 mInitialViewState.mMinScale = mViewportMinimumScale / 100.0f;
2337 mInitialViewState.mMaxScale = mViewportMaximumScale / 100.0f;
2338 mInitialViewState.mDefaultScale = adjust;
2339 mInitialViewState.mScrollX = mRestoredX;
2340 mInitialViewState.mScrollY = mRestoredY;
2341 mInitialViewState.mMobileSite = (0 == mViewportWidth);
Grace Klobaef347ef2009-07-30 11:20:32 -07002342 if (mRestoredScale > 0) {
Shimeng (Simon) Wang96fcb872010-11-24 16:01:12 -08002343 mInitialViewState.mIsRestored = true;
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002344 mInitialViewState.mViewScale = mRestoredScale;
Grace Klobae80cbcc2010-05-28 18:07:50 -07002345 if (mRestoredTextWrapScale > 0) {
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002346 mInitialViewState.mTextWrapScale = mRestoredTextWrapScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002347 } else {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002348 mInitialViewState.mTextWrapScale = mInitialViewState.mViewScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002350 } else {
2351 if (mViewportInitialScale > 0) {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002352 mInitialViewState.mViewScale = mInitialViewState.mTextWrapScale =
Grace Klobaef347ef2009-07-30 11:20:32 -07002353 mViewportInitialScale / 100.0f;
Shimeng (Simon) Wang9c64bae2010-10-22 10:52:57 -07002354 } else if (mViewportWidth > 0 && mViewportWidth < webViewWidth &&
2355 !mWebView.getSettings().getUseFixedViewport()) {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002356 mInitialViewState.mViewScale = mInitialViewState.mTextWrapScale =
Grace Klobaef347ef2009-07-30 11:20:32 -07002357 (float) webViewWidth / mViewportWidth;
2358 } else {
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002359 mInitialViewState.mTextWrapScale = adjust;
Grace Klobaef347ef2009-07-30 11:20:32 -07002360 // 0 will trigger WebView to turn on zoom overview mode
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002361 mInitialViewState.mViewScale = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002364
2365 if (mWebView.mHeightCanMeasure) {
2366 // Trick to ensure that the Picture has the exact height for the
2367 // content by forcing to layout with 0 height after the page is
2368 // ready, which is indicated by didFirstLayout. This is essential to
2369 // get rid of the white space in the GMail which uses WebView for
2370 // message view.
2371 mWebView.mLastHeightSent = 0;
2372 // Send a negative scale to indicate that WebCore should reuse
2373 // the current scale
2374 WebView.ViewSizeData data = new WebView.ViewSizeData();
2375 data.mWidth = mWebView.mLastWidthSent;
2376 data.mHeight = 0;
2377 // if mHeightCanMeasure is true, getUseWideViewPort() can't be
2378 // true. It is safe to use mWidth for mTextWrapWidth.
2379 data.mTextWrapWidth = data.mWidth;
2380 data.mScale = -1.0f;
Cary Clark6d45acc2009-08-27 15:42:57 -04002381 data.mIgnoreHeight = false;
Grace Kloba3a0def22010-01-23 21:11:54 -08002382 data.mAnchorX = data.mAnchorY = 0;
Grace Kloba0d03b912009-09-27 17:46:31 -07002383 // send VIEW_SIZE_CHANGED to the front of the queue so that we can
2384 // avoid pushing the wrong picture to the WebView side. If there is
2385 // a VIEW_SIZE_CHANGED in the queue, probably from WebView side,
2386 // ignore it as we have a new size. If we leave VIEW_SIZE_CHANGED
2387 // in the queue, as mLastHeightSent has been updated here, we may
2388 // miss the requestLayout in WebView side after the new picture.
2389 mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED);
Grace Klobaef347ef2009-07-30 11:20:32 -07002390 mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
2391 EventHub.VIEW_SIZE_CHANGED, data));
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002392 } else if (mSettings.getUseWideViewPort()) {
Grace Kloba6ed525e2009-09-17 15:31:12 -07002393 if (viewportWidth == 0) {
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002394 // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView
2395 // to WebViewCore
2396 mWebView.mLastWidthSent = 0;
2397 } else {
2398 WebView.ViewSizeData data = new WebView.ViewSizeData();
2399 // mViewScale as 0 means it is in zoom overview mode. So we don't
2400 // know the exact scale. If mRestoredScale is non-zero, use it;
2401 // otherwise just use mTextWrapScale as the initial scale.
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002402 float tentativeScale = mInitialViewState.mViewScale;
2403 if (tentativeScale == 0) {
2404 // The following tries to figure out more correct view scale
2405 // and text wrap scale to be sent to webkit, by using some
2406 // knowledge from web settings and zoom manager.
2407
2408 // Calculated window width will be used to guess the scale
2409 // in zoom overview mode.
2410 tentativeScale = mInitialViewState.mTextWrapScale;
2411 int tentativeViewWidth = Math.round(webViewWidth / tentativeScale);
2412 int windowWidth = calculateWindowWidth(tentativeViewWidth,
2413 tentativeViewWidth);
2414 // In viewport setup time, since no content width is known, we assume
2415 // the windowWidth will be the content width, to get a more likely
2416 // zoom overview scale.
2417 data.mScale = (float) webViewWidth / windowWidth;
2418 if (!mSettings.getLoadWithOverviewMode()) {
2419 // If user choose non-overview mode.
2420 data.mScale = Math.max(data.mScale, tentativeScale);
2421 }
2422 if (mSettings.isNarrowColumnLayout() &&
2423 mSettings.getUseFixedViewport()) {
2424 // In case of automatic text reflow in fixed view port mode.
2425 mInitialViewState.mTextWrapScale =
2426 ZoomManager.computeReadingLevelScale(data.mScale);
2427 }
2428 } else {
2429 // Scale is given such as when page is restored, use it.
2430 data.mScale = tentativeScale;
2431 }
Cary Clark35155c12009-10-29 15:34:00 -04002432 if (DebugFlags.WEB_VIEW_CORE) {
2433 Log.v(LOGTAG, "setupViewport"
2434 + " mRestoredScale=" + mRestoredScale
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002435 + " mViewScale=" + mInitialViewState.mViewScale
2436 + " mTextWrapScale=" + mInitialViewState.mTextWrapScale
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002437 + " data.mScale= " + data.mScale
Cary Clark35155c12009-10-29 15:34:00 -04002438 );
2439 }
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002440 data.mWidth = Math.round(webViewWidth / data.mScale);
Ben Murdochd1bee052010-03-05 11:30:07 +00002441 // We may get a call here when mCurrentViewHeight == 0 if webcore completes the
2442 // first layout before we sync our webview dimensions to it. In that case, we
2443 // request the real height of the webview. This is not a perfect solution as we
2444 // are calling a WebView method from the WebCore thread. But this is preferable
2445 // to syncing an incorrect height.
2446 data.mHeight = mCurrentViewHeight == 0 ?
2447 Math.round(mWebView.getViewHeight() / data.mScale)
Shimeng (Simon) Wangf7107d72011-02-18 15:27:28 -08002448 : Math.round((float) mCurrentViewHeight * data.mWidth / viewportWidth);
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002449 data.mTextWrapWidth = Math.round(webViewWidth
Derek Sollenbergerb983c892010-06-28 08:38:28 -04002450 / mInitialViewState.mTextWrapScale);
Cary Clark6d45acc2009-08-27 15:42:57 -04002451 data.mIgnoreHeight = false;
Grace Kloba3a0def22010-01-23 21:11:54 -08002452 data.mAnchorX = data.mAnchorY = 0;
Grace Kloba0d03b912009-09-27 17:46:31 -07002453 // send VIEW_SIZE_CHANGED to the front of the queue so that we
2454 // can avoid pushing the wrong picture to the WebView side.
2455 mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED);
Shimeng (Simon) Wang76064642011-02-22 15:31:02 -08002456 // Let webkit know the scale and inner width/height immediately
2457 // in viewport setup time to avoid wrong information.
2458 viewSizeChanged(data);
Grace Kloba7a02d6e2009-08-18 10:10:51 -07002459 }
Grace Klobaef347ef2009-07-30 11:20:32 -07002460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 }
2462
2463 // called by JNI
Shimeng (Simon) Wang5d8e7a42011-01-07 15:51:06 -08002464 private void restoreScale(float scale, float textWrapScale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 if (mBrowserFrame.firstLayoutDone() == false) {
2466 mRestoredScale = scale;
Grace Klobae80cbcc2010-05-28 18:07:50 -07002467 if (mSettings.getUseWideViewPort()) {
2468 mRestoredTextWrapScale = textWrapScale;
2469 }
Grace Kloba8b97e4b2009-07-28 13:11:38 -07002470 }
2471 }
2472
2473 // called by JNI
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 private void needTouchEvents(boolean need) {
2475 if (mWebView != null) {
2476 Message.obtain(mWebView.mPrivateHandler,
2477 WebView.WEBCORE_NEED_TOUCH_EVENTS, need ? 1 : 0, 0)
2478 .sendToTarget();
2479 }
2480 }
2481
2482 // called by JNI
2483 private void updateTextfield(int ptr, boolean changeToPassword,
2484 String text, int textGeneration) {
2485 if (mWebView != null) {
2486 Message msg = Message.obtain(mWebView.mPrivateHandler,
Cary Clarkd6982c92009-05-29 11:02:22 -04002487 WebView.UPDATE_TEXTFIELD_TEXT_MSG_ID, ptr,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488 textGeneration, text);
2489 msg.getData().putBoolean("password", changeToPassword);
2490 msg.sendToTarget();
2491 }
2492 }
2493
Cary Clark243ea062009-06-25 10:49:32 -04002494 // called by JNI
Leon Scroggins6679f2f2009-08-12 18:48:10 -04002495 private void updateTextSelection(int pointer, int start, int end,
2496 int textGeneration) {
2497 if (mWebView != null) {
2498 Message.obtain(mWebView.mPrivateHandler,
2499 WebView.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration,
2500 new TextSelectionData(start, end)).sendToTarget();
2501 }
2502 }
2503
2504 // called by JNI
Cary Clark243ea062009-06-25 10:49:32 -04002505 private void clearTextEntry() {
2506 if (mWebView == null) return;
2507 Message.obtain(mWebView.mPrivateHandler,
2508 WebView.CLEAR_TEXT_ENTRY).sendToTarget();
2509 }
2510
Leon Scroggins5de63892009-10-29 09:48:43 -04002511 // called by JNI
2512 private void sendFindAgain() {
2513 if (mWebView == null) return;
2514 Message.obtain(mWebView.mPrivateHandler,
2515 WebView.FIND_AGAIN).sendToTarget();
2516 }
2517
Cary Clark77d98f42009-07-31 09:40:38 -04002518 private native void nativeUpdateFrameCacheIfLoading();
Leon Scroggins200c13d2010-05-14 15:35:42 -04002519 private native void nativeRevealSelection();
Leon Scroggins3a503392010-01-06 17:04:38 -05002520 private native String nativeRequestLabel(int framePtr, int nodePtr);
Leon Scroggins72543e12009-07-23 15:29:45 -04002521 /**
Cary Clarkeaa18de2009-09-28 12:50:42 -04002522 * Scroll the focused textfield to (xPercent, y) in document space
Leon Scroggins72543e12009-07-23 15:29:45 -04002523 */
Cary Clarkeaa18de2009-09-28 12:50:42 -04002524 private native void nativeScrollFocusedTextInput(float xPercent, int y);
Leon Scroggins72543e12009-07-23 15:29:45 -04002525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 // these must be in document space (i.e. not scaled/zoomed).
Patrick Scottfa8be1c2011-02-02 14:09:34 -05002527 private native void nativeSetScrollOffset(int gen, boolean sendScrollEvent, int dx, int dy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528
2529 private native void nativeSetGlobalBounds(int x, int y, int w, int h);
2530
2531 // called by JNI
Leon Scrogginsa8da1732009-10-19 19:04:30 -04002532 private void requestListBox(String[] array, int[] enabledArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002533 int[] selectedArray) {
2534 if (mWebView != null) {
2535 mWebView.requestListBox(array, enabledArray, selectedArray);
2536 }
2537 }
2538
2539 // called by JNI
Leon Scrogginsa8da1732009-10-19 19:04:30 -04002540 private void requestListBox(String[] array, int[] enabledArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 int selection) {
2542 if (mWebView != null) {
2543 mWebView.requestListBox(array, enabledArray, selection);
2544 }
Cary Clarkd6982c92009-05-29 11:02:22 -04002545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 }
Mike Reedd205d5b2009-05-27 11:02:29 -04002547
Derek Sollenberger4c41e8d2009-06-29 13:49:27 -04002548 // called by JNI
Leon Scrogginsb4157792010-03-18 12:42:33 -04002549 private void requestKeyboardWithSelection(int pointer, int selStart,
2550 int selEnd, int textGeneration) {
Derek Sollenberger4c41e8d2009-06-29 13:49:27 -04002551 if (mWebView != null) {
2552 Message.obtain(mWebView.mPrivateHandler,
Leon Scrogginsb4157792010-03-18 12:42:33 -04002553 WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
2554 textGeneration, new TextSelectionData(selStart, selEnd))
2555 .sendToTarget();
2556 }
2557 }
2558
2559 // called by JNI
2560 private void requestKeyboard(boolean showKeyboard) {
2561 if (mWebView != null) {
2562 Message.obtain(mWebView.mPrivateHandler,
2563 WebView.REQUEST_KEYBOARD, showKeyboard ? 1 : 0, 0)
Derek Sollenberger4c41e8d2009-06-29 13:49:27 -04002564 .sendToTarget();
2565 }
2566 }
2567
Ben Murdochdb8d19c2010-10-29 11:44:17 +01002568 private void setWebTextViewAutoFillable(int queryId, String preview) {
Ben Murdoch62275a42010-09-07 11:27:28 +01002569 if (mWebView != null) {
Ben Murdochdb8d19c2010-10-29 11:44:17 +01002570 Message.obtain(mWebView.mPrivateHandler, WebView.SET_AUTOFILLABLE,
2571 new AutoFillData(queryId, preview))
2572 .sendToTarget();
Ben Murdoch62275a42010-09-07 11:27:28 +01002573 }
2574 }
2575
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002576 // called by JNI
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002577 private Context getContext() {
2578 return mContext;
2579 }
2580
2581 // called by JNI
Derek Sollenbergerf3196cd2011-01-27 17:33:14 -05002582 private void keepScreenOn(boolean screenOn) {
2583 if (mWebView != null) {
2584 Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SCREEN_ON);
2585 message.arg1 = screenOn ? 1 : 0;
2586 message.sendToTarget();
2587 }
2588 }
2589
2590 // called by JNI
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002591 private Class<?> getPluginClass(String libName, String clsName) {
2592
2593 if (mWebView == null) {
2594 return null;
2595 }
2596
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002597 PluginManager pluginManager = PluginManager.getInstance(null);
2598
2599 String pkgName = pluginManager.getPluginsAPKName(libName);
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002600 if (pkgName == null) {
2601 Log.w(LOGTAG, "Unable to resolve " + libName + " to a plugin APK");
2602 return null;
2603 }
2604
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002605 try {
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002606 return pluginManager.getPluginClass(pkgName, clsName);
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002607 } catch (NameNotFoundException e) {
2608 Log.e(LOGTAG, "Unable to find plugin classloader for the apk (" + pkgName + ")");
2609 } catch (ClassNotFoundException e) {
2610 Log.e(LOGTAG, "Unable to find plugin class (" + clsName +
2611 ") in the apk (" + pkgName + ")");
2612 }
2613
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002614 return null;
Derek Sollenberger9e28c4c2009-11-09 14:45:58 -05002615 }
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002616
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002617 // called by JNI. PluginWidget function to launch a full-screen view using a
2618 // View object provided by the plugin class.
Derek Sollenbergerc28ff442010-03-09 17:38:49 -05002619 private void showFullScreenPlugin(ViewManager.ChildView childView, int npp) {
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002620 if (mWebView == null) {
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002621 return;
2622 }
2623
Derek Sollenbergerc28ff442010-03-09 17:38:49 -05002624 Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN);
2625 message.obj = childView.mView;
2626 message.arg1 = npp;
2627 message.sendToTarget();
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002628 }
2629
Grace Kloba11438c32009-12-16 11:39:12 -08002630 // called by JNI
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002631 private void hideFullScreenPlugin() {
2632 if (mWebView == null) {
2633 return;
2634 }
Grace Kloba11438c32009-12-16 11:39:12 -08002635 mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN)
2636 .sendToTarget();
2637 }
Derek Sollenberger51ef5732009-12-07 16:15:13 -05002638
Derek Sollenberger36a4f232011-01-04 16:05:43 -05002639 private ViewManager.ChildView createSurface(View pluginView) {
Patrick Scottfb6aecb2009-07-17 16:38:07 -04002640 if (mWebView == null) {
2641 return null;
2642 }
Derek Sollenbergerc0b8a962009-09-22 14:08:09 -04002643
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002644 if (pluginView == null) {
2645 Log.e(LOGTAG, "Attempted to add an empty plugin view to the view hierarchy");
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002646 return null;
2647 }
Derek Sollenbergerc0b8a962009-09-22 14:08:09 -04002648
Derek Sollenberger7c5bf462010-01-11 12:50:51 -05002649 // ensures the view system knows the view can redraw itself
Derek Sollenberger42d00fb2009-12-01 15:19:42 -05002650 pluginView.setWillNotDraw(false);
Derek Sollenbergerc0b8a962009-09-22 14:08:09 -04002651
Derek Sollenberger2120cd62010-02-23 16:52:45 -05002652 if(pluginView instanceof SurfaceView)
2653 ((SurfaceView)pluginView).setZOrderOnTop(true);
2654
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002655 ViewManager.ChildView view = mWebView.mViewManager.createView();
2656 view.mView = pluginView;
Derek Sollenberger36a4f232011-01-04 16:05:43 -05002657 return view;
2658 }
2659
2660 // called by JNI. PluginWidget functions for creating an embedded View for
2661 // the surface drawing model.
2662 private ViewManager.ChildView addSurface(View pluginView, int x, int y,
2663 int width, int height) {
2664 ViewManager.ChildView view = createSurface(pluginView);
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002665 view.attachView(x, y, width, height);
2666 return view;
Patrick Scottfb6aecb2009-07-17 16:38:07 -04002667 }
Derek Sollenbergercb37e712009-11-24 14:58:09 -05002668
Derek Sollenberger3dafca12009-10-13 11:38:25 -04002669 private void updateSurface(ViewManager.ChildView childView, int x, int y,
2670 int width, int height) {
2671 childView.attachView(x, y, width, height);
2672 }
2673
Derek Sollenberger0b3a5d62009-09-08 18:31:40 -04002674 private void destroySurface(ViewManager.ChildView childView) {
2675 childView.removeView();
Patrick Scottfb6aecb2009-07-17 16:38:07 -04002676 }
2677
Grace Kloba3a0def22010-01-23 21:11:54 -08002678 // called by JNI
2679 static class ShowRectData {
2680 int mLeft;
2681 int mTop;
2682 int mWidth;
2683 int mHeight;
2684 int mContentWidth;
2685 int mContentHeight;
2686 float mXPercentInDoc;
2687 float mXPercentInView;
2688 float mYPercentInDoc;
2689 float mYPercentInView;
2690 }
2691
2692 private void showRect(int left, int top, int width, int height,
2693 int contentWidth, int contentHeight, float xPercentInDoc,
2694 float xPercentInView, float yPercentInDoc, float yPercentInView) {
2695 if (mWebView != null) {
2696 ShowRectData data = new ShowRectData();
2697 data.mLeft = left;
2698 data.mTop = top;
2699 data.mWidth = width;
2700 data.mHeight = height;
2701 data.mContentWidth = contentWidth;
2702 data.mContentHeight = contentHeight;
2703 data.mXPercentInDoc = xPercentInDoc;
2704 data.mXPercentInView = xPercentInView;
2705 data.mYPercentInDoc = yPercentInDoc;
2706 data.mYPercentInView = yPercentInView;
2707 Message.obtain(mWebView.mPrivateHandler, WebView.SHOW_RECT_MSG_ID,
2708 data).sendToTarget();
2709 }
2710 }
2711
Grace Klobae8300a12010-03-12 13:32:55 -08002712 // called by JNI
2713 private void centerFitRect(int x, int y, int width, int height) {
2714 if (mWebView == null) {
2715 return;
2716 }
2717 mWebView.mPrivateHandler.obtainMessage(WebView.CENTER_FIT_RECT,
2718 new Rect(x, y, x + width, y + height)).sendToTarget();
2719 }
2720
Grace Kloba50004bc2010-04-13 22:58:51 -07002721 // called by JNI
2722 private void setScrollbarModes(int hMode, int vMode) {
2723 if (mWebView == null) {
2724 return;
2725 }
2726 mWebView.mPrivateHandler.obtainMessage(WebView.SET_SCROLLBAR_MODES,
2727 hMode, vMode).sendToTarget();
2728 }
2729
Svetoslav Ganov9504f572011-01-14 11:38:17 -08002730 // called by JNI
2731 @SuppressWarnings("unused")
2732 private void selectAt(int x, int y) {
2733 if (mWebView != null) {
2734 mWebView.mPrivateHandler.obtainMessage(WebView.SELECT_AT, x, y).sendToTarget();
2735 }
2736 }
2737
Steve Block68dede32010-08-04 10:28:46 +01002738 private void useMockDeviceOrientation() {
Steve Block1be73392010-10-15 16:31:01 +01002739 mDeviceMotionAndOrientationManager.useMock();
Steve Blockf4a705f2010-08-11 13:08:24 +01002740 }
2741
2742 public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
2743 boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
Steve Block1be73392010-10-15 16:31:01 +01002744 mDeviceMotionAndOrientationManager.setMockOrientation(canProvideAlpha, alpha,
2745 canProvideBeta, beta, canProvideGamma, gamma);
Steve Block68dede32010-08-04 10:28:46 +01002746 }
2747
Steve Blockdc82a292010-10-06 14:34:15 +01002748 protected DeviceMotionService getDeviceMotionService() {
2749 if (mDeviceMotionService == null) {
2750 mDeviceMotionService =
Steve Block1be73392010-10-15 16:31:01 +01002751 new DeviceMotionService(mDeviceMotionAndOrientationManager, mContext);
Steve Blockdc82a292010-10-06 14:34:15 +01002752 }
2753 return mDeviceMotionService;
2754 }
2755
Steve Blockc43565b2010-08-11 13:12:37 +01002756 protected DeviceOrientationService getDeviceOrientationService() {
2757 if (mDeviceOrientationService == null) {
Steve Blockbb9db222010-08-18 11:12:07 +01002758 mDeviceOrientationService =
Steve Block1be73392010-10-15 16:31:01 +01002759 new DeviceOrientationService(mDeviceMotionAndOrientationManager, mContext);
Steve Blockc43565b2010-08-11 13:12:37 +01002760 }
2761 return mDeviceOrientationService;
2762 }
2763
Mike Reedd205d5b2009-05-27 11:02:29 -04002764 private native void nativePause();
2765 private native void nativeResume();
Derek Sollenbergere0155e92009-06-10 15:35:45 -04002766 private native void nativeFreeMemory();
Derek Sollenbergerb6ddc7a2009-12-08 15:41:46 -05002767 private native void nativeFullScreenPluginHidden(int npp);
Cary Clark1cb97ee2009-12-11 12:10:36 -05002768 private native boolean nativeValidNodeAndBounds(int frame, int node,
2769 Rect bounds);
2770
Grace Kloba178db412010-05-18 22:22:23 -07002771 private native ArrayList<Rect> nativeGetTouchHighlightRects(int x, int y,
2772 int slop);
Ben Murdoch62275a42010-09-07 11:27:28 +01002773
2774 private native void nativeAutoFillForm(int queryId);
Patrick Scottcfa734a2011-02-22 11:19:02 -05002775 private native void nativeScrollLayer(int layer, Rect rect);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776}