blob: d1c8d0ec259f78c0fed6c13516099188bbff322a [file] [log] [blame]
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content.browser;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Build;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.FrameLayout;
import org.chromium.base.TraceEvent;
/**
* The containing view for {@link ContentViewCore} that exists in the Android UI hierarchy and
* exposes the various {@link View} functionality to it.
*/
public class ContentView extends FrameLayout
implements ContentViewCore.InternalAccessDelegate {
protected final ContentViewCore mContentViewCore;
/**
* Creates an instance of a ContentView.
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param cvc A pointer to the content view core managing this content view.
* @return A ContentView instance.
*/
public static ContentView newInstance(Context context, ContentViewCore cvc) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
return new ContentView(context, cvc);
} else {
return new JellyBeanContentView(context, cvc);
}
}
protected ContentView(Context context, ContentViewCore cvc) {
super(context, null, android.R.attr.webViewStyle);
if (getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
setHorizontalScrollBarEnabled(false);
setVerticalScrollBarEnabled(false);
}
setFocusable(true);
setFocusableInTouchMode(true);
mContentViewCore = cvc;
}
// Needed by ContentViewCore.InternalAccessDelegate
@Override
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
return super.drawChild(canvas, child, drawingTime);
}
// Needed by ContentViewCore.InternalAccessDelegate
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
@Override
protected void onSizeChanged(int w, int h, int ow, int oh) {
TraceEvent.begin();
super.onSizeChanged(w, h, ow, oh);
mContentViewCore.onSizeChanged(w, h, ow, oh);
TraceEvent.end();
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return mContentViewCore.onCreateInputConnection(outAttrs);
}
@Override
public boolean onCheckIsTextEditor() {
return mContentViewCore.onCheckIsTextEditor();
}
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
TraceEvent.begin();
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
mContentViewCore.onFocusChanged(gainFocus);
TraceEvent.end();
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
mContentViewCore.onWindowFocusChanged(hasWindowFocus);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return mContentViewCore.onKeyUp(keyCode, event);
}
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
return mContentViewCore.dispatchKeyEventPreIme(event);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (isFocused()) {
return mContentViewCore.dispatchKeyEvent(event);
} else {
return super.dispatchKeyEvent(event);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mContentViewCore.onTouchEvent(event);
}
/**
* Mouse move events are sent on hover enter, hover move and hover exit.
* They are sent on hover exit because sometimes it acts as both a hover
* move and hover exit.
*/
@Override
public boolean onHoverEvent(MotionEvent event) {
boolean consumed = mContentViewCore.onHoverEvent(event);
if (!mContentViewCore.isTouchExplorationEnabled()) super.onHoverEvent(event);
return consumed;
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
return mContentViewCore.onGenericMotionEvent(event);
}
@Override
public boolean performLongClick() {
return false;
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
mContentViewCore.onConfigurationChanged(newConfig);
}
/**
* Currently the ContentView scrolling happens in the native side. In
* the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
* are overridden, so that View's mScrollX and mScrollY will be unchanged at
* (0, 0). This is critical for drawing ContentView correctly.
*/
@Override
public void scrollBy(int x, int y) {
mContentViewCore.scrollBy(x, y);
}
@Override
public void scrollTo(int x, int y) {
mContentViewCore.scrollTo(x, y);
}
@Override
protected int computeHorizontalScrollExtent() {
// TODO(dtrainor): Need to expose scroll events properly to public. Either make getScroll*
// work or expose computeHorizontalScrollOffset()/computeVerticalScrollOffset as public.
return mContentViewCore.computeHorizontalScrollExtent();
}
@Override
protected int computeHorizontalScrollOffset() {
return mContentViewCore.computeHorizontalScrollOffset();
}
@Override
protected int computeHorizontalScrollRange() {
return mContentViewCore.computeHorizontalScrollRange();
}
@Override
protected int computeVerticalScrollExtent() {
return mContentViewCore.computeVerticalScrollExtent();
}
@Override
protected int computeVerticalScrollOffset() {
return mContentViewCore.computeVerticalScrollOffset();
}
@Override
protected int computeVerticalScrollRange() {
return mContentViewCore.computeVerticalScrollRange();
}
// End FrameLayout overrides.
@Override
public boolean awakenScrollBars(int startDelay, boolean invalidate) {
return mContentViewCore.awakenScrollBars(startDelay, invalidate);
}
@Override
public boolean awakenScrollBars() {
return super.awakenScrollBars();
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
mContentViewCore.onInitializeAccessibilityNodeInfo(info);
}
/**
* Fills in scrolling values for AccessibilityEvents.
* @param event Event being fired.
*/
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
mContentViewCore.onInitializeAccessibilityEvent(event);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mContentViewCore.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mContentViewCore.onDetachedFromWindow();
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
mContentViewCore.onVisibilityChanged(changedView, visibility);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Start Implementation of ContentViewCore.InternalAccessDelegate //
///////////////////////////////////////////////////////////////////////////////////////////////
@Override
public boolean super_onKeyUp(int keyCode, KeyEvent event) {
return super.onKeyUp(keyCode, event);
}
@Override
public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
return super.dispatchKeyEventPreIme(event);
}
@Override
public boolean super_dispatchKeyEvent(KeyEvent event) {
return super.dispatchKeyEvent(event);
}
@Override
public boolean super_onGenericMotionEvent(MotionEvent event) {
return super.onGenericMotionEvent(event);
}
@Override
public void super_onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
return super.awakenScrollBars(startDelay, invalidate);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// End Implementation of ContentViewCore.InternalAccessDelegate //
///////////////////////////////////////////////////////////////////////////////////////////////
}