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