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