1 // Copyright 2014 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.chrome.shell;
7 import android.content.Context;
8 import android.content.res.Configuration;
9 import android.graphics.drawable.ClipDrawable;
10 import android.util.AttributeSet;
11 import android.view.KeyEvent;
12 import android.view.MotionEvent;
13 import android.view.View;
14 import android.view.inputmethod.EditorInfo;
15 import android.view.inputmethod.InputMethodManager;
16 import android.widget.EditText;
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.CommandLine;
23 import org.chromium.chrome.browser.EmptyTabObserver;
24 import org.chromium.chrome.browser.Tab;
25 import org.chromium.chrome.browser.TabObserver;
26 import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper;
27 import org.chromium.chrome.browser.appmenu.AppMenuHandler;
28 import org.chromium.chrome.shell.omnibox.SuggestionPopup;
29 import org.chromium.content.common.ContentSwitches;
32 * A Toolbar {@link View} that shows the URL and navigation buttons.
34 public class ChromeShellToolbar extends LinearLayout {
35 private static final long COMPLETED_PROGRESS_TIMEOUT_MS = 200;
37 private final Runnable mClearProgressRunnable = new Runnable() {
40 mProgressDrawable.setLevel(0);
44 private EditText mUrlTextView;
45 private ClipDrawable mProgressDrawable;
47 private ChromeShellTab mTab;
48 private final TabObserver mTabObserver;
50 private AppMenuHandler mMenuHandler;
51 private AppMenuButtonHelper mAppMenuButtonHelper;
53 private SuggestionPopup mSuggestionPopup;
56 * @param context The Context the view is running in.
57 * @param attrs The attributes of the XML tag that is inflating the view.
59 public ChromeShellToolbar(Context context, AttributeSet attrs) {
60 super(context, attrs);
61 // When running performance benchmark, we don't want to observe the tab
62 // invalidation which would interfere with browser's processing content
63 // frame. See crbug.com/394976.
64 if (CommandLine.getInstance().hasSwitch(
65 ContentSwitches.RUNNING_PERFORMANCE_BENCHMARK)) {
66 mTabObserver = new EmptyTabObserver();
68 mTabObserver = new TabObserverImpl();
73 * The toolbar will visually represent the state of {@code tab}.
74 * @param tab The Tab that should be represented.
76 public void showTab(ChromeShellTab tab) {
77 if (mTab != null) mTab.removeObserver(mTabObserver);
79 mTab.addObserver(mTabObserver);
80 mUrlTextView.setText(mTab.getContentViewCore().getUrl());
83 private void onUpdateUrl(String url) {
84 mUrlTextView.setText(url);
87 private void onLoadProgressChanged(int progress) {
88 removeCallbacks(mClearProgressRunnable);
89 mProgressDrawable.setLevel(100 * progress);
90 if (progress == 100) postDelayed(mClearProgressRunnable, COMPLETED_PROGRESS_TIMEOUT_MS);
94 * Closes the suggestion popup.
96 public void hideSuggestions() {
97 if (mSuggestionPopup != null) mSuggestionPopup.hideSuggestions();
101 protected void onFinishInflate() {
102 super.onFinishInflate();
104 mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground();
105 initializeUrlField();
106 initializeMenuButton();
109 void setMenuHandler(AppMenuHandler menuHandler) {
110 mMenuHandler = menuHandler;
111 ImageButton menuButton = (ImageButton) findViewById(R.id.menu_button);
112 mAppMenuButtonHelper = new AppMenuButtonHelper(menuButton, mMenuHandler);
115 private void initializeUrlField() {
116 mUrlTextView = (EditText) findViewById(R.id.url);
117 mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
119 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
120 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null ||
121 event.getKeyCode() != KeyEvent.KEYCODE_ENTER ||
122 event.getAction() != KeyEvent.ACTION_DOWN)) {
126 mTab.loadUrlWithSanitization(mUrlTextView.getText().toString());
127 mUrlTextView.clearFocus();
128 setKeyboardVisibilityForUrl(false);
129 mTab.getView().requestFocus();
133 mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
135 public void onFocusChange(View v, boolean hasFocus) {
136 setKeyboardVisibilityForUrl(hasFocus);
138 mUrlTextView.setText(mTab.getContentViewCore().getUrl());
139 mSuggestionPopup.dismissPopup();
144 mSuggestionPopup = new SuggestionPopup(getContext(), mUrlTextView, this);
145 mUrlTextView.addTextChangedListener(mSuggestionPopup);
148 private void initializeMenuButton() {
149 ImageButton menuButton = (ImageButton) findViewById(R.id.menu_button);
150 menuButton.setOnClickListener(new OnClickListener() {
152 public void onClick(View view) {
153 if (mMenuHandler != null) mMenuHandler.showAppMenu(view, false, false);
156 menuButton.setOnTouchListener(new OnTouchListener() {
158 public boolean onTouch(View view, MotionEvent event) {
159 return mAppMenuButtonHelper != null && mAppMenuButtonHelper.onTouch(view, event);
165 * @return Current tab that is shown by ChromeShell.
167 public ChromeShellTab getCurrentTab() {
172 * Change the visibility of the software keyboard.
173 * @param visible Whether the keyboard should be shown or hidden.
175 public void setKeyboardVisibilityForUrl(boolean visible) {
176 InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
177 Context.INPUT_METHOD_SERVICE);
179 imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
181 imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
186 protected void onConfigurationChanged(Configuration newConfig) {
187 super.onConfigurationChanged(newConfig);
188 if (mMenuHandler != null) mMenuHandler.hideAppMenu();
191 private class TabObserverImpl extends EmptyTabObserver {
193 public void onLoadProgressChanged(Tab tab, int progress) {
194 if (tab == mTab) ChromeShellToolbar.this.onLoadProgressChanged(progress);
198 public void onUpdateUrl(Tab tab, String url) {
199 if (tab == mTab) ChromeShellToolbar.this.onUpdateUrl(url);