WebViewChromium.java revision a125e0eeade22bc4b7a998e8f0e732c0f965663f
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.webview.chromium; 18 19import android.content.res.Configuration; 20import android.graphics.Bitmap; 21import android.graphics.Canvas; 22import android.graphics.Paint; 23import android.graphics.Picture; 24import android.graphics.Rect; 25import android.graphics.drawable.Drawable; 26import android.net.http.SslCertificate; 27import android.os.Build; 28import android.os.Bundle; 29import android.os.Message; 30import android.util.Base64; 31import android.util.Log; 32import android.view.HardwareCanvas; 33import android.view.KeyEvent; 34import android.view.MotionEvent; 35import android.view.View; 36import android.view.View.MeasureSpec; 37import android.view.ViewGroup; 38import android.view.accessibility.AccessibilityEvent; 39import android.view.accessibility.AccessibilityNodeInfo; 40import android.view.accessibility.AccessibilityNodeProvider; 41import android.view.inputmethod.EditorInfo; 42import android.view.inputmethod.InputConnection; 43import android.webkit.DownloadListener; 44import android.webkit.FindActionModeCallback; 45import android.webkit.JavascriptInterface; 46import android.webkit.ValueCallback; 47import android.webkit.WebBackForwardList; 48import android.webkit.WebChromeClient; 49import android.webkit.WebSettings; 50import android.webkit.WebView; 51import android.webkit.WebViewClient; 52import android.webkit.WebViewProvider; 53 54import org.chromium.android_webview.AwBrowserContext; 55import org.chromium.android_webview.AwContents; 56import org.chromium.base.ThreadUtils; 57import org.chromium.content.browser.LoadUrlParams; 58import org.chromium.net.NetworkChangeNotifier; 59 60import java.io.BufferedWriter; 61import java.io.File; 62import java.lang.annotation.Annotation; 63import java.util.Map; 64 65/** 66 * This class is the delegate to which WebViewProxy forwards all API calls. 67 * 68 * Most of the actual functionality is implemented by AwContents (or ContentViewCore within 69 * it). This class also contains WebView-specific APIs that require the creation of other 70 * adapters (otherwise org.chromium.content would depend on the webview.chromium package) 71 * and a small set of no-op deprecated APIs. 72 */ 73class WebViewChromium implements WebViewProvider, 74 WebViewProvider.ScrollDelegate, WebViewProvider.ViewDelegate { 75 76 private static final String TAG = WebViewChromium.class.getSimpleName(); 77 78 // The WebView that this WebViewChromium is the provider for. 79 WebView mWebView; 80 // Lets us access protected View-derived methods on the WebView instance we're backing. 81 WebView.PrivateAccess mWebViewPrivate; 82 // The client adapter class. 83 private WebViewContentsClientAdapter mContentsClientAdapter; 84 85 // Variables for functionality provided by this adapter --------------------------------------- 86 // WebSettings adapter, lazily initialized in the getter 87 private WebSettings mWebSettings; 88 // The WebView wrapper for ContentViewCore and required browser compontents. 89 private AwContents mAwContents; 90 // Non-null if this webview is using the GL accelerated draw path. 91 private DrawGLFunctor mGLfunctor; 92 93 private AwBrowserContext mBrowserContext; 94 95 private final WebView.HitTestResult mHitTestResult; 96 97 private final int mAppTargetSdkVersion; 98 99 public WebViewChromium(WebView webView, WebView.PrivateAccess webViewPrivate, 100 AwBrowserContext browserContext) { 101 mWebView = webView; 102 mWebViewPrivate = webViewPrivate; 103 mHitTestResult = new WebView.HitTestResult(); 104 mBrowserContext = browserContext; 105 mAppTargetSdkVersion = mWebView.getContext().getApplicationInfo().targetSdkVersion; 106 } 107 108 static void completeWindowCreation(WebView parent, WebView child) { 109 AwContents parentContents = ((WebViewChromium) parent.getWebViewProvider()).mAwContents; 110 AwContents childContents = 111 child == null ? null : ((WebViewChromium) child.getWebViewProvider()).mAwContents; 112 parentContents.supplyContentsForPopup(childContents); 113 } 114 115 // WebViewProvider methods -------------------------------------------------------------------- 116 117 @Override 118 public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) { 119 // BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete DumpRenderTree 120 // so is ignored. TODO: remove it from WebViewProvider. 121 final boolean isAccessFromFileURLsGrantedByDefault = 122 mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN; 123 mContentsClientAdapter = new WebViewContentsClientAdapter(mWebView); 124 mAwContents = new AwContents(mBrowserContext, mWebView, new InternalAccessAdapter(), 125 mContentsClientAdapter, isAccessFromFileURLsGrantedByDefault); 126 127 if (privateBrowsing) { 128 final String msg = "Private browsing is not supported in WebView."; 129 if (mAppTargetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) { 130 throw new IllegalArgumentException(msg); 131 } else { 132 Log.w(TAG, msg); 133 // Intentionally irreversibly disable the webview instance, so that private 134 // user data cannot leak through misuse of a non-privateBrowing WebView instance. 135 // Can't just null out mAwContents as we never null-check it before use. 136 mAwContents.destroy(); 137 } 138 } 139 140 } 141 142 @Override 143 public void setHorizontalScrollbarOverlay(boolean overlay) { 144 UnimplementedWebViewApi.invoke(); 145 } 146 147 @Override 148 public void setVerticalScrollbarOverlay(boolean overlay) { 149 UnimplementedWebViewApi.invoke(); 150 } 151 152 @Override 153 public boolean overlayHorizontalScrollbar() { 154 UnimplementedWebViewApi.invoke(); 155 return false; 156 } 157 158 @Override 159 public boolean overlayVerticalScrollbar() { 160 UnimplementedWebViewApi.invoke(); 161 return false; 162 } 163 164 @Override 165 public int getVisibleTitleHeight() { 166 // This is deprecated in WebView and should always return 0. 167 return 0; 168 } 169 170 @Override 171 public SslCertificate getCertificate() { 172 return mAwContents.getCertificate(); 173 } 174 175 @Override 176 public void setCertificate(SslCertificate certificate) { 177 UnimplementedWebViewApi.invoke(); 178 } 179 180 @Override 181 public void savePassword(String host, String username, String password) { 182 // This is a deprecated API: intentional no-op. 183 } 184 185 @Override 186 public void setHttpAuthUsernamePassword(String host, String realm, String username, 187 String password) { 188 mAwContents.setHttpAuthUsernamePassword(host, realm, username, password); 189 } 190 191 @Override 192 public String[] getHttpAuthUsernamePassword(String host, String realm) { 193 return mAwContents.getHttpAuthUsernamePassword(host, realm); 194 } 195 196 @Override 197 public void destroy() { 198 mAwContents.destroy(); 199 if (mGLfunctor != null) { 200 mGLfunctor.destroy(); 201 mGLfunctor = null; 202 } 203 } 204 205 @Override 206 public void setNetworkAvailable(boolean networkUp) { 207 NetworkChangeNotifier.forceConnectivityState(networkUp); 208 } 209 210 @Override 211 public WebBackForwardList saveState(Bundle outState) { 212 if (outState == null) return null; 213 if (!mAwContents.saveState(outState)) return null; 214 return copyBackForwardList(); 215 } 216 217 @Override 218 public boolean savePicture(Bundle b, File dest) { 219 // Intentional no-op: hidden method on WebView. 220 return false; 221 } 222 223 @Override 224 public boolean restorePicture(Bundle b, File src) { 225 // Intentional no-op: hidden method on WebView. 226 return false; 227 } 228 229 @Override 230 public WebBackForwardList restoreState(Bundle inState) { 231 if (inState == null) return null; 232 if (!mAwContents.restoreState(inState)) return null; 233 return copyBackForwardList(); 234 } 235 236 @Override 237 public void loadUrl(String url, Map<String, String> additionalHttpHeaders) { 238 // TODO: We may actually want to do some sanity checks here (like filter about://chrome). 239 240 // For backwards compatibility, apps targeting less than K will have JS URLs evaluated 241 // directly and any result of the evaluation will not replace the current page content. 242 // Matching Chrome behavior more closely; apps targetting >= K that load a JS URL will 243 // have the result of that URL replace the content of the current page. 244 final String JAVASCRIPT_SCHEME = "javascript:"; 245 if (mAppTargetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE && 246 url.startsWith(JAVASCRIPT_SCHEME)) { 247 evaluateJavaScript(url.substring(JAVASCRIPT_SCHEME.length()), null); 248 return; 249 } 250 251 LoadUrlParams params = new LoadUrlParams(url); 252 if (additionalHttpHeaders != null) params.setExtraHeaders(additionalHttpHeaders); 253 loadUrlOnUiThread(params); 254 } 255 256 @Override 257 public void loadUrl(String url) { 258 loadUrl(url, null); 259 } 260 261 @Override 262 public void postUrl(String url, byte[] postData) { 263 loadUrlOnUiThread(LoadUrlParams.createLoadHttpPostParams(url, postData)); 264 } 265 266 private static boolean isBase64Encoded(String encoding) { 267 return "base64".equals(encoding); 268 } 269 270 @Override 271 public void loadData(String data, String mimeType, String encoding) { 272 loadUrlOnUiThread(LoadUrlParams.createLoadDataParams( 273 data, mimeType, isBase64Encoded(encoding))); 274 } 275 276 @Override 277 public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, 278 String historyUrl) { 279 LoadUrlParams loadUrlParams; 280 281 if (baseUrl != null && baseUrl.startsWith("data:")) { 282 // For backwards compatibility with WebViewClassic, we use the value of |encoding| 283 // as the charset, as long as it's not "base64". 284 boolean isBase64 = isBase64Encoded(encoding); 285 loadUrlParams = LoadUrlParams.createLoadDataParamsWithBaseUrl( 286 data, mimeType, isBase64, baseUrl, historyUrl, isBase64 ? null : encoding); 287 } else { 288 if (baseUrl == null || baseUrl.length() == 0) baseUrl = "about:blank"; 289 // When loading data with a non-data: base URL, the classic WebView would effectively 290 // "dump" that string of data into the WebView without going through regular URL 291 // loading steps such as decoding URL-encoded entities. We achieve this same behavior by 292 // base64 encoding the data that is passed here and then loading that as a data: URL. 293 try { 294 loadUrlParams = LoadUrlParams.createLoadDataParamsWithBaseUrl( 295 Base64.encodeToString(data.getBytes("utf-8"), Base64.DEFAULT), mimeType, 296 true, baseUrl, historyUrl, "utf-8"); 297 } catch (java.io.UnsupportedEncodingException e) { 298 Log.wtf(TAG, "Unable to load data string " + data, e); 299 return; 300 } 301 } 302 loadUrlOnUiThread(loadUrlParams); 303 } 304 305 private void loadUrlOnUiThread(final LoadUrlParams loadUrlParams) { 306 if (ThreadUtils.runningOnUiThread()) { 307 mAwContents.loadUrl(loadUrlParams); 308 } else { 309 // Disallowed in WebView API for apps targetting a new SDK 310 assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2; 311 ThreadUtils.postOnUiThread(new Runnable() { 312 @Override 313 public void run() { 314 mAwContents.loadUrl(loadUrlParams); 315 } 316 }); 317 } 318 } 319 320 public void evaluateJavaScript(String script, ValueCallback<String> resultCallback) { 321 mAwContents.evaluateJavaScript(script, resultCallback); 322 } 323 324 @Override 325 public void saveWebArchive(String filename) { 326 saveWebArchive(filename, false, null); 327 } 328 329 @Override 330 public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) { 331 mAwContents.saveWebArchive(basename, autoname, callback); 332 } 333 334 @Override 335 public void stopLoading() { 336 mAwContents.stopLoading(); 337 } 338 339 @Override 340 public void reload() { 341 mAwContents.reload(); 342 } 343 344 @Override 345 public boolean canGoBack() { 346 return mAwContents.canGoBack(); 347 } 348 349 @Override 350 public void goBack() { 351 mAwContents.goBack(); 352 } 353 354 @Override 355 public boolean canGoForward() { 356 return mAwContents.canGoForward(); 357 } 358 359 @Override 360 public void goForward() { 361 mAwContents.goForward(); 362 } 363 364 @Override 365 public boolean canGoBackOrForward(int steps) { 366 return mAwContents.canGoBackOrForward(steps); 367 } 368 369 @Override 370 public void goBackOrForward(int steps) { 371 mAwContents.goBackOrForward(steps); 372 } 373 374 @Override 375 public boolean isPrivateBrowsingEnabled() { 376 // Not supported in this WebView implementation. 377 return false; 378 } 379 380 @Override 381 public boolean pageUp(boolean top) { 382 return mAwContents.pageUp(top); 383 } 384 385 @Override 386 public boolean pageDown(boolean bottom) { 387 return mAwContents.pageDown(bottom); 388 } 389 390 @Override 391 public void clearView() { 392 UnimplementedWebViewApi.invoke(); 393 } 394 395 @Override 396 public Picture capturePicture() { 397 return mAwContents.capturePicture(); 398 } 399 400 @Override 401 public float getScale() { 402 return mAwContents.getScale(); 403 } 404 405 @Override 406 public void setInitialScale(int scaleInPercent) { 407 mAwContents.getSettings().setInitialPageScale(scaleInPercent); 408 } 409 410 @Override 411 public void invokeZoomPicker() { 412 mAwContents.invokeZoomPicker(); 413 } 414 415 @Override 416 public WebView.HitTestResult getHitTestResult() { 417 AwContents.HitTestData data = mAwContents.getLastHitTestResult(); 418 mHitTestResult.setType(data.hitTestResultType); 419 mHitTestResult.setExtra(data.hitTestResultExtraData); 420 return mHitTestResult; 421 } 422 423 @Override 424 public void requestFocusNodeHref(Message hrefMsg) { 425 mAwContents.requestFocusNodeHref(hrefMsg); 426 } 427 428 @Override 429 public void requestImageRef(Message msg) { 430 mAwContents.requestImageRef(msg); 431 } 432 433 @Override 434 public String getUrl() { 435 String url = mAwContents.getUrl(); 436 if (url == null || url.trim().isEmpty()) return null; 437 return url; 438 } 439 440 @Override 441 public String getOriginalUrl() { 442 String url = mAwContents.getOriginalUrl(); 443 if (url == null || url.trim().isEmpty()) return null; 444 return url; 445 } 446 447 @Override 448 public String getTitle() { 449 return mAwContents.getTitle(); 450 } 451 452 @Override 453 public Bitmap getFavicon() { 454 return mAwContents.getFavicon(); 455 } 456 457 @Override 458 public String getTouchIconUrl() { 459 // Intentional no-op: hidden method on WebView. 460 return null; 461 } 462 463 @Override 464 public int getProgress() { 465 return mAwContents.getMostRecentProgress(); 466 } 467 468 @Override 469 public int getContentHeight() { 470 return mAwContents.getContentHeightCss(); 471 } 472 473 @Override 474 public int getContentWidth() { 475 return mAwContents.getContentWidthCss(); 476 } 477 478 @Override 479 public void pauseTimers() { 480 mAwContents.pauseTimers(); 481 } 482 483 @Override 484 public void resumeTimers() { 485 mAwContents.resumeTimers(); 486 } 487 488 @Override 489 public void onPause() { 490 mAwContents.onPause(); 491 } 492 493 @Override 494 public void onResume() { 495 mAwContents.onResume(); 496 } 497 498 @Override 499 public boolean isPaused() { 500 return mAwContents.isPaused(); 501 } 502 503 @Override 504 public void freeMemory() { 505 UnimplementedWebViewApi.invoke(); 506 } 507 508 @Override 509 public void clearCache(boolean includeDiskFiles) { 510 mAwContents.clearCache(includeDiskFiles); 511 } 512 513 /** 514 * This is a poorly named method, but we keep it for historical reasons. 515 */ 516 @Override 517 public void clearFormData() { 518 mAwContents.hideAutofillPopup(); 519 } 520 521 @Override 522 public void clearHistory() { 523 mAwContents.clearHistory(); 524 } 525 526 @Override 527 public void clearSslPreferences() { 528 mAwContents.clearSslPreferences(); 529 } 530 531 @Override 532 public WebBackForwardList copyBackForwardList() { 533 return new WebBackForwardListChromium( 534 mAwContents.getNavigationHistory()); 535 } 536 537 @Override 538 public void setFindListener(WebView.FindListener listener) { 539 mContentsClientAdapter.setFindListener(listener); 540 } 541 542 @Override 543 public void findNext(boolean forwards) { 544 mAwContents.findNext(forwards); 545 } 546 547 @Override 548 public int findAll(String searchString) { 549 mAwContents.findAllAsync(searchString); 550 return 0; 551 } 552 553 @Override 554 public void findAllAsync(String searchString) { 555 mAwContents.findAllAsync(searchString); 556 } 557 558 @Override 559 public boolean showFindDialog(String text, boolean showIme) { 560 if (mWebView.getParent() == null) { 561 return false; 562 } 563 564 FindActionModeCallback findAction = new FindActionModeCallback(mWebView.getContext()); 565 if (findAction == null) { 566 return false; 567 } 568 569 mWebView.startActionMode(findAction); 570 findAction.setWebView(mWebView); 571 if (showIme) { 572 findAction.showSoftInput(); 573 } 574 575 if (text != null) { 576 findAction.setText(text); 577 findAction.findAll(); 578 } 579 580 return true; 581 } 582 583 @Override 584 public void notifyFindDialogDismissed() { 585 clearMatches(); 586 } 587 588 @Override 589 public void clearMatches() { 590 mAwContents.clearMatches(); 591 } 592 593 @Override 594 public void documentHasImages(Message response) { 595 mAwContents.documentHasImages(response); 596 } 597 598 @Override 599 public void setWebViewClient(WebViewClient client) { 600 mContentsClientAdapter.setWebViewClient(client); 601 } 602 603 @Override 604 public void setDownloadListener(DownloadListener listener) { 605 mContentsClientAdapter.setDownloadListener(listener); 606 } 607 608 @Override 609 public void setWebChromeClient(WebChromeClient client) { 610 mContentsClientAdapter.setWebChromeClient(client); 611 } 612 613 @Override 614 public void setPictureListener(WebView.PictureListener listener) { 615 mContentsClientAdapter.setPictureListener(listener); 616 mAwContents.enableOnNewPicture(listener != null, 617 mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2); 618 } 619 620 @Override 621 public void addJavascriptInterface(Object obj, String interfaceName) { 622 Class<? extends Annotation> requiredAnnotation = null; 623 if (mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 624 requiredAnnotation = JavascriptInterface.class; 625 } 626 mAwContents.addPossiblyUnsafeJavascriptInterface(obj, interfaceName, requiredAnnotation); 627 } 628 629 @Override 630 public void removeJavascriptInterface(String interfaceName) { 631 mAwContents.removeJavascriptInterface(interfaceName); 632 } 633 634 @Override 635 public WebSettings getSettings() { 636 if (mWebSettings == null) { 637 mWebSettings = new ContentSettingsAdapter(mAwContents.getSettings()); 638 } 639 return mWebSettings; 640 } 641 642 @Override 643 public void setMapTrackballToArrowKeys(boolean setMap) { 644 // This is a deprecated API: intentional no-op. 645 } 646 647 @Override 648 public void flingScroll(int vx, int vy) { 649 mAwContents.flingScroll(vx, vy); 650 } 651 652 @Override 653 public View getZoomControls() { 654 // This was deprecated in 2009 and hidden in JB MR1, so just provide the minimum needed 655 // to stop very out-dated applications from crashing. 656 Log.w(TAG, "WebView doesn't support getZoomControls"); 657 return mAwContents.getSettings().supportZoom() ? new View(mWebView.getContext()) : null; 658 } 659 660 @Override 661 public boolean canZoomIn() { 662 return mAwContents.canZoomIn(); 663 } 664 665 @Override 666 public boolean canZoomOut() { 667 return mAwContents.canZoomOut(); 668 } 669 670 @Override 671 public boolean zoomIn() { 672 return mAwContents.zoomIn(); 673 } 674 675 @Override 676 public boolean zoomOut() { 677 return mAwContents.zoomOut(); 678 } 679 680 @Override 681 public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) { 682 UnimplementedWebViewApi.invoke(); 683 } 684 685 @Override 686 public View findHierarchyView(String className, int hashCode) { 687 UnimplementedWebViewApi.invoke(); 688 return null; 689 } 690 691 // WebViewProvider glue methods --------------------------------------------------------------- 692 693 @Override 694 public WebViewProvider.ViewDelegate getViewDelegate() { 695 return this; 696 } 697 698 @Override 699 public WebViewProvider.ScrollDelegate getScrollDelegate() { 700 return this; 701 } 702 703 704 // WebViewProvider.ViewDelegate implementation ------------------------------------------------ 705 706 // TODO: remove from WebViewProvider and use default implementation from 707 // ViewGroup. 708 // @Override 709 public boolean shouldDelayChildPressedState() { 710 return true; 711 } 712 713// @Override 714 public AccessibilityNodeProvider getAccessibilityNodeProvider() { 715 return mAwContents.getAccessibilityNodeProvider(); 716 } 717 718 @Override 719 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 720 mAwContents.onInitializeAccessibilityNodeInfo(info); 721 } 722 723 @Override 724 public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 725 mAwContents.onInitializeAccessibilityEvent(event); 726 } 727 728 @Override 729 public boolean performAccessibilityAction(int action, Bundle arguments) { 730 if (mAwContents.supportsAccessibilityAction(action)) { 731 return mAwContents.performAccessibilityAction(action, arguments); 732 } 733 return mWebViewPrivate.super_performAccessibilityAction(action, arguments); 734 } 735 736 @Override 737 public void setOverScrollMode(int mode) { 738 // This gets called from the android.view.View c'tor that WebView inherits from. This 739 // causes the method to be called when mAwContents == null. 740 // It's safe to ignore these calls however since AwContents will read the current value of 741 // this setting when it's created. 742 if (mAwContents != null) { 743 mAwContents.setOverScrollMode(mode); 744 } 745 } 746 747 @Override 748 public void setScrollBarStyle(int style) { 749 UnimplementedWebViewApi.invoke(); 750 } 751 752 @Override 753 public void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, 754 int l, int t, int r, int b) { 755 UnimplementedWebViewApi.invoke(); 756 } 757 758 @Override 759 public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { 760 mAwContents.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY); 761 } 762 763 @Override 764 public void onWindowVisibilityChanged(int visibility) { 765 mAwContents.onWindowVisibilityChanged(visibility); 766 } 767 768 @Override 769 public void onDraw(Canvas canvas) { 770 mAwContents.onDraw(canvas); 771 } 772 773 @Override 774 public void setLayoutParams(ViewGroup.LayoutParams layoutParams) { 775 // TODO: This is the minimum implementation for HTMLViewer 776 // bringup. Likely will need to go up to ContentViewCore for 777 // a complete implementation. 778 mWebViewPrivate.super_setLayoutParams(layoutParams); 779 } 780 781 @Override 782 public boolean performLongClick() { 783 return mWebViewPrivate.super_performLongClick(); 784 } 785 786 @Override 787 public void onConfigurationChanged(Configuration newConfig) { 788 mAwContents.onConfigurationChanged(newConfig); 789 } 790 791 @Override 792 public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 793 return mAwContents.onCreateInputConnection(outAttrs); 794 } 795 796 @Override 797 public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 798 UnimplementedWebViewApi.invoke(); 799 return false; 800 } 801 802 @Override 803 public boolean onKeyDown(int keyCode, KeyEvent event) { 804 UnimplementedWebViewApi.invoke(); 805 return false; 806 } 807 808 @Override 809 public boolean onKeyUp(int keyCode, KeyEvent event) { 810 return mAwContents.onKeyUp(keyCode, event); 811 } 812 813 @Override 814 public void onAttachedToWindow() { 815 mAwContents.onAttachedToWindow(); 816 } 817 818 @Override 819 public void onDetachedFromWindow() { 820 mAwContents.onDetachedFromWindow(); 821 if (mGLfunctor != null) { 822 mGLfunctor.detach(); 823 } 824 } 825 826 @Override 827 public void onVisibilityChanged(View changedView, int visibility) { 828 // The AwContents will find out the container view visibility before the first draw so we 829 // can safely ignore onVisibilityChanged callbacks that happen before init(). 830 if (mAwContents != null) { 831 mAwContents.onVisibilityChanged(changedView, visibility); 832 } 833 } 834 835 @Override 836 public void onWindowFocusChanged(boolean hasWindowFocus) { 837 mAwContents.onWindowFocusChanged(hasWindowFocus); 838 } 839 840 @Override 841 public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 842 mAwContents.onFocusChanged(focused, direction, previouslyFocusedRect); 843 } 844 845 @Override 846 public boolean setFrame(int left, int top, int right, int bottom) { 847 // TODO(joth): This is the minimum implementation for initial 848 // bringup. Likely will need to go up to AwContents for a complete 849 // implementation, e.g. setting the compositor visible region (to 850 // avoid painting tiles that are offscreen due to the view's position). 851 return mWebViewPrivate.super_setFrame(left, top, right, bottom); 852 } 853 854 @Override 855 public void onSizeChanged(int w, int h, int ow, int oh) { 856 mAwContents.onSizeChanged(w, h, ow, oh); 857 } 858 859 @Override 860 public void onScrollChanged(int l, int t, int oldl, int oldt) { 861 } 862 863 @Override 864 public boolean dispatchKeyEvent(KeyEvent event) { 865 return mAwContents.dispatchKeyEvent(event); 866 } 867 868 @Override 869 public boolean onTouchEvent(MotionEvent ev) { 870 return mAwContents.onTouchEvent(ev); 871 } 872 873 @Override 874 public boolean onHoverEvent(MotionEvent event) { 875 return mAwContents.onHoverEvent(event); 876 } 877 878 @Override 879 public boolean onGenericMotionEvent(MotionEvent event) { 880 return mAwContents.onGenericMotionEvent(event); 881 } 882 883 @Override 884 public boolean onTrackballEvent(MotionEvent ev) { 885 // Trackball event not handled, which eventually gets converted to DPAD keyevents 886 return false; 887 } 888 889 @Override 890 public boolean requestFocus(int direction, Rect previouslyFocusedRect) { 891 mAwContents.requestFocus(); 892 return mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect); 893 } 894 895 @Override 896 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 897 mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec); 898 } 899 900 @Override 901 public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) { 902 UnimplementedWebViewApi.invoke(); 903 return false; 904 } 905 906 @Override 907 public void setBackgroundColor(int color) { 908 mAwContents.setBackgroundColor(color); 909 } 910 911 @Override 912 public void setLayerType(int layerType, Paint paint) { 913 UnimplementedWebViewApi.invoke(); 914 } 915 916 @Override 917 public void preDispatchDraw(Canvas canvas) { 918 // TODO(leandrogracia): remove this method from WebViewProvider if we think 919 // we won't need it again. 920 } 921 922 // WebViewProvider.ScrollDelegate implementation ---------------------------------------------- 923 924 @Override 925 public int computeHorizontalScrollRange() { 926 return mAwContents.computeHorizontalScrollRange(); 927 } 928 929 @Override 930 public int computeHorizontalScrollOffset() { 931 return mAwContents.computeHorizontalScrollOffset(); 932 } 933 934 @Override 935 public int computeVerticalScrollRange() { 936 return mAwContents.computeVerticalScrollRange(); 937 } 938 939 @Override 940 public int computeVerticalScrollOffset() { 941 return mAwContents.computeVerticalScrollOffset(); 942 } 943 944 @Override 945 public int computeVerticalScrollExtent() { 946 return mAwContents.computeVerticalScrollExtent(); 947 } 948 949 @Override 950 public void computeScroll() { 951 mAwContents.computeScroll(); 952 } 953 954 // AwContents.InternalAccessDelegate implementation -------------------------------------- 955 private class InternalAccessAdapter implements AwContents.InternalAccessDelegate { 956 @Override 957 public boolean drawChild(Canvas arg0, View arg1, long arg2) { 958 UnimplementedWebViewApi.invoke(); 959 return false; 960 } 961 962 @Override 963 public boolean super_onKeyUp(int arg0, KeyEvent arg1) { 964 UnimplementedWebViewApi.invoke(); 965 return false; 966 } 967 968 @Override 969 public boolean super_dispatchKeyEventPreIme(KeyEvent arg0) { 970 UnimplementedWebViewApi.invoke(); 971 return false; 972 } 973 974 @Override 975 public boolean super_dispatchKeyEvent(KeyEvent event) { 976 return mWebViewPrivate.super_dispatchKeyEvent(event); 977 } 978 979 @Override 980 public boolean super_onGenericMotionEvent(MotionEvent arg0) { 981 UnimplementedWebViewApi.invoke(); 982 return false; 983 } 984 985 @Override 986 public void super_onConfigurationChanged(Configuration arg0) { 987 UnimplementedWebViewApi.invoke(); 988 } 989 990 @Override 991 public boolean awakenScrollBars() { 992 mWebViewPrivate.awakenScrollBars(0); 993 // TODO: modify the WebView.PrivateAccess to provide a return value. 994 return true; 995 } 996 997 @Override 998 public boolean super_awakenScrollBars(int arg0, boolean arg1) { 999 // TODO: need method on WebView.PrivateAccess? 1000 UnimplementedWebViewApi.invoke(); 1001 return false; 1002 } 1003 1004 @Override 1005 public void onScrollChanged(int l, int t, int oldl, int oldt) { 1006 mWebViewPrivate.setScrollXRaw(l); 1007 mWebViewPrivate.setScrollYRaw(t); 1008 mWebViewPrivate.onScrollChanged(l, t, oldl, oldt); 1009 } 1010 1011 @Override 1012 public void overScrollBy(int deltaX, int deltaY, 1013 int scrollX, int scrollY, 1014 int scrollRangeX, int scrollRangeY, 1015 int maxOverScrollX, int maxOverScrollY, 1016 boolean isTouchEvent) { 1017 mWebViewPrivate.overScrollBy(deltaX, deltaY, scrollX, scrollY, 1018 scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 1019 } 1020 1021 @Override 1022 public void super_scrollTo(int scrollX, int scrollY) { 1023 mWebViewPrivate.super_scrollTo(scrollX, scrollY); 1024 } 1025 1026 @Override 1027 public void setMeasuredDimension(int measuredWidth, int measuredHeight) { 1028 mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight); 1029 } 1030 1031 @Override 1032 public boolean requestDrawGL(Canvas canvas) { 1033 if (mGLfunctor == null) { 1034 mGLfunctor = new DrawGLFunctor(mAwContents.getAwDrawGLViewContext()); 1035 } 1036 return mGLfunctor.requestDrawGL((HardwareCanvas)canvas, mWebView.getViewRootImpl()); 1037 } 1038 } 1039} 1040