├── .gitignore ├── README.md ├── config └── buildvms.sh.template ├── res ├── raw │ └── blank_html.html └── values │ └── strings.xml ├── script ├── README.md ├── download.sh ├── pull.sh └── push.sh ├── src └── us │ └── costan │ └── chrome │ ├── ChromeCookieManager.java │ ├── ChromeHttpAuthHandler.java │ ├── ChromeJavascriptInterface.java │ ├── ChromeJsPromptResult.java │ ├── ChromeJsResult.java │ ├── ChromeSettings.java │ ├── ChromeSslErrorHandler.java │ ├── ChromeView.java │ ├── ChromeViewClient.java │ ├── ChromeWebClient.java │ └── impl │ ├── ChromeAwContentsClientProxy.java │ ├── ChromeHttpAuthHandlerProxy.java │ ├── ChromeInitializer.java │ ├── ChromeJsPromptResultProxy.java │ ├── ChromeJsResultReceiverProxy.java │ ├── ChromeSettingsProxy.java │ └── ChromeSslErrorHandlerProxy.java └── vm ├── README.md ├── build.sh └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Files for the dex VM. 2 | *.dex 3 | 4 | # Java class files. 5 | *.class 6 | 7 | # Generated files. 8 | bin/ 9 | gen/ 10 | 11 | # Local configuration file (sdk path, etc). 12 | local.properties 13 | 14 | # Vim. 15 | *.sw* 16 | 17 | # Downloaded build. 18 | build 19 | 20 | # Build VM configuration. 21 | config/buildvms.sh 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecation Notice 2 | 3 | This project is un-maintained. The recommended alternative is 4 | [the Crosswalk Project](https://crosswalk-project.org/). 5 | 6 | I did not have the time to keep the project up to date. In the mean 7 | time, the fine folks at Intel did a great job of embedding Chromium 8 | using the Content Shell API, which is what Chromium's developers 9 | intended. Therefore, I cannot justify spending any time on this. 10 | The original README and the code are here for historical purposes. 11 | 12 | I think that [the Crosswalk Project](https://crosswalk-project.org/) 13 | will meet all your embedding needs, and I'm contributing to it. 14 | 15 | # ChromeView Source Code 16 | 17 | ChormeView works like Android's WebView, but is backed by the latest Chromium 18 | code. 19 | 20 | [pwnall/chromeview](https://github.com/pwnall/chromeview) contains a binary 21 | distribution of ChromeView, with all the hard-to-build Chrome bits. This 22 | repository gets rebased, because it would become too large otherwise. 23 | 24 | [pwnall/chromeview-src](https://github.com/pwnall/chromeview-src) has the 25 | original source code (that is not pulled in from the Chromium project) and the 26 | scripts for building and extracting the bits from the Chromium source tree. 27 | 28 | 29 | ## Why ChromeView 30 | 31 | ChromeView lets you ship your own Chromium code, instead of using whatever 32 | version comes with your user's Android image. This gives your application 33 | early access to the newest features in Chromium, and removes the variability 34 | due to different WebView implementations in different versions of Android. 35 | 36 | 37 | ## Setting Up 38 | 39 | This section explains how to set up your Android project to use ChromeView. 40 | 41 | ### Get the Code 42 | 43 | Check out the repository in your Eclipse workspace, and make your project use 44 | ChromeView as a library. In Eclipse, right-click your project directory, select 45 | `Properties`, choose the `Android` category, and click on the `Add` button in 46 | the `Library section`. 47 | 48 | ### Copy Data 49 | 50 | Copy `assets/webviewchromium.pak` to your project's `assets` directory. 51 | 52 | In your `Application` subclass, call `ChromeView.initialize` and pass it the 53 | application's context. For example, 54 | 55 | ### Initialize Chromium 56 | 57 | ```java 58 | import us.costan.chrome.ChromeView; 59 | import android.app.Application; 60 | 61 | public class MyApplication extends Application { 62 | @Override 63 | public void onCreate() { 64 | super.onCreate(); 65 | ChromeView.initialize(this); 66 | } 67 | } 68 | ``` 69 | 70 | Now you can use ChromeView in the same contexts as you would use WebView. 71 | 72 | ### Make Some Noise 73 | 74 | If you use this project and want to help move it along, please star the 75 | following bugs. 76 | 77 | * [crbug.com/113088](http://crbug.com/113088) 78 | * [crbug.com/234907](http://crbug.com/234907) and 79 | * [this Android bug](https://code.google.com/p/android/issues/detail?id=35748) 80 | 81 | 82 | ## Usage 83 | 84 | To access ChromeView in the graphical layout editor, go to the `Palette`, 85 | expand the `Custom and Library Views` section, and click the `Refresh` button. 86 | 87 | ChromeView supports most of the WebView methods. For example, 88 | 89 | ```java 90 | ChromeView chromeView = (ChromeView)findViewById(R.id.gameUiView); 91 | chromeView.getSettings().setJavaScriptEnabled(true); 92 | chromeView.loadUrl("http://www.google.com"); 93 | ``` 94 | 95 | ### JavaScript 96 | 97 | ChromeView's `addJavaScriptInterface` exposes public methods that are annotated 98 | with `@ChromeJavascriptInterface`. This is because WebView's 99 | `@JavascriptInterface` is only available on Android 4.2 and above, but 100 | ChromeView targets 4.0 and 4.1 as well. 101 | 102 | ```java 103 | import us.costan.chrome.ChromeJavascriptInterface; 104 | 105 | public class JsBindings { 106 | @ChromeJavascriptInterface 107 | public String getHello() { 108 | return "Hello world"; 109 | } 110 | } 111 | 112 | chromeView.addJavascriptInterface(new JsBindings(), "AndroidBindings"); 113 | ``` 114 | 115 | ### Cookies 116 | 117 | ChromeCookieManager is ChromeView's equivalent of CookieManager. 118 | 119 | ```java 120 | ChromeCookieManager.getInstance().getCookie("https://www.google.com"); 121 | ``` 122 | 123 | ### Faster Development 124 | 125 | To speed up the application launch on real devices, remove the `libs/x86` 126 | directory. When developing on Atom devices, remove the ARM directory instead. 127 | 128 | Remember to `git checkout -- .` and get the library back before building a 129 | release APK. 130 | 131 | ### Internet Access 132 | 133 | If your application manifest doesn't specify the 134 | [INTERNET permission](http://developer.android.com/reference/android/Manifest.permission.html#INTERNET), 135 | the Chromium code behind ChromeView silentely blocks all network requests. This 136 | is mentioned here because it can be hard to debug. 137 | 138 | 139 | ## Building 140 | 141 | The bulk of this project is Chromium source code and build products. With the 142 | appropriate infrastructure, the Chromium bits can be easily updated. 143 | 144 | [crbuild/vm-build.md](crbuild/vm-build.md) contains step-by-step instructions 145 | for setting up a VM and building the Chromium for Android components used by 146 | ChromeView. 147 | 148 | Once Chromium has been successfully built, running 149 | [crbuild/update.sh](crbuild/update.sh) will copy the relevant bits from the 150 | build VM into the ChromeView source tree. 151 | 152 | 153 | ## Issues 154 | 155 | Attempting to scroll the view (by swiping a finger across the screen) does not 156 | update the displayed image. However, internally, the view is scrolled. This can 157 | be seen by displaying a stack of buttons and trying to click on the topmost 158 | one. This issue makes ChromeView mostly unusable in production. 159 | 160 | The core issue is that the integration is done via `AwContent` in the 161 | `android_webview` directory of the Chromium source tree, which is experimental 162 | and not intended for embedding use. The "right" way of doing this is to embed 163 | a `ContentView` from the `content` directory, or a `Shell` in `content/shell`. 164 | Unfortunately, these components' APIs don't match WebView nearly as well as 165 | AwContent, and they're much harder to integrate. Pull requests or a fork would 166 | be welcome. 167 | 168 | This repository is rebased often, because the large files in `lib/` would 169 | result in a huge repository if new commits were created for each build. The 170 | large files are Chromium build products. 171 | 172 | 173 | ## Contributing 174 | 175 | Please don't hesitate to send your Pull Requests! 176 | 177 | Please don't send pull requests including the binary assets or code extracted 178 | from Android (`assets/`, `libs/`, `src/com/googlecode/` and `src/org/android`). 179 | If your Pull Request requires updated Android bits, mention that in the PR 180 | description, and I will rebuild the Android bits. 181 | 182 | 183 | ## Copyright and License 184 | 185 | The directories below contain code from the 186 | [The Chromium Project](http://www.chromium.org/), which is subject to the 187 | copyright and license on the project site. 188 | 189 | * `assets/` 190 | * `libs/` 191 | * `src/com/googlecode` 192 | * `src/org/chromium` 193 | 194 | Some of the source code in `src/us/costan/chrome` has been derived from the 195 | Android source code, and is therefore covered by the 196 | [Android project licenses](http://source.android.com/source/licenses.html). 197 | 198 | The rest of the code is Copyright 2013, Victor Costan, and available under the 199 | MIT license. 200 | -------------------------------------------------------------------------------- /config/buildvms.sh.template: -------------------------------------------------------------------------------- 1 | # The URL of the VM that does ARM builds. 2 | ARM_BUILDVM=http://arm.buildbot.org 3 | 4 | # The URL of the VM that does X86 builds. 5 | # 6 | # This can be the same as the URL above, if the same VM is used for both 7 | # architectures. 8 | X86_BUILDVM=http://x86.buildbot.org 9 | -------------------------------------------------------------------------------- /res/raw/blank_html.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |56 | * The built-in mechanisms are the only currently supported zoom 57 | * mechanisms, so it is recommended that this setting is always enabled. 58 | * 59 | * @param enabled whether the WebView should use its built-in zoom mechanisms 60 | */ 61 | // This method was intended to select between the built-in zoom mechanisms 62 | // and the separate zoom controls. The latter were obtained using 63 | // {@link WebView#getZoomControls}, which is now hidden. 64 | public abstract void setBuiltInZoomControls(boolean enabled); 65 | 66 | /** 67 | * Gets whether the zoom mechanisms built into WebView are being used. 68 | * 69 | * @return true if the zoom mechanisms built into WebView are being used 70 | * @see #setBuiltInZoomControls 71 | */ 72 | public abstract boolean getBuiltInZoomControls(); 73 | 74 | /** 75 | * Sets whether the WebView should display on-screen zoom controls when 76 | * using the built-in zoom mechanisms. See {@link #setBuiltInZoomControls}. 77 | * The default is true. 78 | * 79 | * @param enabled whether the WebView should display on-screen zoom controls 80 | */ 81 | public abstract void setDisplayZoomControls(boolean enabled); 82 | 83 | /** 84 | * Gets whether the WebView displays on-screen zoom controls when using 85 | * the built-in zoom mechanisms. 86 | * 87 | * @return true if the WebView displays on-screen zoom controls when using 88 | * the built-in zoom mechanisms 89 | * @see #setDisplayZoomControls 90 | */ 91 | public abstract boolean getDisplayZoomControls(); 92 | 93 | /** 94 | * Enables or disables file access within WebView. File access is enabled by 95 | * default. Note that this enables or disables file system access only. 96 | * Assets and resources are still accessible using file:///android_asset and 97 | * file:///android_res. 98 | */ 99 | public abstract void setAllowFileAccess(boolean allow); 100 | 101 | /** 102 | * Gets whether this WebView supports file access. 103 | * 104 | * @see #setAllowFileAccess 105 | */ 106 | public abstract boolean getAllowFileAccess(); 107 | 108 | /** 109 | * Enables or disables content URL access within WebView. Content URL 110 | * access allows WebView to load content from a content provider installed 111 | * in the system. The default is enabled. 112 | */ 113 | public abstract void setAllowContentAccess(boolean allow); 114 | 115 | /** 116 | * Gets whether this WebView supports content URL access. 117 | * 118 | * @see #setAllowContentAccess 119 | */ 120 | public abstract boolean getAllowContentAccess(); 121 | 122 | /** 123 | * Sets whether the WebView loads pages in overview mode. The default is 124 | * false. 125 | */ 126 | public abstract void setLoadWithOverviewMode(boolean overview); 127 | 128 | /** 129 | * Gets whether this WebView loads pages in overview mode. 130 | * 131 | * @return whether this WebView loads pages in overview mode 132 | * @see #setLoadWithOverviewMode 133 | */ 134 | public abstract boolean getLoadWithOverviewMode(); 135 | 136 | /** 137 | * Sets whether the WebView should save form data. The default is true, 138 | * unless in private browsing mode, when the value is always false. 139 | */ 140 | public abstract void setSaveFormData(boolean save); 141 | 142 | /** 143 | * Gets whether the WebView saves form data. Always false in private 144 | * browsing mode. 145 | * 146 | * @return whether the WebView saves form data 147 | * @see #setSaveFormData 148 | */ 149 | public abstract boolean getSaveFormData(); 150 | 151 | /** 152 | * Sets whether the WebView should save passwords. The default is true. 153 | */ 154 | public abstract void setSavePassword(boolean save); 155 | 156 | /** 157 | * Gets whether the WebView saves passwords. 158 | * 159 | * @return whether the WebView saves passwords 160 | * @see #setSavePassword 161 | */ 162 | public abstract boolean getSavePassword(); 163 | 164 | /** 165 | * Sets the text zoom of the page in percent. The default is 100. 166 | * 167 | * @param textZoom the text zoom in percent 168 | */ 169 | public abstract void setTextZoom(int textZoom); 170 | 171 | /** 172 | * Gets the text zoom of the page in percent. 173 | * 174 | * @return the text zoom of the page in percent 175 | * @see #setTextZoom 176 | */ 177 | public abstract int getTextZoom(); 178 | 179 | /** 180 | * Sets the default zoom density of the page. This must be called from the UI 181 | * thread. The default is {@link ZoomDensity#MEDIUM}. 182 | * 183 | * @param zoom the zoom density 184 | */ 185 | public abstract void setDefaultZoom(ZoomDensity zoom); 186 | 187 | /** 188 | * Gets the default zoom density of the page. This should be called from 189 | * the UI thread. 190 | * 191 | * @return the zoom density 192 | * @see #setDefaultZoom 193 | */ 194 | public abstract ZoomDensity getDefaultZoom(); 195 | 196 | /** 197 | * Enables using light touches to make a selection and activate mouseovers. 198 | * The default is false. 199 | */ 200 | public abstract void setLightTouchEnabled(boolean enabled); 201 | 202 | /** 203 | * Gets whether light touches are enabled. 204 | * 205 | * @return whether light touches are enabled 206 | * @see #setLightTouchEnabled 207 | */ 208 | public abstract boolean getLightTouchEnabled(); 209 | 210 | /** 211 | * Tells the WebView to use a wide viewport. The default is false. 212 | * 213 | * @param use whether to use a wide viewport 214 | */ 215 | public abstract void setUseWideViewPort(boolean use); 216 | 217 | /** 218 | * Gets whether the WebView is using a wide viewport. 219 | * 220 | * @return true if the WebView is using a wide viewport 221 | * @see #setUseWideViewPort 222 | */ 223 | public abstract boolean getUseWideViewPort(); 224 | 225 | /** 226 | * Sets whether the WebView whether supports multiple windows. If set to 227 | * true, {@link WebChromeClient#onCreateWindow} must be implemented by the 228 | * host application. The default is false. 229 | * 230 | * @param support whether to suport multiple windows 231 | */ 232 | public abstract void setSupportMultipleWindows(boolean support); 233 | 234 | /** 235 | * Gets whether the WebView supports multiple windows. 236 | * 237 | * @return true if the WebView supports multiple windows 238 | * @see #setSupportMultipleWindows 239 | */ 240 | public abstract boolean supportMultipleWindows(); 241 | 242 | /** 243 | * Sets the underlying layout algorithm. This will cause a relayout of the 244 | * WebView. The default is {@link LayoutAlgorithm#NARROW_COLUMNS}. 245 | * 246 | * @param l the layout algorithm to use, as a {@link LayoutAlgorithm} value 247 | */ 248 | public abstract void setLayoutAlgorithm(LayoutAlgorithm l); 249 | 250 | /** 251 | * Gets the current layout algorithm. 252 | * 253 | * @return the layout algorithm in use, as a {@link LayoutAlgorithm} value 254 | * @see #setLayoutAlgorithm 255 | */ 256 | public abstract LayoutAlgorithm getLayoutAlgorithm(); 257 | 258 | /** 259 | * Sets the standard font family name. The default is "sans-serif". 260 | * 261 | * @param font a font family name 262 | */ 263 | public abstract void setStandardFontFamily(String font); 264 | 265 | /** 266 | * Gets the standard font family name. 267 | * 268 | * @return the standard font family name as a string 269 | * @see #setStandardFontFamily 270 | */ 271 | public abstract String getStandardFontFamily(); 272 | 273 | /** 274 | * Sets the fixed font family name. The default is "monospace". 275 | * 276 | * @param font a font family name 277 | */ 278 | public abstract void setFixedFontFamily(String font); 279 | 280 | /** 281 | * Gets the fixed font family name. 282 | * 283 | * @return the fixed font family name as a string 284 | * @see #setFixedFontFamily 285 | */ 286 | public abstract String getFixedFontFamily(); 287 | 288 | /** 289 | * Sets the sans-serif font family name. The default is "sans-serif". 290 | * 291 | * @param font a font family name 292 | */ 293 | public abstract void setSansSerifFontFamily(String font); 294 | 295 | /** 296 | * Gets the sans-serif font family name. 297 | * 298 | * @return the sans-serif font family name as a string 299 | * @see #setSansSerifFontFamily 300 | */ 301 | public abstract String getSansSerifFontFamily(); 302 | 303 | /** 304 | * Sets the serif font family name. The default is "sans-serif". 305 | * 306 | * @param font a font family name 307 | */ 308 | public abstract void setSerifFontFamily(String font); 309 | 310 | /** 311 | * Gets the serif font family name. The default is "serif". 312 | * 313 | * @return the serif font family name as a string 314 | * @see #setSerifFontFamily 315 | */ 316 | public abstract String getSerifFontFamily(); 317 | 318 | /** 319 | * Sets the cursive font family name. The default is "cursive". 320 | * 321 | * @param font a font family name 322 | */ 323 | public abstract void setCursiveFontFamily(String font); 324 | 325 | /** 326 | * Gets the cursive font family name. 327 | * 328 | * @return the cursive font family name as a string 329 | * @see #setCursiveFontFamily 330 | */ 331 | public abstract String getCursiveFontFamily(); 332 | 333 | /** 334 | * Sets the fantasy font family name. The default is "fantasy". 335 | * 336 | * @param font a font family name 337 | */ 338 | public abstract void setFantasyFontFamily(String font); 339 | 340 | /** 341 | * Gets the fantasy font family name. 342 | * 343 | * @return the fantasy font family name as a string 344 | * @see #setFantasyFontFamily 345 | */ 346 | public abstract String getFantasyFontFamily(); 347 | 348 | /** 349 | * Sets the minimum font size. The default is 8. 350 | * 351 | * @param size a non-negative integer between 1 and 72. Any number outside 352 | * the specified range will be pinned. 353 | */ 354 | public abstract void setMinimumFontSize(int size); 355 | 356 | /** 357 | * Gets the minimum font size. 358 | * 359 | * @return a non-negative integer between 1 and 72 360 | * @see #setMinimumFontSize 361 | */ 362 | public abstract int getMinimumFontSize(); 363 | 364 | /** 365 | * Sets the minimum logical font size. The default is 8. 366 | * 367 | * @param size a non-negative integer between 1 and 72. Any number outside 368 | * the specified range will be pinned. 369 | */ 370 | public abstract void setMinimumLogicalFontSize(int size); 371 | 372 | /** 373 | * Gets the minimum logical font size. 374 | * 375 | * @return a non-negative integer between 1 and 72 376 | * @see #setMinimumLogicalFontSize 377 | */ 378 | public abstract int getMinimumLogicalFontSize(); 379 | 380 | /** 381 | * Sets the default font size. The default is 16. 382 | * 383 | * @param size a non-negative integer between 1 and 72. Any number outside 384 | * the specified range will be pinned. 385 | */ 386 | public abstract void setDefaultFontSize(int size); 387 | 388 | /** 389 | * Gets the default font size. 390 | * 391 | * @return a non-negative integer between 1 and 72 392 | * @see #setDefaultFontSize 393 | */ 394 | public abstract int getDefaultFontSize(); 395 | 396 | /** 397 | * Sets the default fixed font size. The default is 16. 398 | * 399 | * @param size a non-negative integer between 1 and 72. Any number outside 400 | * the specified range will be pinned. 401 | */ 402 | public abstract void setDefaultFixedFontSize(int size); 403 | 404 | /** 405 | * Gets the default fixed font size. 406 | * 407 | * @return a non-negative integer between 1 and 72 408 | * @see #setDefaultFixedFontSize 409 | */ 410 | public abstract int getDefaultFixedFontSize(); 411 | 412 | /** 413 | * Sets whether the WebView should load image resources. Note that this method 414 | * controls loading of all images, including those embedded using the data 415 | * URI scheme. Use {@link #setBlockNetworkImage} to control loading only 416 | * of images specified using network URI schemes. Note that if the value of this 417 | * setting is changed from false to true, all images resources referenced 418 | * by content currently displayed by the WebView are loaded automatically. 419 | * The default is true. 420 | * 421 | * @param flag whether the WebView should load image resources 422 | */ 423 | public abstract void setLoadsImagesAutomatically(boolean flag); 424 | 425 | /** 426 | * Gets whether the WebView loads image resources. This includes 427 | * images embedded using the data URI scheme. 428 | * 429 | * @return true if the WebView loads image resources 430 | * @see #setLoadsImagesAutomatically 431 | */ 432 | public abstract boolean getLoadsImagesAutomatically(); 433 | 434 | /** 435 | * Sets whether the WebView should not load image resources from the 436 | * network (resources accessed via http and https URI schemes). Note 437 | * that this method has no effect unless 438 | * {@link #getLoadsImagesAutomatically} returns true. Also note that 439 | * disabling all network loads using {@link #setBlockNetworkLoads} 440 | * will also prevent network images from loading, even if this flag is set 441 | * to false. When the value of this setting is changed from true to false, 442 | * network images resources referenced by content currently displayed by 443 | * the WebView are fetched automatically. The default is false. 444 | * 445 | * @param flag whether the WebView should not load image resources from the 446 | * network 447 | * @see #setBlockNetworkLoads 448 | */ 449 | public abstract void setBlockNetworkImage(boolean flag); 450 | 451 | /** 452 | * Gets whether the WebView does not load image resources from the network. 453 | * 454 | * @return true if the WebView does not load image resources from the network 455 | * @see #setBlockNetworkImage 456 | */ 457 | public abstract boolean getBlockNetworkImage(); 458 | 459 | /** 460 | * Sets whether the WebView should not load resources from the network. 461 | * Use {@link #setBlockNetworkImage} to only avoid loading 462 | * image resources. Note that if the value of this setting is 463 | * changed from true to false, network resources referenced by content 464 | * currently displayed by the WebView are not fetched until 465 | * {@link android.webkit.WebView#reload} is called. 466 | * If the application does not have the 467 | * {@link android.Manifest.permission#INTERNET} permission, attempts to set 468 | * a value of false will cause a {@link java.lang.SecurityException} 469 | * to be thrown. The default value is false if the application has the 470 | * {@link android.Manifest.permission#INTERNET} permission, otherwise it is 471 | * true. 472 | * 473 | * @param flag whether the WebView should not load any resources from the 474 | * network 475 | * @see android.webkit.WebView#reload 476 | */ 477 | public abstract void setBlockNetworkLoads(boolean flag); 478 | 479 | /** 480 | * Gets whether the WebView does not load any resources from the network. 481 | * 482 | * @return true if the WebView does not load any resources from the network 483 | * @see #setBlockNetworkLoads 484 | */ 485 | public abstract boolean getBlockNetworkLoads(); 486 | 487 | /** 488 | * Tells the WebView to enable JavaScript execution. 489 | * The default is false. 490 | * 491 | * @param flag true if the WebView should execute JavaScript 492 | */ 493 | public abstract void setJavaScriptEnabled(boolean flag); 494 | 495 | /** 496 | * Sets whether JavaScript running in the context of a file scheme URL 497 | * should be allowed to access content from any origin. This includes 498 | * access to content from other file scheme URLs. See 499 | * {@link #setAllowFileAccessFromFileURLs}. To enable the most restrictive, 500 | * and therefore secure policy, this setting should be disabled. 501 | *
502 | * The default value is true for API level 503 | * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below, 504 | * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} 505 | * and above. 506 | * 507 | * @param flag whether JavaScript running in the context of a file scheme 508 | * URL should be allowed to access content from any origin 509 | */ 510 | public abstract void setAllowUniversalAccessFromFileURLs(boolean flag); 511 | 512 | /** 513 | * Sets whether JavaScript running in the context of a file scheme URL 514 | * should be allowed to access content from other file scheme URLs. To 515 | * enable the most restrictive, and therefore secure policy, this setting 516 | * should be disabled. Note that the value of this setting is ignored if 517 | * the value of {@link #getAllowUniversalAccessFromFileURLs} is true. 518 | *
519 | * The default value is true for API level
520 | * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
521 | * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
522 | * and above.
523 | *
524 | * @param flag whether JavaScript running in the context of a file scheme
525 | * URL should be allowed to access content from other file
526 | * scheme URLs
527 | */
528 | public abstract void setAllowFileAccessFromFileURLs(boolean flag);
529 |
530 | /**
531 | * Tells the WebView to enable, disable, or have plugins on demand. On
532 | * demand mode means that if a plugin exists that can handle the embedded
533 | * content, a placeholder icon will be shown instead of the plugin. When
534 | * the placeholder is clicked, the plugin will be enabled. The default is
535 | * {@link PluginState#OFF}.
536 | *
537 | * @param state a PluginState value
538 | */
539 | public abstract void setPluginState(PluginState state);
540 |
541 | /**
542 | * Sets the path to where database storage API databases should be saved.
543 | * In order for the database storage API to function correctly, this method
544 | * must be called with a path to which the application can write. This
545 | * method should only be called once: repeated calls are ignored.
546 | *
547 | * @param databasePath a path to the directory where databases should be
548 | * saved.
549 | */
550 | // This will update WebCore when the Sync runs in the C++ side.
551 | // Note that the WebCore Database Tracker only allows the path to be set
552 | // once.
553 | public abstract void setDatabasePath(String databasePath);
554 |
555 | /**
556 | * Sets the path where the Geolocation databases should be saved. In order
557 | * for Geolocation permissions and cached positions to be persisted, this
558 | * method must be called with a path to which the application can write.
559 | *
560 | * @param databasePath a path to the directory where databases should be
561 | * saved.
562 | */
563 | // This will update WebCore when the Sync runs in the C++ side.
564 | public abstract void setGeolocationDatabasePath(String databasePath);
565 |
566 | /**
567 | * Sets whether the Application Caches API should be enabled. The default
568 | * is false. Note that in order for the Application Caches API to be
569 | * enabled, a valid database path must also be supplied to
570 | * {@link #setAppCachePath}.
571 | *
572 | * @param flag true if the WebView should enable Application Caches
573 | */
574 | public abstract void setAppCacheEnabled(boolean flag);
575 |
576 | /**
577 | * Sets the path to the Application Caches files. In order for the
578 | * Application Caches API to be enabled, this method must be called with a
579 | * path to which the application can write. This method should only be
580 | * called once: repeated calls are ignored.
581 | *
582 | * @param appCachePath a String path to the directory containing
583 | * Application Caches files.
584 | * @see setAppCacheEnabled
585 | */
586 | public abstract void setAppCachePath(String appCachePath);
587 |
588 | /**
589 | * Sets the maximum size for the Application Cache content. The passed size
590 | * will be rounded to the nearest value that the database can support, so
591 | * this should be viewed as a guide, not a hard limit. Setting the
592 | * size to a value less than current database size does not cause the
593 | * database to be trimmed. The default size is {@link Long#MAX_VALUE}.
594 | *
595 | * @param appCacheMaxSize the maximum size in bytes
596 | */
597 | public abstract void setAppCacheMaxSize(long appCacheMaxSize);
598 |
599 | /**
600 | * Sets whether the database storage API is enabled. The default value is
601 | * false. See also {@link #setDatabasePath} for how to correctly set up the
602 | * database storage API.
603 | *
604 | * @param flag true if the WebView should use the database storage API
605 | */
606 | public abstract void setDatabaseEnabled(boolean flag);
607 |
608 | /**
609 | * Sets whether the DOM storage API is enabled. The default value is false.
610 | *
611 | * @param flag true if the WebView should use the DOM storage API
612 | */
613 | public abstract void setDomStorageEnabled(boolean flag);
614 |
615 | /**
616 | * Gets whether the DOM Storage APIs are enabled.
617 | *
618 | * @return true if the DOM Storage APIs are enabled
619 | * @see #setDomStorageEnabled
620 | */
621 | public abstract boolean getDomStorageEnabled();
622 | /**
623 | * Gets the path to where database storage API databases are saved.
624 | *
625 | * @return the String path to the database storage API databases
626 | * @see #setDatabasePath
627 | */
628 | public abstract String getDatabasePath();
629 |
630 | /**
631 | * Gets whether the database storage API is enabled.
632 | *
633 | * @return true if the database storage API is enabled
634 | * @see #setDatabaseEnabled
635 | */
636 | public abstract boolean getDatabaseEnabled();
637 |
638 | /**
639 | * Sets whether Geolocation is enabled. The default is true. See also
640 | * {@link #setGeolocationDatabasePath} for how to correctly set up
641 | * Geolocation.
642 | *
643 | * @param flag whether Geolocation should be enabled
644 | */
645 | public abstract void setGeolocationEnabled(boolean flag);
646 |
647 | /**
648 | * Gets whether JavaScript is enabled.
649 | *
650 | * @return true if JavaScript is enabled
651 | * @see #setJavaScriptEnabled
652 | */
653 | public abstract boolean getJavaScriptEnabled();
654 |
655 | /**
656 | * Gets whether JavaScript running in the context of a file scheme URL can
657 | * access content from any origin. This includes access to content from
658 | * other file scheme URLs.
659 | *
660 | * @return whether JavaScript running in the context of a file scheme URL
661 | * can access content from any origin
662 | * @see #setAllowUniversalAccessFromFileURLs
663 | */
664 | public abstract boolean getAllowUniversalAccessFromFileURLs();
665 |
666 | /**
667 | * Gets whether JavaScript running in the context of a file scheme URL can
668 | * access content from other file scheme URLs.
669 | *
670 | * @return whether JavaScript running in the context of a file scheme URL
671 | * can access content from other file scheme URLs
672 | * @see #setAllowFileAccessFromFileURLs
673 | */
674 | public abstract boolean getAllowFileAccessFromFileURLs();
675 |
676 | /**
677 | * Gets the current state regarding whether plugins are enabled.
678 | *
679 | * @return the plugin state as a {@link PluginState} value
680 | * @see #setPluginState
681 | */
682 | public abstract PluginState getPluginState();
683 |
684 | /**
685 | * Tells JavaScript to open windows automatically. This applies to the
686 | * JavaScript function window.open(). The default is false.
687 | *
688 | * @param flag true if JavaScript can open windows automatically
689 | */
690 | public abstract void setJavaScriptCanOpenWindowsAutomatically(boolean flag);
691 |
692 | /**
693 | * Gets whether JavaScript can open windows automatically.
694 | *
695 | * @return true if JavaScript can open windows automatically during
696 | * window.open()
697 | * @see #setJavaScriptCanOpenWindowsAutomatically
698 | */
699 | public abstract boolean getJavaScriptCanOpenWindowsAutomatically();
700 | /**
701 | * Sets the default text encoding name to use when decoding html pages.
702 | * The default is "Latin-1".
703 | *
704 | * @param encoding the text encoding name
705 | */
706 | public abstract void setDefaultTextEncodingName(String encoding);
707 |
708 | /**
709 | * Gets the default text encoding name.
710 | *
711 | * @return the default text encoding name as a string
712 | * @see #setDefaultTextEncodingName
713 | */
714 | public abstract String getDefaultTextEncodingName();
715 |
716 | /**
717 | * Sets the WebView's user-agent string. If the string is null or empty,
718 | * the system default value will be used.
719 | */
720 | public abstract void setUserAgentString(String ua);
721 |
722 | /**
723 | * Gets the WebView's user-agent string.
724 | *
725 | * @return the WebView's user-agent string
726 | * @see #setUserAgentString
727 | */
728 | public abstract String getUserAgentString();
729 |
730 | /**
731 | * Tells the WebView whether it needs to set a node to have focus when
732 | * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. The
733 | * default value is true.
734 | *
735 | * @param flag whether the WebView needs to set a node
736 | */
737 | public abstract void setNeedInitialFocus(boolean flag);
738 |
739 | /**
740 | * Sets the priority of the Render thread. Unlike the other settings, this
741 | * one only needs to be called once per process. The default value is
742 | * {@link RenderPriority#NORMAL}.
743 | *
744 | * @param priority the priority
745 | */
746 | public abstract void setRenderPriority(RenderPriority priority);
747 |
748 | /**
749 | * Overrides the way the cache is used. The way the cache is used is based
750 | * on the navigation type. For a normal page load, the cache is checked
751 | * and content is re-validated as needed. When navigating back, content is
752 | * not revalidated, instead the content is just retrieved from the cache.
753 | * This method allows the client to override this behavior by specifying
754 | * one of {@link #LOAD_DEFAULT}, {@link #LOAD_NORMAL},
755 | * {@link #LOAD_CACHE_ELSE_NETWORK}, {@link #LOAD_NO_CACHE} or
756 | * {@link #LOAD_CACHE_ONLY}. The default value is {@link #LOAD_DEFAULT}.
757 | *
758 | * @param mode the mode to use
759 | */
760 | public abstract void setCacheMode(int mode);
761 |
762 | /**
763 | * Gets the current setting for overriding the cache mode.
764 | *
765 | * @return the current setting for overriding the cache mode
766 | * @see #setCacheMode
767 | */
768 | public abstract int getCacheMode();
769 | }
770 |
--------------------------------------------------------------------------------
/src/us/costan/chrome/ChromeSslErrorHandler.java:
--------------------------------------------------------------------------------
1 | package us.costan.chrome;
2 |
3 | /**
4 | * ChromeView equivalent of SslErrorHandler.
5 | *
6 | * This is necessary because SslErrorHandler's constructor is package-private,
7 | * so it is impossible to extend the class, which would have been cleaner.
8 | *
9 | * @see android.webkit.SslErrorHandler
10 | */
11 | public interface ChromeSslErrorHandler {
12 | // Mostly mirrors
13 | // platform/frameworks/base/ ./core/java/android/webkit/SslErrorHandler
14 | /**
15 | * Proceed with the SSL certificate.
16 | */
17 | public void proceed();
18 |
19 | /**
20 | * Cancel this request and all pending requests for the WebView that had
21 | * the error.
22 | */
23 | public void cancel();
24 | }
25 |
--------------------------------------------------------------------------------
/src/us/costan/chrome/ChromeView.java:
--------------------------------------------------------------------------------
1 | package us.costan.chrome;
2 |
3 | import java.util.Map;
4 |
5 | import org.chromium.android_webview.AwBrowserContext;
6 | import org.chromium.android_webview.AwContents;
7 | import org.chromium.content.browser.ContentViewCore;
8 | import org.chromium.content.browser.ContentViewStatics;
9 | import org.chromium.content.browser.LoadUrlParams;
10 | import org.chromium.content.browser.ContentViewCore.JavaScriptCallback;
11 |
12 | import us.costan.chrome.impl.ChromeAwContentsClientProxy;
13 | import us.costan.chrome.impl.ChromeInitializer;
14 | import us.costan.chrome.impl.ChromeSettingsProxy;
15 | import android.annotation.SuppressLint;
16 | import android.annotation.TargetApi;
17 | import android.app.Activity;
18 | import android.content.Context;
19 | import android.content.SharedPreferences;
20 | import android.content.res.Configuration;
21 | import android.graphics.Bitmap;
22 | import android.graphics.Canvas;
23 | import android.graphics.Picture;
24 | import android.graphics.Rect;
25 | import android.net.http.SslCertificate;
26 | import android.os.Build;
27 | import android.os.Bundle;
28 | import android.os.Message;
29 | import android.util.AttributeSet;
30 | import android.view.KeyEvent;
31 | import android.view.MotionEvent;
32 | import android.view.View;
33 | import android.view.WindowManager;
34 | import android.view.accessibility.AccessibilityEvent;
35 | import android.view.accessibility.AccessibilityNodeInfo;
36 | import android.view.inputmethod.EditorInfo;
37 | import android.view.inputmethod.InputConnection;
38 | import android.webkit.DownloadListener;
39 | import android.webkit.ValueCallback;
40 | import android.webkit.WebSettings;
41 | import android.webkit.WebView.FindListener;
42 | import android.widget.FrameLayout;
43 |
44 | /** WebView-like layer. */
45 | public class ChromeView extends FrameLayout {
46 | /** The closest thing to a WebView that Chromium has to offer. */
47 | private AwContents awContents_;
48 |
49 | /** Implements some of AwContents. */
50 | private ContentViewCore contentViewCore_;
51 |
52 | /** Glue that passes calls from the Chromium view to a WebChromeClient. */
53 | private ChromeAwContentsClientProxy awContentsClient_;
54 |
55 | /** Everything pertaining to the user's browsing session. */
56 | private AwBrowserContext browserContext_;
57 |
58 | /** Glue that passes calls from the Chromium view to its parent (us). */
59 | private ChromeInternalAcccessAdapter internalAccessAdapter_;
60 |
61 | public ChromeView(Context context) {
62 | this(context, null);
63 | }
64 |
65 | /** Constructor for inflating via XML. */
66 | public ChromeView(Context context, AttributeSet attrs) {
67 | super(context, attrs, android.R.attr.webViewStyle);
68 |
69 | if (isInEditMode()) {
70 | return; // Chromium isn't loaded in edit mode.
71 | }
72 |
73 | try {
74 | Activity activity = (Activity)context;
75 | activity.getWindow().setFlags(
76 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
77 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
78 |
79 | } catch(ClassCastException e) {
80 | // Hope that hardware acceleration is enabled.
81 | }
82 |
83 | SharedPreferences sharedPreferences = context.getSharedPreferences(
84 | "chromeview", Context.MODE_PRIVATE);
85 | // TODO(pwnall): is there a better way to get an AwBrowserContext?
86 | browserContext_ = new AwBrowserContext(sharedPreferences);
87 |
88 | internalAccessAdapter_ = new ChromeView.ChromeInternalAcccessAdapter();
89 | awContentsClient_ = new ChromeAwContentsClientProxy(this);
90 | awContents_ = new AwContents(browserContext_, this, internalAccessAdapter_,
91 | awContentsClient_, true);
92 | contentViewCore_ = awContents_.getContentViewCore();
93 | }
94 |
95 | //// Non-WebView extensions
96 |
97 | /**
98 | * Injects the passed Javascript code in the current page and evaluates it.
99 | * If a result is required, pass in a callback.
100 | * Used in automation tests.
101 | *
102 | * @param script The Javascript to execute.
103 | * @param message The callback to be fired off when a result is ready. The script's
104 | * result will be json encoded and passed as the parameter, and the call
105 | * will be made on the main thread.
106 | * If no result is required, pass null.
107 | * @throws IllegalStateException If the ContentView has been destroyed.
108 | */
109 | public void evaluateJavaScript(String script, JavaScriptCallback callback) {
110 | if (awContents_ != null) {
111 | contentViewCore_.evaluateJavaScript(script, callback);
112 | }
113 | }
114 |
115 | //// WebView methods
116 |
117 | /**
118 | * Return the first substring consisting of the address of a physical
119 | * location. Currently, only addresses in the United States are detected,
120 | * and consist of:
121 | * - a house number
122 | * - a street name
123 | * - a street type (Road, Circle, etc), either spelled out or abbreviated
124 | * - a city name
125 | * - a state or territory, either spelled out or two-letter abbr.
126 | * - an optional 5 digit or 9 digit zip code.
127 | *
128 | * All names must be correctly capitalized, and the zip code, if present,
129 | * must be valid for the state. The street type must be a standard USPS
130 | * spelling or abbreviation. The state or territory must also be spelled
131 | * or abbreviated using USPS standards. The house number may not exceed
132 | * five digits.
133 | * @param addr The string to search for addresses.
134 | *
135 | * @return the address, or if no address is found, return null.
136 | */
137 | public static String findAddress(String addr) {
138 | return ContentViewStatics.findAddress(addr);
139 | }
140 |
141 | /**
142 | * Sets the ChromeViewClient associated with this view.
143 | *
144 | * @param chromeViewClient the new handler; replaces the old handler
145 | * @see android.webkit.WebView#setWebViewClient(android.webkit.WebViewClient)
146 | * @see android.webkit.WebViewClient
147 | */
148 | public void setChromeViewClient(ChromeViewClient chromeViewClient) {
149 | awContentsClient_.setChromeViewClient(chromeViewClient);
150 | }
151 |
152 | /**
153 | * Sets the ChromeWebClient associated with this view.
154 | *
155 | * @param chromeWebClient the new handler; replaces the old handler
156 | * @see android.webkit.WebView#setWebChromeClient(android.webkit.WebChromeClient)
157 | * @see android.webkit.WebChromeClient
158 | */
159 | public void setChromeWebClient(ChromeWebClient chromeWebClient) {
160 | awContentsClient_.setChromeWebClient(chromeWebClient);
161 | }
162 |
163 | /**
164 | * Sets the DownloadListener associated with this view.
165 | *
166 | * @param downloadListener the new listener; replaces the old listener
167 | * @see android.webkit.WebView#setDownloadListener(DownloadListener)
168 | */
169 | public void setDownloadListener(DownloadListener downloadListener) {
170 | awContentsClient_.setDownloadListener(downloadListener);
171 | }
172 |
173 | /**
174 | * Sets the FindListener associated with this view.
175 | *
176 | * @param findListener the new listener; replaces the old listener
177 | * @see android.webkit.WebView#setFindListener(FindListener)
178 | */
179 | public void setFindListener(FindListener findListener) {
180 | awContentsClient_.setFindListener(findListener);
181 | }
182 |
183 | /**
184 | * Gets the SSL certificate for the main top-level page or null if there is
185 | * no certificate (the site is not secure).
186 | *
187 | * @return the SSL certificate for the main top-level page
188 | */
189 | public SslCertificate getCertificate() {
190 | return awContents_.getCertificate();
191 | }
192 |
193 | /**
194 | * Stores HTTP authentication credentials for a given host and realm. This
195 | * method is intended to be used with
196 | * {@link ChromeViewClient#onReceivedHttpAuthRequest(ChromeView, ChromeHttpAuthHandler, String, String)}
197 | *
198 | * @param host the host to which the credentials apply
199 | * @param realm the realm to which the credentials apply
200 | * @param username the username
201 | * @param password the password
202 | * @see getHttpAuthUsernamePassword
203 | * @see android.webkit.WebViewDatabase#hasHttpAuthUsernamePassword()
204 | * @see android.webkit.WebViewDatabase#clearHttpAuthUsernamePassword()
205 | */
206 | public void setHttpAuthUsernamePassword(String host, String realm,
207 | String username, String password) {
208 | awContents_.setHttpAuthUsernamePassword(host, realm, username, password);
209 | }
210 |
211 | /**
212 | * Retrieves HTTP authentication credentials for a given host and realm.
213 | * This method is intended to be used with
214 | * {@link ChromeViewClient#onReceivedHttpAuthRequest(ChromeView, ChromeHttpAuthHandler, String, String)}.
215 | *
216 | * @param host the host to which the credentials apply
217 | * @param realm the realm to which the credentials apply
218 | * @return the credentials as a String array, if found. The first element
219 | * is the username and the second element is the password. Null if no
220 | * credentials are found.
221 | * @see setHttpAuthUsernamePassword
222 | * @see android.webkit.WebViewDatabase#hasHttpAuthUsernamePassword()
223 | * @see android.webkit.WebViewDatabase#clearHttpAuthUsernamePassword()
224 | */
225 | public String[] getHttpAuthUsernamePassword(String host, String realm) {
226 | return awContents_.getHttpAuthUsernamePassword(host, realm);
227 | }
228 |
229 | /**
230 | * Saves the state of this WebView used in
231 | * {@link android.app.Activity#onSaveInstanceState}. Please note that this
232 | * method no longer stores the display data for this WebView. The previous
233 | * behavior could potentially leak files if {@link #restoreState} was never
234 | * called.
235 | *
236 | * @param outState the Bundle to store this WebView's state
237 | * @return false if saveState fails
238 | */
239 | public boolean saveState(Bundle outState) {
240 | return awContents_.saveState(outState);
241 | }
242 |
243 | /**
244 | * Restores the state of this WebView from the given Bundle. This method is
245 | * intended for use in {@link android.app.Activity#onRestoreInstanceState}
246 | * and should be called to restore the state of this WebView. If
247 | * it is called after this WebView has had a chance to build state (load
248 | * pages, create a back/forward list, etc.) there may be undesirable
249 | * side-effects. Please note that this method no longer restores the
250 | * display data for this WebView.
251 | *
252 | * @param inState the incoming Bundle of state
253 | * @return false if restoreState failed
254 | */
255 | public boolean restoreState(Bundle inState) {
256 | return awContents_.restoreState(inState);
257 | }
258 |
259 | /**
260 | * Loads the given URL with the specified additional HTTP headers.
261 | *
262 | * @param url the URL of the resource to load
263 | * @param additionalHttpHeaders the additional headers to be used in the
264 | * HTTP request for this URL, specified as a map from name to
265 | * value. Note that if this map contains any of the headers
266 | * that are set by default by this WebView, such as those
267 | * controlling caching, accept types or the User-Agent, their
268 | * values may be overriden by this WebView's defaults.
269 | */
270 | public void loadUrl(String url, Map
300 | * Note that JavaScript's same origin policy means that script running in a
301 | * page loaded using this method will be unable to access content loaded
302 | * using any scheme other than 'data', including 'http(s)'. To avoid this
303 | * restriction, use {@link
304 | * #loadDataWithBaseURL(String,String,String,String,String)
305 | * loadDataWithBaseURL()} with an appropriate base URL.
306 | *
307 | * The encoding parameter specifies whether the data is base64 or URL
308 | * encoded. If the data is base64 encoded, the value of the encoding
309 | * parameter must be 'base64'. For all other values of the parameter,
310 | * including null, it is assumed that the data uses ASCII encoding for
311 | * octets inside the range of safe URL characters and use the standard %xx
312 | * hex encoding of URLs for octets outside that range. For example, '#',
313 | * '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
314 | *
315 | * The 'data' scheme URL formed by this method uses the default US-ASCII
316 | * charset. If you need need to set a different charset, you should form a
317 | * 'data' scheme URL which explicitly specifies a charset parameter in the
318 | * mediatype portion of the URL and call {@link #loadUrl(String)} instead.
319 | * Note that the charset obtained from the mediatype portion of a data URL
320 | * always overrides that specified in the HTML or XML document itself.
321 | *
322 | * @param data a String of data in the given encoding
323 | * @param mimeType the MIME type of the data, e.g. 'text/html'
324 | * @param encoding the encoding of the data
325 | */
326 | public void loadData(String data, String mimeType, String encoding) {
327 | LoadUrlParams loadUrlParams = LoadUrlParams.createLoadDataParams(data,
328 | mimeType, encoding.equals("base64"));
329 | awContents_.loadUrl(loadUrlParams);
330 | }
331 |
332 | /**
333 | * Loads the given data into this WebView, using baseUrl as the base URL for
334 | * the content. The base URL is used both to resolve relative URLs and when
335 | * applying JavaScript's same origin policy. The historyUrl is used for the
336 | * history entry.
337 | *
338 | * Note that content specified in this way can access local device files
339 | * (via 'file' scheme URLs) only if baseUrl specifies a scheme other than
340 | * 'http', 'https', 'ftp', 'ftps', 'about' or 'javascript'.
341 | *
342 | * If the base URL uses the data scheme, this method is equivalent to
343 | * calling {@link #loadData(String,String,String) loadData()} and the
344 | * historyUrl is ignored.
345 | *
346 | * @param baseUrl the URL to use as the page's base URL. If null defaults to
347 | * 'about:blank'.
348 | * @param data a String of data in the given encoding
349 | * @param mimeType the MIMEType of the data, e.g. 'text/html'. If null,
350 | * defaults to 'text/html'.
351 | * @param encoding the encoding of the data
352 | * @param historyUrl the URL to use as the history entry. If null defaults
353 | * to 'about:blank'.
354 | */
355 | public void loadDataWithBaseURL(String baseUrl, String data,
356 | String mimeType, String encoding, String historyUrl) {
357 | LoadUrlParams loadUrlParams =
358 | LoadUrlParams.createLoadDataParamsWithBaseUrl(data, mimeType,
359 | encoding.equals("base64"), baseUrl, historyUrl);
360 | awContents_.loadUrl(loadUrlParams);
361 | }
362 |
363 | /**
364 | * Saves the current view as a web archive.
365 | *
366 | * @param filename the filename where the archive should be placed
367 | */
368 | public void saveWebArchive(String filename) {
369 | ValueCallback
496 | * Note that due to internal changes, for API levels between
497 | * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and
498 | * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} inclusive, the
499 | * picture does not include fixed position elements or scrollable divs.
500 | *
501 | * @return a picture that captures the current contents of this WebView
502 | */
503 | public Picture capturePicture() {
504 | return awContents_.capturePicture();
505 | }
506 |
507 | /**
508 | * Sets the initial scale for this WebView. 0 means default. If
509 | * {@link WebSettings#getUseWideViewPort()} is true, it zooms out all the
510 | * way. Otherwise it starts with 100%. If initial scale is greater than 0,
511 | * WebView starts with this value as initial scale.
512 | * Please note that unlike the scale properties in the viewport meta tag,
513 | * this method doesn't take the screen density into account.
514 | *
515 | * @param scaleInPercent the initial scale in percent
516 | */
517 | public void setInitialScale(int scaleInPercent) {
518 | // TODO(pwnall): seems useful
519 | }
520 |
521 | /**
522 | * Invokes the graphical zoom picker widget for this WebView. This will
523 | * result in the zoom widget appearing on the screen to control the zoom
524 | * level of this WebView.
525 | */
526 | public void invokeZoomPicker() {
527 | awContents_.invokeZoomPicker();
528 | }
529 |
530 | /**
531 | * Requests the anchor or image element URL at the last tapped point.
532 | * If hrefMsg is null, this method returns immediately and does not
533 | * dispatch hrefMsg to its target. If the tapped point hits an image,
534 | * an anchor, or an image in an anchor, the message associates
535 | * strings in named keys in its data. The value paired with the key
536 | * may be an empty string.
537 | *
538 | * @param hrefMsg the message to be dispatched with the result of the
539 | * request. The message data contains three keys. "url"
540 | * returns the anchor's href attribute. "title" returns the
541 | * anchor's text. "src" returns the image's src attribute.
542 | */
543 | public void requestFocusNodeHref(Message hrefMsg) {
544 | awContents_.requestFocusNodeHref(hrefMsg);
545 | }
546 |
547 | /**
548 | * Requests the URL of the image last touched by the user. msg will be sent
549 | * to its target with a String representing the URL as its object.
550 | *
551 | * @param msg the message to be dispatched with the result of the request
552 | * as the data member with "url" as key. The result can be null.
553 | */
554 | public void requestImageRef(Message msg) {
555 | awContents_.requestImageRef(msg);
556 | }
557 |
558 | /**
559 | * Gets the URL for the current page. This is not always the same as the URL
560 | * passed to WebViewClient.onPageStarted because although the load for
561 | * that URL has begun, the current page may not have changed.
562 | *
563 | * @return the URL for the current page
564 | */
565 | public String getUrl() {
566 | return awContents_.getUrl();
567 | }
568 |
569 | /**
570 | * Gets the original URL for the current page. This is not always the same
571 | * as the URL passed to WebViewClient.onPageStarted because although the
572 | * load for that URL has begun, the current page may not have changed.
573 | * Also, there may have been redirects resulting in a different URL to that
574 | * originally requested.
575 | *
576 | * @return the URL that was originally requested for the current page
577 | */
578 | public String getOriginalUrl() {
579 | return awContents_.getOriginalUrl();
580 | }
581 |
582 | /**
583 | * Gets the title for the current page. This is the title of the current page
584 | * until WebViewClient.onReceivedTitle is called.
585 | *
586 | * @return the title for the current page
587 | */
588 | public String getTitle() {
589 | return awContents_.getTitle();
590 | }
591 |
592 | /**
593 | * Gets the favicon for the current page. This is the favicon of the current
594 | * page until WebViewClient.onReceivedIcon is called.
595 | *
596 | * @return the favicon for the current page
597 | */
598 | public Bitmap getFavicon() {
599 | return awContents_.getFavicon();
600 | }
601 |
602 | /**
603 | * Gets the height of the HTML content.
604 | *
605 | * @return the height of the HTML content
606 | */
607 | public int getContentHeight() {
608 | return awContents_.getContentHeightCss();
609 | }
610 |
611 | /**
612 | * Gets the width of the HTML content.
613 | *
614 | * @return the width of the HTML content
615 | * @hide
616 | */
617 | public int getContentWidth() {
618 | return awContents_.getContentWidthCss();
619 | }
620 |
621 | /**
622 | * Pauses all layout, parsing, and JavaScript timers for all WebViews. This
623 | * is a global requests, not restricted to just this WebView. This can be
624 | * useful if the application has been paused.
625 | */
626 | public void pauseTimers() {
627 | awContents_.pauseTimers();
628 | }
629 |
630 | /**
631 | * Resumes all layout, parsing, and JavaScript timers for all WebViews.
632 | * This will resume dispatching all timers.
633 | */
634 | public void resumeTimers() {
635 | awContents_.resumeTimers();
636 | }
637 |
638 | /**
639 | * Pauses any extra processing associated with this WebView and its
640 | * associated DOM, plugins, JavaScript etc. For example, if this WebView is
641 | * taken offscreen, this could be called to reduce unnecessary CPU or
642 | * network traffic. When this WebView is again "active", call onResume().
643 | * Note that this differs from pauseTimers(), which affects all WebViews.
644 | */
645 | public void onPause() {
646 | awContents_.onPause();
647 | }
648 |
649 | /**
650 | * Resumes a WebView after a previous call to onPause().
651 | */
652 | public void onResume() {
653 | awContents_.onResume();
654 | }
655 |
656 | /**
657 | * Gets whether this WebView is paused, meaning onPause() was called.
658 | * Calling onResume() sets the paused state back to false.
659 | *
660 | * @hide
661 | */
662 | public boolean isPaused() {
663 | return awContents_.isPaused();
664 | }
665 |
666 | /**
667 | * Clears the resource cache. Note that the cache is per-application, so
668 | * this will clear the cache for all WebViews used.
669 | *
670 | * @param includeDiskFiles if false, only the RAM cache is cleared
671 | */
672 | public void clearCache(boolean includeDiskFiles) {
673 | awContents_.clearCache(includeDiskFiles);
674 | }
675 |
676 | /**
677 | * Tells this WebView to clear its internal back/forward list.
678 | */
679 | public void clearHistory() {
680 | awContents_.clearHistory();
681 | }
682 |
683 | /**
684 | * Clears the SSL preferences table stored in response to proceeding with
685 | * SSL certificate errors.
686 | */
687 | public void clearSslPreferences() {
688 | awContents_.clearSslPreferences();
689 | }
690 |
691 | /**
692 | * Highlights and scrolls to the next match found by
693 | * {@link #findAllAsync}, wrapping around page boundaries as necessary.
694 | * Notifies any registered {@link FindListener}. If {@link #findAllAsync(String)}
695 | * has not been called yet, or if {@link #clearMatches} has been called since the
696 | * last find operation, this function does nothing.
697 | *
698 | * @param forward the direction to search
699 | * @see #setFindListener
700 | */
701 | public void findNext(boolean forward) {
702 | awContents_.findNext(forward);
703 | }
704 |
705 | /**
706 | * Finds all instances of find on the page and highlights them,
707 | * asynchronously. Notifies any registered {@link FindListener}.
708 | * Successive calls to this will cancel any pending searches.
709 | *
710 | * @param find the string to find.
711 | * @see #setFindListener
712 | */
713 | public void findAllAsync(String find) {
714 | awContents_.findAllAsync(find);
715 | }
716 |
717 | /**
718 | * Starts an ActionMode for finding text in this WebView. Only works if this
719 | * WebView is attached to the view system.
720 | *
721 | * @param text if non-null, will be the initial text to search for.
722 | * Otherwise, the last String searched for in this WebView will
723 | * be used to start.
724 | * @param showIme if true, show the IME, assuming the user will begin typing.
725 | * If false and text is non-null, perform a find all.
726 | * @return true if the find dialog is shown, false otherwise
727 | */
728 | public boolean showFindDialog(String text, boolean showIme) {
729 | // TODO(pwnall): seems useful
730 | return false;
731 | }
732 |
733 | /**
734 | * Clears the highlighting surrounding text matches created by
735 | * {@link #findAllAsync}.
736 | */
737 | public void clearMatches() {
738 | awContents_.clearMatches();
739 | }
740 |
741 | /**
742 | * Queries the document to see if it contains any image references. The
743 | * message object will be dispatched with arg1 being set to 1 if images
744 | * were found and 0 if the document does not reference any images.
745 | *
746 | * @param response the message that will be dispatched with the result
747 | */
748 | public void documentHasImages(Message response) {
749 | awContents_.documentHasImages(response);
750 | }
751 |
752 | /**
753 | * Injects the supplied Java object into this WebView. The object is
754 | * injected into the JavaScript context of the main frame, using the
755 | * supplied name. This allows the Java object's methods to be
756 | * accessed from JavaScript. Only public methods that are annotated with
757 | * {@link us.costan.chrome.ChromeJavascriptInterface} can be accessed from
758 | * JavaScript.
759 | * Note that injected objects will not
760 | * appear in JavaScript until the page is next (re)loaded. For example:
761 | *
770 | * IMPORTANT:
771 | *
762 | * class JsObject {
763 | * {@literal @}ChromeJavascriptInterface
764 | * public String toString() { return "injectedObject"; }
765 | * }
766 | * webView.addJavascriptInterface(new JsObject(), "injectedObject");
767 | * webView.loadData("
769 | *
772 | *
783 | *
784 | * @param object the Java object to inject into this WebView's JavaScript
785 | * context. Null values are ignored.
786 | * @param name the name used to expose the object in JavaScript
787 | */
788 | public void addJavascriptInterface(Object object, String name) {
789 | awContents_.addPossiblyUnsafeJavascriptInterface(object, name,
790 | ChromeJavascriptInterface.class);
791 | }
792 |
793 | /**
794 | * Removes a previously injected Java object from this WebView. Note that
795 | * the removal will not be reflected in JavaScript until the page is next
796 | * (re)loaded. See {@link #addJavascriptInterface}.
797 | *
798 | * @param name the name used to expose the object in JavaScript
799 | */
800 | public void removeJavascriptInterface(String name) {
801 | awContents_.removeJavascriptInterface(name);
802 | }
803 |
804 | /**
805 | * Gets the ChromeSettings object used to control the settings for this
806 | * ChromeView.
807 | *
808 | * @return a ChromeSettings object that can be used to control this
809 | * ChromeView's settings
810 | */
811 | public ChromeSettings getSettings() {
812 | return new ChromeSettingsProxy(awContents_);
813 | }
814 |
815 | public void flingScroll(int vx, int vy) {
816 | awContents_.flingScroll(vx, vy);
817 | }
818 |
819 | /**
820 | * Performs zoom in in this WebView.
821 | *
822 | * @return true if zoom in succeeds, false if no zoom changes
823 | */
824 | public boolean zoomIn() {
825 | return awContents_.zoomIn();
826 | }
827 |
828 | /**
829 | * Performs zoom out in this WebView.
830 | *
831 | * @return true if zoom out succeeds, false if no zoom changes
832 | */
833 | public boolean zoomOut() {
834 | return awContents_.zoomOut();
835 | }
836 |
837 |
838 | //// Methods outside WebView.
839 |
840 | /**
841 | * Sets up the Chromium libraries backing ChromeView.
842 | *
843 | * This should be called from {@link android.app.Application#onCreate()}.
844 | *
845 | * @param context Android context for the application using ChromeView
846 | */
847 | public static void initialize(Context context) {
848 | ChromeInitializer.initialize(context);
849 | }
850 |
851 | /**
852 | * The object that implements the WebView API.
853 | */
854 | public ContentViewCore getContentViewCore() {
855 | return contentViewCore_;
856 | }
857 |
858 | //// Forward a bunch of calls to the Chromium view.
859 | //// Lifted from chromium/src/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView
860 |
861 | public void destroy() {
862 | awContents_.destroy();
863 | }
864 |
865 | @SuppressLint("WrongCall")
866 | @Override
867 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
868 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
869 | if (awContents_ != null) {
870 | awContents_.onMeasure(widthMeasureSpec, heightMeasureSpec);
871 | } else {
872 | }
873 | }
874 | @Override
875 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
876 | super.onSizeChanged(w, h, oldw, oldh);
877 | if (awContents_ != null) {
878 | awContents_.onSizeChanged(w, h, oldw, oldh);
879 | }
880 | }
881 | @Override
882 | protected void onAttachedToWindow() {
883 | super.onAttachedToWindow();
884 | if (awContents_ != null) {
885 | awContents_.onAttachedToWindow();
886 | }
887 | }
888 | @Override
889 | protected void onConfigurationChanged(Configuration newConfig) {
890 | if (awContents_ != null) {
891 | awContents_.onConfigurationChanged(newConfig);
892 | } else {
893 | super.onConfigurationChanged(newConfig);
894 | }
895 | }
896 | @Override
897 | protected void onDetachedFromWindow() {
898 | super.onDetachedFromWindow();
899 | if (awContents_ != null) {
900 | awContents_.onDetachedFromWindow();
901 | }
902 | }
903 | @SuppressLint("WrongCall")
904 | @Override
905 | protected void onDraw(Canvas canvas) {
906 | super.onDraw(canvas);
907 | if (awContents_ != null) {
908 | awContents_.onDraw(canvas);
909 | }
910 | }
911 | @Override
912 | protected void onFocusChanged(boolean gainFocus, int direction,
913 | Rect previouslyFocusedRect) {
914 | super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
915 | if (awContents_ != null) {
916 | awContents_.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
917 | }
918 | }
919 | @Override
920 | public boolean onTouchEvent(MotionEvent event) {
921 | if (awContents_ != null) {
922 | return awContents_.onTouchEvent(event);
923 | } else {
924 | return super.onTouchEvent(event);
925 | }
926 | }
927 | @Override
928 | protected void onVisibilityChanged(View changedView, int visibility) {
929 | super.onVisibilityChanged(changedView, visibility);
930 | if (awContents_ != null) {
931 | awContents_.onVisibilityChanged(changedView, visibility);
932 | }
933 | }
934 | @Override
935 | protected void onWindowVisibilityChanged(int visibility) {
936 | super.onWindowVisibilityChanged(visibility);
937 | if (awContents_ != null) {
938 | awContents_.onWindowVisibilityChanged(visibility);
939 | }
940 | }
941 |
942 | //// Forward a bunch more calls to the Chromium view.
943 | //// Lifted from
944 | //// platform/frameworks/base ./core/java/android/webkit/WebKit.java
945 |
946 | @Override
947 | protected int computeHorizontalScrollRange() {
948 | if (awContents_ != null) {
949 | return awContents_.computeHorizontalScrollRange();
950 | } else {
951 | return super.computeHorizontalScrollRange();
952 | }
953 | }
954 | @Override
955 | protected int computeHorizontalScrollOffset() {
956 | if (awContents_ != null) {
957 | return awContents_.computeHorizontalScrollOffset();
958 | } else {
959 | return super.computeHorizontalScrollOffset();
960 | }
961 | }
962 | @Override
963 | protected int computeVerticalScrollRange() {
964 | if (awContents_ != null) {
965 | return awContents_.computeVerticalScrollRange();
966 | } else {
967 | return super.computeVerticalScrollRange();
968 | }
969 | }
970 | @Override
971 | protected int computeVerticalScrollOffset() {
972 | if (awContents_ != null) {
973 | return awContents_.computeVerticalScrollOffset();
974 | } else {
975 | return super.computeVerticalScrollOffset();
976 | }
977 | }
978 | @Override
979 | protected int computeVerticalScrollExtent() {
980 | if (awContents_ != null) {
981 | return awContents_.computeVerticalScrollExtent();
982 | } else {
983 | return super.computeVerticalScrollExtent();
984 | }
985 | }
986 | @Override
987 | public boolean onHoverEvent(MotionEvent event) {
988 | if (awContents_ != null) {
989 | return awContents_.onHoverEvent(event);
990 | } else {
991 | return super.onHoverEvent(event);
992 | }
993 | }
994 | @Override
995 | public boolean onGenericMotionEvent(MotionEvent event) {
996 | if (awContents_ != null) {
997 | return awContents_.onGenericMotionEvent(event);
998 | } else {
999 | return super.onGenericMotionEvent(event);
1000 | }
1001 | }
1002 | @Override
1003 | public boolean onKeyUp(int keyCode, KeyEvent event) {
1004 | if (awContents_ != null) {
1005 | return awContents_.onKeyUp(keyCode, event);
1006 | } else {
1007 | return super.onKeyUp(keyCode, event);
1008 | }
1009 | }
1010 | @Override
1011 | public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
1012 | super.onInitializeAccessibilityNodeInfo(info);
1013 | if (awContents_ != null) {
1014 | info.setClassName(ChromeView.class.getName());
1015 | awContents_.onInitializeAccessibilityNodeInfo(info);
1016 | }
1017 | }
1018 | @Override
1019 | public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
1020 | super.onInitializeAccessibilityEvent(event);
1021 | if (awContents_ != null) {
1022 | event.setClassName(ChromeView.class.getName());
1023 | awContents_.onInitializeAccessibilityEvent(event);
1024 | }
1025 | }
1026 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
1027 | @Override
1028 | public boolean performAccessibilityAction(int action, Bundle arguments) {
1029 | if (awContents_ != null) {
1030 | // Lifted from content.browser.JellyBeanContentView
1031 | if (contentViewCore_.supportsAccessibilityAction(action)) {
1032 | return awContents_.performAccessibilityAction(action, arguments);
1033 | }
1034 | }
1035 | return super.performAccessibilityAction(action, arguments);
1036 | }
1037 | @Override
1038 | public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
1039 | if (awContents_ != null) {
1040 | return awContents_.onCreateInputConnection(outAttrs);
1041 | } else {
1042 | return super.onCreateInputConnection(outAttrs);
1043 | }
1044 | }
1045 | @Override
1046 | public void onWindowFocusChanged(boolean hasWindowFocus) {
1047 | if (awContents_ != null) {
1048 | awContents_.onWindowFocusChanged(hasWindowFocus);
1049 | }
1050 | super.onWindowFocusChanged(hasWindowFocus);
1051 | }
1052 | @Override
1053 | public boolean dispatchKeyEvent(KeyEvent event) {
1054 | if (awContents_ != null) {
1055 | return awContents_.dispatchKeyEvent(event);
1056 | } else {
1057 | return super.dispatchKeyEvent(event);
1058 | }
1059 | }
1060 | @Override
1061 | public boolean dispatchKeyEventPreIme(KeyEvent event) {
1062 | if (awContents_ != null) {
1063 | return contentViewCore_.dispatchKeyEventPreIme(event);
1064 | } else {
1065 | return super.dispatchKeyEventPreIme(event);
1066 | }
1067 | }
1068 |
1069 | //// Forward calls that ContentViewCore responds to.
1070 |
1071 | @Override
1072 | public boolean onCheckIsTextEditor() {
1073 | if (awContents_ != null) {
1074 | return contentViewCore_.onCheckIsTextEditor();
1075 | } else {
1076 | return super.onCheckIsTextEditor();
1077 | }
1078 | }
1079 | @Override
1080 | public void scrollTo(int x, int y) {
1081 | super.scrollTo(x, y);
1082 | if (awContents_ != null) {
1083 | contentViewCore_.scrollTo(x, y);
1084 | }
1085 | }
1086 | @Override
1087 | public void scrollBy(int x, int y) {
1088 | super.scrollBy(x, y);
1089 | if (awContents_ != null) {
1090 | contentViewCore_.scrollBy(x, y);
1091 | }
1092 | }
1093 | @Override
1094 | protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
1095 | if (awContents_ != null) {
1096 | return contentViewCore_.awakenScrollBars(startDelay, invalidate);
1097 | } else {
1098 | return super.awakenScrollBars(startDelay, invalidate);
1099 | }
1100 | }
1101 |
1102 | /** Glue that passes calls from the Chromium view to its container (us). */
1103 | private class ChromeInternalAcccessAdapter implements AwContents.InternalAccessDelegate {
1104 | //// Lifted from chromium/src/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView
1105 | @Override
1106 | public boolean drawChild(Canvas canvas, View child, long drawingTime) {
1107 | return ChromeView.this.drawChild(canvas, child, drawingTime);
1108 | }
1109 | @Override
1110 | public boolean super_onKeyUp(int keyCode, KeyEvent event) {
1111 | return ChromeView.super.onKeyUp(keyCode, event);
1112 | }
1113 | @Override
1114 | public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
1115 | return ChromeView.super.dispatchKeyEventPreIme(event);
1116 | }
1117 | @Override
1118 | public boolean super_dispatchKeyEvent(KeyEvent event) {
1119 | return ChromeView.super.dispatchKeyEvent(event);
1120 | }
1121 | @Override
1122 | public boolean super_onGenericMotionEvent(MotionEvent event) {
1123 | return ChromeView.super.onGenericMotionEvent(event);
1124 | }
1125 | @Override
1126 | public void super_onConfigurationChanged(Configuration newConfig) {
1127 | ChromeView.super.onConfigurationChanged(newConfig);
1128 | }
1129 | @Override
1130 | public void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix) {
1131 | ChromeView.this.onScrollChanged(lPix, tPix, oldlPix, oldtPix);
1132 | }
1133 | @Override
1134 | public boolean awakenScrollBars() {
1135 | return ChromeView.this.awakenScrollBars();
1136 | }
1137 | @Override
1138 | public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
1139 | return ChromeView.super.awakenScrollBars(startDelay, invalidate);
1140 | }
1141 | @Override
1142 | public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
1143 | ChromeView.this.setMeasuredDimension(measuredWidth, measuredHeight);
1144 | }
1145 | @Override
1146 | public boolean requestDrawGL(Canvas canvas) {
1147 | if (canvas != null) {
1148 | if (canvas.isHardwareAccelerated()) {
1149 | // TODO(pwnall): figure out what AwContents wants from us, and do it;
1150 | // most likely something to do with
1151 | // AwContents.getAwDrawGLFunction()
1152 | return false;
1153 | } else {
1154 | return false;
1155 | }
1156 | } else {
1157 | if (ChromeView.this.isHardwareAccelerated()) {
1158 | // TODO(pwnall): figure out what AwContents wants from us, and do it;
1159 | // most likely something to do with
1160 | // AwContents.getAwDrawGLFunction()
1161 | return false;
1162 | } else {
1163 | return false;
1164 | }
1165 | }
1166 | }
1167 | @Override
1168 | public void overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
1169 | int scrollRangeX, int scrollRangeY, int maxOverScrollX,
1170 | int maxOverScrollY, boolean isTouchEvent) {
1171 | ChromeView.this.overScrollBy(deltaX, deltaY, scrollX, scrollY,
1172 | scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,
1173 | isTouchEvent);
1174 | }
1175 | @Override
1176 | public void super_scrollTo(int scrollX, int scrollY) {
1177 | ChromeView.super.scrollTo(scrollX, scrollY);
1178 | }
1179 | @Override
1180 | public int super_getScrollBarStyle() {
1181 | return ChromeView.super.getScrollBarStyle();
1182 | }
1183 | }
1184 | }
1185 |
--------------------------------------------------------------------------------
/src/us/costan/chrome/ChromeViewClient.java:
--------------------------------------------------------------------------------
1 | package us.costan.chrome;
2 |
3 | import android.graphics.Bitmap;
4 | import android.net.http.SslError;
5 | import android.os.Message;
6 | import android.view.KeyEvent;
7 | import android.webkit.WebResourceResponse;
8 |
9 | /**
10 | * ChromeView equivalent of WebViewClient.
11 | *
12 | * @see android.webkit.WebViewClient
13 | */
14 | public class ChromeViewClient {
15 | // Mostly mirrors
16 | // platform/frameworks/base/ ./core/java/android/webkit/WebViewClient
17 |
18 | /**
19 | * Give the host application a chance to take over the control when a new
20 | * url is about to be loaded in the current ChromeView. If ChromeViewClient is not
21 | * provided, by default ChromeView will ask Activity Manager to choose the
22 | * proper handler for the url. If ChromeViewClient is provided, return true
23 | * means the host application handles the url, while return false means the
24 | * current ChromeView handles the url.
25 | *
26 | * @param view The ChromeView that is initiating the callback.
27 | * @param url The url to be loaded.
28 | * @return True if the host application wants to leave the current ChromeView
29 | * and handle the url itself, otherwise return false.
30 | */
31 | public boolean shouldOverrideUrlLoading(ChromeView view, String url) {
32 | return false;
33 | }
34 |
35 | /**
36 | * Notify the host application that a page has started loading. This method
37 | * is called once for each main frame load so a page with iframes or
38 | * framesets will call onPageStarted one time for the main frame. This also
39 | * means that onPageStarted will not be called when the contents of an
40 | * embedded frame changes, i.e. clicking a link whose target is an iframe.
41 | *
42 | * @param view The ChromeView that is initiating the callback.
43 | * @param url The url to be loaded.
44 | * @param favicon The favicon for this page if it already exists in the
45 | * database.
46 | */
47 | public void onPageStarted(ChromeView view, String url, Bitmap favicon) {
48 | }
49 |
50 | /**
51 | * Notify the host application that a page has finished loading. This method
52 | * is called only for main frame. When onPageFinished() is called, the
53 | * rendering picture may not be updated yet. To get the notification for the
54 | * new Picture, use {@link ChromeView.PictureListener#onNewPicture}.
55 | *
56 | * @param view The ChromeView that is initiating the callback.
57 | * @param url The url of the page.
58 | */
59 | public void onPageFinished(ChromeView view, String url) {
60 | }
61 |
62 | /**
63 | * Notify the host application that the ChromeView will load the resource
64 | * specified by the given url.
65 | *
66 | * @param view The ChromeView that is initiating the callback.
67 | * @param url The url of the resource the ChromeView will load.
68 | */
69 | public void onLoadResource(ChromeView view, String url) {
70 | }
71 |
72 | /**
73 | * Notify the host application of a resource request and allow the
74 | * application to return the data. If the return value is null, the ChromeView
75 | * will continue to load the resource as usual. Otherwise, the return
76 | * response and data will be used. NOTE: This method is called by the
77 | * network thread so clients should exercise caution when accessing private
78 | * data.
79 | *
80 | * @param view The {@link us.costan.chrome.ChromeView} that is requesting the
81 | * resource.
82 | * @param url The raw url of the resource.
83 | * @return A {@link android.webkit.WebResourceResponse} containing the
84 | * response information or null if the ChromeView should load the
85 | * resource itself.
86 | */
87 | public WebResourceResponse shouldInterceptRequest(ChromeView view,
88 | String url) {
89 | return null;
90 | }
91 |
92 | // These ints must match up to the hidden values in EventHandler.
93 | /** Generic error */
94 | public static final int ERROR_UNKNOWN = -1;
95 | /** Server or proxy hostname lookup failed */
96 | public static final int ERROR_HOST_LOOKUP = -2;
97 | /** Unsupported authentication scheme (not basic or digest) */
98 | public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
99 | /** User authentication failed on server */
100 | public static final int ERROR_AUTHENTICATION = -4;
101 | /** User authentication failed on proxy */
102 | public static final int ERROR_PROXY_AUTHENTICATION = -5;
103 | /** Failed to connect to the server */
104 | public static final int ERROR_CONNECT = -6;
105 | /** Failed to read or write to the server */
106 | public static final int ERROR_IO = -7;
107 | /** Connection timed out */
108 | public static final int ERROR_TIMEOUT = -8;
109 | /** Too many redirects */
110 | public static final int ERROR_REDIRECT_LOOP = -9;
111 | /** Unsupported URI scheme */
112 | public static final int ERROR_UNSUPPORTED_SCHEME = -10;
113 | /** Failed to perform SSL handshake */
114 | public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
115 | /** Malformed URL */
116 | public static final int ERROR_BAD_URL = -12;
117 | /** Generic file error */
118 | public static final int ERROR_FILE = -13;
119 | /** File not found */
120 | public static final int ERROR_FILE_NOT_FOUND = -14;
121 | /** Too many requests during this load */
122 | public static final int ERROR_TOO_MANY_REQUESTS = -15;
123 |
124 | /**
125 | * Report an error to the host application. These errors are unrecoverable
126 | * (i.e. the main resource is unavailable). The errorCode parameter
127 | * corresponds to one of the ERROR_* constants.
128 | * @param view The ChromeView that is initiating the callback.
129 | * @param errorCode The error code corresponding to an ERROR_* value.
130 | * @param description A String describing the error.
131 | * @param failingUrl The url that failed to load.
132 | */
133 | public void onReceivedError(ChromeView view, int errorCode,
134 | String description, String failingUrl) {
135 | }
136 |
137 | /**
138 | * As the host application if the browser should resend data as the
139 | * requested page was a result of a POST. The default is to not resend the
140 | * data.
141 | *
142 | * @param view The ChromeView that is initiating the callback.
143 | * @param dontResend The message to send if the browser should not resend
144 | * @param resend The message to send if the browser should resend data
145 | */
146 | public void onFormResubmission(ChromeView view, Message dontResend,
147 | Message resend) {
148 | dontResend.sendToTarget();
149 | }
150 |
151 | /**
152 | * Notify the host application to update its visited links database.
153 | *
154 | * @param view The ChromeView that is initiating the callback.
155 | * @param url The url being visited.
156 | * @param isReload True if this url is being reloaded.
157 | */
158 | public void doUpdateVisitedHistory(ChromeView view, String url,
159 | boolean isReload) {
160 | }
161 |
162 | /**
163 | * Notify the host application that an SSL error occurred while loading a
164 | * resource. The host application must call either handler.cancel() or
165 | * handler.proceed(). Note that the decision may be retained for use in
166 | * response to future SSL errors. The default behavior is to cancel the
167 | * load.
168 | *
169 | * @param view The ChromeView that is initiating the callback.
170 | * @param handler A ChromeSslErrorHandler object that will handle the user's
171 | * response.
172 | * @param error The SSL error object.
173 | */
174 | public void onReceivedSslError(ChromeView view, ChromeSslErrorHandler handler,
175 | SslError error) {
176 | handler.cancel();
177 | }
178 |
179 | /**
180 | * Notify the host application that an SSL error occurred while loading a
181 | * resource, but the ChromeView chose to proceed anyway based on a
182 | * decision retained from a previous response to onReceivedSslError().
183 | * @hide
184 | */
185 | public void onProceededAfterSslError(ChromeView view, SslError error) {
186 | }
187 |
188 | /**
189 | * Notify the host application to handle an authentication request. The
190 | * default behavior is to cancel the request.
191 | *
192 | * @param view The ChromeView that is initiating the callback.
193 | * @param handler The HttpAuthHandler that will handle the user's response.
194 | * @param host The host requiring authentication.
195 | * @param realm A description to help store user credentials for future
196 | * visits.
197 | */
198 | public void onReceivedHttpAuthRequest(ChromeView view,
199 | ChromeHttpAuthHandler handler, String host, String realm) {
200 | handler.cancel();
201 | }
202 |
203 | /**
204 | * Give the host application a chance to handle the key event synchronously.
205 | * e.g. menu shortcut key events need to be filtered this way. If return
206 | * true, ChromeView will not handle the key event. If return false, ChromeView
207 | * will always handle the key event, so none of the super in the view chain
208 | * will see the key event. The default behavior returns false.
209 | *
210 | * @param view The ChromeView that is initiating the callback.
211 | * @param event The key event.
212 | * @return True if the host application wants to handle the key event
213 | * itself, otherwise return false
214 | */
215 | public boolean shouldOverrideKeyEvent(ChromeView view, KeyEvent event) {
216 | return false;
217 | }
218 |
219 | /**
220 | * Notify the host application that a key was not handled by the ChromeView.
221 | * Except system keys, ChromeView always consumes the keys in the normal flow
222 | * or if shouldOverrideKeyEvent returns true. This is called asynchronously
223 | * from where the key is dispatched. It gives the host application a chance
224 | * to handle the unhandled key events.
225 | *
226 | * @param view The ChromeView that is initiating the callback.
227 | * @param event The key event.
228 | */
229 | public void onUnhandledKeyEvent(ChromeView view, KeyEvent event) {
230 | }
231 |
232 | /**
233 | * Notify the host application that the scale applied to the ChromeView has
234 | * changed.
235 | *
236 | * @param view he ChromeView that is initiating the callback.
237 | * @param oldScale The old scale factor
238 | * @param newScale The new scale factor
239 | */
240 | public void onScaleChanged(ChromeView view, float oldScale, float newScale) {
241 | }
242 |
243 | /**
244 | * Notify the host application that a request to automatically log in the
245 | * user has been processed.
246 | * @param view The ChromeView requesting the login.
247 | * @param realm The account realm used to look up accounts.
248 | * @param account An optional account. If not null, the account should be
249 | * checked against accounts on the device. If it is a valid
250 | * account, it should be used to log in the user.
251 | * @param args Authenticator specific arguments used to log in the user.
252 | */
253 | public void onReceivedLoginRequest(ChromeView view, String realm,
254 | String account, String args) {
255 | }
256 | }
257 |
--------------------------------------------------------------------------------
/src/us/costan/chrome/ChromeWebClient.java:
--------------------------------------------------------------------------------
1 | package us.costan.chrome;
2 |
3 | import android.graphics.Bitmap;
4 | import android.net.Uri;
5 | import android.os.Message;
6 | import android.view.View;
7 | import android.webkit.ConsoleMessage;
8 | import android.webkit.GeolocationPermissions;
9 | import android.webkit.JsPromptResult;
10 | import android.webkit.ValueCallback;
11 | import android.webkit.WebChromeClient.CustomViewCallback;
12 | import android.webkit.WebStorage;
13 |
14 | /**
15 | * ChromeView equivalent of WebChromeClient.
16 | *
17 | * @see android.webkit.WebChromeClient
18 | */
19 | public class ChromeWebClient {
20 | // Mostly mirrors
21 | // platform/frameworks/base/ ./core/java/android/webkit/WebChromeClient
22 |
23 | /**
24 | * Tell the host application the current progress of loading a page.
25 | * @param view The ChromeView that initiated the callback.
26 | * @param newProgress Current page loading progress, represented by
27 | * an integer between 0 and 100.
28 | */
29 | public void onProgressChanged(ChromeView view, int newProgress) {}
30 |
31 | /**
32 | * Notify the host application of a change in the document title.
33 | * @param view The ChromeView that initiated the callback.
34 | * @param title A String containing the new title of the document.
35 | */
36 | public void onReceivedTitle(ChromeView view, String title) {}
37 |
38 | /**
39 | * Notify the host application of a new favicon for the current page.
40 | * @param view The ChromeView that initiated the callback.
41 | * @param icon A Bitmap containing the favicon for the current page.
42 | */
43 | public void onReceivedIcon(ChromeView view, Bitmap icon) {}
44 |
45 | /**
46 | * Notify the host application of the url for an apple-touch-icon.
47 | * @param view The ChromeView that initiated the callback.
48 | * @param url The icon url.
49 | * @param precomposed True if the url is for a precomposed touch icon.
50 | */
51 | public void onReceivedTouchIconUrl(ChromeView view, String url,
52 | boolean precomposed) {}
53 |
54 | /**
55 | * Notify the host application that the current page would
56 | * like to show a custom View.
57 | * @param view is the View object to be shown.
58 | * @param callback is the callback to be invoked if and when the view
59 | * is dismissed.
60 | */
61 | public void onShowCustomView(View view, CustomViewCallback callback) {};
62 |
63 | /**
64 | * Notify the host application that the current page would
65 | * like to show a custom View in a particular orientation.
66 | * @param view is the View object to be shown.
67 | * @param requestedOrientation An orientation constant as used in
68 | * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
69 | * @param callback is the callback to be invoked if and when the view
70 | * is dismissed.
71 | */
72 | public void onShowCustomView(View view, int requestedOrientation,
73 | CustomViewCallback callback) {};
74 |
75 | /**
76 | * Notify the host application that the current page would
77 | * like to hide its custom view.
78 | */
79 | public void onHideCustomView() {}
80 |
81 | /**
82 | * Request the host application to create a new window. If the host
83 | * application chooses to honor this request, it should return true from
84 | * this method, create a new ChromeView to host the window, insert it into the
85 | * View system and send the supplied resultMsg message to its target with
86 | * the new ChromeView as an argument. If the host application chooses not to
87 | * honor the request, it should return false from this method. The default
88 | * implementation of this method does nothing and hence returns false.
89 | * @param view The ChromeView from which the request for a new window
90 | * originated.
91 | * @param isDialog True if the new window should be a dialog, rather than
92 | * a full-size window.
93 | * @param isUserGesture True if the request was initiated by a user gesture,
94 | * such as the user clicking a link.
95 | * @param resultMsg The message to send when once a new ChromeView has been
96 | * created. resultMsg.obj is a
97 | * {@link ChromeView.ChromeViewTransport} object. This should be
98 | * used to transport the new ChromeView, by calling
99 | * {@link ChromeView.ChromeViewTransport#setChromeView(ChromeView)
100 | * ChromeView.ChromeViewTransport.setChromeView(ChromeView)}.
101 | * @return This method should return true if the host application will
102 | * create a new window, in which case resultMsg should be sent to
103 | * its target. Otherwise, this method should return false. Returning
104 | * false from this method but also sending resultMsg will result in
105 | * undefined behavior.
106 | */
107 | public boolean onCreateWindow(ChromeView view, boolean isDialog,
108 | boolean isUserGesture, Message resultMsg) {
109 | return false;
110 | }
111 |
112 | /**
113 | * Request display and focus for this ChromeView. This may happen due to
114 | * another ChromeView opening a link in this ChromeView and requesting that this
115 | * ChromeView be displayed.
116 | * @param view The ChromeView that needs to be focused.
117 | */
118 | public void onRequestFocus(ChromeView view) {}
119 |
120 | /**
121 | * Notify the host application to close the given ChromeView and remove it
122 | * from the view system if necessary. At this point, WebCore has stopped
123 | * any loading in this window and has removed any cross-scripting ability
124 | * in javascript.
125 | * @param window The ChromeView that needs to be closed.
126 | */
127 | public void onCloseWindow(ChromeView window) {}
128 |
129 | /**
130 | * Tell the client to display a javascript alert dialog. If the client
131 | * returns true, ChromeView will assume that the client will handle the
132 | * dialog. If the client returns false, it will continue execution.
133 | * @param view The ChromeView that initiated the callback.
134 | * @param url The url of the page requesting the dialog.
135 | * @param message Message to be displayed in the window.
136 | * @param result A JsResult to confirm that the user hit enter.
137 | * @return boolean Whether the client will handle the alert dialog.
138 | */
139 | public boolean onJsAlert(ChromeView view, String url, String message,
140 | ChromeJsResult result) {
141 | return false;
142 | }
143 |
144 | /**
145 | * Tell the client to display a confirm dialog to the user. If the client
146 | * returns true, ChromeView will assume that the client will handle the
147 | * confirm dialog and call the appropriate JsResult method. If the
148 | * client returns false, a default value of false will be returned to
149 | * javascript. The default behavior is to return false.
150 | * @param view The ChromeView that initiated the callback.
151 | * @param url The url of the page requesting the dialog.
152 | * @param message Message to be displayed in the window.
153 | * @param result A JsResult used to send the user's response to
154 | * javascript.
155 | * @return boolean Whether the client will handle the confirm dialog.
156 | */
157 | public boolean onJsConfirm(ChromeView view, String url, String message,
158 | ChromeJsResult result) {
159 | return false;
160 | }
161 |
162 | /**
163 | * Tell the client to display a prompt dialog to the user. If the client
164 | * returns true, ChromeView will assume that the client will handle the
165 | * prompt dialog and call the appropriate JsPromptResult method. If the
166 | * client returns false, a default value of false will be returned to to
167 | * javascript. The default behavior is to return false.
168 | * @param view The ChromeView that initiated the callback.
169 | * @param url The url of the page requesting the dialog.
170 | * @param message Message to be displayed in the window.
171 | * @param defaultValue The default value displayed in the prompt dialog.
172 | * @param result A JsPromptResult used to send the user's reponse to
173 | * javascript.
174 | * @return boolean Whether the client will handle the prompt dialog.
175 | */
176 | public boolean onJsPrompt(ChromeView view, String url, String message,
177 | String defaultValue, JsPromptResult result) {
178 | return false;
179 | }
180 |
181 | /**
182 | * Tell the client to display a dialog to confirm navigation away from the
183 | * current page. This is the result of the onbeforeunload javascript event.
184 | * If the client returns true, ChromeView will assume that the client will
185 | * handle the confirm dialog and call the appropriate JsResult method. If
186 | * the client returns false, a default value of true will be returned to
187 | * javascript to accept navigation away from the current page. The default
188 | * behavior is to return false. Setting the JsResult to true will navigate
189 | * away from the current page, false will cancel the navigation.
190 | * @param view The ChromeView that initiated the callback.
191 | * @param url The url of the page requesting the dialog.
192 | * @param message Message to be displayed in the window.
193 | * @param result A JsResult used to send the user's response to
194 | * javascript.
195 | * @return boolean Whether the client will handle the confirm dialog.
196 | */
197 | public boolean onJsBeforeUnload(ChromeView view, String url, String message,
198 | ChromeJsResult result) {
199 | return false;
200 | }
201 |
202 | /**
203 | * Tell the client that the quota has been exceeded for the Web SQL Database
204 | * API for a particular origin and request a new quota. The client must
205 | * respond by invoking the
206 | * {@link WebStorage.QuotaUpdater#updateQuota(long) updateQuota(long)}
207 | * method of the supplied {@link WebStorage.QuotaUpdater} instance. The
208 | * minimum value that can be set for the new quota is the current quota. The
209 | * default implementation responds with the current quota, so the quota will
210 | * not be increased.
211 | * @param url The URL of the page that triggered the notification
212 | * @param databaseIdentifier The identifier of the database where the quota
213 | * was exceeded.
214 | * @param quota The quota for the origin, in bytes
215 | * @param estimatedDatabaseSize The estimated size of the offending
216 | * database, in bytes
217 | * @param totalQuota The total quota for all origins, in bytes
218 | * @param quotaUpdater An instance of {@link WebStorage.QuotaUpdater} which
219 | * must be used to inform the ChromeView of the new quota.
220 | */
221 | // Note that the callback must always be executed at some point to ensure
222 | // that the sleeping WebCore thread is woken up.
223 | public void onExceededDatabaseQuota(String url, String databaseIdentifier,
224 | long quota, long estimatedDatabaseSize, long totalQuota,
225 | WebStorage.QuotaUpdater quotaUpdater) {
226 | // This default implementation passes the current quota back to WebCore.
227 | // WebCore will interpret this that new quota was declined.
228 | quotaUpdater.updateQuota(quota);
229 | }
230 |
231 | /**
232 | * Tell the client that the quota has been reached for the Application Cache
233 | * API and request a new quota. The client must respond by invoking the
234 | * {@link WebStorage.QuotaUpdater#updateQuota(long) updateQuota(long)}
235 | * method of the supplied {@link WebStorage.QuotaUpdater} instance. The
236 | * minimum value that can be set for the new quota is the current quota. The
237 | * default implementation responds with the current quota, so the quota will
238 | * not be increased.
239 | * @param requiredStorage The amount of storage required by the Application
240 | * Cache operation that triggered this notification,
241 | * in bytes.
242 | * @param quota The quota, in bytes
243 | * @param quotaUpdater An instance of {@link WebStorage.QuotaUpdater} which
244 | * must be used to inform the ChromeView of the new quota.
245 | */
246 | // Note that the callback must always be executed at some point to ensure
247 | // that the sleeping WebCore thread is woken up.
248 | public void onReachedMaxAppCacheSize(long requiredStorage, long quota,
249 | WebStorage.QuotaUpdater quotaUpdater) {
250 | quotaUpdater.updateQuota(quota);
251 | }
252 |
253 | /**
254 | * Notify the host application that web content from the specified origin
255 | * is attempting to use the Geolocation API, but no permission state is
256 | * currently set for that origin. The host application should invoke the
257 | * specified callback with the desired permission state. See
258 | * {@link GeolocationPermissions} for details.
259 | * @param origin The origin of the web content attempting to use the
260 | * Geolocation API.
261 | * @param callback The callback to use to set the permission state for the
262 | * origin.
263 | */
264 | public void onGeolocationPermissionsShowPrompt(String origin,
265 | GeolocationPermissions.Callback callback) {}
266 |
267 | /**
268 | * Notify the host application that a request for Geolocation permissions,
269 | * made with a previous call to
270 | * {@link #onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback) onGeolocationPermissionsShowPrompt()}
271 | * has been canceled. Any related UI should therefore be hidden.
272 | */
273 | public void onGeolocationPermissionsHidePrompt() {}
274 |
275 | /**
276 | * Tell the client that a JavaScript execution timeout has occured. And the
277 | * client may decide whether or not to interrupt the execution. If the
278 | * client returns true, the JavaScript will be interrupted. If the client
279 | * returns false, the execution will continue. Note that in the case of
280 | * continuing execution, the timeout counter will be reset, and the callback
281 | * will continue to occur if the script does not finish at the next check
282 | * point.
283 | * @return boolean Whether the JavaScript execution should be interrupted.
284 | */
285 | public boolean onJsTimeout() {
286 | return true;
287 | }
288 |
289 | /**
290 | * Report a JavaScript error message to the host application. The ChromeClient
291 | * should override this to process the log message as they see fit.
292 | * @param message The error message to report.
293 | * @param lineNumber The line number of the error.
294 | * @param sourceID The name of the source file that caused the error.
295 | * @deprecated Use {@link #onConsoleMessage(ConsoleMessage) onConsoleMessage(ConsoleMessage)}
296 | * instead.
297 | */
298 | @Deprecated
299 | public void onConsoleMessage(String message, int lineNumber, String sourceID) { }
300 |
301 | /**
302 | * Report a JavaScript console message to the host application. The ChromeClient
303 | * should override this to process the log message as they see fit.
304 | * @param consoleMessage Object containing details of the console message.
305 | * @return true if the message is handled by the client.
306 | */
307 | public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
308 | // Call the old version of this function for backwards compatability.
309 | onConsoleMessage(consoleMessage.message(), consoleMessage.lineNumber(),
310 | consoleMessage.sourceId());
311 | return false;
312 | }
313 |
314 | /**
315 | * When not playing, video elements are represented by a 'poster' image. The
316 | * image to use can be specified by the poster attribute of the video tag in
317 | * HTML. If the attribute is absent, then a default poster will be used. This
318 | * method allows the ChromeClient to provide that default image.
319 | *
320 | * @return Bitmap The image to use as a default poster, or null if no such image is
321 | * available.
322 | */
323 | public Bitmap getDefaultVideoPoster() {
324 | return null;
325 | }
326 |
327 | /**
328 | * When the user starts to playback a video element, it may take time for enough
329 | * data to be buffered before the first frames can be rendered. While this buffering
330 | * is taking place, the ChromeClient can use this function to provide a View to be
331 | * displayed. For example, the ChromeClient could show a spinner animation.
332 | *
333 | * @return View The View to be displayed whilst the video is loading.
334 | */
335 | public View getVideoLoadingProgressView() {
336 | return null;
337 | }
338 |
339 | /** Obtains a list of all visited history items, used for link coloring
340 | */
341 | public void getVisitedHistory(ValueCallback