The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* |
| 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 | |
| 17 | package android.webkit; |
| 18 | |
Ben Murdoch | f7093be | 2010-11-01 10:27:33 +0000 | [diff] [blame] | 19 | import android.app.ActivityManager; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 20 | import android.content.Context; |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 21 | import android.content.pm.PackageManager.NameNotFoundException; |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 22 | import android.database.Cursor; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 23 | import android.graphics.Point; |
| 24 | import android.graphics.Rect; |
| 25 | import android.graphics.Region; |
Shimeng (Simon) Wang | bf01312 | 2010-10-05 16:59:05 -0700 | [diff] [blame] | 26 | import android.media.MediaFile; |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 27 | import android.net.Uri; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 28 | import android.os.Handler; |
| 29 | import android.os.Looper; |
| 30 | import android.os.Message; |
| 31 | import android.os.Process; |
Ben Murdoch | 65b4cda | 2010-05-28 11:07:15 +0100 | [diff] [blame] | 32 | import android.provider.MediaStore; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 | import android.util.Log; |
| 34 | import android.util.SparseBooleanArray; |
| 35 | import android.view.KeyEvent; |
Huahui Wu | 0904c0d | 2011-01-07 17:30:53 -0800 | [diff] [blame] | 36 | import android.view.MotionEvent; |
Patrick Scott | fb6aecb | 2009-07-17 16:38:07 -0400 | [diff] [blame] | 37 | import android.view.SurfaceView; |
Derek Sollenberger | 0b3a5d6 | 2009-09-08 18:31:40 -0400 | [diff] [blame] | 38 | import android.view.View; |
Steve Block | dc82a29 | 2010-10-06 14:34:15 +0100 | [diff] [blame] | 39 | import android.webkit.DeviceMotionService; |
Steve Block | 1be7339 | 2010-10-15 16:31:01 +0100 | [diff] [blame] | 40 | import android.webkit.DeviceMotionAndOrientationManager; |
Steve Block | c43565b | 2010-08-11 13:12:37 +0100 | [diff] [blame] | 41 | import android.webkit.DeviceOrientationService; |
Steve Block | 808751f | 2011-01-04 14:26:27 +0000 | [diff] [blame] | 42 | import android.webkit.JniUtil; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 43 | |
| 44 | import java.util.ArrayList; |
Nicolas Roard | 6c24b4d | 2009-09-22 18:44:52 +0100 | [diff] [blame] | 45 | import java.util.Collection; |
Andrei Popescu | 4950b2b | 2009-09-03 13:56:07 +0100 | [diff] [blame] | 46 | import java.util.Map; |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 47 | import java.util.Set; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 48 | |
| 49 | import junit.framework.Assert; |
| 50 | |
| 51 | final class WebViewCore { |
| 52 | |
| 53 | private static final String LOGTAG = "webcore"; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 54 | |
| 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 Queru | c0e9504 | 2011-01-31 15:43:19 -0800 | [diff] [blame] | 59 | try { |
| 60 | System.loadLibrary("webcore"); |
| 61 | } catch (UnsatisfiedLinkError e) { |
| 62 | Log.e(LOGTAG, "Unable to load webcore library"); |
| 63 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 64 | } |
| 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 Popescu | 4950b2b | 2009-09-03 13:56:07 +0100 | [diff] [blame] | 82 | // Custom JS interfaces to add during the initialization. |
| 83 | private Map<String, Object> mJavascriptInterfaces; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 84 | /* |
| 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 Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 112 | |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 113 | /* |
| 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) Wang | 5d8e7a4 | 2011-01-07 15:51:06 -0800 | [diff] [blame] | 122 | private float mRestoredScale = 0; |
| 123 | private float mRestoredTextWrapScale = 0; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 124 | private int mRestoredX = 0; |
| 125 | private int mRestoredY = 0; |
| 126 | |
Steve Block | 1be7339 | 2010-10-15 16:31:01 +0100 | [diff] [blame] | 127 | private DeviceMotionAndOrientationManager mDeviceMotionAndOrientationManager = |
| 128 | new DeviceMotionAndOrientationManager(this); |
Steve Block | dc82a29 | 2010-10-06 14:34:15 +0100 | [diff] [blame] | 129 | private DeviceMotionService mDeviceMotionService; |
Steve Block | c43565b | 2010-08-11 13:12:37 +0100 | [diff] [blame] | 130 | private DeviceOrientationService mDeviceOrientationService; |
Steve Block | f4a705f | 2010-08-11 13:08:24 +0100 | [diff] [blame] | 131 | |
Ben Murdoch | f7093be | 2010-11-01 10:27:33 +0000 | [diff] [blame] | 132 | private int mLowMemoryUsageThresholdMb; |
| 133 | private int mHighMemoryUsageThresholdMb; |
Shimeng (Simon) Wang | 7c1bcfd | 2011-01-24 14:38:46 -0800 | [diff] [blame] | 134 | private int mHighUsageDeltaMb; |
Ben Murdoch | f7093be | 2010-11-01 10:27:33 +0000 | [diff] [blame] | 135 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 136 | // 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 Popescu | 4950b2b | 2009-09-03 13:56:07 +0100 | [diff] [blame] | 140 | public WebViewCore(Context context, WebView w, CallbackProxy proxy, |
| 141 | Map<String, Object> javascriptInterfaces) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 142 | // No need to assign this in the WebCore thread. |
| 143 | mCallbackProxy = proxy; |
| 144 | mWebView = w; |
Andrei Popescu | 4950b2b | 2009-09-03 13:56:07 +0100 | [diff] [blame] | 145 | mJavascriptInterfaces = javascriptInterfaces; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 146 | // 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 Kloba | 0d8b77c | 2009-06-25 11:20:51 -0700 | [diff] [blame] | 173 | mSettings = new WebSettings(mContext, mWebView); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 174 | // The WebIconDatabase needs to be initialized within the UI thread so |
| 175 | // just request the instance here. |
| 176 | WebIconDatabase.getInstance(); |
Nicolas Roard | 6c24b4d | 2009-09-22 18:44:52 +0100 | [diff] [blame] | 177 | // Create the WebStorage singleton and the UI handler |
| 178 | WebStorage.getInstance().createUIHandler(); |
| 179 | // Create the UI handler for GeolocationPermissions |
| 180 | GeolocationPermissions.getInstance().createUIHandler(); |
Ben Murdoch | f7093be | 2010-11-01 10:27:33 +0000 | [diff] [blame] | 181 | |
| 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) Wang | 7c1bcfd | 2011-01-24 14:38:46 -0800 | [diff] [blame] | 191 | mLowMemoryUsageThresholdMb = manager.getLargeMemoryClass(); |
Shimeng (Simon) Wang | 7114f3b | 2011-01-26 10:34:26 -0800 | [diff] [blame] | 192 | mHighMemoryUsageThresholdMb = (int) (mLowMemoryUsageThresholdMb * 1.5); |
Shimeng (Simon) Wang | 7c1bcfd | 2011-01-24 14:38:46 -0800 | [diff] [blame] | 193 | // Avoid constant V8 GC when memory usage equals to working set estimate. |
Shimeng (Simon) Wang | 7114f3b | 2011-01-26 10:34:26 -0800 | [diff] [blame] | 194 | mHighUsageDeltaMb = mLowMemoryUsageThresholdMb / 32; |
Ben Murdoch | f7093be | 2010-11-01 10:27:33 +0000 | [diff] [blame] | 195 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 196 | // 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 Popescu | 4950b2b | 2009-09-03 13:56:07 +0100 | [diff] [blame] | 210 | mSettings, mJavascriptInterfaces); |
| 211 | mJavascriptInterfaces = null; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 212 | // 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 Roard | 11e8fe5 | 2009-05-11 15:04:16 +0100 | [diff] [blame] | 216 | // Create the handler for WebStorage |
| 217 | WebStorage.getInstance().createHandler(); |
Steve Block | 0ac031b | 2009-07-28 11:53:20 +0100 | [diff] [blame] | 218 | // Create the handler for GeolocationPermissions. |
| 219 | GeolocationPermissions.getInstance().createHandler(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 220 | // 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) Wang | bf01312 | 2010-10-05 16:59:05 -0700 | [diff] [blame] | 282 | /* |
| 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 Merrick | 4e7665d | 2010-10-27 10:15:14 +0100 | [diff] [blame] | 286 | /* package */ static boolean isSupportedMediaMimeType(String mimeType) { |
| 287 | int fileType = MediaFile.getFileTypeForMimeType(mimeType); |
Andreas Huber | 5dffd0e | 2010-11-15 08:54:40 -0800 | [diff] [blame] | 288 | return MediaFile.isAudioFileType(fileType) |
| 289 | || MediaFile.isVideoFileType(fileType) |
Shimeng (Simon) Wang | b394d9a | 2010-11-17 17:55:06 -0800 | [diff] [blame] | 290 | || MediaFile.isPlayListFileType(fileType) |
| 291 | // The following is not in Media framework, but it's supported. |
| 292 | || (mimeType != null && mimeType.startsWith("video/m4v")); |
Shimeng (Simon) Wang | bf01312 | 2010-10-05 16:59:05 -0700 | [diff] [blame] | 293 | } |
Iain Merrick | 4e7665d | 2010-10-27 10:15:14 +0100 | [diff] [blame] | 294 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 295 | /** |
Ben Murdoch | 6262ae5 | 2009-04-17 13:21:53 +0100 | [diff] [blame] | 296 | * 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 Murdoch | 3141e0a | 2010-01-28 15:06:32 +0000 | [diff] [blame] | 300 | * @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 Murdoch | 6262ae5 | 2009-04-17 13:21:53 +0100 | [diff] [blame] | 302 | */ |
Ben Murdoch | 3141e0a | 2010-01-28 15:06:32 +0000 | [diff] [blame] | 303 | protected void addMessageToConsole(String message, int lineNumber, String sourceID, |
| 304 | int msgLevel) { |
| 305 | mCallbackProxy.addMessageToConsole(message, lineNumber, sourceID, msgLevel); |
Ben Murdoch | 6262ae5 | 2009-04-17 13:21:53 +0100 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | /** |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 309 | * 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 Scroggins | f2e17a8 | 2010-09-24 15:58:50 -0400 | [diff] [blame] | 316 | /** |
| 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 Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 326 | |
| 327 | /** |
| 328 | * Called by JNI. Open a file chooser to upload a file. |
Ben Murdoch | 4ae32f5 | 2010-05-18 14:30:39 +0100 | [diff] [blame] | 329 | * @param acceptType The value of the 'accept' attribute of the |
| 330 | * input tag associated with this file picker. |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 331 | * @return String version of the URI. |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 332 | */ |
Ben Murdoch | 4ae32f5 | 2010-05-18 14:30:39 +0100 | [diff] [blame] | 333 | private String openFileChooser(String acceptType) { |
| 334 | Uri uri = mCallbackProxy.openFileChooser(acceptType); |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 335 | if (uri != null) { |
Ben Murdoch | 65b4cda | 2010-05-28 11:07:15 +0100 | [diff] [blame] | 336 | String filePath = ""; |
| 337 | // Note - querying for MediaStore.Images.Media.DATA |
| 338 | // seems to work for all content URIs, not just images |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 339 | Cursor cursor = mContext.getContentResolver().query( |
| 340 | uri, |
Ben Murdoch | 65b4cda | 2010-05-28 11:07:15 +0100 | [diff] [blame] | 341 | new String[] { MediaStore.Images.Media.DATA }, |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 342 | null, null, null); |
| 343 | if (cursor != null) { |
| 344 | try { |
| 345 | if (cursor.moveToNext()) { |
Ben Murdoch | 65b4cda | 2010-05-28 11:07:15 +0100 | [diff] [blame] | 346 | filePath = cursor.getString(0); |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 347 | } |
| 348 | } finally { |
| 349 | cursor.close(); |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 350 | } |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 351 | } else { |
Ben Murdoch | 65b4cda | 2010-05-28 11:07:15 +0100 | [diff] [blame] | 352 | filePath = uri.getLastPathSegment(); |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 353 | } |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 354 | String uriString = uri.toString(); |
Ben Murdoch | 65b4cda | 2010-05-28 11:07:15 +0100 | [diff] [blame] | 355 | BrowserFrame.sJavaBridge.storeFilePathForContentUri(filePath, uriString); |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 356 | return uriString; |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 357 | } |
Ben Murdoch | cc749de | 2010-05-18 12:37:00 +0100 | [diff] [blame] | 358 | return ""; |
Leon Scroggins | 70ca3c2 | 2009-10-02 15:58:55 -0400 | [diff] [blame] | 359 | } |
| 360 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 361 | /** |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 362 | * Notify the browser that the origin has exceeded it's database quota. |
Ben Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 363 | * @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 Murdoch | d497d87 | 2009-08-25 19:32:54 +0100 | [diff] [blame] | 366 | * @param estimatedSize The estimated size of the database. |
Ben Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 367 | */ |
| 368 | protected void exceededDatabaseQuota(String url, |
| 369 | String databaseIdentifier, |
Ben Murdoch | d497d87 | 2009-08-25 19:32:54 +0100 | [diff] [blame] | 370 | long currentQuota, |
| 371 | long estimatedSize) { |
Ben Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 372 | // 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 Murdoch | d497d87 | 2009-08-25 19:32:54 +0100 | [diff] [blame] | 377 | currentQuota, estimatedSize, getUsedQuota(), |
| 378 | new WebStorage.QuotaUpdater() { |
| 379 | public void updateQuota(long quota) { |
| 380 | nativeSetNewStorageLimit(quota); |
| 381 | } |
| 382 | }); |
Ben Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 383 | } |
| 384 | |
| 385 | /** |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 386 | * 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 Clarke | 194e345 | 2009-09-28 11:42:12 +0100 | [diff] [blame] | 399 | 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 Clarke | 9c8d886 | 2009-09-24 15:20:10 +0100 | [diff] [blame] | 406 | } |
| 407 | |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 408 | /** |
Steve Block | 4faee09 | 2009-07-28 18:20:50 +0100 | [diff] [blame] | 409 | * 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 436 | * 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 Zhu | 81e4143 | 2009-05-08 16:09:55 -0700 | [diff] [blame] | 466 | /** |
| 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 Murdoch | 6312de2 | 2010-06-29 19:20:11 +0100 | [diff] [blame] | 476 | /** |
| 477 | * Notify the webview that this is an installable web app. |
| 478 | */ |
| 479 | protected void setInstallableWebApp() { |
| 480 | mCallbackProxy.setInstallableWebApp(); |
| 481 | } |
| 482 | |
Nicolas Roard | 0e778a1 | 2011-03-11 14:29:05 -0800 | [diff] [blame] | 483 | /** |
| 484 | * Notify the webview that we want to display the video layer fullscreen. |
| 485 | */ |
Teng-Hui Zhu | 10ab654 | 2011-03-16 16:42:32 -0700 | [diff] [blame] | 486 | protected void enterFullscreenForVideoLayer(int layerId, String url) { |
Nicolas Roard | 0e778a1 | 2011-03-11 14:29:05 -0800 | [diff] [blame] | 487 | if (mWebView == null) return; |
Teng-Hui Zhu | 10ab654 | 2011-03-16 16:42:32 -0700 | [diff] [blame] | 488 | Message message = Message.obtain(mWebView.mPrivateHandler, |
| 489 | WebView.ENTER_FULLSCREEN_VIDEO, layerId, 0); |
| 490 | message.obj = url; |
| 491 | message.sendToTarget(); |
Nicolas Roard | 0e778a1 | 2011-03-11 14:29:05 -0800 | [diff] [blame] | 492 | } |
| 493 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 494 | //------------------------------------------------------------------------- |
| 495 | // JNI methods |
| 496 | //------------------------------------------------------------------------- |
| 497 | |
Cary Clark | 3e399de | 2009-06-17 10:00:57 -0400 | [diff] [blame] | 498 | static native String nativeFindAddress(String addr, boolean caseInsensitive); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 499 | |
| 500 | /** |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 501 | * Empty the picture set. |
| 502 | */ |
| 503 | private native void nativeClearContent(); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 504 | |
Cary Clark | 75796bb | 2010-08-24 14:59:58 -0400 | [diff] [blame] | 505 | private native void nativeContentInvalidateAll(); |
| 506 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 507 | /** |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 508 | * Redraw a portion of the picture set. The Point wh returns the |
| 509 | * width and height of the overall picture. |
| 510 | */ |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 511 | private native int nativeRecordContent(Region invalRegion, Point wh); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 512 | |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 513 | /** |
| 514 | * Update the layers' content |
| 515 | */ |
Patrick Scott | 2f49227 | 2010-12-03 09:52:35 -0500 | [diff] [blame] | 516 | private native int nativeUpdateLayers(Region invalRegion); |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 517 | |
Cary Clark | 5da9aeb | 2009-10-06 17:40:53 -0400 | [diff] [blame] | 518 | private native boolean nativeFocusBoundsChanged(); |
| 519 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 520 | /** |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 521 | * 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 523 | */ |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 524 | private native void nativeSplitContent(int content); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 525 | |
| 526 | private native boolean nativeKey(int keyCode, int unichar, |
Cary Clark | 215b72c | 2009-06-26 14:38:43 -0400 | [diff] [blame] | 527 | int repeatCount, boolean isShift, boolean isAlt, boolean isSym, |
| 528 | boolean isDown); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 529 | |
Leon Scroggins | b45a263 | 2011-01-12 14:11:24 -0500 | [diff] [blame] | 530 | private native void nativeClick(int framePtr, int nodePtr, boolean fake); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 531 | |
| 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 Kloba | e80cbcc | 2010-05-28 18:07:50 -0700 | [diff] [blame] | 540 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 542 | should this be called nativeSetViewPortSize? |
| 543 | */ |
Grace Kloba | e80cbcc | 2010-05-28 18:07:50 -0700 | [diff] [blame] | 544 | private native void nativeSetSize(int width, int height, int textWrapWidth, |
| 545 | float scale, int screenWidth, int screenHeight, int anchorX, |
Grace Kloba | 3a0def2 | 2010-01-23 21:11:54 -0800 | [diff] [blame] | 546 | int anchorY, boolean ignoreHeight); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 547 | |
| 548 | private native int nativeGetContentMinPrefWidth(); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 549 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 550 | // Start: functions that deal with text editing |
Cary Clark | 2f1d60c | 2009-06-03 08:05:53 -0400 | [diff] [blame] | 551 | private native void nativeReplaceTextfieldText( |
Leon Scroggins | 43488fc | 2009-07-06 14:32:49 -0400 | [diff] [blame] | 552 | int oldStart, int oldEnd, String replace, int newStart, int newEnd, |
| 553 | int textGeneration); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 554 | |
Cary Clark | 2f1d60c | 2009-06-03 08:05:53 -0400 | [diff] [blame] | 555 | private native void passToJs(int gen, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 556 | String currentText, int keyCode, int keyValue, boolean down, |
| 557 | boolean cap, boolean fn, boolean sym); |
| 558 | |
Leon Scroggins | 8cdad88 | 2009-06-30 08:47:04 -0400 | [diff] [blame] | 559 | private native void nativeSetFocusControllerActive(boolean active); |
Leon Scroggins | 63dda1c | 2009-04-15 13:25:00 -0400 | [diff] [blame] | 560 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 561 | private native void nativeSaveDocumentState(int frame); |
| 562 | |
Leon Scroggins | 47fabbf | 2009-12-08 16:57:26 -0500 | [diff] [blame] | 563 | private native void nativeMoveFocus(int framePtr, int nodePointer); |
Cary Clark | ed56eda | 2009-06-18 09:48:47 -0400 | [diff] [blame] | 564 | private native void nativeMoveMouse(int framePtr, int x, int y); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 565 | |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 566 | private native void nativeMoveMouseIfLatest(int moveGeneration, |
Cary Clark | ed56eda | 2009-06-18 09:48:47 -0400 | [diff] [blame] | 567 | int framePtr, int x, int y); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 568 | |
Cary Clark | e41bb53 | 2010-11-30 15:59:59 -0500 | [diff] [blame] | 569 | private native String nativeRetrieveHref(int x, int y); |
| 570 | private native String nativeRetrieveAnchorText(int x, int y); |
Cary Clark | 861368a | 2010-12-15 11:24:37 -0500 | [diff] [blame] | 571 | private native String nativeRetrieveImageSource(int x, int y); |
Leon Scroggins | b611213 | 2011-02-24 12:35:50 -0500 | [diff] [blame] | 572 | private native void nativeStopPaintingCaret(); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 573 | private native void nativeTouchUp(int touchGeneration, |
Leon Scroggins | 22e883d | 2011-01-31 10:54:19 -0500 | [diff] [blame] | 574 | int framePtr, int nodePtr, int x, int y); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 575 | |
Huahui Wu | e838a42 | 2011-01-13 16:03:43 -0800 | [diff] [blame] | 576 | private native boolean nativeHandleTouchEvent(int action, int[] idArray, |
Huahui Wu | 2d3ef37 | 2011-03-13 18:13:42 -0700 | [diff] [blame] | 577 | int[] xArray, int[] yArray, int count, int actionIndex, int metaState); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 578 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 579 | private native void nativeUpdateFrameCache(); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 580 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 581 | private native void nativeSetBackgroundColor(int color); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 582 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 583 | private native void nativeDumpDomTree(boolean useFile); |
| 584 | |
| 585 | private native void nativeDumpRenderTree(boolean useFile); |
| 586 | |
| 587 | private native void nativeDumpNavTree(); |
| 588 | |
Andrei Popescu | 5e7bb0a | 2010-02-01 22:32:16 +0000 | [diff] [blame] | 589 | private native void nativeDumpV8Counters(); |
| 590 | |
Feng Qian | b308137 | 2009-06-29 15:55:18 -0700 | [diff] [blame] | 591 | private native void nativeSetJsFlags(String flags); |
| 592 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 593 | /** |
| 594 | * Delete text from start to end in the focused textfield. If there is no |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 595 | * focus, or if start == end, silently fail. If start and end are out of |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 596 | * order, swap them. |
| 597 | * @param start Beginning of selection to delete. |
| 598 | * @param end End of selection to delete. |
Leon Scroggins | 43488fc | 2009-07-06 14:32:49 -0400 | [diff] [blame] | 599 | * @param textGeneration Text generation number when delete was pressed. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 600 | */ |
Leon Scroggins | 43488fc | 2009-07-06 14:32:49 -0400 | [diff] [blame] | 601 | private native void nativeDeleteSelection(int start, int end, |
| 602 | int textGeneration); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 603 | |
| 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 Clark | 2f1d60c | 2009-06-03 08:05:53 -0400 | [diff] [blame] | 610 | private native void nativeSetSelection(int start, int end); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 611 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 612 | // 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 Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 616 | /* |
| 617 | * Inform webcore that the user has decided whether to allow or deny new |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 618 | * 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 Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 621 | */ |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 622 | private native void nativeSetNewStorageLimit(long limit); |
Ben Murdoch | 7df1985 | 2009-04-22 13:07:58 +0100 | [diff] [blame] | 623 | |
Steve Block | 4faee09 | 2009-07-28 18:20:50 +0100 | [diff] [blame] | 624 | /** |
| 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 Clarke | 194e345 | 2009-09-28 11:42:12 +0100 | [diff] [blame] | 634 | /** |
| 635 | * Provide WebCore with the previously visted links from the history database |
| 636 | */ |
Svetoslav Ganov | da35551 | 2010-05-12 22:04:44 -0700 | [diff] [blame] | 637 | private native void nativeProvideVisitedHistory(String[] history); |
| 638 | |
| 639 | /** |
| 640 | * Modifies the current selection. |
| 641 | * |
Svetoslav Ganov | c93fb65 | 2011-01-05 18:52:05 -0800 | [diff] [blame] | 642 | * Note: Accessibility support. |
| 643 | * |
Svetoslav Ganov | da35551 | 2010-05-12 22:04:44 -0700 | [diff] [blame] | 644 | * @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 Ganov | 585f13f8d | 2010-08-10 07:59:15 -0700 | [diff] [blame] | 649 | private native String nativeModifySelection(int direction, int granularity); |
Leon Clarke | 194e345 | 2009-09-28 11:42:12 +0100 | [diff] [blame] | 650 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 651 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 661 | |
| 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 Monsen | 4190aab | 2010-12-16 18:39:21 +0000 | [diff] [blame] | 686 | |
| 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 Monsen | 41e7e6f | 2010-12-21 12:51:11 +0000 | [diff] [blame] | 702 | |
| 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 710 | } |
| 711 | } |
| 712 | }; |
| 713 | WebViewCore.class.notify(); |
| 714 | } |
| 715 | Looper.loop(); |
| 716 | } |
| 717 | } |
| 718 | |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 719 | static class BaseUrlData { |
| 720 | String mBaseUrl; |
| 721 | String mData; |
| 722 | String mMimeType; |
| 723 | String mEncoding; |
Leon Scroggins | 1bb1a91 | 2010-03-23 15:39:46 -0400 | [diff] [blame] | 724 | String mHistoryUrl; |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 725 | } |
| 726 | |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 727 | static class CursorData { |
| 728 | CursorData() {} |
| 729 | CursorData(int frame, int node, int x, int y) { |
| 730 | mFrame = frame; |
Leon Scroggins | 47fabbf | 2009-12-08 16:57:26 -0500 | [diff] [blame] | 731 | mNode = node; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 732 | mX = x; |
| 733 | mY = y; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 734 | } |
| 735 | int mMoveGeneration; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 736 | int mFrame; |
Leon Scroggins | 47fabbf | 2009-12-08 16:57:26 -0500 | [diff] [blame] | 737 | int mNode; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 738 | int mX; |
| 739 | int mY; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 740 | } |
| 741 | |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 742 | static class JSInterfaceData { |
| 743 | Object mObject; |
| 744 | String mInterfaceName; |
| 745 | } |
| 746 | |
| 747 | static class JSKeyData { |
| 748 | String mCurrentText; |
| 749 | KeyEvent mEvent; |
| 750 | } |
| 751 | |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 752 | static class MotionUpData { |
| 753 | int mFrame; |
| 754 | int mNode; |
| 755 | Rect mBounds; |
| 756 | int mX; |
| 757 | int mY; |
| 758 | } |
| 759 | |
Grace Kloba | d0d9bc2 | 2010-01-26 18:08:28 -0800 | [diff] [blame] | 760 | static class GetUrlData { |
| 761 | String mUrl; |
| 762 | Map<String, String> mExtraHeaders; |
| 763 | } |
| 764 | |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 765 | 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 Scroggins | 43488fc | 2009-07-06 14:32:49 -0400 | [diff] [blame] | 774 | int mTextGeneration; |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 775 | } |
| 776 | |
Leon Scroggins | 6679f2f | 2009-08-12 18:48:10 -0400 | [diff] [blame] | 777 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 786 | static class TouchUpData { |
| 787 | int mMoveGeneration; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 788 | int mFrame; |
| 789 | int mNode; |
| 790 | int mX; |
| 791 | int mY; |
Patrick Scott | cfa734a | 2011-02-22 11:19:02 -0500 | [diff] [blame] | 792 | int mNativeLayer; |
| 793 | Rect mNativeLayerRect = new Rect(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 794 | } |
| 795 | |
Grace Kloba | 178db41 | 2010-05-18 22:22:23 -0700 | [diff] [blame] | 796 | static class TouchHighlightData { |
| 797 | int mX; |
| 798 | int mY; |
| 799 | int mSlop; |
| 800 | } |
| 801 | |
Ben Murdoch | db8d19c | 2010-10-29 11:44:17 +0100 | [diff] [blame] | 802 | 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 Kloba | 5f68d6f | 2009-12-08 18:42:54 -0800 | [diff] [blame] | 825 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 830 | static class TouchEventData { |
Grace Kloba | 5f68d6f | 2009-12-08 18:42:54 -0800 | [diff] [blame] | 831 | int mAction; |
Huahui Wu | e838a42 | 2011-01-13 16:03:43 -0800 | [diff] [blame] | 832 | int[] mIds; // Ids of the touch points |
Huahui Wu | 41865f4 | 2010-09-02 13:41:41 -0700 | [diff] [blame] | 833 | Point[] mPoints; |
Huahui Wu | 88b869a | 2011-03-17 17:42:12 -0700 | [diff] [blame] | 834 | Point[] mPointsInView; // the point coordinates in view axis. |
Huahui Wu | 2d3ef37 | 2011-03-13 18:13:42 -0700 | [diff] [blame] | 835 | int mActionIndex; // Associated pointer index for ACTION_POINTER_DOWN/UP |
Ben Murdoch | 8a032a3 | 2010-02-02 18:20:11 +0000 | [diff] [blame] | 836 | int mMetaState; |
Grace Kloba | c2242f2 | 2010-03-05 14:00:26 -0800 | [diff] [blame] | 837 | boolean mReprocess; |
Huahui Wu | 0904c0d | 2011-01-07 17:30:53 -0800 | [diff] [blame] | 838 | MotionEvent mMotionEvent; |
Patrick Scott | cfa734a | 2011-02-22 11:19:02 -0500 | [diff] [blame] | 839 | int mNativeLayer; |
| 840 | Rect mNativeLayerRect = new Rect(); |
Adam Powell | 4fb35d4 | 2011-03-03 17:54:55 -0800 | [diff] [blame] | 841 | long mSequence; |
| 842 | boolean mNativeResult; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 843 | } |
| 844 | |
Steve Block | 4faee09 | 2009-07-28 18:20:50 +0100 | [diff] [blame] | 845 | static class GeolocationPermissionsData { |
| 846 | String mOrigin; |
| 847 | boolean mAllow; |
| 848 | boolean mRemember; |
| 849 | } |
| 850 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 851 | static final String[] HandlerDebugString = { |
Leon Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 852 | "REVEAL_SELECTION", // 96 |
Leon Scroggins | 3a50339 | 2010-01-06 17:04:38 -0500 | [diff] [blame] | 853 | "REQUEST_LABEL", // 97 |
Cary Clark | 77d98f4 | 2009-07-31 09:40:38 -0400 | [diff] [blame] | 854 | "UPDATE_FRAME_CACHE_IF_LOADING", // = 98 |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 855 | "SCROLL_TEXT_INPUT", // = 99 |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 856 | "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 Kloba | a72cc09 | 2009-04-02 08:50:17 -0700 | [diff] [blame] | 875 | "SET_NETWORK_STATE", // = 119; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 876 | "DOC_HAS_IMAGES", // = 120; |
Leon Scroggins | b45a263 | 2011-01-12 14:11:24 -0500 | [diff] [blame] | 877 | "FAKE_CLICK", // = 121; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 878 | "DELETE_SELECTION", // = 122; |
| 879 | "LISTBOX_CHOICES", // = 123; |
| 880 | "SINGLE_LISTBOX_CHOICE", // = 124; |
Grace Kloba | b3230cb | 2009-04-13 14:04:23 -0700 | [diff] [blame] | 881 | "MESSAGE_RELAY", // = 125; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 882 | "SET_BACKGROUND_COLOR", // = 126; |
Leon Scroggins | 47fabbf | 2009-12-08 16:57:26 -0500 | [diff] [blame] | 883 | "SET_MOVE_FOCUS", // = 127 |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 884 | "SAVE_DOCUMENT_STATE", // = 128; |
Cary Clark | 57d2c3a | 2009-12-23 13:57:15 -0500 | [diff] [blame] | 885 | "129", // = 129; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 886 | "WEBKIT_DRAW", // = 130; |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 887 | "131", // = 131; |
Grace Kloba | 5753430 | 2009-05-22 18:55:02 -0700 | [diff] [blame] | 888 | "POST_URL", // = 132; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 889 | "SPLIT_PICTURE_SET", // = 133; |
| 890 | "CLEAR_CONTENT", // = 134; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 891 | "SET_MOVE_MOUSE", // = 135; |
| 892 | "SET_MOVE_MOUSE_IF_LATEST", // = 136; |
Leon Scroggins | 1c7f8c5 | 2009-06-05 13:49:26 -0400 | [diff] [blame] | 893 | "REQUEST_CURSOR_HREF", // = 137; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 894 | "ADD_JS_INTERFACE", // = 138; |
| 895 | "LOAD_DATA", // = 139; |
| 896 | "TOUCH_UP", // = 140; |
| 897 | "TOUCH_EVENT", // = 141; |
Leon Scroggins | 8cdad88 | 2009-06-30 08:47:04 -0400 | [diff] [blame] | 898 | "SET_ACTIVE", // = 142; |
Mike Reed | d205d5b | 2009-05-27 11:02:29 -0400 | [diff] [blame] | 899 | "ON_PAUSE", // = 143 |
| 900 | "ON_RESUME", // = 144 |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 901 | "FREE_MEMORY", // = 145 |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 902 | "VALID_NODE_BOUNDS", // = 146 |
Elliott Slaughter | b48fdbe | 2010-06-30 11:39:52 -0700 | [diff] [blame] | 903 | "SAVE_WEBARCHIVE", // = 147 |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 904 | "WEBKIT_DRAW_LAYERS", // = 148; |
Steve Block | 689a342 | 2010-12-07 18:18:26 +0000 | [diff] [blame] | 905 | "REMOVE_JS_INTERFACE", // = 149; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 906 | }; |
| 907 | |
| 908 | class EventHub { |
| 909 | // Message Ids |
Leon Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 910 | static final int REVEAL_SELECTION = 96; |
Leon Scroggins | 3a50339 | 2010-01-06 17:04:38 -0500 | [diff] [blame] | 911 | static final int REQUEST_LABEL = 97; |
Cary Clark | 77d98f4 | 2009-07-31 09:40:38 -0400 | [diff] [blame] | 912 | static final int UPDATE_FRAME_CACHE_IF_LOADING = 98; |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 913 | static final int SCROLL_TEXT_INPUT = 99; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 914 | 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 Kloba | a72cc09 | 2009-04-02 08:50:17 -0700 | [diff] [blame] | 933 | static final int SET_NETWORK_STATE = 119; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 934 | static final int DOC_HAS_IMAGES = 120; |
Leon Scroggins | b45a263 | 2011-01-12 14:11:24 -0500 | [diff] [blame] | 935 | static final int FAKE_CLICK = 121; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 936 | static final int DELETE_SELECTION = 122; |
| 937 | static final int LISTBOX_CHOICES = 123; |
| 938 | static final int SINGLE_LISTBOX_CHOICE = 124; |
Grace Kloba | b3230cb | 2009-04-13 14:04:23 -0700 | [diff] [blame] | 939 | static final int MESSAGE_RELAY = 125; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 940 | static final int SET_BACKGROUND_COLOR = 126; |
Leon Scroggins | 47fabbf | 2009-12-08 16:57:26 -0500 | [diff] [blame] | 941 | static final int SET_MOVE_FOCUS = 127; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 942 | static final int SAVE_DOCUMENT_STATE = 128; |
Cary Clark | 57d2c3a | 2009-12-23 13:57:15 -0500 | [diff] [blame] | 943 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 944 | static final int WEBKIT_DRAW = 130; |
Grace Kloba | 5753430 | 2009-05-22 18:55:02 -0700 | [diff] [blame] | 945 | static final int POST_URL = 132; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 946 | static final int SPLIT_PICTURE_SET = 133; |
| 947 | static final int CLEAR_CONTENT = 134; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 948 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 949 | // UI nav messages |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 950 | static final int SET_MOVE_MOUSE = 135; |
| 951 | static final int SET_MOVE_MOUSE_IF_LATEST = 136; |
Leon Scroggins | 1c7f8c5 | 2009-06-05 13:49:26 -0400 | [diff] [blame] | 952 | static final int REQUEST_CURSOR_HREF = 137; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 953 | 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 Scroggins | fa03cde | 2009-06-15 15:48:46 -0400 | [diff] [blame] | 961 | // 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 Scroggins | 8cdad88 | 2009-06-30 08:47:04 -0400 | [diff] [blame] | 964 | static final int SET_ACTIVE = 142; |
Leon Scroggins | 63dda1c | 2009-04-15 13:25:00 -0400 | [diff] [blame] | 965 | |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 966 | // lifecycle activities for just this DOM (unlike pauseTimers, which |
Mike Reed | d205d5b | 2009-05-27 11:02:29 -0400 | [diff] [blame] | 967 | // is global) |
| 968 | static final int ON_PAUSE = 143; |
| 969 | static final int ON_RESUME = 144; |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 970 | static final int FREE_MEMORY = 145; |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 971 | static final int VALID_NODE_BOUNDS = 146; |
Mike Reed | d205d5b | 2009-05-27 11:02:29 -0400 | [diff] [blame] | 972 | |
Elliott Slaughter | b48fdbe | 2010-06-30 11:39:52 -0700 | [diff] [blame] | 973 | // Load and save web archives |
| 974 | static final int SAVE_WEBARCHIVE = 147; |
| 975 | |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 976 | // Update layers |
| 977 | static final int WEBKIT_DRAW_LAYERS = 148; |
| 978 | |
Steve Block | 689a342 | 2010-12-07 18:18:26 +0000 | [diff] [blame] | 979 | static final int REMOVE_JS_INTERFACE = 149; |
| 980 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 981 | // 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 Popescu | 5e7bb0a | 2010-02-01 22:32:16 +0000 | [diff] [blame] | 992 | static final int DUMP_V8COUNTERS = 173; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 993 | |
Andrei Popescu | 5e7bb0a | 2010-02-01 22:32:16 +0000 | [diff] [blame] | 994 | static final int SET_JS_FLAGS = 174; |
Steve Block | 4faee09 | 2009-07-28 18:20:50 +0100 | [diff] [blame] | 995 | // Geolocation |
| 996 | static final int GEOLOCATION_PERMISSIONS_PROVIDE = 180; |
Feng Qian | b308137 | 2009-06-29 15:55:18 -0700 | [diff] [blame] | 997 | |
Leon Clarke | 194e345 | 2009-09-28 11:42:12 +0100 | [diff] [blame] | 998 | static final int POPULATE_VISITED_LINKS = 181; |
| 999 | |
Grace Kloba | 11438c3 | 2009-12-16 11:39:12 -0800 | [diff] [blame] | 1000 | static final int HIDE_FULLSCREEN = 182; |
| 1001 | |
Andrei Popescu | f5dba88 | 2010-01-12 22:42:41 +0000 | [diff] [blame] | 1002 | static final int SET_NETWORK_TYPE = 183; |
| 1003 | |
Andrei Popescu | a6d747d | 2010-02-11 13:19:21 +0000 | [diff] [blame] | 1004 | // 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 Kloba | 178db41 | 2010-05-18 22:22:23 -0700 | [diff] [blame] | 1009 | static final int GET_TOUCH_HIGHLIGHT_RECTS = 187; |
| 1010 | static final int REMOVE_TOUCH_HIGHLIGHT_RECTS = 188; |
| 1011 | |
Svetoslav Ganov | da35551 | 2010-05-12 22:04:44 -0700 | [diff] [blame] | 1012 | // accessibility support |
| 1013 | static final int MODIFY_SELECTION = 190; |
| 1014 | |
Steve Block | 68dede3 | 2010-08-04 10:28:46 +0100 | [diff] [blame] | 1015 | static final int USE_MOCK_DEVICE_ORIENTATION = 191; |
| 1016 | |
Ben Murdoch | 62275a4 | 2010-09-07 11:27:28 +0100 | [diff] [blame] | 1017 | static final int AUTOFILL_FORM = 192; |
| 1018 | |
Kristian Monsen | 41e7e6f | 2010-12-21 12:51:11 +0000 | [diff] [blame] | 1019 | static final int PROXY_CHANGED = 193; |
| 1020 | |
Narayan Kamath | 9497c5f | 2011-02-22 12:05:34 +0000 | [diff] [blame] | 1021 | static final int EXECUTE_JS = 194; |
| 1022 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1023 | // private message ids |
| 1024 | private static final int DESTROY = 200; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1025 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1026 | // 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 Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 1043 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1046 | /** |
| 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 Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 1056 | if (DebugFlags.WEB_VIEW_CORE) { |
Leon Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 1057 | Log.v(LOGTAG, (msg.what < FIRST_PACKAGE_MSG_ID |
| 1058 | || msg.what > LAST_PACKAGE_MSG_ID |
| 1059 | ? Integer.toString(msg.what) |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 1060 | : HandlerDebugString[msg.what |
Leon Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 1061 | - FIRST_PACKAGE_MSG_ID]) |
Cary Clark | 243ea06 | 2009-06-25 10:49:32 -0400 | [diff] [blame] | 1062 | + " arg1=" + msg.arg1 + " arg2=" + msg.arg2 |
| 1063 | + " obj=" + msg.obj); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1064 | } |
| 1065 | switch (msg.what) { |
| 1066 | case WEBKIT_DRAW: |
| 1067 | webkitDraw(); |
| 1068 | break; |
| 1069 | |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 1070 | case WEBKIT_DRAW_LAYERS: |
| 1071 | webkitDrawLayers(); |
| 1072 | break; |
| 1073 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1074 | case DESTROY: |
| 1075 | // Time to take down the world. Cancel all pending |
| 1076 | // loads and destroy the native view and frame. |
Cary Clark | 674a844 | 2009-09-15 16:25:43 -0400 | [diff] [blame] | 1077 | synchronized (WebViewCore.this) { |
| 1078 | mBrowserFrame.destroy(); |
| 1079 | mBrowserFrame = null; |
Andrei Popescu | dee76be | 2009-09-22 18:28:21 +0100 | [diff] [blame] | 1080 | mSettings.onDestroyed(); |
Cary Clark | 674a844 | 2009-09-15 16:25:43 -0400 | [diff] [blame] | 1081 | mNativeClass = 0; |
Ben Murdoch | 3dba1e4 | 2009-09-22 15:50:30 +0100 | [diff] [blame] | 1082 | mWebView = null; |
Cary Clark | 674a844 | 2009-09-15 16:25:43 -0400 | [diff] [blame] | 1083 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1084 | break; |
| 1085 | |
Leon Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 1086 | case REVEAL_SELECTION: |
| 1087 | nativeRevealSelection(); |
| 1088 | break; |
| 1089 | |
Leon Scroggins | 3a50339 | 2010-01-06 17:04:38 -0500 | [diff] [blame] | 1090 | 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 Clark | 77d98f4 | 2009-07-31 09:40:38 -0400 | [diff] [blame] | 1103 | case UPDATE_FRAME_CACHE_IF_LOADING: |
| 1104 | nativeUpdateFrameCacheIfLoading(); |
| 1105 | break; |
| 1106 | |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 1107 | case SCROLL_TEXT_INPUT: |
Leon Scroggins | 22e883d | 2011-01-31 10:54:19 -0500 | [diff] [blame] | 1108 | 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 Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 1115 | break; |
| 1116 | |
Grace Kloba | d0d9bc2 | 2010-01-26 18:08:28 -0800 | [diff] [blame] | 1117 | case LOAD_URL: { |
Kristian Monsen | 8517305 | 2010-12-08 15:29:29 +0000 | [diff] [blame] | 1118 | CookieManager.getInstance().waitForCookieOperationsToComplete(); |
Grace Kloba | d0d9bc2 | 2010-01-26 18:08:28 -0800 | [diff] [blame] | 1119 | GetUrlData param = (GetUrlData) msg.obj; |
| 1120 | loadUrl(param.mUrl, param.mExtraHeaders); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1121 | break; |
Grace Kloba | d0d9bc2 | 2010-01-26 18:08:28 -0800 | [diff] [blame] | 1122 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1123 | |
Grace Kloba | 5753430 | 2009-05-22 18:55:02 -0700 | [diff] [blame] | 1124 | case POST_URL: { |
Kristian Monsen | 8517305 | 2010-12-08 15:29:29 +0000 | [diff] [blame] | 1125 | CookieManager.getInstance().waitForCookieOperationsToComplete(); |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1126 | PostUrlData param = (PostUrlData) msg.obj; |
| 1127 | mBrowserFrame.postUrl(param.mUrl, param.mPostData); |
Grace Kloba | 5753430 | 2009-05-22 18:55:02 -0700 | [diff] [blame] | 1128 | break; |
| 1129 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1130 | case LOAD_DATA: |
Kristian Monsen | 8517305 | 2010-12-08 15:29:29 +0000 | [diff] [blame] | 1131 | CookieManager.getInstance().waitForCookieOperationsToComplete(); |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1132 | BaseUrlData loadParams = (BaseUrlData) msg.obj; |
| 1133 | String baseUrl = loadParams.mBaseUrl; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1134 | 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 Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1146 | */ |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1147 | 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 Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1157 | loadParams.mData, |
| 1158 | loadParams.mMimeType, |
| 1159 | loadParams.mEncoding, |
Leon Scroggins | 1bb1a91 | 2010-03-23 15:39:46 -0400 | [diff] [blame] | 1160 | loadParams.mHistoryUrl); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1161 | break; |
| 1162 | |
| 1163 | case STOP_LOADING: |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1164 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1167 | // 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 Scroggins | b45a263 | 2011-01-12 14:11:24 -0500 | [diff] [blame] | 1188 | case FAKE_CLICK: |
| 1189 | nativeClick(msg.arg1, msg.arg2, true); |
| 1190 | break; |
| 1191 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1192 | case CLICK: |
Leon Scroggins | b45a263 | 2011-01-12 14:11:24 -0500 | [diff] [blame] | 1193 | nativeClick(msg.arg1, msg.arg2, false); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1194 | break; |
| 1195 | |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1196 | case VIEW_SIZE_CHANGED: { |
Shimeng (Simon) Wang | 48fc909 | 2011-02-03 14:29:54 -0800 | [diff] [blame] | 1197 | viewSizeChanged((WebView.ViewSizeData) msg.obj); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1198 | break; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1199 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1200 | case SET_SCROLL_OFFSET: |
| 1201 | // note: these are in document coordinates |
| 1202 | // (inv-zoom) |
Cary Clark | ed56eda | 2009-06-18 09:48:47 -0400 | [diff] [blame] | 1203 | Point pt = (Point) msg.obj; |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 1204 | nativeSetScrollOffset(msg.arg1, msg.arg2 == 1, |
| 1205 | pt.x, pt.y); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1206 | break; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1207 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1208 | 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 Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1218 | (mBrowserFrame.loadType() == |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1219 | 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 Block | 808751f | 2011-01-04 14:26:27 +0000 | [diff] [blame] | 1236 | if (!JniUtil.useChromiumHttpStack()) { |
| 1237 | WebViewWorker.getHandler().sendEmptyMessage( |
| 1238 | WebViewWorker.MSG_PAUSE_CACHE_TRANSACTION); |
| 1239 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1240 | break; |
| 1241 | |
| 1242 | case RESUME_TIMERS: |
| 1243 | Process.setThreadPriority(mTid, mSavedPriority); |
| 1244 | resumeTimers(); |
Steve Block | 808751f | 2011-01-04 14:26:27 +0000 | [diff] [blame] | 1245 | if (!JniUtil.useChromiumHttpStack()) { |
| 1246 | WebViewWorker.getHandler().sendEmptyMessage( |
| 1247 | WebViewWorker.MSG_RESUME_CACHE_TRANSACTION); |
| 1248 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1249 | break; |
| 1250 | |
Mike Reed | d205d5b | 2009-05-27 11:02:29 -0400 | [diff] [blame] | 1251 | case ON_PAUSE: |
| 1252 | nativePause(); |
| 1253 | break; |
| 1254 | |
| 1255 | case ON_RESUME: |
| 1256 | nativeResume(); |
| 1257 | break; |
| 1258 | |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 1259 | case FREE_MEMORY: |
| 1260 | clearCache(false); |
| 1261 | nativeFreeMemory(); |
| 1262 | break; |
| 1263 | |
Grace Kloba | a72cc09 | 2009-04-02 08:50:17 -0700 | [diff] [blame] | 1264 | 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 Popescu | f5dba88 | 2010-01-12 22:42:41 +0000 | [diff] [blame] | 1273 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1283 | case CLEAR_CACHE: |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 1284 | clearCache(msg.arg1 == 1); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1285 | break; |
| 1286 | |
| 1287 | case CLEAR_HISTORY: |
| 1288 | mCallbackProxy.getBackForwardList(). |
| 1289 | close(mBrowserFrame.mNativeFrame); |
| 1290 | break; |
| 1291 | |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1292 | case REPLACE_TEXT: |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1293 | ReplaceTextData rep = (ReplaceTextData) msg.obj; |
| 1294 | nativeReplaceTextfieldText(msg.arg1, msg.arg2, |
Leon Scroggins | 43488fc | 2009-07-06 14:32:49 -0400 | [diff] [blame] | 1295 | rep.mReplace, rep.mNewStart, rep.mNewEnd, |
| 1296 | rep.mTextGeneration); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1297 | break; |
| 1298 | |
| 1299 | case PASS_TO_JS: { |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1300 | JSKeyData jsData = (JSKeyData) msg.obj; |
| 1301 | KeyEvent evt = jsData.mEvent; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1302 | int keyCode = evt.getKeyCode(); |
| 1303 | int keyValue = evt.getUnicodeChar(); |
| 1304 | int generation = msg.arg1; |
Cary Clark | 2f1d60c | 2009-06-03 08:05:53 -0400 | [diff] [blame] | 1305 | passToJs(generation, |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1306 | jsData.mCurrentText, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1307 | keyCode, |
| 1308 | keyValue, |
| 1309 | evt.isDown(), |
| 1310 | evt.isShiftPressed(), evt.isAltPressed(), |
| 1311 | evt.isSymPressed()); |
| 1312 | break; |
| 1313 | } |
| 1314 | |
| 1315 | case SAVE_DOCUMENT_STATE: { |
Leon Scroggins | 1c7f8c5 | 2009-06-05 13:49:26 -0400 | [diff] [blame] | 1316 | CursorData cDat = (CursorData) msg.obj; |
| 1317 | nativeSaveDocumentState(cDat.mFrame); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1318 | 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 Scott | cfa734a | 2011-02-22 11:19:02 -0500 | [diff] [blame] | 1328 | if (touchUpData.mNativeLayer != 0) { |
| 1329 | nativeScrollLayer(touchUpData.mNativeLayer, |
| 1330 | touchUpData.mNativeLayerRect); |
| 1331 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1332 | nativeTouchUp(touchUpData.mMoveGeneration, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1333 | touchUpData.mFrame, touchUpData.mNode, |
Leon Scroggins | 22e883d | 2011-01-31 10:54:19 -0500 | [diff] [blame] | 1334 | touchUpData.mX, touchUpData.mY); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1335 | break; |
| 1336 | |
| 1337 | case TOUCH_EVENT: { |
| 1338 | TouchEventData ted = (TouchEventData) msg.obj; |
Huahui Wu | 41865f4 | 2010-09-02 13:41:41 -0700 | [diff] [blame] | 1339 | 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 Scott | cfa734a | 2011-02-22 11:19:02 -0500 | [diff] [blame] | 1346 | if (ted.mNativeLayer != 0) { |
| 1347 | nativeScrollLayer(ted.mNativeLayer, |
| 1348 | ted.mNativeLayerRect); |
| 1349 | } |
Adam Powell | 4fb35d4 | 2011-03-03 17:54:55 -0800 | [diff] [blame] | 1350 | ted.mNativeResult = nativeHandleTouchEvent(ted.mAction, ted.mIds, |
Huahui Wu | 2d3ef37 | 2011-03-13 18:13:42 -0700 | [diff] [blame] | 1351 | xArray, yArray, count, ted.mActionIndex, ted.mMetaState); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1352 | Message.obtain( |
| 1353 | mWebView.mPrivateHandler, |
Grace Kloba | c2242f2 | 2010-03-05 14:00:26 -0800 | [diff] [blame] | 1354 | WebView.PREVENT_TOUCH_ID, |
| 1355 | ted.mAction, |
Adam Powell | 4fb35d4 | 2011-03-03 17:54:55 -0800 | [diff] [blame] | 1356 | ted.mNativeResult ? 1 : 0, |
| 1357 | ted).sendToTarget(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1358 | break; |
| 1359 | } |
| 1360 | |
Leon Scroggins | 8cdad88 | 2009-06-30 08:47:04 -0400 | [diff] [blame] | 1361 | case SET_ACTIVE: |
| 1362 | nativeSetFocusControllerActive(msg.arg1 == 1); |
Leon Scroggins | 63dda1c | 2009-04-15 13:25:00 -0400 | [diff] [blame] | 1363 | break; |
| 1364 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1365 | case ADD_JS_INTERFACE: |
Cary Clark | ded054c | 2009-06-15 10:26:08 -0400 | [diff] [blame] | 1366 | JSInterfaceData jsData = (JSInterfaceData) msg.obj; |
| 1367 | mBrowserFrame.addJavascriptInterface(jsData.mObject, |
| 1368 | jsData.mInterfaceName); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1369 | break; |
| 1370 | |
Steve Block | 689a342 | 2010-12-07 18:18:26 +0000 | [diff] [blame] | 1371 | case REMOVE_JS_INTERFACE: |
| 1372 | jsData = (JSInterfaceData) msg.obj; |
| 1373 | mBrowserFrame.removeJavascriptInterface( |
| 1374 | jsData.mInterfaceName); |
| 1375 | break; |
| 1376 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1377 | 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 Scroggins | 47fabbf | 2009-12-08 16:57:26 -0500 | [diff] [blame] | 1386 | case SET_MOVE_FOCUS: |
| 1387 | CursorData focusData = (CursorData) msg.obj; |
| 1388 | nativeMoveFocus(focusData.mFrame, focusData.mNode); |
| 1389 | break; |
| 1390 | |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1391 | case SET_MOVE_MOUSE: |
Leon Scroggins | 1c7f8c5 | 2009-06-05 13:49:26 -0400 | [diff] [blame] | 1392 | CursorData cursorData = (CursorData) msg.obj; |
| 1393 | nativeMoveMouse(cursorData.mFrame, |
Cary Clark | ed56eda | 2009-06-18 09:48:47 -0400 | [diff] [blame] | 1394 | cursorData.mX, cursorData.mY); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1395 | break; |
| 1396 | |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1397 | case SET_MOVE_MOUSE_IF_LATEST: |
Leon Scroggins | 1c7f8c5 | 2009-06-05 13:49:26 -0400 | [diff] [blame] | 1398 | CursorData cData = (CursorData) msg.obj; |
| 1399 | nativeMoveMouseIfLatest(cData.mMoveGeneration, |
Cary Clark | ed56eda | 2009-06-18 09:48:47 -0400 | [diff] [blame] | 1400 | cData.mFrame, |
| 1401 | cData.mX, cData.mY); |
Leon Scroggins | b611213 | 2011-02-24 12:35:50 -0500 | [diff] [blame] | 1402 | if (msg.arg1 == 1) { |
| 1403 | nativeStopPaintingCaret(); |
| 1404 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1405 | break; |
| 1406 | |
Leon Scroggins | 1c7f8c5 | 2009-06-05 13:49:26 -0400 | [diff] [blame] | 1407 | case REQUEST_CURSOR_HREF: { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1408 | Message hrefMsg = (Message) msg.obj; |
Ben Murdoch | 0a784a5 | 2009-11-17 18:13:02 +0000 | [diff] [blame] | 1409 | hrefMsg.getData().putString("url", |
| 1410 | nativeRetrieveHref(msg.arg1, msg.arg2)); |
| 1411 | hrefMsg.getData().putString("title", |
| 1412 | nativeRetrieveAnchorText(msg.arg1, msg.arg2)); |
Cary Clark | 861368a | 2010-12-15 11:24:37 -0500 | [diff] [blame] | 1413 | hrefMsg.getData().putString("src", |
| 1414 | nativeRetrieveImageSource(msg.arg1, msg.arg2)); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1415 | hrefMsg.sendToTarget(); |
| 1416 | break; |
| 1417 | } |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1418 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1419 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1435 | case DELETE_SELECTION: |
Leon Scroggins | 6679f2f | 2009-08-12 18:48:10 -0400 | [diff] [blame] | 1436 | TextSelectionData deleteSelectionData |
| 1437 | = (TextSelectionData) msg.obj; |
Leon Scroggins | 43488fc | 2009-07-06 14:32:49 -0400 | [diff] [blame] | 1438 | nativeDeleteSelection(deleteSelectionData.mStart, |
Leon Scroggins | 6679f2f | 2009-08-12 18:48:10 -0400 | [diff] [blame] | 1439 | deleteSelectionData.mEnd, msg.arg1); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1440 | break; |
| 1441 | |
| 1442 | case SET_SELECTION: |
Cary Clark | 2f1d60c | 2009-06-03 08:05:53 -0400 | [diff] [blame] | 1443 | nativeSetSelection(msg.arg1, msg.arg2); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1444 | break; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1445 | |
Svetoslav Ganov | da35551 | 2010-05-12 22:04:44 -0700 | [diff] [blame] | 1446 | case MODIFY_SELECTION: |
Svetoslav Ganov | c93fb65 | 2011-01-05 18:52:05 -0800 | [diff] [blame] | 1447 | String modifiedSelectionString = nativeModifySelection(msg.arg1, |
| 1448 | msg.arg2); |
Svetoslav Ganov | 585f13f8d | 2010-08-10 07:59:15 -0700 | [diff] [blame] | 1449 | mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED, |
Svetoslav Ganov | c93fb65 | 2011-01-05 18:52:05 -0800 | [diff] [blame] | 1450 | modifiedSelectionString).sendToTarget(); |
| 1451 | break; |
| 1452 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1453 | 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 Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1461 | nativeSendListBoxChoices(choicesArray, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1462 | choicesSize); |
| 1463 | break; |
| 1464 | |
| 1465 | case SINGLE_LISTBOX_CHOICE: |
| 1466 | nativeSendListBoxChoice(msg.arg1); |
| 1467 | break; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1468 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1469 | case SET_BACKGROUND_COLOR: |
| 1470 | nativeSetBackgroundColor(msg.arg1); |
| 1471 | break; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1472 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1473 | 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 Popescu | 5e7bb0a | 2010-02-01 22:32:16 +0000 | [diff] [blame] | 1485 | case DUMP_V8COUNTERS: |
| 1486 | nativeDumpV8Counters(); |
| 1487 | break; |
| 1488 | |
Feng Qian | b308137 | 2009-06-29 15:55:18 -0700 | [diff] [blame] | 1489 | case SET_JS_FLAGS: |
| 1490 | nativeSetJsFlags((String)msg.obj); |
Feng Qian | 706cee4 | 2009-08-03 16:01:42 -0700 | [diff] [blame] | 1491 | break; |
Steve Block | 4faee09 | 2009-07-28 18:20:50 +0100 | [diff] [blame] | 1492 | |
Elliott Slaughter | b48fdbe | 2010-06-30 11:39:52 -0700 | [diff] [blame] | 1493 | 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 Block | 4faee09 | 2009-07-28 18:20:50 +0100 | [diff] [blame] | 1502 | case GEOLOCATION_PERMISSIONS_PROVIDE: |
| 1503 | GeolocationPermissionsData data = |
| 1504 | (GeolocationPermissionsData) msg.obj; |
| 1505 | nativeGeolocationPermissionsProvide(data.mOrigin, |
| 1506 | data.mAllow, data.mRemember); |
Feng Qian | b308137 | 2009-06-29 15:55:18 -0700 | [diff] [blame] | 1507 | break; |
| 1508 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1509 | case SPLIT_PICTURE_SET: |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 1510 | nativeSplitContent(msg.arg1); |
| 1511 | mWebView.mPrivateHandler.obtainMessage( |
| 1512 | WebView.REPLACE_BASE_CONTENT, msg.arg1, 0); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1513 | mSplitPictureIsScheduled = false; |
| 1514 | break; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1515 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1516 | 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 Kloba | b3230cb | 2009-04-13 14:04:23 -0700 | [diff] [blame] | 1522 | |
| 1523 | case MESSAGE_RELAY: |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 1524 | ((Message) msg.obj).sendToTarget(); |
Grace Kloba | b3230cb | 2009-04-13 14:04:23 -0700 | [diff] [blame] | 1525 | break; |
Leon Clarke | 194e345 | 2009-09-28 11:42:12 +0100 | [diff] [blame] | 1526 | |
| 1527 | case POPULATE_VISITED_LINKS: |
| 1528 | nativeProvideVisitedHistory((String[])msg.obj); |
| 1529 | break; |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 1530 | |
| 1531 | case VALID_NODE_BOUNDS: { |
| 1532 | MotionUpData motionUpData = (MotionUpData) msg.obj; |
Cary Clark | bad0c54 | 2010-01-11 14:58:21 -0500 | [diff] [blame] | 1533 | if (!nativeValidNodeAndBounds( |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 1534 | motionUpData.mFrame, motionUpData.mNode, |
Cary Clark | bad0c54 | 2010-01-11 14:58:21 -0500 | [diff] [blame] | 1535 | motionUpData.mBounds)) { |
| 1536 | nativeUpdateFrameCache(); |
| 1537 | } |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 1538 | Message message = mWebView.mPrivateHandler |
| 1539 | .obtainMessage(WebView.DO_MOTION_UP, |
Cary Clark | bad0c54 | 2010-01-11 14:58:21 -0500 | [diff] [blame] | 1540 | motionUpData.mX, motionUpData.mY); |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 1541 | mWebView.mPrivateHandler.sendMessageAtFrontOfQueue( |
| 1542 | message); |
| 1543 | break; |
| 1544 | } |
Grace Kloba | 11438c3 | 2009-12-16 11:39:12 -0800 | [diff] [blame] | 1545 | |
| 1546 | case HIDE_FULLSCREEN: |
| 1547 | nativeFullScreenPluginHidden(msg.arg1); |
| 1548 | break; |
Andrei Popescu | a6d747d | 2010-02-11 13:19:21 +0000 | [diff] [blame] | 1549 | |
| 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 Kloba | 178db41 | 2010-05-18 22:22:23 -0700 | [diff] [blame] | 1559 | 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 Block | 68dede3 | 2010-08-04 10:28:46 +0100 | [diff] [blame] | 1573 | |
| 1574 | case USE_MOCK_DEVICE_ORIENTATION: |
| 1575 | useMockDeviceOrientation(); |
| 1576 | break; |
Ben Murdoch | 62275a4 | 2010-09-07 11:27:28 +0100 | [diff] [blame] | 1577 | |
| 1578 | case AUTOFILL_FORM: |
| 1579 | nativeAutoFillForm(msg.arg1); |
Ben Murdoch | 961d55f | 2010-12-02 13:58:24 +0000 | [diff] [blame] | 1580 | mWebView.mPrivateHandler.obtainMessage(WebView.AUTOFILL_COMPLETE, null) |
| 1581 | .sendToTarget(); |
Ben Murdoch | 62275a4 | 2010-09-07 11:27:28 +0100 | [diff] [blame] | 1582 | break; |
Narayan Kamath | 9497c5f | 2011-02-22 12:05:34 +0000 | [diff] [blame] | 1583 | |
| 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1592 | } |
| 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 Kloba | 9217c45 | 2009-09-01 00:59:27 -0700 | [diff] [blame] | 1633 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1645 | 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 Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 1693 | if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "CORE stopLoading"); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1694 | 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 Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 1735 | void sendMessageAtFrontOfQueue(int what, Object obj) { |
| 1736 | mEventHub.sendMessageAtFrontOfQueue(Message.obtain( |
| 1737 | null, what, obj)); |
| 1738 | } |
| 1739 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1740 | 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 Kloba | 9217c45 | 2009-09-01 00:59:27 -0700 | [diff] [blame] | 1761 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1766 | mEventHub.removeMessages(); |
| 1767 | mEventHub.sendMessageAtFrontOfQueue( |
| 1768 | Message.obtain(null, EventHub.DESTROY)); |
Grace Kloba | 9217c45 | 2009-09-01 00:59:27 -0700 | [diff] [blame] | 1769 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1777 | mEventHub.blockMessages(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1778 | } |
| 1779 | } |
| 1780 | |
| 1781 | //------------------------------------------------------------------------- |
| 1782 | // WebViewCore private methods |
| 1783 | //------------------------------------------------------------------------- |
| 1784 | |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 1785 | private void clearCache(boolean includeDiskFiles) { |
| 1786 | mBrowserFrame.clearCache(); |
Kristian Monsen | cedb3a7 | 2011-01-20 12:42:16 +0000 | [diff] [blame] | 1787 | if (includeDiskFiles) { |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 1788 | CacheManager.removeAllCacheFiles(); |
| 1789 | } |
| 1790 | } |
| 1791 | |
Grace Kloba | d0d9bc2 | 2010-01-26 18:08:28 -0800 | [diff] [blame] | 1792 | private void loadUrl(String url, Map<String, String> extraHeaders) { |
Derek Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 1793 | if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, " CORE loadUrl " + url); |
Grace Kloba | d0d9bc2 | 2010-01-26 18:08:28 -0800 | [diff] [blame] | 1794 | mBrowserFrame.loadUrl(url, extraHeaders); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1795 | } |
| 1796 | |
Elliott Slaughter | b48fdbe | 2010-06-30 11:39:52 -0700 | [diff] [blame] | 1797 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1804 | private void key(KeyEvent evt, boolean isDown) { |
Derek Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 1805 | if (DebugFlags.WEB_VIEW_CORE) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1806 | Log.v(LOGTAG, "CORE key at " + System.currentTimeMillis() + ", " |
| 1807 | + evt); |
| 1808 | } |
Leon Scroggins | e322567 | 2009-06-03 15:53:13 -0400 | [diff] [blame] | 1809 | int keyCode = evt.getKeyCode(); |
Derek Sollenberger | ff0f973 | 2010-08-06 11:50:49 -0400 | [diff] [blame] | 1810 | 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 Scroggins | e322567 | 2009-06-03 15:53:13 -0400 | [diff] [blame] | 1820 | isDown) && keyCode != KeyEvent.KEYCODE_ENTER) { |
Cary Clark | 215b72c | 2009-06-26 14:38:43 -0400 | [diff] [blame] | 1821 | if (keyCode >= KeyEvent.KEYCODE_DPAD_UP |
| 1822 | && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { |
| 1823 | if (DebugFlags.WEB_VIEW_CORE) { |
Leon Scroggins | 9ab32b6 | 2010-05-03 14:19:50 +0100 | [diff] [blame] | 1824 | Log.v(LOGTAG, "key: arrow unused by page: " + keyCode); |
Cary Clark | 215b72c | 2009-06-26 14:38:43 -0400 | [diff] [blame] | 1825 | } |
| 1826 | if (mWebView != null && evt.isDown()) { |
| 1827 | Message.obtain(mWebView.mPrivateHandler, |
Leon Scroggins | 9ab32b6 | 2010-05-03 14:19:50 +0100 | [diff] [blame] | 1828 | WebView.UNHANDLED_NAV_KEY, keyCode, |
| 1829 | 0).sendToTarget(); |
Cary Clark | 215b72c | 2009-06-26 14:38:43 -0400 | [diff] [blame] | 1830 | } |
| 1831 | return; |
| 1832 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1833 | // bubble up the event handling |
Leon Scroggins | e322567 | 2009-06-03 15:53:13 -0400 | [diff] [blame] | 1834 | // but do not bubble up the ENTER key, which would open the search |
| 1835 | // bar without any text. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1836 | 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 Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1843 | private float mCurrentViewScale = 1.0f; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1844 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1845 | // notify webkit that our virtual view size changed size (after inv-zoom) |
Shimeng (Simon) Wang | 48fc909 | 2011-02-03 14:29:54 -0800 | [diff] [blame] | 1846 | 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 Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1851 | if (DebugFlags.WEB_VIEW_CORE) { |
| 1852 | Log.v(LOGTAG, "viewSizeChanged w=" + w + "; h=" + h |
| 1853 | + "; textwrapWidth=" + textwrapWidth + "; scale=" + scale); |
| 1854 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1855 | if (w == 0) { |
| 1856 | Log.w(LOGTAG, "skip viewSizeChanged as w is 0"); |
| 1857 | return; |
| 1858 | } |
Shimeng (Simon) Wang | f7107d7 | 2011-02-18 15:27:28 -0800 | [diff] [blame] | 1859 | int width = calculateWindowWidth(w, textwrapWidth); |
Shimeng (Simon) Wang | a0cc864 | 2011-02-03 10:24:03 -0800 | [diff] [blame] | 1860 | int height = h; |
| 1861 | if (width != w) { |
Shimeng (Simon) Wang | 48fc909 | 2011-02-03 14:29:54 -0800 | [diff] [blame] | 1862 | float heightWidthRatio = data.mHeightWidthRatio; |
Shimeng (Simon) Wang | a0cc864 | 2011-02-03 10:24:03 -0800 | [diff] [blame] | 1863 | float ratio = (heightWidthRatio > 0) ? heightWidthRatio : (float) h / w; |
| 1864 | height = Math.round(ratio * width); |
| 1865 | } |
Shimeng (Simon) Wang | 48fc909 | 2011-02-03 14:29:54 -0800 | [diff] [blame] | 1866 | nativeSetSize(width, height, textwrapWidth, scale, w, |
| 1867 | data.mActualViewHeight > 0 ? data.mActualViewHeight : h, |
| 1868 | data.mAnchorX, data.mAnchorY, data.mIgnoreHeight); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1869 | // Remember the current width and height |
| 1870 | boolean needInvalidate = (mCurrentViewWidth == 0); |
| 1871 | mCurrentViewWidth = w; |
| 1872 | mCurrentViewHeight = h; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1873 | mCurrentViewScale = scale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1874 | if (needInvalidate) { |
| 1875 | // ensure {@link #webkitDraw} is called as we were blocking in |
| 1876 | // {@link #contentDraw} when mCurrentViewWidth is 0 |
Derek Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 1877 | if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "viewSizeChanged"); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1878 | contentDraw(); |
| 1879 | } |
| 1880 | mEventHub.sendMessage(Message.obtain(null, |
| 1881 | EventHub.UPDATE_CACHE_AND_TEXT_ENTRY)); |
| 1882 | } |
| 1883 | |
Shimeng (Simon) Wang | f7107d7 | 2011-02-18 15:27:28 -0800 | [diff] [blame] | 1884 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1925 | private void sendUpdateTextEntry() { |
| 1926 | if (mWebView != null) { |
| 1927 | Message.obtain(mWebView.mPrivateHandler, |
| 1928 | WebView.UPDATE_TEXT_ENTRY_MSG_ID).sendToTarget(); |
| 1929 | } |
| 1930 | } |
| 1931 | |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 1932 | // 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 Roard | 6c24b4d | 2009-09-22 18:44:52 +0100 | [diff] [blame] | 1936 | Collection<WebStorage.Origin> origins = webStorage.getOriginsSync(); |
| 1937 | |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 1938 | if (origins == null) { |
| 1939 | return 0; |
| 1940 | } |
| 1941 | long usedQuota = 0; |
Nicolas Roard | 6c24b4d | 2009-09-22 18:44:52 +0100 | [diff] [blame] | 1942 | for (WebStorage.Origin website : origins) { |
| 1943 | usedQuota += website.getQuota(); |
Andrei Popescu | 59e2ad9 | 2009-07-28 13:38:06 +0100 | [diff] [blame] | 1944 | } |
| 1945 | return usedQuota; |
| 1946 | } |
| 1947 | |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 1948 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1956 | // Used to avoid posting more than one draw message. |
| 1957 | private boolean mDrawIsScheduled; |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 1958 | private boolean mDrawLayersIsScheduled; |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1959 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1960 | // Used to avoid posting more than one split picture message. |
| 1961 | private boolean mSplitPictureIsScheduled; |
| 1962 | |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 1963 | // Used to suspend drawing. |
| 1964 | private boolean mDrawIsPaused; |
| 1965 | |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 1966 | // 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 Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1969 | |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 1970 | static class ViewState { |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1971 | float mMinScale; |
| 1972 | float mMaxScale; |
| 1973 | float mViewScale; |
| 1974 | float mTextWrapScale; |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 1975 | float mDefaultScale; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1976 | int mScrollX; |
| 1977 | int mScrollY; |
Leon Scroggins | b235926 | 2009-08-19 16:19:26 -0400 | [diff] [blame] | 1978 | boolean mMobileSite; |
Shimeng (Simon) Wang | 96fcb87 | 2010-11-24 16:01:12 -0800 | [diff] [blame] | 1979 | boolean mIsRestored; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1980 | } |
| 1981 | |
| 1982 | static class DrawData { |
| 1983 | DrawData() { |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 1984 | mBaseLayer = 0; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1985 | mInvalRegion = new Region(); |
Derek Sollenberger | 7e6bf6f | 2010-10-28 09:33:47 -0400 | [diff] [blame] | 1986 | mContentSize = new Point(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1987 | } |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 1988 | int mBaseLayer; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 1989 | Region mInvalRegion; |
Derek Sollenberger | 7e6bf6f | 2010-10-28 09:33:47 -0400 | [diff] [blame] | 1990 | // view size that was used by webkit during the most recent layout |
| 1991 | Point mViewSize; |
| 1992 | Point mContentSize; |
Grace Kloba | 188bf8d | 2010-04-07 11:30:19 -0700 | [diff] [blame] | 1993 | int mMinPrefWidth; |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 1994 | // only non-null if it is for the first picture set after the first layout |
| 1995 | ViewState mViewState; |
Cary Clark | 5da9aeb | 2009-10-06 17:40:53 -0400 | [diff] [blame] | 1996 | boolean mFocusSizeChanged; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1997 | } |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 1998 | |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 1999 | // 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 Scott | 2f49227 | 2010-12-03 09:52:35 -0500 | [diff] [blame] | 2009 | draw.mBaseLayer = nativeUpdateLayers(draw.mInvalRegion); |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 2010 | webkitDraw(draw); |
| 2011 | } |
| 2012 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2013 | private void webkitDraw() { |
| 2014 | mDrawIsScheduled = false; |
| 2015 | DrawData draw = new DrawData(); |
Derek Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 2016 | if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start"); |
Derek Sollenberger | 7e6bf6f | 2010-10-28 09:33:47 -0400 | [diff] [blame] | 2017 | draw.mBaseLayer = nativeRecordContent(draw.mInvalRegion, draw.mContentSize); |
Grace Kloba | 8abd50b | 2010-07-08 15:02:14 -0700 | [diff] [blame] | 2018 | if (draw.mBaseLayer == 0) { |
Derek Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 2019 | if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort"); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2020 | return; |
| 2021 | } |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 2022 | webkitDraw(draw); |
| 2023 | } |
| 2024 | |
| 2025 | private void webkitDraw(DrawData draw) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2026 | if (mWebView != null) { |
Cary Clark | 5da9aeb | 2009-10-06 17:40:53 -0400 | [diff] [blame] | 2027 | draw.mFocusSizeChanged = nativeFocusBoundsChanged(); |
Derek Sollenberger | 7e6bf6f | 2010-10-28 09:33:47 -0400 | [diff] [blame] | 2028 | draw.mViewSize = new Point(mCurrentViewWidth, mCurrentViewHeight); |
Grace Kloba | 188bf8d | 2010-04-07 11:30:19 -0700 | [diff] [blame] | 2029 | 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 Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2036 | if (mInitialViewState != null) { |
| 2037 | draw.mViewState = mInitialViewState; |
| 2038 | mInitialViewState = null; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2039 | } |
Derek Sollenberger | 2e5c150 | 2009-06-03 10:44:42 -0400 | [diff] [blame] | 2040 | if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID"); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2041 | Message.obtain(mWebView.mPrivateHandler, |
The Android Open Source Project | ba87e3e | 2009-03-13 13:04:22 -0700 | [diff] [blame] | 2042 | WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2043 | } |
| 2044 | } |
| 2045 | |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2046 | static void reducePriority() { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2047 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2052 | } |
| 2053 | |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2054 | static void resumePriority() { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2055 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2060 | } |
| 2061 | |
Kristian Monsen | d4819a7 | 2010-12-16 17:42:57 +0000 | [diff] [blame] | 2062 | static void sendStaticMessage(int messageType, Object argument) { |
| 2063 | if (sWebCoreHandler == null) |
| 2064 | return; |
| 2065 | |
| 2066 | sWebCoreHandler.sendMessage(sWebCoreHandler.obtainMessage(messageType, argument)); |
| 2067 | } |
| 2068 | |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2069 | 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 Kloba | f9b731d | 2010-06-21 19:23:57 -0700 | [diff] [blame] | 2074 | if (!core.getSettings().enableSmoothTransition()) return; |
| 2075 | |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2076 | 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 Kloba | f9b731d | 2010-06-21 19:23:57 -0700 | [diff] [blame] | 2088 | // if mDrawIsPaused is true, ignore the setting, continue to resume |
| 2089 | if (!core.mDrawIsPaused |
| 2090 | && !core.getSettings().enableSmoothTransition()) return; |
| 2091 | |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2092 | synchronized (core) { |
| 2093 | core.mDrawIsPaused = false; |
Cary Clark | 75796bb | 2010-08-24 14:59:58 -0400 | [diff] [blame] | 2094 | // always redraw on resume to reenable gif animations |
| 2095 | core.mDrawIsScheduled = false; |
| 2096 | core.nativeContentInvalidateAll(); |
| 2097 | core.contentDraw(); |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2098 | } |
| 2099 | } |
| 2100 | } |
| 2101 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2102 | ////////////////////////////////////////////////////////////////////////// |
| 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 Kloba | 3f40bd4 | 2009-12-07 14:47:28 -0800 | [diff] [blame] | 2128 | if (mDrawIsScheduled) return; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2129 | mDrawIsScheduled = true; |
Grace Kloba | a7bc87c | 2010-01-29 14:56:25 -0800 | [diff] [blame] | 2130 | if (mDrawIsPaused) return; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2131 | mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW)); |
| 2132 | } |
| 2133 | } |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 2134 | |
Nicolas Roard | fb7bc34 | 2010-11-01 15:08:03 -0700 | [diff] [blame] | 2135 | // 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2144 | // called by JNI |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 2145 | private void contentScrollTo(int x, int y, boolean animate, |
| 2146 | boolean onlyIfImeIsShowing) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2147 | 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 Kloba | b3230cb | 2009-04-13 14:04:23 -0700 | [diff] [blame] | 2158 | Message msg = Message.obtain(mWebView.mPrivateHandler, |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 2159 | WebView.SCROLL_TO_MSG_ID, animate ? 1 : 0, |
| 2160 | onlyIfImeIsShowing ? 1 : 0, new Point(x, y)); |
Grace Kloba | b3230cb | 2009-04-13 14:04:23 -0700 | [diff] [blame] | 2161 | if (mDrawIsScheduled) { |
| 2162 | mEventHub.sendMessage(Message.obtain(null, |
| 2163 | EventHub.MESSAGE_RELAY, msg)); |
| 2164 | } else { |
| 2165 | msg.sendToTarget(); |
| 2166 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2167 | } |
| 2168 | } |
| 2169 | |
| 2170 | // called by JNI |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2171 | private void sendNotifyProgressFinished() { |
| 2172 | sendUpdateTextEntry(); |
Steve Block | 808751f | 2011-01-04 14:26:27 +0000 | [diff] [blame] | 2173 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2181 | contentDraw(); |
| 2182 | } |
| 2183 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2184 | /* 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 Roard | 3886333 | 2010-01-04 19:30:55 +0000 | [diff] [blame] | 2196 | 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 Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2205 | /* package */ WebView getWebView() { |
| 2206 | return mWebView; |
| 2207 | } |
| 2208 | |
| 2209 | private native void setViewportSettingsFromNative(); |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 2210 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2211 | // called by JNI |
Grace Kloba | 45dee41 | 2009-04-06 10:47:26 -0700 | [diff] [blame] | 2212 | private void didFirstLayout(boolean standardLoad) { |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2213 | if (DebugFlags.WEB_VIEW_CORE) { |
| 2214 | Log.v(LOGTAG, "didFirstLayout standardLoad =" + standardLoad); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2215 | } |
| 2216 | |
| 2217 | mBrowserFrame.didFirstLayout(); |
| 2218 | |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2219 | if (mWebView == null) return; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2220 | |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2221 | boolean updateViewState = standardLoad || mRestoredScale > 0; |
| 2222 | setupViewport(updateViewState); |
Grace Kloba | 9a67c82 | 2009-12-20 11:33:58 -0800 | [diff] [blame] | 2223 | // if updateRestoreState is true, ViewManager.postReadyToDrawAll() will |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2224 | // be called after the WebView updates its state. If updateRestoreState |
Grace Kloba | 9a67c82 | 2009-12-20 11:33:58 -0800 | [diff] [blame] | 2225 | // is false, start to draw now as it is ready. |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2226 | if (!updateViewState) { |
Grace Kloba | 9a67c82 | 2009-12-20 11:33:58 -0800 | [diff] [blame] | 2227 | mWebView.mViewManager.postReadyToDrawAll(); |
| 2228 | } |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2229 | |
Grace Kloba | 178db41 | 2010-05-18 22:22:23 -0700 | [diff] [blame] | 2230 | // 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 Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2236 | // reset the scroll position, the restored offset and scales |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 2237 | mRestoredX = mRestoredY = 0; |
Shimeng (Simon) Wang | 5d8e7a4 | 2011-01-07 15:51:06 -0800 | [diff] [blame] | 2238 | mRestoredScale = mRestoredTextWrapScale = 0; |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2239 | } |
| 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 Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2252 | private void setupViewport(boolean updateViewState) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2253 | // set the viewport settings from WebKit |
| 2254 | setViewportSettingsFromNative(); |
| 2255 | |
John Reck | 7818aaa | 2011-04-26 16:57:46 -0700 | [diff] [blame] | 2256 | if (mSettings.forceUserScalable()) { |
| 2257 | mViewportUserScalable = true; |
| 2258 | if (mViewportInitialScale > 0) { |
| 2259 | if (mViewportMinimumScale > 0) { |
| 2260 | mViewportMinimumScale = Math.min(mViewportMinimumScale, |
| 2261 | mViewportInitialScale / 2); |
| 2262 | } |
| 2263 | if (mViewportMaximumScale > 0) { |
| 2264 | mViewportMaximumScale = Math.max(mViewportMaximumScale, |
| 2265 | mViewportInitialScale * 2); |
| 2266 | } |
| 2267 | } else { |
| 2268 | if (mViewportMinimumScale > 0) { |
| 2269 | mViewportMinimumScale = Math.min(mViewportMinimumScale, 50); |
| 2270 | } |
| 2271 | if (mViewportMaximumScale > 0) { |
| 2272 | mViewportMaximumScale = Math.max(mViewportMaximumScale, 200); |
| 2273 | } |
| 2274 | } |
| 2275 | } |
| 2276 | |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 2277 | // adjust the default scale to match the densityDpi |
| 2278 | float adjust = 1.0f; |
| 2279 | if (mViewportDensityDpi == -1) { |
Derek Sollenberger | 03e4891 | 2010-05-18 17:03:42 -0400 | [diff] [blame] | 2280 | // convert default zoom scale to a integer (percentage) to avoid any |
| 2281 | // issues with floating point comparisons |
| 2282 | if (mWebView != null && (int)(mWebView.getDefaultZoomScale() * 100) != 100) { |
| 2283 | adjust = mWebView.getDefaultZoomScale(); |
Grace Kloba | 0d8b77c | 2009-06-25 11:20:51 -0700 | [diff] [blame] | 2284 | } |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 2285 | } else if (mViewportDensityDpi > 0) { |
| 2286 | adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi |
| 2287 | / mViewportDensityDpi; |
| 2288 | } |
| 2289 | int defaultScale = (int) (adjust * 100); |
| 2290 | |
| 2291 | if (mViewportInitialScale > 0) { |
| 2292 | mViewportInitialScale *= adjust; |
| 2293 | } |
| 2294 | if (mViewportMinimumScale > 0) { |
| 2295 | mViewportMinimumScale *= adjust; |
| 2296 | } |
| 2297 | if (mViewportMaximumScale > 0) { |
| 2298 | mViewportMaximumScale *= adjust; |
Grace Kloba | 0d8b77c | 2009-06-25 11:20:51 -0700 | [diff] [blame] | 2299 | } |
| 2300 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2301 | // infer the values if they are not defined. |
| 2302 | if (mViewportWidth == 0) { |
| 2303 | if (mViewportInitialScale == 0) { |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 2304 | mViewportInitialScale = defaultScale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2305 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2306 | } |
| 2307 | if (mViewportUserScalable == false) { |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 2308 | mViewportInitialScale = defaultScale; |
| 2309 | mViewportMinimumScale = defaultScale; |
| 2310 | mViewportMaximumScale = defaultScale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2311 | } |
Grace Kloba | f53c186 | 2009-09-21 16:26:11 -0700 | [diff] [blame] | 2312 | if (mViewportMinimumScale > mViewportInitialScale |
| 2313 | && mViewportInitialScale != 0) { |
| 2314 | mViewportMinimumScale = mViewportInitialScale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2315 | } |
Grace Kloba | f53c186 | 2009-09-21 16:26:11 -0700 | [diff] [blame] | 2316 | if (mViewportMaximumScale > 0 |
| 2317 | && mViewportMaximumScale < mViewportInitialScale) { |
| 2318 | mViewportMaximumScale = mViewportInitialScale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2319 | } |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 2320 | if (mViewportWidth < 0 && mViewportInitialScale == defaultScale) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2321 | mViewportWidth = 0; |
| 2322 | } |
| 2323 | |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2324 | // if mViewportWidth is 0, it means device-width, always update. |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2325 | if (mViewportWidth != 0 && !updateViewState) { |
| 2326 | ViewState viewState = new ViewState(); |
| 2327 | viewState.mMinScale = mViewportMinimumScale / 100.0f; |
| 2328 | viewState.mMaxScale = mViewportMaximumScale / 100.0f; |
| 2329 | viewState.mDefaultScale = adjust; |
Grace Kloba | 769ed21 | 2010-01-27 10:52:47 -0800 | [diff] [blame] | 2330 | // as mViewportWidth is not 0, it is not mobile site. |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2331 | viewState.mMobileSite = false; |
Grace Kloba | 188bf8d | 2010-04-07 11:30:19 -0700 | [diff] [blame] | 2332 | // for non-mobile site, we don't need minPrefWidth, set it as 0 |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2333 | viewState.mScrollX = 0; |
Grace Kloba | 769ed21 | 2010-01-27 10:52:47 -0800 | [diff] [blame] | 2334 | Message.obtain(mWebView.mPrivateHandler, |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2335 | WebView.UPDATE_ZOOM_RANGE, viewState).sendToTarget(); |
Grace Kloba | 769ed21 | 2010-01-27 10:52:47 -0800 | [diff] [blame] | 2336 | return; |
| 2337 | } |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2338 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2339 | // now notify webview |
Grace Kloba | 6ed525e | 2009-09-17 15:31:12 -0700 | [diff] [blame] | 2340 | // webViewWidth refers to the width in the view system |
| 2341 | int webViewWidth; |
| 2342 | // viewportWidth refers to the width in the document system |
| 2343 | int viewportWidth = mCurrentViewWidth; |
| 2344 | if (viewportWidth == 0) { |
| 2345 | // this may happen when WebView just starts. This is not perfect as |
| 2346 | // we call WebView method from WebCore thread. But not perfect |
| 2347 | // reference is better than no reference. |
| 2348 | webViewWidth = mWebView.getViewWidth(); |
Grace Kloba | 408cf85 | 2009-09-20 16:34:44 -0700 | [diff] [blame] | 2349 | viewportWidth = (int) (webViewWidth / adjust); |
Grace Kloba | 6ed525e | 2009-09-17 15:31:12 -0700 | [diff] [blame] | 2350 | if (viewportWidth == 0) { |
| 2351 | Log.w(LOGTAG, "Can't get the viewWidth after the first layout"); |
| 2352 | } |
| 2353 | } else { |
| 2354 | webViewWidth = Math.round(viewportWidth * mCurrentViewScale); |
| 2355 | } |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2356 | mInitialViewState = new ViewState(); |
| 2357 | mInitialViewState.mMinScale = mViewportMinimumScale / 100.0f; |
| 2358 | mInitialViewState.mMaxScale = mViewportMaximumScale / 100.0f; |
| 2359 | mInitialViewState.mDefaultScale = adjust; |
| 2360 | mInitialViewState.mScrollX = mRestoredX; |
| 2361 | mInitialViewState.mScrollY = mRestoredY; |
| 2362 | mInitialViewState.mMobileSite = (0 == mViewportWidth); |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2363 | if (mRestoredScale > 0) { |
Shimeng (Simon) Wang | 96fcb87 | 2010-11-24 16:01:12 -0800 | [diff] [blame] | 2364 | mInitialViewState.mIsRestored = true; |
Shimeng (Simon) Wang | 5d8e7a4 | 2011-01-07 15:51:06 -0800 | [diff] [blame] | 2365 | mInitialViewState.mViewScale = mRestoredScale; |
Grace Kloba | e80cbcc | 2010-05-28 18:07:50 -0700 | [diff] [blame] | 2366 | if (mRestoredTextWrapScale > 0) { |
Shimeng (Simon) Wang | 5d8e7a4 | 2011-01-07 15:51:06 -0800 | [diff] [blame] | 2367 | mInitialViewState.mTextWrapScale = mRestoredTextWrapScale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2368 | } else { |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2369 | mInitialViewState.mTextWrapScale = mInitialViewState.mViewScale; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2370 | } |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2371 | } else { |
| 2372 | if (mViewportInitialScale > 0) { |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2373 | mInitialViewState.mViewScale = mInitialViewState.mTextWrapScale = |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2374 | mViewportInitialScale / 100.0f; |
Shimeng (Simon) Wang | 9c64bae | 2010-10-22 10:52:57 -0700 | [diff] [blame] | 2375 | } else if (mViewportWidth > 0 && mViewportWidth < webViewWidth && |
| 2376 | !mWebView.getSettings().getUseFixedViewport()) { |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2377 | mInitialViewState.mViewScale = mInitialViewState.mTextWrapScale = |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2378 | (float) webViewWidth / mViewportWidth; |
| 2379 | } else { |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2380 | mInitialViewState.mTextWrapScale = adjust; |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2381 | // 0 will trigger WebView to turn on zoom overview mode |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2382 | mInitialViewState.mViewScale = 0; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2383 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2384 | } |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2385 | |
| 2386 | if (mWebView.mHeightCanMeasure) { |
| 2387 | // Trick to ensure that the Picture has the exact height for the |
| 2388 | // content by forcing to layout with 0 height after the page is |
| 2389 | // ready, which is indicated by didFirstLayout. This is essential to |
| 2390 | // get rid of the white space in the GMail which uses WebView for |
| 2391 | // message view. |
| 2392 | mWebView.mLastHeightSent = 0; |
| 2393 | // Send a negative scale to indicate that WebCore should reuse |
| 2394 | // the current scale |
| 2395 | WebView.ViewSizeData data = new WebView.ViewSizeData(); |
| 2396 | data.mWidth = mWebView.mLastWidthSent; |
| 2397 | data.mHeight = 0; |
| 2398 | // if mHeightCanMeasure is true, getUseWideViewPort() can't be |
| 2399 | // true. It is safe to use mWidth for mTextWrapWidth. |
| 2400 | data.mTextWrapWidth = data.mWidth; |
| 2401 | data.mScale = -1.0f; |
Cary Clark | 6d45acc | 2009-08-27 15:42:57 -0400 | [diff] [blame] | 2402 | data.mIgnoreHeight = false; |
Grace Kloba | 3a0def2 | 2010-01-23 21:11:54 -0800 | [diff] [blame] | 2403 | data.mAnchorX = data.mAnchorY = 0; |
Grace Kloba | 0d03b91 | 2009-09-27 17:46:31 -0700 | [diff] [blame] | 2404 | // send VIEW_SIZE_CHANGED to the front of the queue so that we can |
| 2405 | // avoid pushing the wrong picture to the WebView side. If there is |
| 2406 | // a VIEW_SIZE_CHANGED in the queue, probably from WebView side, |
| 2407 | // ignore it as we have a new size. If we leave VIEW_SIZE_CHANGED |
| 2408 | // in the queue, as mLastHeightSent has been updated here, we may |
| 2409 | // miss the requestLayout in WebView side after the new picture. |
| 2410 | mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED); |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2411 | mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, |
| 2412 | EventHub.VIEW_SIZE_CHANGED, data)); |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2413 | } else if (mSettings.getUseWideViewPort()) { |
Grace Kloba | 6ed525e | 2009-09-17 15:31:12 -0700 | [diff] [blame] | 2414 | if (viewportWidth == 0) { |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2415 | // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView |
| 2416 | // to WebViewCore |
| 2417 | mWebView.mLastWidthSent = 0; |
| 2418 | } else { |
| 2419 | WebView.ViewSizeData data = new WebView.ViewSizeData(); |
| 2420 | // mViewScale as 0 means it is in zoom overview mode. So we don't |
| 2421 | // know the exact scale. If mRestoredScale is non-zero, use it; |
| 2422 | // otherwise just use mTextWrapScale as the initial scale. |
Shimeng (Simon) Wang | 7606464 | 2011-02-22 15:31:02 -0800 | [diff] [blame] | 2423 | float tentativeScale = mInitialViewState.mViewScale; |
| 2424 | if (tentativeScale == 0) { |
| 2425 | // The following tries to figure out more correct view scale |
| 2426 | // and text wrap scale to be sent to webkit, by using some |
| 2427 | // knowledge from web settings and zoom manager. |
| 2428 | |
| 2429 | // Calculated window width will be used to guess the scale |
| 2430 | // in zoom overview mode. |
| 2431 | tentativeScale = mInitialViewState.mTextWrapScale; |
| 2432 | int tentativeViewWidth = Math.round(webViewWidth / tentativeScale); |
| 2433 | int windowWidth = calculateWindowWidth(tentativeViewWidth, |
| 2434 | tentativeViewWidth); |
| 2435 | // In viewport setup time, since no content width is known, we assume |
| 2436 | // the windowWidth will be the content width, to get a more likely |
| 2437 | // zoom overview scale. |
| 2438 | data.mScale = (float) webViewWidth / windowWidth; |
| 2439 | if (!mSettings.getLoadWithOverviewMode()) { |
| 2440 | // If user choose non-overview mode. |
| 2441 | data.mScale = Math.max(data.mScale, tentativeScale); |
| 2442 | } |
| 2443 | if (mSettings.isNarrowColumnLayout() && |
| 2444 | mSettings.getUseFixedViewport()) { |
| 2445 | // In case of automatic text reflow in fixed view port mode. |
| 2446 | mInitialViewState.mTextWrapScale = |
| 2447 | ZoomManager.computeReadingLevelScale(data.mScale); |
| 2448 | } |
| 2449 | } else { |
| 2450 | // Scale is given such as when page is restored, use it. |
| 2451 | data.mScale = tentativeScale; |
| 2452 | } |
Cary Clark | 35155c1 | 2009-10-29 15:34:00 -0400 | [diff] [blame] | 2453 | if (DebugFlags.WEB_VIEW_CORE) { |
| 2454 | Log.v(LOGTAG, "setupViewport" |
| 2455 | + " mRestoredScale=" + mRestoredScale |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2456 | + " mViewScale=" + mInitialViewState.mViewScale |
| 2457 | + " mTextWrapScale=" + mInitialViewState.mTextWrapScale |
Shimeng (Simon) Wang | 7606464 | 2011-02-22 15:31:02 -0800 | [diff] [blame] | 2458 | + " data.mScale= " + data.mScale |
Cary Clark | 35155c1 | 2009-10-29 15:34:00 -0400 | [diff] [blame] | 2459 | ); |
| 2460 | } |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2461 | data.mWidth = Math.round(webViewWidth / data.mScale); |
Ben Murdoch | d1bee05 | 2010-03-05 11:30:07 +0000 | [diff] [blame] | 2462 | // We may get a call here when mCurrentViewHeight == 0 if webcore completes the |
| 2463 | // first layout before we sync our webview dimensions to it. In that case, we |
| 2464 | // request the real height of the webview. This is not a perfect solution as we |
| 2465 | // are calling a WebView method from the WebCore thread. But this is preferable |
| 2466 | // to syncing an incorrect height. |
| 2467 | data.mHeight = mCurrentViewHeight == 0 ? |
| 2468 | Math.round(mWebView.getViewHeight() / data.mScale) |
Shimeng (Simon) Wang | f7107d7 | 2011-02-18 15:27:28 -0800 | [diff] [blame] | 2469 | : Math.round((float) mCurrentViewHeight * data.mWidth / viewportWidth); |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2470 | data.mTextWrapWidth = Math.round(webViewWidth |
Derek Sollenberger | b983c89 | 2010-06-28 08:38:28 -0400 | [diff] [blame] | 2471 | / mInitialViewState.mTextWrapScale); |
Cary Clark | 6d45acc | 2009-08-27 15:42:57 -0400 | [diff] [blame] | 2472 | data.mIgnoreHeight = false; |
Grace Kloba | 3a0def2 | 2010-01-23 21:11:54 -0800 | [diff] [blame] | 2473 | data.mAnchorX = data.mAnchorY = 0; |
Grace Kloba | 0d03b91 | 2009-09-27 17:46:31 -0700 | [diff] [blame] | 2474 | // send VIEW_SIZE_CHANGED to the front of the queue so that we |
| 2475 | // can avoid pushing the wrong picture to the WebView side. |
| 2476 | mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED); |
Shimeng (Simon) Wang | 7606464 | 2011-02-22 15:31:02 -0800 | [diff] [blame] | 2477 | // Let webkit know the scale and inner width/height immediately |
| 2478 | // in viewport setup time to avoid wrong information. |
| 2479 | viewSizeChanged(data); |
Grace Kloba | 7a02d6e | 2009-08-18 10:10:51 -0700 | [diff] [blame] | 2480 | } |
Grace Kloba | ef347ef | 2009-07-30 11:20:32 -0700 | [diff] [blame] | 2481 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2482 | } |
| 2483 | |
| 2484 | // called by JNI |
Shimeng (Simon) Wang | 5d8e7a4 | 2011-01-07 15:51:06 -0800 | [diff] [blame] | 2485 | private void restoreScale(float scale, float textWrapScale) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2486 | if (mBrowserFrame.firstLayoutDone() == false) { |
| 2487 | mRestoredScale = scale; |
Grace Kloba | e80cbcc | 2010-05-28 18:07:50 -0700 | [diff] [blame] | 2488 | if (mSettings.getUseWideViewPort()) { |
| 2489 | mRestoredTextWrapScale = textWrapScale; |
| 2490 | } |
Grace Kloba | 8b97e4b | 2009-07-28 13:11:38 -0700 | [diff] [blame] | 2491 | } |
| 2492 | } |
| 2493 | |
| 2494 | // called by JNI |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2495 | private void needTouchEvents(boolean need) { |
| 2496 | if (mWebView != null) { |
| 2497 | Message.obtain(mWebView.mPrivateHandler, |
| 2498 | WebView.WEBCORE_NEED_TOUCH_EVENTS, need ? 1 : 0, 0) |
| 2499 | .sendToTarget(); |
| 2500 | } |
| 2501 | } |
| 2502 | |
| 2503 | // called by JNI |
| 2504 | private void updateTextfield(int ptr, boolean changeToPassword, |
| 2505 | String text, int textGeneration) { |
| 2506 | if (mWebView != null) { |
| 2507 | Message msg = Message.obtain(mWebView.mPrivateHandler, |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 2508 | WebView.UPDATE_TEXTFIELD_TEXT_MSG_ID, ptr, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2509 | textGeneration, text); |
| 2510 | msg.getData().putBoolean("password", changeToPassword); |
| 2511 | msg.sendToTarget(); |
| 2512 | } |
| 2513 | } |
| 2514 | |
Cary Clark | 243ea06 | 2009-06-25 10:49:32 -0400 | [diff] [blame] | 2515 | // called by JNI |
Leon Scroggins | 6679f2f | 2009-08-12 18:48:10 -0400 | [diff] [blame] | 2516 | private void updateTextSelection(int pointer, int start, int end, |
| 2517 | int textGeneration) { |
| 2518 | if (mWebView != null) { |
| 2519 | Message.obtain(mWebView.mPrivateHandler, |
| 2520 | WebView.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration, |
| 2521 | new TextSelectionData(start, end)).sendToTarget(); |
| 2522 | } |
| 2523 | } |
| 2524 | |
| 2525 | // called by JNI |
Cary Clark | 243ea06 | 2009-06-25 10:49:32 -0400 | [diff] [blame] | 2526 | private void clearTextEntry() { |
| 2527 | if (mWebView == null) return; |
| 2528 | Message.obtain(mWebView.mPrivateHandler, |
| 2529 | WebView.CLEAR_TEXT_ENTRY).sendToTarget(); |
| 2530 | } |
| 2531 | |
Leon Scroggins | 5de6389 | 2009-10-29 09:48:43 -0400 | [diff] [blame] | 2532 | // called by JNI |
| 2533 | private void sendFindAgain() { |
| 2534 | if (mWebView == null) return; |
| 2535 | Message.obtain(mWebView.mPrivateHandler, |
| 2536 | WebView.FIND_AGAIN).sendToTarget(); |
| 2537 | } |
| 2538 | |
Cary Clark | 77d98f4 | 2009-07-31 09:40:38 -0400 | [diff] [blame] | 2539 | private native void nativeUpdateFrameCacheIfLoading(); |
Leon Scroggins | 200c13d | 2010-05-14 15:35:42 -0400 | [diff] [blame] | 2540 | private native void nativeRevealSelection(); |
Leon Scroggins | 3a50339 | 2010-01-06 17:04:38 -0500 | [diff] [blame] | 2541 | private native String nativeRequestLabel(int framePtr, int nodePtr); |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 2542 | /** |
Cary Clark | eaa18de | 2009-09-28 12:50:42 -0400 | [diff] [blame] | 2543 | * Scroll the focused textfield to (xPercent, y) in document space |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 2544 | */ |
Cary Clark | eaa18de | 2009-09-28 12:50:42 -0400 | [diff] [blame] | 2545 | private native void nativeScrollFocusedTextInput(float xPercent, int y); |
Leon Scroggins | 72543e1 | 2009-07-23 15:29:45 -0400 | [diff] [blame] | 2546 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2547 | // these must be in document space (i.e. not scaled/zoomed). |
Patrick Scott | fa8be1c | 2011-02-02 14:09:34 -0500 | [diff] [blame] | 2548 | private native void nativeSetScrollOffset(int gen, boolean sendScrollEvent, int dx, int dy); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2549 | |
| 2550 | private native void nativeSetGlobalBounds(int x, int y, int w, int h); |
| 2551 | |
| 2552 | // called by JNI |
Leon Scroggins | a8da173 | 2009-10-19 19:04:30 -0400 | [diff] [blame] | 2553 | private void requestListBox(String[] array, int[] enabledArray, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2554 | int[] selectedArray) { |
| 2555 | if (mWebView != null) { |
| 2556 | mWebView.requestListBox(array, enabledArray, selectedArray); |
| 2557 | } |
| 2558 | } |
| 2559 | |
| 2560 | // called by JNI |
Leon Scroggins | a8da173 | 2009-10-19 19:04:30 -0400 | [diff] [blame] | 2561 | private void requestListBox(String[] array, int[] enabledArray, |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2562 | int selection) { |
| 2563 | if (mWebView != null) { |
| 2564 | mWebView.requestListBox(array, enabledArray, selection); |
| 2565 | } |
Cary Clark | d6982c9 | 2009-05-29 11:02:22 -0400 | [diff] [blame] | 2566 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2567 | } |
Mike Reed | d205d5b | 2009-05-27 11:02:29 -0400 | [diff] [blame] | 2568 | |
Derek Sollenberger | 4c41e8d | 2009-06-29 13:49:27 -0400 | [diff] [blame] | 2569 | // called by JNI |
Leon Scroggins | b415779 | 2010-03-18 12:42:33 -0400 | [diff] [blame] | 2570 | private void requestKeyboardWithSelection(int pointer, int selStart, |
| 2571 | int selEnd, int textGeneration) { |
Derek Sollenberger | 4c41e8d | 2009-06-29 13:49:27 -0400 | [diff] [blame] | 2572 | if (mWebView != null) { |
| 2573 | Message.obtain(mWebView.mPrivateHandler, |
Leon Scroggins | b415779 | 2010-03-18 12:42:33 -0400 | [diff] [blame] | 2574 | WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer, |
| 2575 | textGeneration, new TextSelectionData(selStart, selEnd)) |
| 2576 | .sendToTarget(); |
| 2577 | } |
| 2578 | } |
| 2579 | |
| 2580 | // called by JNI |
| 2581 | private void requestKeyboard(boolean showKeyboard) { |
| 2582 | if (mWebView != null) { |
| 2583 | Message.obtain(mWebView.mPrivateHandler, |
| 2584 | WebView.REQUEST_KEYBOARD, showKeyboard ? 1 : 0, 0) |
Derek Sollenberger | 4c41e8d | 2009-06-29 13:49:27 -0400 | [diff] [blame] | 2585 | .sendToTarget(); |
| 2586 | } |
| 2587 | } |
| 2588 | |
Ben Murdoch | db8d19c | 2010-10-29 11:44:17 +0100 | [diff] [blame] | 2589 | private void setWebTextViewAutoFillable(int queryId, String preview) { |
Ben Murdoch | 62275a4 | 2010-09-07 11:27:28 +0100 | [diff] [blame] | 2590 | if (mWebView != null) { |
Ben Murdoch | db8d19c | 2010-10-29 11:44:17 +0100 | [diff] [blame] | 2591 | Message.obtain(mWebView.mPrivateHandler, WebView.SET_AUTOFILLABLE, |
| 2592 | new AutoFillData(queryId, preview)) |
| 2593 | .sendToTarget(); |
Ben Murdoch | 62275a4 | 2010-09-07 11:27:28 +0100 | [diff] [blame] | 2594 | } |
| 2595 | } |
| 2596 | |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2597 | // called by JNI |
Derek Sollenberger | 7c5bf46 | 2010-01-11 12:50:51 -0500 | [diff] [blame] | 2598 | private Context getContext() { |
| 2599 | return mContext; |
| 2600 | } |
| 2601 | |
| 2602 | // called by JNI |
Derek Sollenberger | f3196cd | 2011-01-27 17:33:14 -0500 | [diff] [blame] | 2603 | private void keepScreenOn(boolean screenOn) { |
| 2604 | if (mWebView != null) { |
| 2605 | Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SCREEN_ON); |
| 2606 | message.arg1 = screenOn ? 1 : 0; |
| 2607 | message.sendToTarget(); |
| 2608 | } |
| 2609 | } |
| 2610 | |
| 2611 | // called by JNI |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2612 | private Class<?> getPluginClass(String libName, String clsName) { |
John Reck | 7818aaa | 2011-04-26 16:57:46 -0700 | [diff] [blame] | 2613 | |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2614 | if (mWebView == null) { |
| 2615 | return null; |
| 2616 | } |
John Reck | 7818aaa | 2011-04-26 16:57:46 -0700 | [diff] [blame] | 2617 | |
Derek Sollenberger | cb37e71 | 2009-11-24 14:58:09 -0500 | [diff] [blame] | 2618 | PluginManager pluginManager = PluginManager.getInstance(null); |
| 2619 | |
| 2620 | String pkgName = pluginManager.getPluginsAPKName(libName); |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2621 | if (pkgName == null) { |
| 2622 | Log.w(LOGTAG, "Unable to resolve " + libName + " to a plugin APK"); |
| 2623 | return null; |
| 2624 | } |
John Reck | 7818aaa | 2011-04-26 16:57:46 -0700 | [diff] [blame] | 2625 | |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2626 | try { |
Derek Sollenberger | cb37e71 | 2009-11-24 14:58:09 -0500 | [diff] [blame] | 2627 | return pluginManager.getPluginClass(pkgName, clsName); |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2628 | } catch (NameNotFoundException e) { |
| 2629 | Log.e(LOGTAG, "Unable to find plugin classloader for the apk (" + pkgName + ")"); |
| 2630 | } catch (ClassNotFoundException e) { |
| 2631 | Log.e(LOGTAG, "Unable to find plugin class (" + clsName + |
| 2632 | ") in the apk (" + pkgName + ")"); |
| 2633 | } |
| 2634 | |
Derek Sollenberger | cb37e71 | 2009-11-24 14:58:09 -0500 | [diff] [blame] | 2635 | return null; |
Derek Sollenberger | 9e28c4c | 2009-11-09 14:45:58 -0500 | [diff] [blame] | 2636 | } |
Derek Sollenberger | cb37e71 | 2009-11-24 14:58:09 -0500 | [diff] [blame] | 2637 | |
Derek Sollenberger | 51ef573 | 2009-12-07 16:15:13 -0500 | [diff] [blame] | 2638 | // called by JNI. PluginWidget function to launch a full-screen view using a |
| 2639 | // View object provided by the plugin class. |
Derek Sollenberger | c28ff44 | 2010-03-09 17:38:49 -0500 | [diff] [blame] | 2640 | private void showFullScreenPlugin(ViewManager.ChildView childView, int npp) { |
Derek Sollenberger | 7c5bf46 | 2010-01-11 12:50:51 -0500 | [diff] [blame] | 2641 | if (mWebView == null) { |
Derek Sollenberger | 51ef573 | 2009-12-07 16:15:13 -0500 | [diff] [blame] | 2642 | return; |
| 2643 | } |
| 2644 | |
Derek Sollenberger | c28ff44 | 2010-03-09 17:38:49 -0500 | [diff] [blame] | 2645 | Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN); |
| 2646 | message.obj = childView.mView; |
| 2647 | message.arg1 = npp; |
| 2648 | message.sendToTarget(); |
Derek Sollenberger | 51ef573 | 2009-12-07 16:15:13 -0500 | [diff] [blame] | 2649 | } |
| 2650 | |
Grace Kloba | 11438c3 | 2009-12-16 11:39:12 -0800 | [diff] [blame] | 2651 | // called by JNI |
Derek Sollenberger | 51ef573 | 2009-12-07 16:15:13 -0500 | [diff] [blame] | 2652 | private void hideFullScreenPlugin() { |
| 2653 | if (mWebView == null) { |
| 2654 | return; |
| 2655 | } |
Grace Kloba | 11438c3 | 2009-12-16 11:39:12 -0800 | [diff] [blame] | 2656 | mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN) |
| 2657 | .sendToTarget(); |
| 2658 | } |
Derek Sollenberger | 51ef573 | 2009-12-07 16:15:13 -0500 | [diff] [blame] | 2659 | |
Derek Sollenberger | 36a4f23 | 2011-01-04 16:05:43 -0500 | [diff] [blame] | 2660 | private ViewManager.ChildView createSurface(View pluginView) { |
Patrick Scott | fb6aecb | 2009-07-17 16:38:07 -0400 | [diff] [blame] | 2661 | if (mWebView == null) { |
| 2662 | return null; |
| 2663 | } |
Derek Sollenberger | c0b8a96 | 2009-09-22 14:08:09 -0400 | [diff] [blame] | 2664 | |
Derek Sollenberger | 7c5bf46 | 2010-01-11 12:50:51 -0500 | [diff] [blame] | 2665 | if (pluginView == null) { |
| 2666 | Log.e(LOGTAG, "Attempted to add an empty plugin view to the view hierarchy"); |
Derek Sollenberger | 0b3a5d6 | 2009-09-08 18:31:40 -0400 | [diff] [blame] | 2667 | return null; |
| 2668 | } |
Derek Sollenberger | c0b8a96 | 2009-09-22 14:08:09 -0400 | [diff] [blame] | 2669 | |
Derek Sollenberger | 7c5bf46 | 2010-01-11 12:50:51 -0500 | [diff] [blame] | 2670 | // ensures the view system knows the view can redraw itself |
Derek Sollenberger | 42d00fb | 2009-12-01 15:19:42 -0500 | [diff] [blame] | 2671 | pluginView.setWillNotDraw(false); |
Derek Sollenberger | c0b8a96 | 2009-09-22 14:08:09 -0400 | [diff] [blame] | 2672 | |
Derek Sollenberger | 2120cd6 | 2010-02-23 16:52:45 -0500 | [diff] [blame] | 2673 | if(pluginView instanceof SurfaceView) |
| 2674 | ((SurfaceView)pluginView).setZOrderOnTop(true); |
| 2675 | |
Derek Sollenberger | 0b3a5d6 | 2009-09-08 18:31:40 -0400 | [diff] [blame] | 2676 | ViewManager.ChildView view = mWebView.mViewManager.createView(); |
| 2677 | view.mView = pluginView; |
Derek Sollenberger | 36a4f23 | 2011-01-04 16:05:43 -0500 | [diff] [blame] | 2678 | return view; |
| 2679 | } |
John Reck | 7818aaa | 2011-04-26 16:57:46 -0700 | [diff] [blame] | 2680 | |
Derek Sollenberger | 36a4f23 | 2011-01-04 16:05:43 -0500 | [diff] [blame] | 2681 | // called by JNI. PluginWidget functions for creating an embedded View for |
| 2682 | // the surface drawing model. |
| 2683 | private ViewManager.ChildView addSurface(View pluginView, int x, int y, |
| 2684 | int width, int height) { |
| 2685 | ViewManager.ChildView view = createSurface(pluginView); |
Derek Sollenberger | 0b3a5d6 | 2009-09-08 18:31:40 -0400 | [diff] [blame] | 2686 | view.attachView(x, y, width, height); |
| 2687 | return view; |
Patrick Scott | fb6aecb | 2009-07-17 16:38:07 -0400 | [diff] [blame] | 2688 | } |
Derek Sollenberger | cb37e71 | 2009-11-24 14:58:09 -0500 | [diff] [blame] | 2689 | |
Derek Sollenberger | 3dafca1 | 2009-10-13 11:38:25 -0400 | [diff] [blame] | 2690 | private void updateSurface(ViewManager.ChildView childView, int x, int y, |
| 2691 | int width, int height) { |
| 2692 | childView.attachView(x, y, width, height); |
| 2693 | } |
| 2694 | |
Derek Sollenberger | 0b3a5d6 | 2009-09-08 18:31:40 -0400 | [diff] [blame] | 2695 | private void destroySurface(ViewManager.ChildView childView) { |
| 2696 | childView.removeView(); |
Patrick Scott | fb6aecb | 2009-07-17 16:38:07 -0400 | [diff] [blame] | 2697 | } |
| 2698 | |
Grace Kloba | 3a0def2 | 2010-01-23 21:11:54 -0800 | [diff] [blame] | 2699 | // called by JNI |
| 2700 | static class ShowRectData { |
| 2701 | int mLeft; |
| 2702 | int mTop; |
| 2703 | int mWidth; |
| 2704 | int mHeight; |
| 2705 | int mContentWidth; |
| 2706 | int mContentHeight; |
| 2707 | float mXPercentInDoc; |
| 2708 | float mXPercentInView; |
| 2709 | float mYPercentInDoc; |
| 2710 | float mYPercentInView; |
| 2711 | } |
| 2712 | |
| 2713 | private void showRect(int left, int top, int width, int height, |
| 2714 | int contentWidth, int contentHeight, float xPercentInDoc, |
| 2715 | float xPercentInView, float yPercentInDoc, float yPercentInView) { |
| 2716 | if (mWebView != null) { |
| 2717 | ShowRectData data = new ShowRectData(); |
| 2718 | data.mLeft = left; |
| 2719 | data.mTop = top; |
| 2720 | data.mWidth = width; |
| 2721 | data.mHeight = height; |
| 2722 | data.mContentWidth = contentWidth; |
| 2723 | data.mContentHeight = contentHeight; |
| 2724 | data.mXPercentInDoc = xPercentInDoc; |
| 2725 | data.mXPercentInView = xPercentInView; |
| 2726 | data.mYPercentInDoc = yPercentInDoc; |
| 2727 | data.mYPercentInView = yPercentInView; |
| 2728 | Message.obtain(mWebView.mPrivateHandler, WebView.SHOW_RECT_MSG_ID, |
| 2729 | data).sendToTarget(); |
| 2730 | } |
| 2731 | } |
| 2732 | |
Grace Kloba | e8300a1 | 2010-03-12 13:32:55 -0800 | [diff] [blame] | 2733 | // called by JNI |
| 2734 | private void centerFitRect(int x, int y, int width, int height) { |
| 2735 | if (mWebView == null) { |
| 2736 | return; |
| 2737 | } |
| 2738 | mWebView.mPrivateHandler.obtainMessage(WebView.CENTER_FIT_RECT, |
| 2739 | new Rect(x, y, x + width, y + height)).sendToTarget(); |
| 2740 | } |
| 2741 | |
Grace Kloba | 50004bc | 2010-04-13 22:58:51 -0700 | [diff] [blame] | 2742 | // called by JNI |
| 2743 | private void setScrollbarModes(int hMode, int vMode) { |
| 2744 | if (mWebView == null) { |
| 2745 | return; |
| 2746 | } |
| 2747 | mWebView.mPrivateHandler.obtainMessage(WebView.SET_SCROLLBAR_MODES, |
| 2748 | hMode, vMode).sendToTarget(); |
| 2749 | } |
| 2750 | |
Svetoslav Ganov | 9504f57 | 2011-01-14 11:38:17 -0800 | [diff] [blame] | 2751 | // called by JNI |
| 2752 | @SuppressWarnings("unused") |
| 2753 | private void selectAt(int x, int y) { |
| 2754 | if (mWebView != null) { |
| 2755 | mWebView.mPrivateHandler.obtainMessage(WebView.SELECT_AT, x, y).sendToTarget(); |
| 2756 | } |
| 2757 | } |
| 2758 | |
Steve Block | 68dede3 | 2010-08-04 10:28:46 +0100 | [diff] [blame] | 2759 | private void useMockDeviceOrientation() { |
Steve Block | 1be7339 | 2010-10-15 16:31:01 +0100 | [diff] [blame] | 2760 | mDeviceMotionAndOrientationManager.useMock(); |
Steve Block | f4a705f | 2010-08-11 13:08:24 +0100 | [diff] [blame] | 2761 | } |
| 2762 | |
| 2763 | public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha, |
| 2764 | boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) { |
Steve Block | 1be7339 | 2010-10-15 16:31:01 +0100 | [diff] [blame] | 2765 | mDeviceMotionAndOrientationManager.setMockOrientation(canProvideAlpha, alpha, |
| 2766 | canProvideBeta, beta, canProvideGamma, gamma); |
Steve Block | 68dede3 | 2010-08-04 10:28:46 +0100 | [diff] [blame] | 2767 | } |
| 2768 | |
Steve Block | dc82a29 | 2010-10-06 14:34:15 +0100 | [diff] [blame] | 2769 | protected DeviceMotionService getDeviceMotionService() { |
| 2770 | if (mDeviceMotionService == null) { |
| 2771 | mDeviceMotionService = |
Steve Block | 1be7339 | 2010-10-15 16:31:01 +0100 | [diff] [blame] | 2772 | new DeviceMotionService(mDeviceMotionAndOrientationManager, mContext); |
Steve Block | dc82a29 | 2010-10-06 14:34:15 +0100 | [diff] [blame] | 2773 | } |
| 2774 | return mDeviceMotionService; |
| 2775 | } |
| 2776 | |
Steve Block | c43565b | 2010-08-11 13:12:37 +0100 | [diff] [blame] | 2777 | protected DeviceOrientationService getDeviceOrientationService() { |
| 2778 | if (mDeviceOrientationService == null) { |
Steve Block | bb9db22 | 2010-08-18 11:12:07 +0100 | [diff] [blame] | 2779 | mDeviceOrientationService = |
Steve Block | 1be7339 | 2010-10-15 16:31:01 +0100 | [diff] [blame] | 2780 | new DeviceOrientationService(mDeviceMotionAndOrientationManager, mContext); |
Steve Block | c43565b | 2010-08-11 13:12:37 +0100 | [diff] [blame] | 2781 | } |
| 2782 | return mDeviceOrientationService; |
| 2783 | } |
| 2784 | |
Mike Reed | d205d5b | 2009-05-27 11:02:29 -0400 | [diff] [blame] | 2785 | private native void nativePause(); |
| 2786 | private native void nativeResume(); |
Derek Sollenberger | e0155e9 | 2009-06-10 15:35:45 -0400 | [diff] [blame] | 2787 | private native void nativeFreeMemory(); |
Derek Sollenberger | b6ddc7a | 2009-12-08 15:41:46 -0500 | [diff] [blame] | 2788 | private native void nativeFullScreenPluginHidden(int npp); |
Cary Clark | 1cb97ee | 2009-12-11 12:10:36 -0500 | [diff] [blame] | 2789 | private native boolean nativeValidNodeAndBounds(int frame, int node, |
| 2790 | Rect bounds); |
| 2791 | |
Grace Kloba | 178db41 | 2010-05-18 22:22:23 -0700 | [diff] [blame] | 2792 | private native ArrayList<Rect> nativeGetTouchHighlightRects(int x, int y, |
| 2793 | int slop); |
Ben Murdoch | 62275a4 | 2010-09-07 11:27:28 +0100 | [diff] [blame] | 2794 | |
| 2795 | private native void nativeAutoFillForm(int queryId); |
Patrick Scott | cfa734a | 2011-02-22 11:19:02 -0500 | [diff] [blame] | 2796 | private native void nativeScrollLayer(int layer, Rect rect); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 2797 | } |