- add sources.
[platform/framework/web/crosswalk.git] / src / content / public / android / java / src / org / chromium / content / browser / ContentView.java
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser;
6
7 import android.app.Activity;
8 import android.content.Context;
9 import android.content.res.Configuration;
10 import android.graphics.Bitmap;
11 import android.graphics.Canvas;
12 import android.graphics.Rect;
13 import android.os.Build;
14 import android.util.AttributeSet;
15 import android.view.KeyEvent;
16 import android.view.MotionEvent;
17 import android.view.View;
18 import android.view.accessibility.AccessibilityEvent;
19 import android.view.accessibility.AccessibilityNodeInfo;
20 import android.view.inputmethod.EditorInfo;
21 import android.view.inputmethod.InputConnection;
22 import android.widget.FrameLayout;
23
24 import com.google.common.annotations.VisibleForTesting;
25
26 import org.chromium.content.common.TraceEvent;
27 import org.chromium.ui.WindowAndroid;
28
29 /**
30  * The containing view for {@link ContentViewCore} that exists in the Android UI hierarchy and
31  * exposes the various {@link View} functionality to it.
32  *
33  * TODO(joth): Remove any methods overrides from this class that were added for WebView
34  *             compatibility.
35  */
36 public class ContentView extends FrameLayout
37         implements ContentViewCore.InternalAccessDelegate, PageInfo {
38
39     private final ContentViewCore mContentViewCore;
40
41     private float mCurrentTouchOffsetX;
42     private float mCurrentTouchOffsetY;
43     private final int[] mLocationInWindow = new int[2];
44
45     /**
46      * Creates an instance of a ContentView.
47      * @param context The Context the view is running in, through which it can
48      *                access the current theme, resources, etc.
49      * @param nativeWebContents A pointer to the native web contents.
50      * @param windowAndroid An instance of the WindowAndroid.
51      * @return A ContentView instance.
52      */
53     public static ContentView newInstance(Context context, int nativeWebContents,
54             WindowAndroid windowAndroid) {
55         return newInstance(context, nativeWebContents, windowAndroid, null,
56                 android.R.attr.webViewStyle);
57     }
58
59     /**
60      * Creates an instance of a ContentView.
61      * @param context The Context the view is running in, through which it can
62      *                access the current theme, resources, etc.
63      * @param nativeWebContents A pointer to the native web contents.
64      * @param windowAndroid An instance of the WindowAndroid.
65      * @param attrs The attributes of the XML tag that is inflating the view.
66      * @return A ContentView instance.
67      */
68     public static ContentView newInstance(Context context, int nativeWebContents,
69             WindowAndroid windowAndroid, AttributeSet attrs) {
70         // TODO(klobag): use the WebViewStyle as the default style for now. It enables scrollbar.
71         // When ContentView is moved to framework, we can define its own style in the res.
72         return newInstance(context, nativeWebContents, windowAndroid, attrs,
73                 android.R.attr.webViewStyle);
74     }
75
76     /**
77      * Creates an instance of a ContentView.
78      * @param context The Context the view is running in, through which it can
79      *                access the current theme, resources, etc.
80      * @param nativeWebContents A pointer to the native web contents.
81      * @param windowAndroid An instance of the WindowAndroid.
82      * @param attrs The attributes of the XML tag that is inflating the view.
83      * @param defStyle The default style to apply to this view.
84      * @return A ContentView instance.
85      */
86     public static ContentView newInstance(Context context, int nativeWebContents,
87             WindowAndroid windowAndroid, AttributeSet attrs, int defStyle) {
88         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
89             return new ContentView(context, nativeWebContents, windowAndroid, attrs, defStyle);
90         } else {
91             return new JellyBeanContentView(context, nativeWebContents, windowAndroid, attrs,
92                     defStyle);
93         }
94     }
95
96     protected ContentView(Context context, int nativeWebContents, WindowAndroid windowAndroid,
97             AttributeSet attrs, int defStyle) {
98         super(context, attrs, defStyle);
99
100         if (getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
101             setHorizontalScrollBarEnabled(false);
102             setVerticalScrollBarEnabled(false);
103         }
104
105         setFocusable(true);
106         setFocusableInTouchMode(true);
107
108         mContentViewCore = new ContentViewCore(context);
109         mContentViewCore.initialize(this, this, nativeWebContents, windowAndroid,
110                 Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ?
111                 ContentViewCore.INPUT_EVENTS_DELIVERED_AT_VSYNC :
112                 ContentViewCore.INPUT_EVENTS_DELIVERED_IMMEDIATELY);
113     }
114
115     /**
116      * @return The URL of the page.
117      */
118     public String getUrl() {
119         return mContentViewCore.getUrl();
120     }
121
122     // PageInfo implementation.
123
124     @Override
125     public String getTitle() {
126         return mContentViewCore.getTitle();
127     }
128
129     @Override
130     public boolean isReadyForSnapshot() {
131         return !isCrashed() && isReady();
132     }
133
134     @Override
135     public Bitmap getBitmap() {
136         return getBitmap(getWidth(), getHeight());
137     }
138
139     @Override
140     public Bitmap getBitmap(int width, int height) {
141         return mContentViewCore.getBitmap(width, height);
142     }
143
144     @Override
145     public int getBackgroundColor() {
146         return mContentViewCore.getBackgroundColor();
147     }
148
149     @Override
150     public View getView() {
151         return this;
152     }
153
154     /**
155      * @return The core component of the ContentView that handles JNI communication.  Should only be
156      *         used for passing to native.
157      */
158     public ContentViewCore getContentViewCore() {
159         return mContentViewCore;
160     }
161
162     /**
163      * @return The cache of scales and positions used to convert coordinates from/to CSS.
164      */
165     public RenderCoordinates getRenderCoordinates() {
166         return mContentViewCore.getRenderCoordinates();
167     }
168
169     /**
170      * Returns true if the given Activity has hardware acceleration enabled
171      * in its manifest, or in its foreground window.
172      *
173      * TODO(husky): Remove when ContentViewCore.initialize() is refactored (see TODO there)
174      * TODO(dtrainor) This is still used by other classes.  Make sure to pull some version of this
175      * out before removing it.
176      */
177     public static boolean hasHardwareAcceleration(Activity activity) {
178         return ContentViewCore.hasHardwareAcceleration(activity);
179     }
180
181     /**
182      * Destroy the internal state of the WebView. This method may only be called
183      * after the WebView has been removed from the view system. No other methods
184      * may be called on this WebView after this method has been called.
185      */
186     public void destroy() {
187         mContentViewCore.destroy();
188     }
189
190     /**
191      * Returns true initially, false after destroy() has been called.
192      * It is illegal to call any other public method after destroy().
193      */
194     public boolean isAlive() {
195         return mContentViewCore.isAlive();
196     }
197
198     /**
199      * For internal use. Throws IllegalStateException if mNativeContentView is 0.
200      * Use this to ensure we get a useful Java stack trace, rather than a native
201      * crash dump, from use-after-destroy bugs in Java code.
202      */
203     void checkIsAlive() throws IllegalStateException {
204         mContentViewCore.checkIsAlive();
205     }
206
207     public void setContentViewClient(ContentViewClient client) {
208         mContentViewCore.setContentViewClient(client);
209     }
210
211     @VisibleForTesting
212     public ContentViewClient getContentViewClient() {
213         return mContentViewCore.getContentViewClient();
214     }
215
216     /**
217      * Load url without fixing up the url string. Consumers of ContentView are responsible for
218      * ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left
219      * off during user input).
220      *
221      * @param params Parameters for this load.
222      */
223     public void loadUrl(LoadUrlParams params) {
224         mContentViewCore.loadUrl(params);
225     }
226
227     /**
228      * Stops loading the current web contents.
229      */
230     public void stopLoading() {
231         mContentViewCore.stopLoading();
232     }
233
234     /**
235      * @return Whether the current WebContents has a previous navigation entry.
236      */
237     public boolean canGoBack() {
238         return mContentViewCore.canGoBack();
239     }
240
241     /**
242      * @return Whether the current WebContents has a navigation entry after the current one.
243      */
244     public boolean canGoForward() {
245         return mContentViewCore.canGoForward();
246     }
247
248     /**
249      * @param offset The offset into the navigation history.
250      * @return Whether we can move in history by given offset
251      */
252     public boolean canGoToOffset(int offset) {
253         return mContentViewCore.canGoToOffset(offset);
254     }
255
256     /**
257      * Navigates to the specified offset from the "current entry". Does nothing if the offset is out
258      * of bounds.
259      * @param offset The offset into the navigation history.
260      */
261     public void goToOffset(int offset) {
262         mContentViewCore.goToOffset(offset);
263     }
264
265     /**
266      * Goes to the navigation entry before the current one.
267      */
268     public void goBack() {
269         mContentViewCore.goBack();
270     }
271
272     /**
273      * Goes to the navigation entry following the current one.
274      */
275     public void goForward() {
276         mContentViewCore.goForward();
277     }
278
279     /**
280      * Reload the current page.
281      */
282     public void reload() {
283         mContentViewCore.reload();
284     }
285
286     /**
287      * Clears the WebView's page history in both the backwards and forwards
288      * directions.
289      */
290     public void clearHistory() {
291         mContentViewCore.clearHistory();
292     }
293
294     /**
295      * Start profiling the update speed. You must call {@link #stopFpsProfiling}
296      * to stop profiling.
297      */
298     @VisibleForTesting
299     public void startFpsProfiling() {
300         // TODO(nileshagrawal): Implement this.
301     }
302
303     /**
304      * Stop profiling the update speed.
305      */
306     @VisibleForTesting
307     public float stopFpsProfiling() {
308         // TODO(nileshagrawal): Implement this.
309         return 0.0f;
310     }
311
312     /**
313      * Fling the ContentView from the current position.
314      * @param x Fling touch starting position
315      * @param y Fling touch starting position
316      * @param velocityX Initial velocity of the fling (X) measured in pixels per second.
317      * @param velocityY Initial velocity of the fling (Y) measured in pixels per second.
318      */
319     @VisibleForTesting
320     public void fling(long timeMs, int x, int y, int velocityX, int velocityY) {
321         mContentViewCore.getContentViewGestureHandler().fling(timeMs, x, y, velocityX, velocityY);
322     }
323
324     /**
325      * Start pinch zoom. You must call {@link #pinchEnd} to stop.
326      */
327     @VisibleForTesting
328     public void pinchBegin(long timeMs, int x, int y) {
329         mContentViewCore.getContentViewGestureHandler().pinchBegin(timeMs, x, y);
330     }
331
332     /**
333      * Stop pinch zoom.
334      */
335     @VisibleForTesting
336     public void pinchEnd(long timeMs) {
337         mContentViewCore.getContentViewGestureHandler().pinchEnd(timeMs);
338     }
339
340     void setIgnoreSingleTap(boolean value) {
341         mContentViewCore.getContentViewGestureHandler().setIgnoreSingleTap(value);
342     }
343
344     /** @see ContentViewGestureHandler#setIgnoreRemainingTouchEvents */
345     public void setIgnoreRemainingTouchEvents() {
346         mContentViewCore.getContentViewGestureHandler().setIgnoreRemainingTouchEvents();
347     }
348
349     /**
350      * Modify the ContentView magnification level. The effect of calling this
351      * method is exactly as after "pinch zoom".
352      *
353      * @param timeMs The event time in milliseconds.
354      * @param delta The ratio of the new magnification level over the current
355      *            magnification level.
356      * @param anchorX The magnification anchor (X) in the current view
357      *            coordinate.
358      * @param anchorY The magnification anchor (Y) in the current view
359      *            coordinate.
360      */
361     @VisibleForTesting
362     public void pinchBy(long timeMs, int anchorX, int anchorY, float delta) {
363         mContentViewCore.getContentViewGestureHandler().pinchBy(timeMs, anchorX, anchorY, delta);
364     }
365
366     /**
367      * Injects the passed JavaScript code in the current page and evaluates it.
368      *
369      * @throws IllegalStateException If the ContentView has been destroyed.
370      */
371     public void evaluateJavaScript(String script) throws IllegalStateException {
372         mContentViewCore.evaluateJavaScript(script, null);
373     }
374
375     /**
376      * To be called when the ContentView is shown.
377      **/
378     public void onShow() {
379         mContentViewCore.onShow();
380     }
381
382     /**
383      * To be called when the ContentView is hidden.
384      **/
385     public void onHide() {
386         mContentViewCore.onHide();
387     }
388
389     /**
390      * Return the ContentSettings object used to retrieve the settings for this
391      * ContentView.
392      * @return A ContentSettings object that can be used to retrieve this ContentView's
393      *         settings.
394      */
395     public ContentSettings getContentSettings() {
396         return mContentViewCore.getContentSettings();
397     }
398
399     /**
400      * Hides the select action bar.
401      */
402     public void hideSelectActionBar() {
403         mContentViewCore.hideSelectActionBar();
404     }
405
406     // FrameLayout overrides.
407
408     // Needed by ContentViewCore.InternalAccessDelegate
409     @Override
410     public boolean drawChild(Canvas canvas, View child, long drawingTime) {
411         return super.drawChild(canvas, child, drawingTime);
412     }
413
414     // Needed by ContentViewCore.InternalAccessDelegate
415     @Override
416     public void onScrollChanged(int l, int t, int oldl, int oldt) {
417         super.onScrollChanged(l, t, oldl, oldt);
418     }
419
420     @Override
421     protected void onSizeChanged(int w, int h, int ow, int oh) {
422         TraceEvent.begin();
423         super.onSizeChanged(w, h, ow, oh);
424         mContentViewCore.onSizeChanged(w, h, ow, oh);
425         TraceEvent.end();
426     }
427
428     @Override
429     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
430         super.onLayout(changed, left, top, right, bottom);
431         if (changed) {
432             getLocationInWindow(mLocationInWindow);
433             mContentViewCore.onLocationInWindowChanged(mLocationInWindow[0], mLocationInWindow[1]);
434         }
435     }
436
437     @Override
438     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
439         return mContentViewCore.onCreateInputConnection(outAttrs);
440     }
441
442     @Override
443     public boolean onCheckIsTextEditor() {
444         return mContentViewCore.onCheckIsTextEditor();
445     }
446
447     @Override
448     protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
449         TraceEvent.begin();
450         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
451         mContentViewCore.onFocusChanged(gainFocus);
452         TraceEvent.end();
453     }
454
455     @Override
456     public void onWindowFocusChanged(boolean hasWindowFocus) {
457         super.onWindowFocusChanged(hasWindowFocus);
458         mContentViewCore.onWindowFocusChanged(hasWindowFocus);
459     }
460
461     @Override
462     public boolean onKeyUp(int keyCode, KeyEvent event) {
463         return mContentViewCore.onKeyUp(keyCode, event);
464     }
465
466     @Override
467     public boolean dispatchKeyEventPreIme(KeyEvent event) {
468         return mContentViewCore.dispatchKeyEventPreIme(event);
469     }
470
471     @Override
472     public boolean dispatchKeyEvent(KeyEvent event) {
473         if (isFocused()) {
474             return mContentViewCore.dispatchKeyEvent(event);
475         } else {
476             return super.dispatchKeyEvent(event);
477         }
478     }
479
480     @Override
481     public boolean onTouchEvent(MotionEvent event) {
482         MotionEvent offset = createOffsetMotionEvent(event);
483         boolean consumed = mContentViewCore.onTouchEvent(offset);
484         offset.recycle();
485         return consumed;
486     }
487
488     /**
489      * Mouse move events are sent on hover enter, hover move and hover exit.
490      * They are sent on hover exit because sometimes it acts as both a hover
491      * move and hover exit.
492      */
493     @Override
494     public boolean onHoverEvent(MotionEvent event) {
495         MotionEvent offset = createOffsetMotionEvent(event);
496         boolean consumed = mContentViewCore.onHoverEvent(offset);
497         offset.recycle();
498         super.onHoverEvent(event);
499         return consumed;
500     }
501
502     @Override
503     public boolean onGenericMotionEvent(MotionEvent event) {
504         return mContentViewCore.onGenericMotionEvent(event);
505     }
506
507     @Override
508     public boolean performLongClick() {
509         return false;
510     }
511
512     /**
513      * Sets the current amount to offset incoming touch events by.  This is used to handle content
514      * moving and not lining up properly with the android input system.
515      * @param dx The X offset in pixels to shift touch events.
516      * @param dy The Y offset in pixels to shift touch events.
517      */
518     public void setCurrentMotionEventOffsets(float dx, float dy) {
519         mCurrentTouchOffsetX = dx;
520         mCurrentTouchOffsetY = dy;
521     }
522
523     private MotionEvent createOffsetMotionEvent(MotionEvent src) {
524         MotionEvent dst = MotionEvent.obtain(src);
525         dst.offsetLocation(mCurrentTouchOffsetX, mCurrentTouchOffsetY);
526         return dst;
527     }
528
529     @Override
530     protected void onConfigurationChanged(Configuration newConfig) {
531         mContentViewCore.onConfigurationChanged(newConfig);
532     }
533
534     /**
535      * Currently the ContentView scrolling happens in the native side. In
536      * the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
537      * are overridden, so that View's mScrollX and mScrollY will be unchanged at
538      * (0, 0). This is critical for drawing ContentView correctly.
539      */
540     @Override
541     public void scrollBy(int x, int y) {
542         mContentViewCore.scrollBy(x, y);
543     }
544
545     @Override
546     public void scrollTo(int x, int y) {
547         mContentViewCore.scrollTo(x, y);
548     }
549
550     @Override
551     protected int computeHorizontalScrollExtent() {
552         // TODO (dtrainor): Need to expose scroll events properly to public. Either make getScroll*
553         // work or expose computeHorizontalScrollOffset()/computeVerticalScrollOffset as public.
554         return mContentViewCore.computeHorizontalScrollExtent();
555     }
556
557     @Override
558     protected int computeHorizontalScrollOffset() {
559         return mContentViewCore.computeHorizontalScrollOffset();
560     }
561
562     @Override
563     protected int computeHorizontalScrollRange() {
564         return mContentViewCore.computeHorizontalScrollRange();
565     }
566
567     @Override
568     protected int computeVerticalScrollExtent() {
569         return mContentViewCore.computeVerticalScrollExtent();
570     }
571
572     @Override
573     protected int computeVerticalScrollOffset() {
574         return mContentViewCore.computeVerticalScrollOffset();
575     }
576
577     @Override
578     protected int computeVerticalScrollRange() {
579         return mContentViewCore.computeVerticalScrollRange();
580     }
581
582     // End FrameLayout overrides.
583
584     @Override
585     public boolean awakenScrollBars(int startDelay, boolean invalidate) {
586         return mContentViewCore.awakenScrollBars(startDelay, invalidate);
587     }
588
589     @Override
590     public boolean awakenScrollBars() {
591         return super.awakenScrollBars();
592     }
593
594     public int getSingleTapX()  {
595         return mContentViewCore.getContentViewGestureHandler().getSingleTapX();
596     }
597
598     public int getSingleTapY()  {
599         return mContentViewCore.getContentViewGestureHandler().getSingleTapY();
600     }
601
602     @Override
603     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
604         super.onInitializeAccessibilityNodeInfo(info);
605         mContentViewCore.onInitializeAccessibilityNodeInfo(info);
606     }
607
608     /**
609      * Fills in scrolling values for AccessibilityEvents.
610      * @param event Event being fired.
611      */
612     @Override
613     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
614         super.onInitializeAccessibilityEvent(event);
615         mContentViewCore.onInitializeAccessibilityEvent(event);
616     }
617
618     @Override
619     protected void onAttachedToWindow() {
620         super.onAttachedToWindow();
621         mContentViewCore.onAttachedToWindow();
622     }
623
624     @Override
625     protected void onDetachedFromWindow() {
626         super.onDetachedFromWindow();
627         mContentViewCore.onDetachedFromWindow();
628     }
629
630     @Override
631     protected void onVisibilityChanged(View changedView, int visibility) {
632         super.onVisibilityChanged(changedView, visibility);
633         mContentViewCore.onVisibilityChanged(changedView, visibility);
634     }
635
636     /**
637      * Register the delegate to be used when content can not be handled by
638      * the rendering engine, and should be downloaded instead. This will replace
639      * the current delegate.
640      * @param delegate An implementation of ContentViewDownloadDelegate.
641      */
642     public void setDownloadDelegate(ContentViewDownloadDelegate delegate) {
643         mContentViewCore.setDownloadDelegate(delegate);
644     }
645
646     // Called by DownloadController.
647     ContentViewDownloadDelegate getDownloadDelegate() {
648         return mContentViewCore.getDownloadDelegate();
649     }
650
651     public boolean getUseDesktopUserAgent() {
652         return mContentViewCore.getUseDesktopUserAgent();
653     }
654
655     /**
656      * Set whether or not we're using a desktop user agent for the currently loaded page.
657      * @param override If true, use a desktop user agent.  Use a mobile one otherwise.
658      * @param reloadOnChange Reload the page if the UA has changed.
659      */
660     public void setUseDesktopUserAgent(boolean override, boolean reloadOnChange) {
661         mContentViewCore.setUseDesktopUserAgent(override, reloadOnChange);
662     }
663
664     /**
665      * @return Whether the native ContentView has crashed.
666      */
667     public boolean isCrashed() {
668         return mContentViewCore.isCrashed();
669     }
670
671     /**
672      * Zooms in the WebView by 25% (or less if that would result in zooming in
673      * more than possible).
674      *
675      * @return True if there was a zoom change, false otherwise.
676      */
677     // This method uses the term 'zoom' for legacy reasons, but relates
678     // to what chrome calls the 'page scale factor'.
679     public boolean zoomIn() {
680         return mContentViewCore.zoomIn();
681     }
682
683     /**
684      * Zooms out the WebView by 20% (or less if that would result in zooming out
685      * more than possible).
686      *
687      * @return True if there was a zoom change, false otherwise.
688      */
689     // This method uses the term 'zoom' for legacy reasons, but relates
690     // to what chrome calls the 'page scale factor'.
691     public boolean zoomOut() {
692         return mContentViewCore.zoomOut();
693     }
694
695     /**
696      * Resets the zoom factor of the WebView.
697      *
698      * @return True if there was a zoom change, false otherwise.
699      */
700     // This method uses the term 'zoom' for legacy reasons, but relates
701     // to what chrome calls the 'page scale factor'.
702     public boolean zoomReset() {
703         return mContentViewCore.zoomReset();
704     }
705
706     /**
707      * Return the current scale of the WebView
708      * @return The current scale.
709      */
710     public float getScale() {
711         return mContentViewCore.getScale();
712     }
713
714     /**
715      * If the view is ready to draw contents to the screen. In hardware mode,
716      * the initialization of the surface texture may not occur until after the
717      * view has been added to the layout. This method will return {@code true}
718      * once the texture is actually ready.
719      */
720     public boolean isReady() {
721         return mContentViewCore.isReady();
722     }
723
724     /**
725      * Returns whether or not accessibility injection is being used.
726      */
727     public boolean isInjectingAccessibilityScript() {
728         return mContentViewCore.isInjectingAccessibilityScript();
729     }
730
731     /**
732      * Enable or disable accessibility features.
733      */
734     public void setAccessibilityState(boolean state) {
735         mContentViewCore.setAccessibilityState(state);
736     }
737
738     /**
739      * Stop any TTS notifications that are currently going on.
740      */
741     public void stopCurrentAccessibilityNotifications() {
742         mContentViewCore.stopCurrentAccessibilityNotifications();
743     }
744
745     /**
746      * Inform WebKit that Fullscreen mode has been exited by the user.
747      */
748     public void exitFullscreen() {
749         mContentViewCore.exitFullscreen();
750     }
751
752     /**
753      * Return content scroll y.
754      *
755      * @return The vertical scroll position in pixels.
756      */
757     public int getContentScrollY() {
758         return mContentViewCore.computeVerticalScrollOffset();
759     }
760
761     /**
762      * Return content height.
763      *
764      * @return The height of the content in pixels.
765      */
766     public int getContentHeight() {
767         return mContentViewCore.computeVerticalScrollRange();
768     }
769
770     ///////////////////////////////////////////////////////////////////////////////////////////////
771     //              Start Implementation of ContentViewCore.InternalAccessDelegate               //
772     ///////////////////////////////////////////////////////////////////////////////////////////////
773
774     @Override
775     public boolean super_onKeyUp(int keyCode, KeyEvent event) {
776         return super.onKeyUp(keyCode, event);
777     }
778
779     @Override
780     public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
781         return super.dispatchKeyEventPreIme(event);
782     }
783
784     @Override
785     public boolean super_dispatchKeyEvent(KeyEvent event) {
786         return super.dispatchKeyEvent(event);
787     }
788
789     @Override
790     public boolean super_onGenericMotionEvent(MotionEvent event) {
791         return super.onGenericMotionEvent(event);
792     }
793
794     @Override
795     public void super_onConfigurationChanged(Configuration newConfig) {
796         super.onConfigurationChanged(newConfig);
797     }
798
799     @Override
800     public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
801         return super.awakenScrollBars(startDelay, invalidate);
802     }
803
804     ///////////////////////////////////////////////////////////////////////////////////////////////
805     //                End Implementation of ContentViewCore.InternalAccessDelegate               //
806     ///////////////////////////////////////////////////////////////////////////////////////////////
807 }