WebViewChromium.java revision e78d6e40e4e78671e6621ba8cf49835568704899
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.getSettings().supportZoom() ? new View(mWebView.getContext()) : 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