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