Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / content / public / android / java / src / org / chromium / content / browser / ContentView.java
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      */
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
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
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
75     public void onScrollChanged(int l, int t, int oldl, int oldt) {
76         super.onScrollChanged(l, t, oldl, oldt);
77     }
78
79     @Override
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
88     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
89         return mContentViewCore.onCreateInputConnection(outAttrs);
90     }
91
92     @Override
93     public boolean onCheckIsTextEditor() {
94         return mContentViewCore.onCheckIsTextEditor();
95     }
96
97     @Override
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
106     public void onWindowFocusChanged(boolean hasWindowFocus) {
107         super.onWindowFocusChanged(hasWindowFocus);
108         mContentViewCore.onWindowFocusChanged(hasWindowFocus);
109     }
110
111     @Override
112     public boolean onKeyUp(int keyCode, KeyEvent event) {
113         return mContentViewCore.onKeyUp(keyCode, event);
114     }
115
116     @Override
117     public boolean dispatchKeyEventPreIme(KeyEvent event) {
118         return mContentViewCore.dispatchKeyEventPreIme(event);
119     }
120
121     @Override
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
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
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
148     public boolean onGenericMotionEvent(MotionEvent event) {
149         return mContentViewCore.onGenericMotionEvent(event);
150     }
151
152     @Override
153     public boolean performLongClick() {
154         return false;
155     }
156
157     @Override
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
169     public void scrollBy(int x, int y) {
170         mContentViewCore.scrollBy(x, y);
171     }
172
173     @Override
174     public void scrollTo(int x, int y) {
175         mContentViewCore.scrollTo(x, y);
176     }
177
178     @Override
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
186     protected int computeHorizontalScrollOffset() {
187         return mContentViewCore.computeHorizontalScrollOffset();
188     }
189
190     @Override
191     protected int computeHorizontalScrollRange() {
192         return mContentViewCore.computeHorizontalScrollRange();
193     }
194
195     @Override
196     protected int computeVerticalScrollExtent() {
197         return mContentViewCore.computeVerticalScrollExtent();
198     }
199
200     @Override
201     protected int computeVerticalScrollOffset() {
202         return mContentViewCore.computeVerticalScrollOffset();
203     }
204
205     @Override
206     protected int computeVerticalScrollRange() {
207         return mContentViewCore.computeVerticalScrollRange();
208     }
209
210     // End FrameLayout overrides.
211
212     @Override
213     public boolean awakenScrollBars(int startDelay, boolean invalidate) {
214         return mContentViewCore.awakenScrollBars(startDelay, invalidate);
215     }
216
217     @Override
218     public boolean awakenScrollBars() {
219         return super.awakenScrollBars();
220     }
221
222     @Override
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
233     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
234         super.onInitializeAccessibilityEvent(event);
235         mContentViewCore.onInitializeAccessibilityEvent(event);
236     }
237
238     @Override
239     protected void onAttachedToWindow() {
240         super.onAttachedToWindow();
241         mContentViewCore.onAttachedToWindow();
242     }
243
244     @Override
245     protected void onDetachedFromWindow() {
246         super.onDetachedFromWindow();
247         mContentViewCore.onDetachedFromWindow();
248     }
249
250     @Override
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
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
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
293     public boolean super_onKeyUp(int keyCode, KeyEvent event) {
294         return super.onKeyUp(keyCode, event);
295     }
296
297     @Override
298     public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
299         return super.dispatchKeyEventPreIme(event);
300     }
301
302     @Override
303     public boolean super_dispatchKeyEvent(KeyEvent event) {
304         return super.dispatchKeyEvent(event);
305     }
306
307     @Override
308     public boolean super_onGenericMotionEvent(MotionEvent event) {
309         return super.onGenericMotionEvent(event);
310     }
311
312     @Override
313     public void super_onConfigurationChanged(Configuration newConfig) {
314         super.onConfigurationChanged(newConfig);
315     }
316
317     @Override
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 }