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