• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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.content.Context;
8 import android.content.res.Configuration;
9 import android.graphics.Canvas;
10 import android.graphics.Rect;
11 import android.os.Build;
12 import android.os.Bundle;
13 import android.os.Handler;
14 import android.os.Message;
15 import android.util.Log;
16 import android.view.KeyEvent;
17 import android.view.MotionEvent;
18 import android.view.View;
19 import android.view.accessibility.AccessibilityEvent;
20 import android.view.accessibility.AccessibilityNodeInfo;
21 import android.view.inputmethod.EditorInfo;
22 import android.view.inputmethod.InputConnection;
23 import android.widget.FrameLayout;
24 
25 import org.chromium.base.TraceEvent;
26 
27 /**
28  * The containing view for {@link ContentViewCore} that exists in the Android UI hierarchy and
29  * exposes the various {@link View} functionality to it.
30  */
31 public class ContentView extends FrameLayout
32         implements ContentViewCore.InternalAccessDelegate, SmartClipProvider {
33 
34     private static final String TAG = "ContentView";
35 
36     protected final ContentViewCore mContentViewCore;
37 
38     /**
39      * Creates an instance of a ContentView.
40      * @param context The Context the view is running in, through which it can
41      *                access the current theme, resources, etc.
42      * @param cvc A pointer to the content view core managing this content view.
43      * @return A ContentView instance.
44      */
newInstance(Context context, ContentViewCore cvc)45     public static ContentView newInstance(Context context, ContentViewCore cvc) {
46         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
47             return new ContentView(context, cvc);
48         } else {
49             return new JellyBeanContentView(context, cvc);
50         }
51     }
52 
ContentView(Context context, ContentViewCore cvc)53     protected ContentView(Context context, ContentViewCore cvc) {
54         super(context, null, android.R.attr.webViewStyle);
55 
56         if (getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
57             setHorizontalScrollBarEnabled(false);
58             setVerticalScrollBarEnabled(false);
59         }
60 
61         setFocusable(true);
62         setFocusableInTouchMode(true);
63 
64         mContentViewCore = cvc;
65     }
66 
67     // Needed by ContentViewCore.InternalAccessDelegate
68     @Override
drawChild(Canvas canvas, View child, long drawingTime)69     public boolean drawChild(Canvas canvas, View child, long drawingTime) {
70         return super.drawChild(canvas, child, drawingTime);
71     }
72 
73     // Needed by ContentViewCore.InternalAccessDelegate
74     @Override
onScrollChanged(int l, int t, int oldl, int oldt)75     public void onScrollChanged(int l, int t, int oldl, int oldt) {
76         super.onScrollChanged(l, t, oldl, oldt);
77     }
78 
79     @Override
onSizeChanged(int w, int h, int ow, int oh)80     protected void onSizeChanged(int w, int h, int ow, int oh) {
81         TraceEvent.begin();
82         super.onSizeChanged(w, h, ow, oh);
83         mContentViewCore.onSizeChanged(w, h, ow, oh);
84         TraceEvent.end();
85     }
86 
87     @Override
onCreateInputConnection(EditorInfo outAttrs)88     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
89         return mContentViewCore.onCreateInputConnection(outAttrs);
90     }
91 
92     @Override
onCheckIsTextEditor()93     public boolean onCheckIsTextEditor() {
94         return mContentViewCore.onCheckIsTextEditor();
95     }
96 
97     @Override
onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)98     protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
99         TraceEvent.begin();
100         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
101         mContentViewCore.onFocusChanged(gainFocus);
102         TraceEvent.end();
103     }
104 
105     @Override
onWindowFocusChanged(boolean hasWindowFocus)106     public void onWindowFocusChanged(boolean hasWindowFocus) {
107         super.onWindowFocusChanged(hasWindowFocus);
108         mContentViewCore.onWindowFocusChanged(hasWindowFocus);
109     }
110 
111     @Override
onKeyUp(int keyCode, KeyEvent event)112     public boolean onKeyUp(int keyCode, KeyEvent event) {
113         return mContentViewCore.onKeyUp(keyCode, event);
114     }
115 
116     @Override
dispatchKeyEventPreIme(KeyEvent event)117     public boolean dispatchKeyEventPreIme(KeyEvent event) {
118         return mContentViewCore.dispatchKeyEventPreIme(event);
119     }
120 
121     @Override
dispatchKeyEvent(KeyEvent event)122     public boolean dispatchKeyEvent(KeyEvent event) {
123         if (isFocused()) {
124             return mContentViewCore.dispatchKeyEvent(event);
125         } else {
126             return super.dispatchKeyEvent(event);
127         }
128     }
129 
130     @Override
onTouchEvent(MotionEvent event)131     public boolean onTouchEvent(MotionEvent event) {
132         return mContentViewCore.onTouchEvent(event);
133     }
134 
135     /**
136      * Mouse move events are sent on hover enter, hover move and hover exit.
137      * They are sent on hover exit because sometimes it acts as both a hover
138      * move and hover exit.
139      */
140     @Override
onHoverEvent(MotionEvent event)141     public boolean onHoverEvent(MotionEvent event) {
142         boolean consumed = mContentViewCore.onHoverEvent(event);
143         if (!mContentViewCore.isTouchExplorationEnabled()) super.onHoverEvent(event);
144         return consumed;
145     }
146 
147     @Override
onGenericMotionEvent(MotionEvent event)148     public boolean onGenericMotionEvent(MotionEvent event) {
149         return mContentViewCore.onGenericMotionEvent(event);
150     }
151 
152     @Override
performLongClick()153     public boolean performLongClick() {
154         return false;
155     }
156 
157     @Override
onConfigurationChanged(Configuration newConfig)158     protected void onConfigurationChanged(Configuration newConfig) {
159         mContentViewCore.onConfigurationChanged(newConfig);
160     }
161 
162     /**
163      * Currently the ContentView scrolling happens in the native side. In
164      * the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
165      * are overridden, so that View's mScrollX and mScrollY will be unchanged at
166      * (0, 0). This is critical for drawing ContentView correctly.
167      */
168     @Override
scrollBy(int x, int y)169     public void scrollBy(int x, int y) {
170         mContentViewCore.scrollBy(x, y);
171     }
172 
173     @Override
scrollTo(int x, int y)174     public void scrollTo(int x, int y) {
175         mContentViewCore.scrollTo(x, y);
176     }
177 
178     @Override
computeHorizontalScrollExtent()179     protected int computeHorizontalScrollExtent() {
180         // TODO(dtrainor): Need to expose scroll events properly to public. Either make getScroll*
181         // work or expose computeHorizontalScrollOffset()/computeVerticalScrollOffset as public.
182         return mContentViewCore.computeHorizontalScrollExtent();
183     }
184 
185     @Override
computeHorizontalScrollOffset()186     protected int computeHorizontalScrollOffset() {
187         return mContentViewCore.computeHorizontalScrollOffset();
188     }
189 
190     @Override
computeHorizontalScrollRange()191     protected int computeHorizontalScrollRange() {
192         return mContentViewCore.computeHorizontalScrollRange();
193     }
194 
195     @Override
computeVerticalScrollExtent()196     protected int computeVerticalScrollExtent() {
197         return mContentViewCore.computeVerticalScrollExtent();
198     }
199 
200     @Override
computeVerticalScrollOffset()201     protected int computeVerticalScrollOffset() {
202         return mContentViewCore.computeVerticalScrollOffset();
203     }
204 
205     @Override
computeVerticalScrollRange()206     protected int computeVerticalScrollRange() {
207         return mContentViewCore.computeVerticalScrollRange();
208     }
209 
210     // End FrameLayout overrides.
211 
212     @Override
awakenScrollBars(int startDelay, boolean invalidate)213     public boolean awakenScrollBars(int startDelay, boolean invalidate) {
214         return mContentViewCore.awakenScrollBars(startDelay, invalidate);
215     }
216 
217     @Override
awakenScrollBars()218     public boolean awakenScrollBars() {
219         return super.awakenScrollBars();
220     }
221 
222     @Override
onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)223     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
224         super.onInitializeAccessibilityNodeInfo(info);
225         mContentViewCore.onInitializeAccessibilityNodeInfo(info);
226     }
227 
228     /**
229      * Fills in scrolling values for AccessibilityEvents.
230      * @param event Event being fired.
231      */
232     @Override
onInitializeAccessibilityEvent(AccessibilityEvent event)233     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
234         super.onInitializeAccessibilityEvent(event);
235         mContentViewCore.onInitializeAccessibilityEvent(event);
236     }
237 
238     @Override
onAttachedToWindow()239     protected void onAttachedToWindow() {
240         super.onAttachedToWindow();
241         mContentViewCore.onAttachedToWindow();
242     }
243 
244     @Override
onDetachedFromWindow()245     protected void onDetachedFromWindow() {
246         super.onDetachedFromWindow();
247         mContentViewCore.onDetachedFromWindow();
248     }
249 
250     @Override
onVisibilityChanged(View changedView, int visibility)251     protected void onVisibilityChanged(View changedView, int visibility) {
252         super.onVisibilityChanged(changedView, visibility);
253         mContentViewCore.onVisibilityChanged(changedView, visibility);
254     }
255 
256     // Implements SmartClipProvider
257     @Override
extractSmartClipData(int x, int y, int width, int height)258     public void extractSmartClipData(int x, int y, int width, int height) {
259         mContentViewCore.extractSmartClipData(x, y, width, height);
260     }
261 
262     // Implements SmartClipProvider
263     @Override
setSmartClipResultHandler(final Handler resultHandler)264     public void setSmartClipResultHandler(final Handler resultHandler) {
265         if (resultHandler == null) {
266             mContentViewCore.setSmartClipDataListener(null);
267             return;
268         }
269         mContentViewCore.setSmartClipDataListener(new ContentViewCore.SmartClipDataListener() {
270             public void onSmartClipDataExtracted(String text, String html, Rect clipRect) {
271                 Bundle bundle = new Bundle();
272                 bundle.putString("url", mContentViewCore.getWebContents().getVisibleUrl());
273                 bundle.putString("title", mContentViewCore.getWebContents().getTitle());
274                 bundle.putParcelable("rect", clipRect);
275                 bundle.putString("text", text);
276                 bundle.putString("html", html);
277                 try {
278                     Message msg = Message.obtain(resultHandler, 0);
279                     msg.setData(bundle);
280                     msg.sendToTarget();
281                 } catch (Exception e) {
282                     Log.e(TAG, "Error calling handler for smart clip data: ", e);
283                 }
284             }
285         });
286     }
287 
288     ///////////////////////////////////////////////////////////////////////////////////////////////
289     //              Start Implementation of ContentViewCore.InternalAccessDelegate               //
290     ///////////////////////////////////////////////////////////////////////////////////////////////
291 
292     @Override
super_onKeyUp(int keyCode, KeyEvent event)293     public boolean super_onKeyUp(int keyCode, KeyEvent event) {
294         return super.onKeyUp(keyCode, event);
295     }
296 
297     @Override
super_dispatchKeyEventPreIme(KeyEvent event)298     public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
299         return super.dispatchKeyEventPreIme(event);
300     }
301 
302     @Override
super_dispatchKeyEvent(KeyEvent event)303     public boolean super_dispatchKeyEvent(KeyEvent event) {
304         return super.dispatchKeyEvent(event);
305     }
306 
307     @Override
super_onGenericMotionEvent(MotionEvent event)308     public boolean super_onGenericMotionEvent(MotionEvent event) {
309         return super.onGenericMotionEvent(event);
310     }
311 
312     @Override
super_onConfigurationChanged(Configuration newConfig)313     public void super_onConfigurationChanged(Configuration newConfig) {
314         super.onConfigurationChanged(newConfig);
315     }
316 
317     @Override
super_awakenScrollBars(int startDelay, boolean invalidate)318     public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
319         return super.awakenScrollBars(startDelay, invalidate);
320     }
321 
322     ///////////////////////////////////////////////////////////////////////////////////////////////
323     //                End Implementation of ContentViewCore.InternalAccessDelegate               //
324     ///////////////////////////////////////////////////////////////////////////////////////////////
325 }
326