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