- add sources.
[platform/framework/web/crosswalk.git] / src / content / shell / android / java / src / org / chromium / content_shell / Shell.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_shell;
6
7 import android.content.Context;
8 import android.graphics.drawable.ClipDrawable;
9 import android.text.TextUtils;
10 import android.util.AttributeSet;
11 import android.view.KeyEvent;
12 import android.view.View;
13 import android.view.inputmethod.EditorInfo;
14 import android.view.inputmethod.InputMethodManager;
15 import android.widget.EditText;
16 import android.widget.FrameLayout;
17 import android.widget.ImageButton;
18 import android.widget.LinearLayout;
19 import android.widget.TextView;
20 import android.widget.TextView.OnEditorActionListener;
21
22 import org.chromium.base.CalledByNative;
23 import org.chromium.base.JNINamespace;
24 import org.chromium.content.browser.ContentView;
25 import org.chromium.content.browser.ContentViewRenderView;
26 import org.chromium.content.browser.LoadUrlParams;
27 import org.chromium.ui.WindowAndroid;
28
29 /**
30  * Container for the various UI components that make up a shell window.
31  */
32 @JNINamespace("content")
33 public class Shell extends LinearLayout {
34
35     private static final long COMPLETED_PROGRESS_TIMEOUT_MS = 200;
36
37     private Runnable mClearProgressRunnable = new Runnable() {
38         @Override
39         public void run() {
40             mProgressDrawable.setLevel(0);
41         }
42     };
43
44     // TODO(jrg): a mContentView.destroy() call is needed, both upstream and downstream.
45     private ContentView mContentView;
46     private EditText mUrlTextView;
47     private ImageButton mPrevButton;
48     private ImageButton mNextButton;
49
50     private ClipDrawable mProgressDrawable;
51
52     private ContentViewRenderView mContentViewRenderView;
53     private WindowAndroid mWindow;
54
55     private boolean mLoading = false;
56
57     /**
58      * Constructor for inflating via XML.
59      */
60     public Shell(Context context, AttributeSet attrs) {
61         super(context, attrs);
62     }
63
64     /**
65      * Set the SurfaceView being renderered to as soon as it is available.
66      */
67     public void setContentViewRenderView(ContentViewRenderView contentViewRenderView) {
68         FrameLayout contentViewHolder = (FrameLayout) findViewById(R.id.contentview_holder);
69         if (contentViewRenderView == null) {
70             if (mContentViewRenderView != null) {
71                 contentViewHolder.removeView(mContentViewRenderView);
72             }
73         } else {
74             contentViewHolder.addView(contentViewRenderView,
75                     new FrameLayout.LayoutParams(
76                             FrameLayout.LayoutParams.MATCH_PARENT,
77                             FrameLayout.LayoutParams.MATCH_PARENT));
78         }
79         mContentViewRenderView = contentViewRenderView;
80     }
81
82     /**
83      * @param window The owning window for this shell.
84      */
85     public void setWindow(WindowAndroid window) {
86         mWindow = window;
87     }
88
89     /**
90      * @return Whether or not the Shell is loading content.
91      */
92     public boolean isLoading() {
93         return mLoading;
94     }
95
96     @Override
97     protected void onFinishInflate() {
98         super.onFinishInflate();
99
100         mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground();
101         initializeUrlField();
102         initializeNavigationButtons();
103     }
104
105     private void initializeUrlField() {
106         mUrlTextView = (EditText) findViewById(R.id.url);
107         mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
108             @Override
109             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
110                 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null ||
111                         event.getKeyCode() != KeyEvent.KEYCODE_ENTER ||
112                         event.getAction() != KeyEvent.ACTION_DOWN)) {
113                     return false;
114                 }
115                 loadUrl(mUrlTextView.getText().toString());
116                 setKeyboardVisibilityForUrl(false);
117                 mContentView.requestFocus();
118                 return true;
119             }
120         });
121         mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
122             @Override
123             public void onFocusChange(View v, boolean hasFocus) {
124                 setKeyboardVisibilityForUrl(hasFocus);
125                 mNextButton.setVisibility(hasFocus ? GONE : VISIBLE);
126                 mPrevButton.setVisibility(hasFocus ? GONE : VISIBLE);
127                 if (!hasFocus) {
128                     mUrlTextView.setText(mContentView.getUrl());
129                 }
130             }
131         });
132     }
133
134     /**
135      * Loads an URL.  This will perform minimal amounts of sanitizing of the URL to attempt to
136      * make it valid.
137      *
138      * @param url The URL to be loaded by the shell.
139      */
140     public void loadUrl(String url) {
141         if (url == null) return;
142
143         if (TextUtils.equals(url, mContentView.getUrl())) {
144             mContentView.reload();
145         } else {
146             mContentView.loadUrl(new LoadUrlParams(sanitizeUrl(url)));
147         }
148         mUrlTextView.clearFocus();
149         // TODO(aurimas): Remove this when crbug.com/174541 is fixed.
150         mContentView.clearFocus();
151         mContentView.requestFocus();
152     }
153
154     /**
155      * Given an URL, this performs minimal sanitizing to ensure it will be valid.
156      * @param url The url to be sanitized.
157      * @return The sanitized URL.
158      */
159     public static String sanitizeUrl(String url) {
160         if (url == null) return url;
161         if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
162         return url;
163     }
164
165     private void initializeNavigationButtons() {
166         mPrevButton = (ImageButton) findViewById(R.id.prev);
167         mPrevButton.setOnClickListener(new OnClickListener() {
168             @Override
169             public void onClick(View v) {
170                 if (mContentView.canGoBack()) mContentView.goBack();
171             }
172         });
173
174         mNextButton = (ImageButton) findViewById(R.id.next);
175         mNextButton.setOnClickListener(new OnClickListener() {
176             @Override
177             public void onClick(View v) {
178                 if (mContentView.canGoForward()) mContentView.goForward();
179             }
180         });
181     }
182
183     @SuppressWarnings("unused")
184     @CalledByNative
185     private void onUpdateUrl(String url) {
186         mUrlTextView.setText(url);
187     }
188
189     @SuppressWarnings("unused")
190     @CalledByNative
191     private void onLoadProgressChanged(double progress) {
192         removeCallbacks(mClearProgressRunnable);
193         mProgressDrawable.setLevel((int) (10000.0 * progress));
194         if (progress == 1.0) postDelayed(mClearProgressRunnable, COMPLETED_PROGRESS_TIMEOUT_MS);
195     }
196
197     @CalledByNative
198     private void toggleFullscreenModeForTab(boolean enterFullscreen) {
199     }
200
201     @CalledByNative
202     private boolean isFullscreenForTabOrPending() {
203         return false;
204     }
205
206     @SuppressWarnings("unused")
207     @CalledByNative
208     private void setIsLoading(boolean loading) {
209         mLoading = loading;
210     }
211
212     /**
213      * Initializes the ContentView based on the native tab contents pointer passed in.
214      * @param nativeTabContents The pointer to the native tab contents object.
215      */
216     @SuppressWarnings("unused")
217     @CalledByNative
218     private void initFromNativeTabContents(int nativeTabContents) {
219         mContentView = ContentView.newInstance(getContext(), nativeTabContents, mWindow);
220         if (mContentView.getUrl() != null) mUrlTextView.setText(mContentView.getUrl());
221         ((FrameLayout) findViewById(R.id.contentview_holder)).addView(mContentView,
222                 new FrameLayout.LayoutParams(
223                         FrameLayout.LayoutParams.MATCH_PARENT,
224                         FrameLayout.LayoutParams.MATCH_PARENT));
225         mContentView.requestFocus();
226         mContentViewRenderView.setCurrentContentView(mContentView);
227     }
228
229     /**
230      * @return The {@link ContentView} currently shown by this Shell.
231      */
232     public ContentView getContentView() {
233         return mContentView;
234     }
235
236     private void setKeyboardVisibilityForUrl(boolean visible) {
237         InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
238                 Context.INPUT_METHOD_SERVICE);
239         if (visible) {
240             imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
241         } else {
242             imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
243         }
244     }
245 }