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.
5 package org
.chromium
.content_shell
;
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
;
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
.base
.WindowAndroid
;
30 * Container for the various UI components that make up a shell window.
32 @JNINamespace("content")
33 public class Shell
extends LinearLayout
{
35 private static final long COMPLETED_PROGRESS_TIMEOUT_MS
= 200;
37 private final Runnable mClearProgressRunnable
= new Runnable() {
40 mProgressDrawable
.setLevel(0);
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
;
50 private ClipDrawable mProgressDrawable
;
52 private long mNativeShell
;
53 private ContentViewRenderView mContentViewRenderView
;
54 private WindowAndroid mWindow
;
56 private boolean mLoading
= false;
59 * Constructor for inflating via XML.
61 public Shell(Context context
, AttributeSet attrs
) {
62 super(context
, attrs
);
66 * Set the SurfaceView being renderered to as soon as it is available.
68 public void setContentViewRenderView(ContentViewRenderView contentViewRenderView
) {
69 FrameLayout contentViewHolder
= (FrameLayout
) findViewById(R
.id
.contentview_holder
);
70 if (contentViewRenderView
== null) {
71 if (mContentViewRenderView
!= null) {
72 contentViewHolder
.removeView(mContentViewRenderView
);
75 contentViewHolder
.addView(contentViewRenderView
,
76 new FrameLayout
.LayoutParams(
77 FrameLayout
.LayoutParams
.MATCH_PARENT
,
78 FrameLayout
.LayoutParams
.MATCH_PARENT
));
80 mContentViewRenderView
= contentViewRenderView
;
84 * Initializes the Shell for use.
86 * @param nativeShell The pointer to the native Shell object.
87 * @param window The owning window for this shell.
89 public void initialize(long nativeShell
, WindowAndroid window
) {
90 mNativeShell
= nativeShell
;
95 * Closes the shell and cleans up the native instance, which will handle destroying all
99 if (mNativeShell
== 0) return;
100 nativeCloseShell(mNativeShell
);
104 private void onNativeDestroyed() {
107 mContentView
.destroy();
111 * @return Whether the Shell has been destroyed.
112 * @see #onNativeDestroyed()
114 public boolean isDestroyed() {
115 return mNativeShell
== 0;
119 * @return Whether or not the Shell is loading content.
121 public boolean isLoading() {
126 protected void onFinishInflate() {
127 super.onFinishInflate();
129 mProgressDrawable
= (ClipDrawable
) findViewById(R
.id
.toolbar
).getBackground();
130 initializeUrlField();
131 initializeNavigationButtons();
134 private void initializeUrlField() {
135 mUrlTextView
= (EditText
) findViewById(R
.id
.url
);
136 mUrlTextView
.setOnEditorActionListener(new OnEditorActionListener() {
138 public boolean onEditorAction(TextView v
, int actionId
, KeyEvent event
) {
139 if ((actionId
!= EditorInfo
.IME_ACTION_GO
) && (event
== null ||
140 event
.getKeyCode() != KeyEvent
.KEYCODE_ENTER
||
141 event
.getAction() != KeyEvent
.ACTION_DOWN
)) {
144 loadUrl(mUrlTextView
.getText().toString());
145 setKeyboardVisibilityForUrl(false);
146 mContentView
.requestFocus();
150 mUrlTextView
.setOnFocusChangeListener(new OnFocusChangeListener() {
152 public void onFocusChange(View v
, boolean hasFocus
) {
153 setKeyboardVisibilityForUrl(hasFocus
);
154 mNextButton
.setVisibility(hasFocus ? GONE
: VISIBLE
);
155 mPrevButton
.setVisibility(hasFocus ? GONE
: VISIBLE
);
157 mUrlTextView
.setText(mContentView
.getUrl());
164 * Loads an URL. This will perform minimal amounts of sanitizing of the URL to attempt to
167 * @param url The URL to be loaded by the shell.
169 public void loadUrl(String url
) {
170 if (url
== null) return;
172 if (TextUtils
.equals(url
, mContentView
.getUrl())) {
173 mContentView
.getContentViewCore().reload(true);
175 mContentView
.loadUrl(new LoadUrlParams(sanitizeUrl(url
)));
177 mUrlTextView
.clearFocus();
178 // TODO(aurimas): Remove this when crbug.com/174541 is fixed.
179 mContentView
.clearFocus();
180 mContentView
.requestFocus();
184 * Given an URL, this performs minimal sanitizing to ensure it will be valid.
185 * @param url The url to be sanitized.
186 * @return The sanitized URL.
188 public static String
sanitizeUrl(String url
) {
189 if (url
== null) return url
;
190 if (url
.startsWith("www.") || url
.indexOf(":") == -1) url
= "http://" + url
;
194 private void initializeNavigationButtons() {
195 mPrevButton
= (ImageButton
) findViewById(R
.id
.prev
);
196 mPrevButton
.setOnClickListener(new OnClickListener() {
198 public void onClick(View v
) {
199 if (mContentView
.canGoBack()) mContentView
.goBack();
203 mNextButton
= (ImageButton
) findViewById(R
.id
.next
);
204 mNextButton
.setOnClickListener(new OnClickListener() {
206 public void onClick(View v
) {
207 if (mContentView
.canGoForward()) mContentView
.goForward();
212 @SuppressWarnings("unused")
214 private void onUpdateUrl(String url
) {
215 mUrlTextView
.setText(url
);
218 @SuppressWarnings("unused")
220 private void onLoadProgressChanged(double progress
) {
221 removeCallbacks(mClearProgressRunnable
);
222 mProgressDrawable
.setLevel((int) (10000.0 * progress
));
223 if (progress
== 1.0) postDelayed(mClearProgressRunnable
, COMPLETED_PROGRESS_TIMEOUT_MS
);
227 private void toggleFullscreenModeForTab(boolean enterFullscreen
) {
231 private boolean isFullscreenForTabOrPending() {
235 @SuppressWarnings("unused")
237 private void setIsLoading(boolean loading
) {
242 * Initializes the ContentView based on the native tab contents pointer passed in.
243 * @param nativeTabContents The pointer to the native tab contents object.
245 @SuppressWarnings("unused")
247 private void initFromNativeTabContents(long nativeTabContents
) {
248 mContentView
= ContentView
.newInstance(getContext(), nativeTabContents
, mWindow
);
249 if (mContentView
.getUrl() != null) mUrlTextView
.setText(mContentView
.getUrl());
250 ((FrameLayout
) findViewById(R
.id
.contentview_holder
)).addView(mContentView
,
251 new FrameLayout
.LayoutParams(
252 FrameLayout
.LayoutParams
.MATCH_PARENT
,
253 FrameLayout
.LayoutParams
.MATCH_PARENT
));
254 mContentView
.requestFocus();
255 mContentViewRenderView
.setCurrentContentView(mContentView
);
259 * @return The {@link ContentView} currently shown by this Shell.
261 public ContentView
getContentView() {
265 private void setKeyboardVisibilityForUrl(boolean visible
) {
266 InputMethodManager imm
= (InputMethodManager
) getContext().getSystemService(
267 Context
.INPUT_METHOD_SERVICE
);
269 imm
.showSoftInput(mUrlTextView
, InputMethodManager
.SHOW_IMPLICIT
);
271 imm
.hideSoftInputFromWindow(mUrlTextView
.getWindowToken(), 0);
275 private static native void nativeCloseShell(long shellPtr
);