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