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