toolbar_view.cc revision 010d83a9304c5a91596085d917d248abff47903a
1589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// Copyright 2013 The Chromium Authors. All rights reserved.
2589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// Use of this source code is governed by a BSD-style license that can be
3589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// found in the LICENSE file.
4589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
5589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
6589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
7589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "base/command_line.h"
8589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "base/debug/trace_event.h"
9589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "base/i18n/number_formatting.h"
10589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "base/prefs/pref_service.h"
11589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "base/strings/utf_string_conversions.h"
12589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/app/chrome_command_ids.h"
13589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/chrome_notification_types.h"
14589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/command_updater.h"
154ec5c95bc514e15f726ee5c3b83e1578e3d00d13reed@google.com#include "chrome/browser/extensions/extension_action.h"
16589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/extensions/extension_action_manager.h"
17589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/profiles/profile.h"
18589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/search/search.h"
19589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/themes/theme_service.h"
20589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser.h"
21589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser_command_controller.h"
22589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser_commands.h"
23589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h"
24589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser_instant_controller.h"
25589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser_tabstrip.h"
26589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/browser_window.h"
27589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/global_error/global_error_service.h"
28589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/global_error/global_error_service_factory.h"
29589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/omnibox/omnibox_view.h"
30589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/tabs/tab_strip_model.h"
31589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/toolbar/wrench_menu_model.h"
32589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/view_ids.h"
33589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h"
34589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/extensions/extension_popup.h"
35589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/frame/browser_view.h"
36589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
37589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/location_bar/page_action_with_badge_view.h"
38589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/location_bar/star_view.h"
39589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/location_bar/translate_icon_view.h"
40589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/outdated_upgrade_bubble_view.h"
41589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/back_button.h"
42589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
43589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/home_button.h"
44589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/reload_button.h"
45589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/toolbar_button.h"
46589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/toolbar_origin_chip_view.h"
47589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/wrench_menu.h"
48589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/toolbar/wrench_toolbar_button.h"
4934150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "chrome/browser/upgrade_detector.h"
5034150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "chrome/common/chrome_switches.h"
5134150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "chrome/common/pref_names.h"
5234150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "content/public/browser/browser_accessibility_state.h"
5334150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "content/public/browser/notification_service.h"
5434150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "content/public/browser/render_view_host.h"
5534150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "content/public/browser/user_metrics.h"
5634150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "content/public/browser/web_contents.h"
5734150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#include "grit/chromium_strings.h"
58589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "grit/generated_resources.h"
59589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "grit/theme_resources.h"
60589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/accessibility/ax_view_state.h"
61589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/aura/window.h"
62589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/base/l10n/l10n_util.h"
63589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/base/theme_provider.h"
64589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/base/window_open_disposition.h"
65589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/compositor/layer.h"
66589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/gfx/canvas.h"
67589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/gfx/image/canvas_image_source.h"
68589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/keyboard/keyboard_controller.h"
69589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/native_theme/native_theme_aura.h"
70589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/views/controls/menu/menu_listener.h"
71589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/views/focus/view_storage.h"
72589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/views/widget/tooltip_manager.h"
73589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/views/widget/widget.h"
74589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ui/views/window/non_client_view.h"
75589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
76589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#if defined(OS_WIN)
77589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "base/win/windows_version.h"
78589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/enumerate_modules_model_win.h"
79589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/conflicting_module_view_win.h"
80589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/ui/views/critical_notification_bubble_view.h"
81589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#endif
82589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
83589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#if !defined(OS_CHROMEOS)
84589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/signin/signin_global_error_factory.h"
85589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "chrome/browser/sync/sync_global_error_factory.h"
86589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#endif
87589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
88589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#if defined(USE_ASH)
89589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#include "ash/shell.h"
90589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#endif
91589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
92589708bf7c706348b763e8277004cb160b202bdbrileya@google.comusing base::UserMetricsAction;
93589708bf7c706348b763e8277004cb160b202bdbrileya@google.comusing content::WebContents;
94589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
95589708bf7c706348b763e8277004cb160b202bdbrileya@google.comnamespace {
96589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
97589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// The edge graphics have some built-in spacing/shadowing, so we have to adjust
98589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// our spacing to make it match.
99589708bf7c706348b763e8277004cb160b202bdbrileya@google.comconst int kLeftEdgeSpacing = 3;
10055853db3cce9539746fe202519a534c85ecdf62creed@google.comconst int kRightEdgeSpacing = 2;
101589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
102589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// Ash doesn't use a rounded content area and its top edge has an extra shadow.
103589708bf7c706348b763e8277004cb160b202bdbrileya@google.comconst int kContentShadowHeightAsh = 2;
104589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
105589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// Non-ash uses a rounded content area with no shadow in the assets.
106589708bf7c706348b763e8277004cb160b202bdbrileya@google.comconst int kContentShadowHeight = 0;
107589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
108589708bf7c706348b763e8277004cb160b202bdbrileya@google.combool IsStreamlinedHostedAppsEnabled() {
109589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return CommandLine::ForCurrentProcess()->HasSwitch(
110589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      switches::kEnableStreamlinedHostedApps);
111589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
11255853db3cce9539746fe202519a534c85ecdf62creed@google.com
113589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#if !defined(OS_CHROMEOS)
114589708bf7c706348b763e8277004cb160b202bdbrileya@google.combool HasAshShell() {
115589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#if defined(USE_ASH)
116589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return ash::Shell::HasInstance();
11734150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#else
11834150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  return false;
11934150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org#endif  // USE_ASH
12034150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org}
121589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#endif  // OS_CHROMEOS
12234150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org
12334150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org}  // namespace
124589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
125589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// static
12655853db3cce9539746fe202519a534c85ecdf62creed@google.comconst char ToolbarView::kViewClassName[] = "ToolbarView";
127589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
128589708bf7c706348b763e8277004cb160b202bdbrileya@google.com////////////////////////////////////////////////////////////////////////////////
129589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// ToolbarView, public:
130589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
131589708bf7c706348b763e8277004cb160b202bdbrileya@google.comToolbarView::ToolbarView(Browser* browser)
13234150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org    : back_(NULL),
13334150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      forward_(NULL),
13434150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      reload_(NULL),
13534150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      home_(NULL),
13634150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      location_bar_(NULL),
13734150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      origin_chip_view_(NULL),
13834150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      browser_actions_(NULL),
13934150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      app_menu_(NULL),
14034150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      browser_(browser),
14134150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org      extension_message_bubble_factory_(
142589708bf7c706348b763e8277004cb160b202bdbrileya@google.com          new extensions::ExtensionMessageBubbleFactory(browser->profile(),
143589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                                                        this)) {
14434150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  set_id(VIEW_ID_TOOLBAR);
14534150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org
14698e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com  chrome::AddCommandObserver(browser_, IDC_BACK, this);
14798e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com  chrome::AddCommandObserver(browser_, IDC_FORWARD, this);
148589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  chrome::AddCommandObserver(browser_, IDC_RELOAD, this);
1499c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org  chrome::AddCommandObserver(browser_, IDC_HOME, this);
1509c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org  chrome::AddCommandObserver(browser_, IDC_LOAD_NEW_TAB_PAGE, this);
151589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
152589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  display_mode_ = DISPLAYMODE_LOCATION;
153589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ||
154589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      (browser->is_app() && IsStreamlinedHostedAppsEnabled()))
155589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    display_mode_ = DISPLAYMODE_NORMAL;
156589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
157589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
158589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                 content::NotificationService::AllSources());
159589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (OutdatedUpgradeBubbleView::IsAvailable()) {
16087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    registrar_.Add(this, chrome::NOTIFICATION_OUTDATED_INSTALL,
16187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                   content::NotificationService::AllSources());
16287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    registrar_.Add(this, chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
16387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                   content::NotificationService::AllSources());
164ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org  }
165e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org#if defined(OS_WIN)
16687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  registrar_.Add(this, chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED,
16787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                 content::NotificationService::AllSources());
16887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  if (base::win::GetVersion() == base::win::VERSION_XP) {
169e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    registrar_.Add(this, chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
170e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org                   content::NotificationService::AllSources());
17187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  }
17287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#endif
17387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  registrar_.Add(this,
174589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                 chrome::NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE,
175589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                 content::NotificationService::AllSources());
17687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
17787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                 content::Source<Profile>(browser_->profile()));
178589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
179589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
180589708bf7c706348b763e8277004cb160b202bdbrileya@google.comToolbarView::~ToolbarView() {
181589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // NOTE: Don't remove the command observers here.  This object gets destroyed
18287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  // after the Browser (which owns the CommandUpdater), so the CommandUpdater is
18387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  // already gone.
18455853db3cce9539746fe202519a534c85ecdf62creed@google.com}
185589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
186589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::Init() {
187589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  GetWidget()->AddObserver(this);
188589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
189589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_ = new BackButton(this, new BackForwardMenuModel(
190589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      browser_, BackForwardMenuModel::BACKWARD_MENU));
191589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_->set_triggerable_event_flags(
192589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON);
193589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_->set_tag(IDC_BACK);
194589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK));
195589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK));
196589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_->set_id(VIEW_ID_BACK_BUTTON);
197589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  back_->Init();
198589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
199589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  forward_ = new ToolbarButton(this, new BackForwardMenuModel(
200589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      browser_, BackForwardMenuModel::FORWARD_MENU));
201589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  forward_->set_triggerable_event_flags(
202589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON);
203589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  forward_->set_tag(IDC_FORWARD);
20487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  forward_->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_FORWARD));
205589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  forward_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD));
20687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  forward_->set_id(VIEW_ID_FORWARD_BUTTON);
207589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  forward_->Init();
208589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
20987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  location_bar_ = new LocationBarView(
210589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      browser_, browser_->profile(),
211589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      browser_->command_controller()->command_updater(), this,
212589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      display_mode_ == DISPLAYMODE_LOCATION);
213589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
214589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  reload_ = new ReloadButton(browser_->command_controller()->command_updater());
215589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  reload_->set_triggerable_event_flags(
216589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON);
217589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  reload_->set_tag(IDC_RELOAD);
218589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  reload_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD));
219589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  reload_->set_id(VIEW_ID_RELOAD_BUTTON);
220589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  reload_->Init();
221589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
222589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  home_ = new HomeButton(this, browser_);
22355853db3cce9539746fe202519a534c85ecdf62creed@google.com  home_->set_triggerable_event_flags(
224589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON);
225589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  home_->set_tag(IDC_HOME);
226589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  home_->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_HOME));
227589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  home_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_HOME));
228589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  home_->set_id(VIEW_ID_HOME_BUTTON);
229589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  home_->Init();
230fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
231589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  browser_actions_ = new BrowserActionsContainer(browser_, this);
232589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
2331c6d64b78b24083ee9fd7411dac8a4a7e2d03a3crileya@google.com  app_menu_ = new WrenchToolbarButton(this);
234589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  app_menu_->SetBorder(views::Border::NullBorder());
235589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  app_menu_->EnableCanvasFlippingForRTLUI(true);
2363c2102c2d2cdad328a0d87329e1a973f12775836reed@google.com  app_menu_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_APP));
2373c2102c2d2cdad328a0d87329e1a973f12775836reed@google.com  app_menu_->SetTooltipText(l10n_util::GetStringUTF16(IDS_APPMENU_TOOLTIP));
238589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  app_menu_->set_id(VIEW_ID_APP_MENU);
239589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
240589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // Always add children in order from left to right, for accessibility.
241589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  origin_chip_view_ = new ToolbarOriginChipView(this);
242589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  chrome::OriginChipPosition origin_chip_position =
243589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      chrome::GetOriginChipPosition();
244589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(back_);
245589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(forward_);
246589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(reload_);
247589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(home_);
248589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (origin_chip_position == chrome::ORIGIN_CHIP_LEADING_LOCATION_BAR)
249589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    AddChildView(origin_chip_view_);
250589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(location_bar_);
251589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (origin_chip_position == chrome::ORIGIN_CHIP_TRAILING_LOCATION_BAR)
252589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    AddChildView(origin_chip_view_);
253589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(browser_actions_);
254589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (origin_chip_position == chrome::ORIGIN_CHIP_LEADING_MENU_BUTTON ||
255589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      origin_chip_position == chrome::ORIGIN_CHIP_DISABLED)
2568b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org    AddChildView(origin_chip_view_);
257589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  AddChildView(app_menu_);
258589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
259589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  LoadImages();
260589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
261589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // Start global error services now so we badge the menu correctly in non-Ash.
2628b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#if !defined(OS_CHROMEOS)
263589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (!HasAshShell()) {
264589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    SigninGlobalErrorFactory::GetForProfile(browser_->profile());
265589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#if !defined(OS_ANDROID)
266589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    SyncGlobalErrorFactory::GetForProfile(browser_->profile());
267589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#endif
268589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  }
269589708bf7c706348b763e8277004cb160b202bdbrileya@google.com#endif  // OS_CHROMEOS
270589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
271589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // Add any necessary badges to the menu item based on the system state.
272589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // Do this after |app_menu_| has been added as a bubble may be shown that
273589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // needs the widget (widget found by way of app_menu_->GetWidget()).
274589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  UpdateAppMenuState();
275589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
276589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  location_bar_->Init();
277589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
278589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  origin_chip_view_->Init();
279589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (origin_chip_view_->ShouldShow())
280589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    location_bar_->set_toolbar_origin_chip_view(origin_chip_view_);
281589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
282589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  show_home_button_.Init(prefs::kShowHomeButton,
283589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                         browser_->profile()->GetPrefs(),
284589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                         base::Bind(&ToolbarView::OnShowHomeButtonChanged,
285589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                                    base::Unretained(this)));
286589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
287589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  browser_actions_->Init();
288589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
289589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // Accessibility specific tooltip text.
290589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (content::BrowserAccessibilityState::GetInstance()->
291589708bf7c706348b763e8277004cb160b202bdbrileya@google.com          IsAccessibleBrowser()) {
292589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    back_->SetTooltipText(
293589708bf7c706348b763e8277004cb160b202bdbrileya@google.com        l10n_util::GetStringUTF16(IDS_ACCNAME_TOOLTIP_BACK));
294589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    forward_->SetTooltipText(
295589708bf7c706348b763e8277004cb160b202bdbrileya@google.com        l10n_util::GetStringUTF16(IDS_ACCNAME_TOOLTIP_FORWARD));
296589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  }
297589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
298589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
299589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::OnWidgetVisibilityChanged(views::Widget* widget,
300589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                                            bool visible) {
301589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  // Safe to call multiple times; the bubble will only appear once.
302589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (visible)
303589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    extension_message_bubble_factory_->MaybeShow(app_menu_);
304589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
30555853db3cce9539746fe202519a534c85ecdf62creed@google.com
306589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::Update(WebContents* tab) {
307589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (location_bar_)
308589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    location_bar_->Update(tab);
309589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (origin_chip_view_->visible())
310589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    origin_chip_view_->Update(tab);
311589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
312589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (browser_actions_)
313589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    browser_actions_->RefreshBrowserActionViews();
314589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
315589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (reload_)
316589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    reload_->set_menu_enabled(chrome::IsDebuggerAttachedToCurrentTab(browser_));
317589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
318589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
319589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::SetPaneFocusAndFocusAppMenu() {
320589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  SetPaneFocus(app_menu_);
321589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
322589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
323589708bf7c706348b763e8277004cb160b202bdbrileya@google.combool ToolbarView::IsAppMenuFocused() {
324589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return app_menu_->HasFocus();
325589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
326589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
3273c2102c2d2cdad328a0d87329e1a973f12775836reed@google.comvoid ToolbarView::AddMenuListener(views::MenuListener* listener) {
328589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  menu_listeners_.AddObserver(listener);
329589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
33055853db3cce9539746fe202519a534c85ecdf62creed@google.com
331589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::RemoveMenuListener(views::MenuListener* listener) {
332589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  menu_listeners_.RemoveObserver(listener);
333589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
334589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
335589708bf7c706348b763e8277004cb160b202bdbrileya@google.comviews::View* ToolbarView::GetBookmarkBubbleAnchor() {
336589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  views::View* star_view = location_bar()->star_view();
337589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return (star_view && star_view->visible()) ? star_view : app_menu_;
338589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
339589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
340589708bf7c706348b763e8277004cb160b202bdbrileya@google.comviews::View* ToolbarView::GetTranslateBubbleAnchor() {
341589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  views::View* translate_icon_view = location_bar()->translate_icon_view();
342589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return (translate_icon_view && translate_icon_view->visible()) ?
343589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      translate_icon_view : app_menu_;
34460040292be58ac553298209fb2e0684a4cb17dccreed@google.com}
345589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
346589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::ExecuteExtensionCommand(
347589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    const extensions::Extension* extension,
348589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    const extensions::Command& command) {
349589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  browser_actions_->ExecuteExtensionCommand(extension, command);
350589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
351589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
352589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::ShowPageActionPopup(const extensions::Extension* extension) {
353589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  extensions::ExtensionActionManager* extension_manager =
354589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      extensions::ExtensionActionManager::Get(browser_->profile());
35555853db3cce9539746fe202519a534c85ecdf62creed@google.com  ExtensionAction* extension_action =
356589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      extension_manager->GetPageAction(*extension);
357589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (extension_action) {
358589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    location_bar_->GetPageActionView(extension_action)->image_view()->
359589708bf7c706348b763e8277004cb160b202bdbrileya@google.com        ExecuteAction(ExtensionPopup::SHOW);
360589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  }
361589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
362589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
363589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::ShowBrowserActionPopup(
364589708bf7c706348b763e8277004cb160b202bdbrileya@google.com    const extensions::Extension* extension) {
365589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  browser_actions_->ShowPopup(extension, true);
36655853db3cce9539746fe202519a534c85ecdf62creed@google.com}
367589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
368589708bf7c706348b763e8277004cb160b202bdbrileya@google.comviews::MenuButton* ToolbarView::app_menu() const {
369589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return app_menu_;
370589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
371589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
372589708bf7c706348b763e8277004cb160b202bdbrileya@google.com////////////////////////////////////////////////////////////////////////////////
373589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// ToolbarView, AccessiblePaneView overrides:
374589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
375589708bf7c706348b763e8277004cb160b202bdbrileya@google.combool ToolbarView::SetPaneFocus(views::View* initial_focus) {
376589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (!AccessiblePaneView::SetPaneFocus(initial_focus))
37734150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org    return false;
37834150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org
37934150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  location_bar_->SetShowFocusRect(true);
38034150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  return true;
381589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
38234150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org
38334150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.orgvoid ToolbarView::GetAccessibleState(ui::AXViewState* state) {
384589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  state->role = ui::AX_ROLE_TOOLBAR;
385589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_TOOLBAR);
38655853db3cce9539746fe202519a534c85ecdf62creed@google.com}
387589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
388589708bf7c706348b763e8277004cb160b202bdbrileya@google.com////////////////////////////////////////////////////////////////////////////////
389589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// ToolbarView, Menu::Delegate overrides:
390589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
39134150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.orgbool ToolbarView::GetAcceleratorInfo(int id, ui::Accelerator* accel) {
39234150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  return GetWidget()->GetAccelerator(id, accel);
39334150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org}
39434150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org
39534150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
39634150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org// ToolbarView, views::MenuButtonListener implementation:
39734150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org
39834150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.orgvoid ToolbarView::OnMenuButtonClicked(views::View* source,
39934150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org                                      const gfx::Point& point) {
40034150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  TRACE_EVENT0("views", "ToolbarView::OnMenuButtonClicked");
40134150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  DCHECK_EQ(VIEW_ID_APP_MENU, source->id());
402589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
403589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  bool use_new_menu = false;
40434150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  bool supports_new_separators = false;
40534150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.org  // TODO: remove this.
40687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#if !defined(OS_LINUX) || defined(OS_CHROMEOS)
40787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  supports_new_separators =
408589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      GetNativeTheme() == ui::NativeThemeAura::instance();
409589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  use_new_menu = supports_new_separators;
41087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#endif
41187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
412589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  if (keyboard::KeyboardController::GetInstance() &&
413589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      keyboard::KeyboardController::GetInstance()->keyboard_visible()) {
41487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    keyboard::KeyboardController::GetInstance()->HideKeyboard(
41587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        keyboard::KeyboardController::HIDE_REASON_AUTOMATIC);
41655853db3cce9539746fe202519a534c85ecdf62creed@google.com  }
417589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
418589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  wrench_menu_.reset(new WrenchMenu(browser_, use_new_menu,
419589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                                    supports_new_separators));
420589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  wrench_menu_model_.reset(new WrenchMenuModel(this, browser_, use_new_menu));
421589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  wrench_menu_->Init(wrench_menu_model_.get());
422589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
423589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  FOR_EACH_OBSERVER(views::MenuListener, menu_listeners_, OnMenuOpened());
424589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
425589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  wrench_menu_->RunMenu(app_menu_);
426589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
427589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
428589708bf7c706348b763e8277004cb160b202bdbrileya@google.com////////////////////////////////////////////////////////////////////////////////
429589708bf7c706348b763e8277004cb160b202bdbrileya@google.com// ToolbarView, LocationBarView::Delegate implementation:
430589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
431589708bf7c706348b763e8277004cb160b202bdbrileya@google.comWebContents* ToolbarView::GetWebContents() {
432589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return browser_->tab_strip_model()->GetActiveWebContents();
433589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
434589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
43587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgToolbarModel* ToolbarView::GetToolbarModel() {
436589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return browser_->toolbar_model();
43787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org}
438589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
439589708bf7c706348b763e8277004cb160b202bdbrileya@google.comconst ToolbarModel* ToolbarView::GetToolbarModel() const {
44087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org  return browser_->toolbar_model();
441589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
442589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
443589708bf7c706348b763e8277004cb160b202bdbrileya@google.comInstantController* ToolbarView::GetInstant() {
444589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return browser_->instant_controller() ?
445589708bf7c706348b763e8277004cb160b202bdbrileya@google.com      browser_->instant_controller()->instant() : NULL;
446589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
447589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
448589708bf7c706348b763e8277004cb160b202bdbrileya@google.comContentSettingBubbleModelDelegate*
449589708bf7c706348b763e8277004cb160b202bdbrileya@google.comToolbarView::GetContentSettingBubbleModelDelegate() {
450589708bf7c706348b763e8277004cb160b202bdbrileya@google.com  return browser_->content_setting_bubble_model_delegate();
451589708bf7c706348b763e8277004cb160b202bdbrileya@google.com}
452589708bf7c706348b763e8277004cb160b202bdbrileya@google.com
453589708bf7c706348b763e8277004cb160b202bdbrileya@google.comvoid ToolbarView::ShowWebsiteSettings(content::WebContents* web_contents,
454589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                                      const GURL& url,
455589708bf7c706348b763e8277004cb160b202bdbrileya@google.com                                      const content::SSLStatus& ssl) {
456d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com  chrome::ShowWebsiteSettings(browser_, web_contents, url, ssl);
457d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com}
458cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
459cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comviews::Widget* ToolbarView::CreateViewsBubble(
4602eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com    views::BubbleDelegateView* bubble_delegate) {
4619de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  return views::BubbleDelegateView::CreateBubble(bubble_delegate);
4622eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com}
4630707c29413a5a3cc1c2d14b8c65b3692af5c7411bsalomon@google.com
464d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.comPageActionImageView* ToolbarView::CreatePageActionImageView(
465d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com    LocationBarView* owner, ExtensionAction* action) {
466396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com  return new PageActionImageView(owner, action, browser_);
467c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com}
468d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com
469d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com////////////////////////////////////////////////////////////////////////////////
470f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com// ToolbarView, CommandObserver implementation:
471c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
472f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.comvoid ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) {
473f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com  views::Button* button = NULL;
474f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com  switch (id) {
47577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    case IDC_BACK:
476f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com      button = back_;
477d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com      break;
478c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    case IDC_FORWARD:
47982d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com      button = forward_;
480d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com      break;
481d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com    case IDC_RELOAD:
482d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com      button = reload_;
483d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com      break;
4840707c29413a5a3cc1c2d14b8c65b3692af5c7411bsalomon@google.com    case IDC_HOME:
485d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com      button = home_;
486d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com      break;
487d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com  }
48898e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com  if (button)
48998e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com    button->SetEnabled(enabled);
49098e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com}
49198e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com
4920ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
4930ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com// ToolbarView, views::Button::ButtonListener implementation:
4940ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com
4950ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.comvoid ToolbarView::ButtonPressed(views::Button* sender,
4966340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com                                const ui::Event& event) {
497a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com  chrome::ExecuteCommandWithDisposition(
49898e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com      browser_, sender->tag(), ui::DispositionFromEventFlags(event.flags()));
49998e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com}
50098e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com
50198e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com////////////////////////////////////////////////////////////////////////////////
50298e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com// ToolbarView, content::NotificationObserver implementation:
503396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com
504396e61fe440590744345e0c56970b26ab464591dbsalomon@google.comvoid ToolbarView::Observe(int type,
50598e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com                          const content::NotificationSource& source,
50698e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com                          const content::NotificationDetails& details) {
507422e81aeb1f4078367c85efe591c7df8c33874ecbsalomon@google.com  switch (type) {
50898e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com    case chrome::NOTIFICATION_UPGRADE_RECOMMENDED:
50998e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com    case chrome::NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE:
5100ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com    case chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED:
5110ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com    case chrome::NOTIFICATION_MODULE_LIST_ENUMERATED:
5120ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com      UpdateAppMenuState();
5130ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com      break;
5140ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com    case chrome::NOTIFICATION_OUTDATED_INSTALL:
5150ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com      ShowOutdatedInstallNotification(true);
5160ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com      break;
517f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com    case chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU:
51898e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com      ShowOutdatedInstallNotification(false);
51998e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com      break;
52098e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com#if defined(OS_WIN)
52198e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com    case chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED:
52298e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com      ShowCriticalNotification();
52398e8b6de04e4c20451fbe3353645e3e384a76550rileya@google.com      break;
524f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com#endif
525d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com    default:
526e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org      NOTREACHED();
5270ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com  }
528c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com}
5290ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com
530d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com////////////////////////////////////////////////////////////////////////////////
531d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com// ToolbarView, ui::AcceleratorProvider implementation:
532d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
533d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.combool ToolbarView::GetAcceleratorForCommandId(int command_id,
534d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com    ui::Accelerator* accelerator) {
535d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com  return GetWidget()->GetAccelerator(command_id, accelerator);
536d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com}
537d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
538d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com////////////////////////////////////////////////////////////////////////////////
539d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com// ToolbarView, views::View overrides:
540d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com
541e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.comgfx::Size ToolbarView::GetPreferredSize() {
5429de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  gfx::Size size(location_bar_->GetPreferredSize());
5439de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  if (is_display_mode_normal()) {
5449de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    size.Enlarge(
5459de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        kLeftEdgeSpacing + back_->GetPreferredSize().width() +
546d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com            forward_->GetPreferredSize().width() +
547d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com            reload_->GetPreferredSize().width() + kStandardSpacing +
548d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com            (show_home_button_.GetValue() ?
549d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com                home_->GetPreferredSize().width() : 0) +
550f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com            (origin_chip_view_->visible() ?
551c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                (origin_chip_view_->GetPreferredSize().width() +
552d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com                    2 * kStandardSpacing) :
553f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com                0) +
554f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com            browser_actions_->GetPreferredSize().width() +
55577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com            app_menu_->GetPreferredSize().width() + kRightEdgeSpacing,
556f78df33efc72167f94da1b0476c9a86ba18a5f2cbsalomon@google.com        0);
55782d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com    gfx::ImageSkia* normal_background =
558d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com        GetThemeProvider()->GetImageSkiaNamed(IDR_CONTENT_TOP_CENTER);
55977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    size.SetToMax(
560d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com        gfx::Size(0, normal_background->height() - content_shadow_height()));
56182d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com  } else {
562d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com    const int kPopupBottomSpacingGlass = 1;
563d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com    const int kPopupBottomSpacingNonGlass = 2;
564d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com    size.Enlarge(
565d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com        0,
5669de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        PopupTopSpacing() + (GetWidget()->ShouldWindowContentsBeTransparent() ?
5679de5b514d38c5b36066bcdc14fba2f7e5196d372dandov            kPopupBottomSpacingGlass : kPopupBottomSpacingNonGlass));
5689de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  }
56900835cc55046e66b5a33633ec045bc9aa0015ebdbsalomon@google.com  return size;
5709de5b514d38c5b36066bcdc14fba2f7e5196d372dandov}
571dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com
572f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.comvoid ToolbarView::Layout() {
5739de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  // If we have not been initialized yet just do nothing.
574dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com  if (back_ == NULL)
57596fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    return;
57696fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org
57796fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org  if (!is_display_mode_normal()) {
5789de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    location_bar_->SetBounds(0, PopupTopSpacing(), width(),
57996fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org                             location_bar_->GetPreferredSize().height());
58096fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    return;
58196fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org  }
582f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com
5839de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  // We assume all child elements except the location bar are the same height.
5849de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  // Set child_y such that buttons appear vertically centered. We put any excess
5859de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  // padding above the buttons.
5869de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  int child_height =
5879de5b514d38c5b36066bcdc14fba2f7e5196d372dandov      std::min(back_->GetPreferredSize().height(), height());
588d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com  int child_y = (height() - child_height + 1) / 2;
589d7cc651b8da11d52ae90e910b948f5e2d15daaf9rileya@google.com
590cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com  // If the window is maximized, we extend the back button to the left so that
591cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com  // clicking on the left-most pixel will activate the back button.
5929de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  // TODO(abarth):  If the window becomes maximized but is not resized,
5939de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  //                then Layout() might not be called and the back button
5949de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  //                will be slightly the wrong size.  We should force a
595cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com  //                Layout() in this case.
5969de5b514d38c5b36066bcdc14fba2f7e5196d372dandov  //                http://crbug.com/5540
597cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com  bool maximized = browser_->window() && browser_->window()->IsMaximized();
598cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com  int back_width = back_->GetPreferredSize().width();
599cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com  if (maximized) {
60076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    back_->SetBounds(0, child_y, back_width + kLeftEdgeSpacing, child_height);
6010f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org    back_->SetLeadingMargin(kLeftEdgeSpacing);
60276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  } else {
60376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    back_->SetBounds(kLeftEdgeSpacing, child_y, back_width, child_height);
604ff21c2e0ae23da0f4742b47d4d37969a2a18bd99skia.committer@gmail.com    back_->SetLeadingMargin(0);
60576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  }
60676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  int next_element_x = back_->bounds().right();
60776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
60876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  forward_->SetBounds(next_element_x, child_y,
60976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com                      forward_->GetPreferredSize().width(), child_height);
61076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  next_element_x = forward_->bounds().right();
61176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
61276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  reload_->SetBounds(next_element_x, child_y,
61376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com                     reload_->GetPreferredSize().width(), child_height);
61476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  next_element_x = reload_->bounds().right();
61576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
61676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com  if (show_home_button_.GetValue() ||
61776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com      (browser_->is_app() && IsStreamlinedHostedAppsEnabled())) {
618    home_->SetVisible(true);
619    home_->SetBounds(next_element_x, child_y,
620                     home_->GetPreferredSize().width(), child_height);
621  } else {
622    home_->SetVisible(false);
623    home_->SetBounds(next_element_x, child_y, 0, child_height);
624  }
625  next_element_x = home_->bounds().right() + kStandardSpacing;
626
627  int browser_actions_width = browser_actions_->GetPreferredSize().width();
628  int app_menu_width = app_menu_->GetPreferredSize().width();
629  int available_width = std::max(0, width() - kRightEdgeSpacing -
630      app_menu_width - browser_actions_width - next_element_x);
631
632  origin_chip_view_->SetVisible(origin_chip_view_->ShouldShow());
633  int origin_chip_width =
634      origin_chip_view_->ElideDomainTarget(available_width / 2);
635  if (origin_chip_view_->visible())
636    available_width -= origin_chip_width + kStandardSpacing;
637
638  chrome::OriginChipPosition origin_chip_position =
639      chrome::GetOriginChipPosition();
640  if (origin_chip_view_->visible() &&
641      origin_chip_position == chrome::ORIGIN_CHIP_LEADING_LOCATION_BAR) {
642    origin_chip_view_->SetBounds(next_element_x, child_y,
643                                 origin_chip_width, child_height);
644    next_element_x = origin_chip_view_->bounds().right() + kStandardSpacing;
645  }
646
647  int location_height = location_bar_->GetPreferredSize().height();
648  int location_y = (height() - location_height + 1) / 2;
649  location_bar_->SetBounds(next_element_x, location_y,
650                           std::max(available_width, 0), location_height);
651  next_element_x = location_bar_->bounds().right();
652
653  if (origin_chip_view_->visible() &&
654      origin_chip_position == chrome::ORIGIN_CHIP_TRAILING_LOCATION_BAR) {
655    origin_chip_view_->SetBounds(next_element_x + kStandardSpacing, child_y,
656                                 origin_chip_width, child_height);
657    next_element_x = origin_chip_view_->bounds().right();
658  }
659
660  browser_actions_->SetBounds(
661      next_element_x, child_y, browser_actions_width, child_height);
662  next_element_x = browser_actions_->bounds().right();
663
664  // The browser actions need to do a layout explicitly, because when an
665  // extension is loaded/unloaded/changed, BrowserActionContainer removes and
666  // re-adds everything, regardless of whether it has a page action. For a
667  // page action, browser action bounds do not change, as a result of which
668  // SetBounds does not do a layout at all.
669  // TODO(sidchat): Rework the above behavior so that explicit layout is not
670  //                required.
671  browser_actions_->Layout();
672
673  if (origin_chip_view_->visible() &&
674      origin_chip_position == chrome::ORIGIN_CHIP_LEADING_MENU_BUTTON) {
675    origin_chip_view_->SetBounds(next_element_x, child_y,
676                                 origin_chip_width, child_height);
677    next_element_x = origin_chip_view_->bounds().right() + kStandardSpacing;
678  }
679
680  // Extend the app menu to the screen's right edge in maximized mode just like
681  // we extend the back button to the left edge.
682  if (maximized)
683    app_menu_width += kRightEdgeSpacing;
684  app_menu_->SetBounds(next_element_x, child_y, app_menu_width, child_height);
685}
686
687bool ToolbarView::HitTestRect(const gfx::Rect& rect) const {
688  // Fall through to the tab strip above us if none of |rect| intersects
689  // with this view (intersection with the top shadow edge does not
690  // count as intersection with this view).
691  if (rect.bottom() < content_shadow_height())
692    return false;
693  // Otherwise let our superclass take care of it.
694  return AccessiblePaneView::HitTestRect(rect);
695}
696
697void ToolbarView::OnPaint(gfx::Canvas* canvas) {
698  View::OnPaint(canvas);
699
700  if (is_display_mode_normal())
701    return;
702
703  // For glass, we need to draw a black line below the location bar to separate
704  // it from the content area.  For non-glass, the NonClientView draws the
705  // toolbar background below the location bar for us.
706  // NOTE: Keep this in sync with BrowserView::GetInfoBarSeparatorColor()!
707  if (GetWidget()->ShouldWindowContentsBeTransparent())
708    canvas->FillRect(gfx::Rect(0, height() - 1, width(), 1), SK_ColorBLACK);
709}
710
711void ToolbarView::OnThemeChanged() {
712  LoadImages();
713}
714
715const char* ToolbarView::GetClassName() const {
716  return kViewClassName;
717}
718
719bool ToolbarView::AcceleratorPressed(const ui::Accelerator& accelerator) {
720  const views::View* focused_view = focus_manager()->GetFocusedView();
721  if (focused_view && (focused_view->id() == VIEW_ID_OMNIBOX))
722    return false;  // Let the omnibox handle all accelerator events.
723  return AccessiblePaneView::AcceleratorPressed(accelerator);
724}
725
726bool ToolbarView::IsWrenchMenuShowing() const {
727  return wrench_menu_.get() && wrench_menu_->IsShowing();
728}
729
730bool ToolbarView::ShouldPaintBackground() const {
731  return display_mode_ == DISPLAYMODE_NORMAL;
732}
733
734////////////////////////////////////////////////////////////////////////////////
735// ToolbarView, protected:
736
737// Override this so that when the user presses F6 to rotate toolbar panes,
738// the location bar gets focus, not the first control in the toolbar - and
739// also so that it selects all content in the location bar.
740bool ToolbarView::SetPaneFocusAndFocusDefault() {
741  if (!location_bar_->HasFocus()) {
742    SetPaneFocus(location_bar_);
743    location_bar_->FocusLocation(true);
744    return true;
745  }
746
747  if (!AccessiblePaneView::SetPaneFocusAndFocusDefault())
748    return false;
749  browser_->window()->RotatePaneFocus(true);
750  return true;
751}
752
753void ToolbarView::RemovePaneFocus() {
754  AccessiblePaneView::RemovePaneFocus();
755  location_bar_->SetShowFocusRect(false);
756}
757
758////////////////////////////////////////////////////////////////////////////////
759// ToolbarView, private:
760
761bool ToolbarView::ShouldShowUpgradeRecommended() {
762#if defined(OS_CHROMEOS)
763  // In chromeos, the update recommendation is shown in the system tray. So it
764  // should not be displayed in the wrench menu.
765  return false;
766#else
767  return (UpgradeDetector::GetInstance()->notify_upgrade());
768#endif
769}
770
771bool ToolbarView::ShouldShowIncompatibilityWarning() {
772#if defined(OS_WIN)
773  EnumerateModulesModel* loaded_modules = EnumerateModulesModel::GetInstance();
774  loaded_modules->MaybePostScanningTask();
775  return loaded_modules->ShouldShowConflictWarning();
776#else
777  return false;
778#endif
779}
780
781int ToolbarView::PopupTopSpacing() const {
782  const int kPopupTopSpacingNonGlass = 3;
783  return GetWidget()->ShouldWindowContentsBeTransparent()
784             ? 0
785             : kPopupTopSpacingNonGlass;
786}
787
788void ToolbarView::LoadImages() {
789  ui::ThemeProvider* tp = GetThemeProvider();
790
791  back_->SetImage(views::Button::STATE_NORMAL,
792                  *(tp->GetImageSkiaNamed(IDR_BACK)));
793  back_->SetImage(views::Button::STATE_DISABLED,
794                  *(tp->GetImageSkiaNamed(IDR_BACK_D)));
795
796  forward_->SetImage(views::Button::STATE_NORMAL,
797                    *(tp->GetImageSkiaNamed(IDR_FORWARD)));
798  forward_->SetImage(views::Button::STATE_DISABLED,
799                     *(tp->GetImageSkiaNamed(IDR_FORWARD_D)));
800
801  reload_->LoadImages();
802
803  home_->SetImage(views::Button::STATE_NORMAL,
804                  *(tp->GetImageSkiaNamed(IDR_HOME)));
805}
806
807void ToolbarView::ShowCriticalNotification() {
808#if defined(OS_WIN)
809  CriticalNotificationBubbleView* bubble_delegate =
810      new CriticalNotificationBubbleView(app_menu_);
811  views::BubbleDelegateView::CreateBubble(bubble_delegate)->Show();
812#endif
813}
814
815void ToolbarView::ShowOutdatedInstallNotification(bool auto_update_enabled) {
816  if (OutdatedUpgradeBubbleView::IsAvailable()) {
817    OutdatedUpgradeBubbleView::ShowBubble(
818        app_menu_, browser_, auto_update_enabled);
819  }
820}
821
822void ToolbarView::UpdateAppMenuState() {
823  base::string16 accname_app = l10n_util::GetStringUTF16(IDS_ACCNAME_APP);
824  if (ShouldShowUpgradeRecommended()) {
825    accname_app = l10n_util::GetStringFUTF16(
826        IDS_ACCNAME_APP_UPGRADE_RECOMMENDED, accname_app);
827  }
828  app_menu_->SetAccessibleName(accname_app);
829
830  UpdateWrenchButtonSeverity();
831  SchedulePaint();
832}
833
834void ToolbarView::UpdateWrenchButtonSeverity() {
835  // Showing the bubble requires |app_menu_| to be in a widget. See comment
836  // in ConflictingModuleView for details.
837  DCHECK(app_menu_->GetWidget());
838
839  // Keep track of whether we were showing the badge before, so we don't send
840  // multiple UMA events for example when multiple Chrome windows are open.
841  static bool incompatibility_badge_showing = false;
842  // Save the old value before resetting it.
843  bool was_showing = incompatibility_badge_showing;
844  incompatibility_badge_showing = false;
845
846  if (ShouldShowUpgradeRecommended()) {
847    UpgradeDetector::UpgradeNotificationAnnoyanceLevel level =
848        UpgradeDetector::GetInstance()->upgrade_notification_stage();
849    app_menu_->SetSeverity(WrenchIconPainter::SeverityFromUpgradeLevel(level),
850                           WrenchIconPainter::ShouldAnimateUpgradeLevel(level));
851    return;
852  }
853
854  if (ShouldShowIncompatibilityWarning()) {
855    if (!was_showing) {
856      content::RecordAction(UserMetricsAction("ConflictBadge"));
857#if defined(OS_WIN)
858      ConflictingModuleView::MaybeShow(browser_, app_menu_);
859#endif
860    }
861    app_menu_->SetSeverity(WrenchIconPainter::SEVERITY_MEDIUM, true);
862    incompatibility_badge_showing = true;
863    return;
864  }
865
866  GlobalErrorService* service =
867      GlobalErrorServiceFactory::GetForProfile(browser_->profile());
868  GlobalError* error =
869      service->GetHighestSeverityGlobalErrorWithWrenchMenuItem();
870  if (error) {
871    app_menu_->SetSeverity(WrenchIconPainter::GlobalErrorSeverity(), true);
872    return;
873  }
874
875  app_menu_->SetSeverity(WrenchIconPainter::SEVERITY_NONE, true);
876}
877
878void ToolbarView::OnShowHomeButtonChanged() {
879  Layout();
880  SchedulePaint();
881}
882
883int ToolbarView::content_shadow_height() const {
884  return browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH ?
885      kContentShadowHeightAsh : kContentShadowHeight;
886}
887