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