WebViewChromium.java revision 420c0da3a4e06e1ac5574091e7c9c286ef012369
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        return mAwContents.findAllSync(searchString);
484    }
485
486    @Override
487    public void findAllAsync(String searchString) {
488        mAwContents.findAllAsync(searchString);
489    }
490
491    @Override
492    public boolean showFindDialog(String text, boolean showIme) {
493        if (mWebView.getParent() == null) {
494            return false;
495        }
496
497        FindActionModeCallback findAction = new FindActionModeCallback(mWebView.getContext());
498        if (findAction == null) {
499            return false;
500        }
501
502        mWebView.startActionMode(findAction);
503        findAction.setWebView(mWebView);
504        if (showIme) {
505            findAction.showSoftInput();
506        }
507
508        if (text != null) {
509            findAction.setText(text);
510            findAction.findAll();
511        }
512
513        return true;
514    }
515
516    @Override
517    public void notifyFindDialogDismissed() {
518        clearMatches();
519    }
520
521    @Override
522    public void clearMatches() {
523        mAwContents.clearMatches();
524    }
525
526    @Override
527    public void documentHasImages(Message response) {
528        mAwContents.documentHasImages(response);
529    }
530
531    @Override
532    public void setWebViewClient(WebViewClient client) {
533        mContentsClientAdapter.setWebViewClient(client);
534    }
535
536    @Override
537    public void setDownloadListener(DownloadListener listener) {
538        mContentsClientAdapter.setDownloadListener(listener);
539    }
540
541    @Override
542    public void setWebChromeClient(WebChromeClient client) {
543        mContentsClientAdapter.setWebChromeClient(client);
544    }
545
546    @Override
547    public void setPictureListener(WebView.PictureListener listener) {
548        mContentsClientAdapter.setPictureListener(listener);
549        mAwContents.enableOnNewPicture(listener != null,
550                mWebView.getContext().getApplicationInfo().targetSdkVersion >=
551                Build.VERSION_CODES.JELLY_BEAN_MR2);
552    }
553
554    @Override
555    public void addJavascriptInterface(Object obj, String interfaceName) {
556        Class<? extends Annotation> requiredAnnotation = null;
557        if (mWebView.getContext().getApplicationInfo().targetSdkVersion >=
558                Build.VERSION_CODES.JELLY_BEAN_MR1) {
559           requiredAnnotation = JavascriptInterface.class;
560        }
561        mAwContents.addPossiblyUnsafeJavascriptInterface(obj, interfaceName, requiredAnnotation);
562    }
563
564    @Override
565    public void removeJavascriptInterface(String interfaceName) {
566        mAwContents.removeJavascriptInterface(interfaceName);
567    }
568
569    @Override
570    public WebSettings getSettings() {
571        if (mWebSettings == null) {
572            mWebSettings = new ContentSettingsAdapter(mAwContents.getSettings());
573        }
574        return mWebSettings;
575    }
576
577    @Override
578    public void setMapTrackballToArrowKeys(boolean setMap) {
579        // This is a deprecated API: intentional no-op.
580    }
581
582    @Override
583    public void flingScroll(int vx, int vy) {
584        mAwContents.flingScroll(vx, vy);
585    }
586
587    @Override
588    public View getZoomControls() {
589        // This was deprecated in 2009 and hidden in JB MR1, so just provide the minimum needed
590        // to stop very out-dated applications from crashing.
591        Log.w(TAG, "WebView doesn't support getZoomControls");
592        return mAwContents.getSettings().supportZoom() ? new View(mWebView.getContext()) : null;
593    }
594
595    @Override
596    public boolean canZoomIn() {
597        return mAwContents.canZoomIn();
598    }
599
600    @Override
601    public boolean canZoomOut() {
602        return mAwContents.canZoomOut();
603    }
604
605    @Override
606    public boolean zoomIn() {
607        return mAwContents.zoomIn();
608    }
609
610    @Override
611    public boolean zoomOut() {
612        return mAwContents.zoomOut();
613    }
614
615    @Override
616    public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
617        UnimplementedWebViewApi.invoke();
618    }
619
620    @Override
621    public View findHierarchyView(String className, int hashCode) {
622        UnimplementedWebViewApi.invoke();
623        return null;
624    }
625
626    // WebViewProvider glue methods ---------------------------------------------------------------
627
628    @Override
629    public WebViewProvider.ViewDelegate getViewDelegate() {
630        return this;
631    }
632
633    @Override
634    public WebViewProvider.ScrollDelegate getScrollDelegate() {
635        return this;
636    }
637
638
639    // WebViewProvider.ViewDelegate implementation ------------------------------------------------
640
641    @Override
642    public boolean shouldDelayChildPressedState() {
643        UnimplementedWebViewApi.invoke();
644        return false;
645    }
646
647    @Override
648    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
649        mAwContents.onInitializeAccessibilityNodeInfo(info);
650    }
651
652    @Override
653    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
654        mAwContents.onInitializeAccessibilityEvent(event);
655    }
656
657    // TODO: Update WebView to mimic ContentView implementation for the
658    // real View#performAccessibilityAction(int, Bundle).  This method has different behavior.
659    // See ContentViewCore#performAccessibilityAction(int, Bundle) for more details.
660    @Override
661    public boolean performAccessibilityAction(int action, Bundle arguments) {
662        return mAwContents.performAccessibilityAction(action, arguments);
663    }
664
665    @Override
666    public void setOverScrollMode(int mode) {
667        UnimplementedWebViewApi.invoke();
668    }
669
670    @Override
671    public void setScrollBarStyle(int style) {
672        UnimplementedWebViewApi.invoke();
673    }
674
675    @Override
676    public void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
677                                        int l, int t, int r, int b) {
678        UnimplementedWebViewApi.invoke();
679    }
680
681    @Override
682    public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
683        UnimplementedWebViewApi.invoke();
684    }
685
686    @Override
687    public void onWindowVisibilityChanged(int visibility) {
688        mAwContents.onWindowVisibilityChanged(visibility);
689    }
690
691    @Override
692    public void onDraw(Canvas canvas) {
693        mAwContents.onDraw(canvas);
694    }
695
696    @Override
697    public void setLayoutParams(ViewGroup.LayoutParams layoutParams) {
698        // TODO: This is the minimum implementation for HTMLViewer
699        // bringup. Likely will need to go up to ContentViewCore for
700        // a complete implementation.
701        mWebViewPrivate.super_setLayoutParams(layoutParams);
702    }
703
704    @Override
705    public boolean performLongClick() {
706        return mWebViewPrivate.super_performLongClick();
707    }
708
709    @Override
710    public void onConfigurationChanged(Configuration newConfig) {
711        mAwContents.onConfigurationChanged(newConfig);
712    }
713
714    @Override
715    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
716        return mAwContents.onCreateInputConnection(outAttrs);
717    }
718
719    @Override
720    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
721        UnimplementedWebViewApi.invoke();
722        return false;
723    }
724
725    @Override
726    public boolean onKeyDown(int keyCode, KeyEvent event) {
727        UnimplementedWebViewApi.invoke();
728        return false;
729    }
730
731    @Override
732    public boolean onKeyUp(int keyCode, KeyEvent event) {
733        return mAwContents.onKeyUp(keyCode, event);
734    }
735
736    @Override
737    public void onAttachedToWindow() {
738        mAwContents.onAttachedToWindow();
739    }
740
741    @Override
742    public void onDetachedFromWindow() {
743        mAwContents.onDetachedFromWindow();
744        if (mGLfunctor != null) {
745            mGLfunctor.detach();
746        }
747    }
748
749    @Override
750    public void onVisibilityChanged(View changedView, int visibility) {
751        // The AwContents will find out the container view visibility before the first draw so we
752        // can safely ignore onVisibilityChanged callbacks that happen before init().
753        if (mAwContents != null) {
754            mAwContents.onVisibilityChanged(changedView, visibility);
755        }
756    }
757
758    @Override
759    public void onWindowFocusChanged(boolean hasWindowFocus) {
760        mAwContents.onWindowFocusChanged(hasWindowFocus);
761    }
762
763    @Override
764    public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
765        mAwContents.onFocusChanged(focused, direction, previouslyFocusedRect);
766    }
767
768    @Override
769    public boolean setFrame(int left, int top, int right, int bottom) {
770        // TODO(joth): This is the minimum implementation for initial
771        // bringup. Likely will need to go up to AwContents for a complete
772        // implementation, e.g. setting the compositor visible region (to
773        // avoid painting tiles that are offscreen due to the view's position).
774        return mWebViewPrivate.super_setFrame(left, top, right, bottom);
775    }
776
777    @Override
778    public void onSizeChanged(int w, int h, int ow, int oh) {
779        mAwContents.onSizeChanged(w, h, ow, oh);
780    }
781
782    @Override
783    public void onScrollChanged(int l, int t, int oldl, int oldt) {
784    }
785
786    @Override
787    public boolean dispatchKeyEvent(KeyEvent event) {
788        return mAwContents.dispatchKeyEvent(event);
789    }
790
791    @Override
792    public boolean onTouchEvent(MotionEvent ev) {
793        return mAwContents.onTouchEvent(ev);
794    }
795
796    @Override
797    public boolean onHoverEvent(MotionEvent event) {
798        return mAwContents.onHoverEvent(event);
799    }
800
801    @Override
802    public boolean onGenericMotionEvent(MotionEvent event) {
803        return mAwContents.onGenericMotionEvent(event);
804    }
805
806    @Override
807    public boolean onTrackballEvent(MotionEvent ev) {
808        // Trackball event not handled, which eventually gets converted to DPAD keyevents
809        return false;
810    }
811
812    @Override
813    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
814        mAwContents.requestFocus();
815        return mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect);
816    }
817
818    @Override
819    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
820        mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec);
821    }
822
823    @Override
824    public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
825        UnimplementedWebViewApi.invoke();
826        return false;
827    }
828
829    @Override
830    public void setBackgroundColor(int color) {
831        UnimplementedWebViewApi.invoke();
832    }
833
834    @Override
835    public void setLayerType(int layerType, Paint paint) {
836        UnimplementedWebViewApi.invoke();
837    }
838
839    @Override
840    public void preDispatchDraw(Canvas canvas) {
841        // TODO(leandrogracia): remove this method from WebViewProvider if we think
842        // we won't need it again.
843    }
844
845    // WebViewProvider.ScrollDelegate implementation ----------------------------------------------
846
847    @Override
848    public int computeHorizontalScrollRange() {
849        return mAwContents.computeHorizontalScrollRange();
850    }
851
852    @Override
853    public int computeHorizontalScrollOffset() {
854        return mAwContents.computeHorizontalScrollOffset();
855    }
856
857    @Override
858    public int computeVerticalScrollRange() {
859        return mAwContents.computeVerticalScrollRange();
860    }
861
862    @Override
863    public int computeVerticalScrollOffset() {
864        return mAwContents.computeVerticalScrollOffset();
865    }
866
867    @Override
868    public int computeVerticalScrollExtent() {
869        return mAwContents.computeVerticalScrollExtent();
870    }
871
872    @Override
873    public void computeScroll() {
874        // BUG=http://b/6029133
875        // Too much log spam: UnimplementedWebViewApi.invoke();
876    }
877
878    // AwContents.InternalAccessDelegate implementation --------------------------------------
879    private class InternalAccessAdapter implements AwContents.InternalAccessDelegate {
880        @Override
881        public boolean drawChild(Canvas arg0, View arg1, long arg2) {
882            UnimplementedWebViewApi.invoke();
883            return false;
884        }
885
886        @Override
887        public boolean super_onKeyUp(int arg0, KeyEvent arg1) {
888            UnimplementedWebViewApi.invoke();
889            return false;
890        }
891
892        @Override
893        public boolean super_dispatchKeyEventPreIme(KeyEvent arg0) {
894            UnimplementedWebViewApi.invoke();
895            return false;
896        }
897
898        @Override
899        public boolean super_dispatchKeyEvent(KeyEvent event) {
900            return mWebViewPrivate.super_dispatchKeyEvent(event);
901        }
902
903        @Override
904        public boolean super_onGenericMotionEvent(MotionEvent arg0) {
905            UnimplementedWebViewApi.invoke();
906            return false;
907        }
908
909        @Override
910        public void super_onConfigurationChanged(Configuration arg0) {
911            UnimplementedWebViewApi.invoke();
912        }
913
914        @Override
915        public void onScrollChanged(int l, int t, int oldl, int oldt) {
916            mWebViewPrivate.setScrollXRaw(l);
917            mWebViewPrivate.setScrollYRaw(t);
918            mWebViewPrivate.onScrollChanged(l, t, oldl, oldt);
919        }
920
921        @Override
922        public boolean awakenScrollBars() {
923            mWebViewPrivate.awakenScrollBars(0);
924            // TODO: modify the WebView.PrivateAccess to provide a return value.
925            return true;
926        }
927
928        @Override
929        public boolean super_awakenScrollBars(int arg0, boolean arg1) {
930            // TODO: need method on WebView.PrivateAccess?
931            UnimplementedWebViewApi.invoke();
932            return false;
933        }
934
935        @Override
936        public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
937            mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight);
938        }
939
940        @Override
941        public boolean requestDrawGL(Canvas canvas) {
942            if (mGLfunctor == null) {
943                mGLfunctor = new DrawGLFunctor(mAwContents.getAwDrawGLViewContext());
944            }
945            return mGLfunctor.requestDrawGL((HardwareCanvas)canvas, mWebView.getViewRootImpl());
946        }
947    }
948}
949