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