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.
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.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 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 ContentViewRenderView mContentViewRenderView;
53 private WindowAndroid mWindow;
55 private boolean mLoading = false;
58 * Constructor for inflating via XML.
60 public Shell(Context context, AttributeSet attrs) {
61 super(context, attrs);
65 * Set the SurfaceView being renderered to as soon as it is available.
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);
74 contentViewHolder.addView(contentViewRenderView,
75 new FrameLayout.LayoutParams(
76 FrameLayout.LayoutParams.MATCH_PARENT,
77 FrameLayout.LayoutParams.MATCH_PARENT));
79 mContentViewRenderView = contentViewRenderView;
83 * @param window The owning window for this shell.
85 public void setWindow(WindowAndroid window) {
90 * @return Whether or not the Shell is loading content.
92 public boolean isLoading() {
97 protected void onFinishInflate() {
98 super.onFinishInflate();
100 mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground();
101 initializeUrlField();
102 initializeNavigationButtons();
105 private void initializeUrlField() {
106 mUrlTextView = (EditText) findViewById(R.id.url);
107 mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
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)) {
115 loadUrl(mUrlTextView.getText().toString());
116 setKeyboardVisibilityForUrl(false);
117 mContentView.requestFocus();
121 mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
123 public void onFocusChange(View v, boolean hasFocus) {
124 setKeyboardVisibilityForUrl(hasFocus);
125 mNextButton.setVisibility(hasFocus ? GONE : VISIBLE);
126 mPrevButton.setVisibility(hasFocus ? GONE : VISIBLE);
128 mUrlTextView.setText(mContentView.getUrl());
135 * Loads an URL. This will perform minimal amounts of sanitizing of the URL to attempt to
138 * @param url The URL to be loaded by the shell.
140 public void loadUrl(String url) {
141 if (url == null) return;
143 if (TextUtils.equals(url, mContentView.getUrl())) {
144 mContentView.reload();
146 mContentView.loadUrl(new LoadUrlParams(sanitizeUrl(url)));
148 mUrlTextView.clearFocus();
149 // TODO(aurimas): Remove this when crbug.com/174541 is fixed.
150 mContentView.clearFocus();
151 mContentView.requestFocus();
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.
159 public static String sanitizeUrl(String url) {
160 if (url == null) return url;
161 if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
165 private void initializeNavigationButtons() {
166 mPrevButton = (ImageButton) findViewById(R.id.prev);
167 mPrevButton.setOnClickListener(new OnClickListener() {
169 public void onClick(View v) {
170 if (mContentView.canGoBack()) mContentView.goBack();
174 mNextButton = (ImageButton) findViewById(R.id.next);
175 mNextButton.setOnClickListener(new OnClickListener() {
177 public void onClick(View v) {
178 if (mContentView.canGoForward()) mContentView.goForward();
183 @SuppressWarnings("unused")
185 private void onUpdateUrl(String url) {
186 mUrlTextView.setText(url);
189 @SuppressWarnings("unused")
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);
198 private void toggleFullscreenModeForTab(boolean enterFullscreen) {
202 private boolean isFullscreenForTabOrPending() {
206 @SuppressWarnings("unused")
208 private void setIsLoading(boolean loading) {
213 * Initializes the ContentView based on the native tab contents pointer passed in.
214 * @param nativeTabContents The pointer to the native tab contents object.
216 @SuppressWarnings("unused")
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);
230 * @return The {@link ContentView} currently shown by this Shell.
232 public ContentView getContentView() {
236 private void setKeyboardVisibilityForUrl(boolean visible) {
237 InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
238 Context.INPUT_METHOD_SERVICE);
240 imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
242 imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);