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