Home | History | Annotate | Download | only in location_bar
      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 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
      6 
      7 #include <algorithm>
      8 #include <map>
      9 
     10 #include "base/command_line.h"
     11 #include "base/i18n/rtl.h"
     12 #include "base/prefs/pref_service.h"
     13 #include "base/stl_util.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "chrome/app/chrome_command_ids.h"
     16 #include "chrome/browser/chrome_notification_types.h"
     17 #include "chrome/browser/command_updater.h"
     18 #include "chrome/browser/defaults.h"
     19 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
     20 #include "chrome/browser/extensions/extension_service.h"
     21 #include "chrome/browser/extensions/extension_system.h"
     22 #include "chrome/browser/extensions/location_bar_controller.h"
     23 #include "chrome/browser/extensions/script_bubble_controller.h"
     24 #include "chrome/browser/extensions/tab_helper.h"
     25 #include "chrome/browser/favicon/favicon_tab_helper.h"
     26 #include "chrome/browser/profiles/profile.h"
     27 #include "chrome/browser/search/search.h"
     28 #include "chrome/browser/search_engines/template_url.h"
     29 #include "chrome/browser/search_engines/template_url_service.h"
     30 #include "chrome/browser/search_engines/template_url_service_factory.h"
     31 #include "chrome/browser/translate/translate_manager.h"
     32 #include "chrome/browser/translate/translate_tab_helper.h"
     33 #include "chrome/browser/ui/browser.h"
     34 #include "chrome/browser/ui/browser_finder.h"
     35 #include "chrome/browser/ui/browser_instant_controller.h"
     36 #include "chrome/browser/ui/browser_window.h"
     37 #include "chrome/browser/ui/omnibox/location_bar_util.h"
     38 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
     39 #include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
     40 #include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
     41 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     42 #include "chrome/browser/ui/view_ids.h"
     43 #include "chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h"
     44 #include "chrome/browser/ui/views/browser_dialogs.h"
     45 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
     46 #include "chrome/browser/ui/views/location_bar/ev_bubble_view.h"
     47 #include "chrome/browser/ui/views/location_bar/generated_credit_card_view.h"
     48 #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h"
     49 #include "chrome/browser/ui/views/location_bar/location_bar_layout.h"
     50 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
     51 #include "chrome/browser/ui/views/location_bar/open_pdf_in_reader_view.h"
     52 #include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
     53 #include "chrome/browser/ui/views/location_bar/page_action_with_badge_view.h"
     54 #include "chrome/browser/ui/views/location_bar/script_bubble_icon_view.h"
     55 #include "chrome/browser/ui/views/location_bar/selected_keyword_view.h"
     56 #include "chrome/browser/ui/views/location_bar/star_view.h"
     57 #include "chrome/browser/ui/views/location_bar/translate_icon_view.h"
     58 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
     59 #include "chrome/browser/ui/views/location_bar/zoom_view.h"
     60 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
     61 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
     62 #include "chrome/browser/ui/views/toolbar/site_chip_view.h"
     63 #include "chrome/browser/ui/zoom/zoom_controller.h"
     64 #include "chrome/common/chrome_switches.h"
     65 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
     66 #include "chrome/common/pref_names.h"
     67 #include "content/public/browser/notification_service.h"
     68 #include "content/public/browser/render_widget_host_view.h"
     69 #include "content/public/browser/web_contents.h"
     70 #include "extensions/common/feature_switch.h"
     71 #include "extensions/common/permissions/permissions_data.h"
     72 #include "grit/generated_resources.h"
     73 #include "grit/theme_resources.h"
     74 #include "ui/base/accessibility/accessible_view_state.h"
     75 #include "ui/base/dragdrop/drag_drop_types.h"
     76 #include "ui/base/l10n/l10n_util.h"
     77 #include "ui/base/layout.h"
     78 #include "ui/base/resource/resource_bundle.h"
     79 #include "ui/base/theme_provider.h"
     80 #include "ui/events/event.h"
     81 #include "ui/gfx/canvas.h"
     82 #include "ui/gfx/color_utils.h"
     83 #include "ui/gfx/image/image.h"
     84 #include "ui/gfx/image/image_skia_operations.h"
     85 #include "ui/gfx/skia_util.h"
     86 #include "ui/native_theme/native_theme.h"
     87 #include "ui/views/background.h"
     88 #include "ui/views/border.h"
     89 #include "ui/views/button_drag_utils.h"
     90 #include "ui/views/controls/button/image_button.h"
     91 #include "ui/views/controls/button/label_button.h"
     92 #include "ui/views/controls/button/label_button_border.h"
     93 #include "ui/views/controls/label.h"
     94 #include "ui/views/widget/widget.h"
     95 
     96 #if !defined(OS_CHROMEOS)
     97 #include "chrome/browser/ui/views/first_run_bubble.h"
     98 #endif
     99 
    100 using content::WebContents;
    101 using views::View;
    102 
    103 namespace {
    104 
    105 #if !defined(OS_CHROMEOS)
    106 Browser* GetBrowserFromDelegate(LocationBarView::Delegate* delegate) {
    107   WebContents* contents = delegate->GetWebContents();
    108   return contents ? chrome::FindBrowserWithWebContents(contents) : NULL;
    109 }
    110 #endif
    111 
    112 // Given a containing |height| and a |base_font_list|, shrinks the font size
    113 // until the font list will fit within |height| while having its cap height
    114 // vertically centered.  Returns the correctly-sized font list.
    115 //
    116 // The expected layout:
    117 //   +--------+-----------------------------------------------+------------+
    118 //   |        | y offset                                      | space      |
    119 //   |        +--------+-------------------+------------------+ above      |
    120 //   |        |        |                   | internal leading | cap height |
    121 //   | box    | font   | ascent (baseline) +------------------+------------+
    122 //   | height | height |                   | cap height                    |
    123 //   |        |        |-------------------+------------------+------------+
    124 //   |        |        | descent (height - baseline)          | space      |
    125 //   |        +--------+--------------------------------------+ below      |
    126 //   |        | space at bottom                               | cap height |
    127 //   +--------+-----------------------------------------------+------------+
    128 // Goal:
    129 //     center of box height == center of cap height
    130 //     (i.e. space above cap height == space below cap height)
    131 // Restrictions:
    132 //     y offset >= 0
    133 //     space at bottom >= 0
    134 //     (i.e. Entire font must be visible inside the box.)
    135 gfx::FontList GetLargestFontListWithHeightBound(
    136     const gfx::FontList& base_font_list,
    137     int height) {
    138   gfx::FontList font_list = base_font_list;
    139   for (int font_size = font_list.GetFontSize(); font_size > 1; --font_size) {
    140     const int internal_leading =
    141         font_list.GetBaseline() - font_list.GetCapHeight();
    142     // Some platforms don't support getting the cap height, and simply return
    143     // the entire font ascent from GetCapHeight().  Centering the ascent makes
    144     // the font look too low, so if GetCapHeight() returns the ascent, center
    145     // the entire font height instead.
    146     const int space =
    147         height - ((internal_leading != 0) ?
    148                   font_list.GetCapHeight() : font_list.GetHeight());
    149     const int y_offset = space / 2 - internal_leading;
    150     const int space_at_bottom = height - (y_offset + font_list.GetHeight());
    151     if ((y_offset >= 0) && (space_at_bottom >= 0))
    152       break;
    153     font_list = font_list.DeriveFontListWithSizeDelta(-1);
    154   }
    155   return font_list;
    156 }
    157 
    158 // Functor for moving BookmarkManagerPrivate page actions to the right via
    159 // stable_partition.
    160 class IsPageActionViewRightAligned {
    161  public:
    162   explicit IsPageActionViewRightAligned(ExtensionService* extension_service)
    163       : extension_service_(extension_service) {}
    164 
    165   bool operator()(PageActionWithBadgeView* page_action_view) {
    166     const extensions::Extension* extension =
    167         extension_service_->GetExtensionById(
    168             page_action_view->image_view()->page_action()->extension_id(),
    169             false);
    170 
    171     return extensions::PermissionsData::HasAPIPermission(
    172         extension,
    173         extensions::APIPermission::kBookmarkManagerPrivate);
    174   }
    175 
    176  private:
    177   ExtensionService* extension_service_;
    178 };
    179 
    180 }  // namespace
    181 
    182 
    183 // LocationBarView -----------------------------------------------------------
    184 
    185 // static
    186 const int LocationBarView::kNormalEdgeThickness = 2;
    187 const int LocationBarView::kPopupEdgeThickness = 1;
    188 const int LocationBarView::kIconInternalPadding = 2;
    189 const int LocationBarView::kBubblePadding = 1;
    190 const char LocationBarView::kViewClassName[] = "LocationBarView";
    191 
    192 LocationBarView::LocationBarView(Browser* browser,
    193                                  Profile* profile,
    194                                  CommandUpdater* command_updater,
    195                                  Delegate* delegate,
    196                                  bool is_popup_mode)
    197     : OmniboxEditController(command_updater),
    198       browser_(browser),
    199       omnibox_view_(NULL),
    200       profile_(profile),
    201       delegate_(delegate),
    202       location_icon_view_(NULL),
    203       ev_bubble_view_(NULL),
    204       ime_inline_autocomplete_view_(NULL),
    205       selected_keyword_view_(NULL),
    206       suggested_text_view_(NULL),
    207       keyword_hint_view_(NULL),
    208       mic_search_view_(NULL),
    209       zoom_view_(NULL),
    210       generated_credit_card_view_(NULL),
    211       open_pdf_in_reader_view_(NULL),
    212       manage_passwords_icon_view_(NULL),
    213       script_bubble_icon_view_(NULL),
    214       site_chip_view_(NULL),
    215       translate_icon_view_(NULL),
    216       star_view_(NULL),
    217       search_button_(NULL),
    218       is_popup_mode_(is_popup_mode),
    219       show_focus_rect_(false),
    220       template_url_service_(NULL),
    221       animation_offset_(0),
    222       weak_ptr_factory_(this) {
    223   const int kOmniboxBorderImages[] = IMAGE_GRID(IDR_OMNIBOX_BORDER);
    224   const int kOmniboxPopupImages[] = IMAGE_GRID(IDR_OMNIBOX_POPUP_BORDER);
    225   background_border_painter_.reset(
    226       views::Painter::CreateImageGridPainter(
    227           is_popup_mode_ ? kOmniboxPopupImages : kOmniboxBorderImages));
    228 #if defined(OS_CHROMEOS)
    229   if (!is_popup_mode_) {
    230     const int kOmniboxFillingImages[] = IMAGE_GRID(IDR_OMNIBOX_FILLING);
    231     background_filling_painter_.reset(
    232         views::Painter::CreateImageGridPainter(kOmniboxFillingImages));
    233   }
    234 #endif
    235 
    236   edit_bookmarks_enabled_.Init(
    237       prefs::kEditBookmarksEnabled,
    238       profile_->GetPrefs(),
    239       base::Bind(&LocationBarView::Update,
    240                  base::Unretained(this),
    241                  static_cast<content::WebContents*>(NULL)));
    242 
    243   if (browser_)
    244     browser_->search_model()->AddObserver(this);
    245 }
    246 
    247 LocationBarView::~LocationBarView() {
    248   if (template_url_service_)
    249     template_url_service_->RemoveObserver(this);
    250   if (browser_)
    251     browser_->search_model()->RemoveObserver(this);
    252 }
    253 
    254 // static
    255 void LocationBarView::InitTouchableLocationBarChildView(views::View* view) {
    256   int horizontal_padding = GetBuiltInHorizontalPaddingForChildViews();
    257   if (horizontal_padding != 0) {
    258     view->set_border(views::Border::CreateEmptyBorder(
    259         3, horizontal_padding, 3, horizontal_padding));
    260   }
    261 }
    262 
    263 void LocationBarView::Init() {
    264   // We need to be in a Widget, otherwise GetNativeTheme() may change and we're
    265   // not prepared for that.
    266   DCHECK(GetWidget());
    267 
    268   location_icon_view_ = new LocationIconView(this);
    269   location_icon_view_->set_drag_controller(this);
    270   AddChildView(location_icon_view_);
    271 
    272   // Determine the main font.
    273   gfx::FontList font_list = ResourceBundle::GetSharedInstance().GetFontList(
    274       ResourceBundle::BaseFont);
    275   const int current_font_size = font_list.GetFontSize();
    276   const int desired_font_size = browser_defaults::kOmniboxFontPixelSize;
    277   if (current_font_size < desired_font_size)
    278     font_list = font_list.DeriveFontListWithSize(desired_font_size);
    279   // Shrink large fonts to make them fit.
    280   // TODO(pkasting): Stretch the location bar instead in this case.
    281   const int location_height = GetInternalHeight(true);
    282   font_list = GetLargestFontListWithHeightBound(font_list, location_height);
    283 
    284   // Determine the font for use inside the bubbles.  The bubble background
    285   // images have 1 px thick edges, which we don't want to overlap.
    286   const int kBubbleInteriorVerticalPadding = 1;
    287   const int bubble_vertical_padding =
    288       (kBubblePadding + kBubbleInteriorVerticalPadding) * 2;
    289   const gfx::FontList bubble_font_list(
    290       GetLargestFontListWithHeightBound(
    291           font_list, location_height - bubble_vertical_padding));
    292 
    293   const SkColor background_color =
    294       GetColor(ToolbarModel::NONE, LocationBarView::BACKGROUND);
    295   ev_bubble_view_ = new EVBubbleView(
    296       bubble_font_list, GetColor(ToolbarModel::EV_SECURE, SECURITY_TEXT),
    297       background_color, this);
    298   ev_bubble_view_->set_drag_controller(this);
    299   AddChildView(ev_bubble_view_);
    300 
    301   // Initialize the Omnibox view.
    302   omnibox_view_ = new OmniboxViewViews(this, profile_, command_updater(),
    303                                        is_popup_mode_, this, font_list);
    304   omnibox_view_->Init();
    305   omnibox_view_->SetFocusable(true);
    306   AddChildView(omnibox_view_);
    307 
    308   // Initialize the inline autocomplete view which is visible only when IME is
    309   // turned on.  Use the same font with the omnibox and highlighted background.
    310   ime_inline_autocomplete_view_ = new views::Label(base::string16(), font_list);
    311   ime_inline_autocomplete_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    312   ime_inline_autocomplete_view_->SetAutoColorReadabilityEnabled(false);
    313   ime_inline_autocomplete_view_->set_background(
    314       views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
    315           ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
    316   ime_inline_autocomplete_view_->SetEnabledColor(
    317       GetNativeTheme()->GetSystemColor(
    318           ui::NativeTheme::kColorId_TextfieldSelectionColor));
    319   ime_inline_autocomplete_view_->SetVisible(false);
    320   AddChildView(ime_inline_autocomplete_view_);
    321 
    322   const SkColor text_color = GetColor(ToolbarModel::NONE, TEXT);
    323   selected_keyword_view_ = new SelectedKeywordView(
    324       bubble_font_list, text_color, background_color, profile_);
    325   AddChildView(selected_keyword_view_);
    326 
    327   suggested_text_view_ = new views::Label(base::string16(), font_list);
    328   suggested_text_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    329   suggested_text_view_->SetAutoColorReadabilityEnabled(false);
    330   suggested_text_view_->SetEnabledColor(GetColor(
    331       ToolbarModel::NONE, LocationBarView::DEEMPHASIZED_TEXT));
    332   suggested_text_view_->SetVisible(false);
    333   AddChildView(suggested_text_view_);
    334 
    335   keyword_hint_view_ = new KeywordHintView(
    336       profile_, font_list,
    337       GetColor(ToolbarModel::NONE, LocationBarView::DEEMPHASIZED_TEXT),
    338       background_color);
    339   AddChildView(keyword_hint_view_);
    340 
    341   mic_search_view_ = new views::ImageButton(this);
    342   mic_search_view_->set_id(VIEW_ID_MIC_SEARCH_BUTTON);
    343   mic_search_view_->SetAccessibilityFocusable(true);
    344   mic_search_view_->SetTooltipText(
    345       l10n_util::GetStringUTF16(IDS_TOOLTIP_MIC_SEARCH));
    346   mic_search_view_->SetImage(
    347       views::Button::STATE_NORMAL,
    348       ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    349           IDR_OMNIBOX_MIC_SEARCH));
    350   mic_search_view_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
    351                                       views::ImageButton::ALIGN_MIDDLE);
    352   mic_search_view_->SetVisible(false);
    353   InitTouchableLocationBarChildView(mic_search_view_);
    354   AddChildView(mic_search_view_);
    355 
    356   for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
    357     ContentSettingImageView* content_blocked_view =
    358         new ContentSettingImageView(static_cast<ContentSettingsType>(i), this,
    359                                     bubble_font_list, text_color,
    360                                     background_color);
    361     content_setting_views_.push_back(content_blocked_view);
    362     content_blocked_view->SetVisible(false);
    363     AddChildView(content_blocked_view);
    364   }
    365 
    366   generated_credit_card_view_ = new GeneratedCreditCardView(delegate_);
    367   AddChildView(generated_credit_card_view_);
    368 
    369   zoom_view_ = new ZoomView(delegate_);
    370   zoom_view_->set_id(VIEW_ID_ZOOM_BUTTON);
    371   AddChildView(zoom_view_);
    372 
    373   open_pdf_in_reader_view_ = new OpenPDFInReaderView(this);
    374   AddChildView(open_pdf_in_reader_view_);
    375 
    376   manage_passwords_icon_view_ = new ManagePasswordsIconView(delegate_);
    377   manage_passwords_icon_view_->set_id(VIEW_ID_MANAGE_PASSWORDS_ICON_BUTTON);
    378   AddChildView(manage_passwords_icon_view_);
    379 
    380   script_bubble_icon_view_ = new ScriptBubbleIconView(delegate());
    381   script_bubble_icon_view_->SetVisible(false);
    382   AddChildView(script_bubble_icon_view_);
    383 
    384   translate_icon_view_ = new TranslateIconView(command_updater());
    385   translate_icon_view_->SetVisible(false);
    386   AddChildView(translate_icon_view_);
    387 
    388   star_view_ = new StarView(command_updater());
    389   star_view_->SetVisible(false);
    390   AddChildView(star_view_);
    391 
    392   search_button_ = new views::LabelButton(this, base::string16());
    393   search_button_->set_triggerable_event_flags(
    394       ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON);
    395   search_button_->SetStyle(views::Button::STYLE_BUTTON);
    396   search_button_->SetFocusable(false);
    397   search_button_->set_min_size(gfx::Size());
    398   views::LabelButtonBorder* search_button_border =
    399       static_cast<views::LabelButtonBorder*>(search_button_->border());
    400   search_button_border->set_insets(gfx::Insets());
    401   const int kSearchButtonNormalImages[] = IMAGE_GRID(IDR_OMNIBOX_SEARCH_BUTTON);
    402   search_button_border->SetPainter(
    403       false, views::Button::STATE_NORMAL,
    404       views::Painter::CreateImageGridPainter(kSearchButtonNormalImages));
    405   const int kSearchButtonHoveredImages[] =
    406       IMAGE_GRID(IDR_OMNIBOX_SEARCH_BUTTON_HOVER);
    407   search_button_border->SetPainter(
    408       false, views::Button::STATE_HOVERED,
    409       views::Painter::CreateImageGridPainter(kSearchButtonHoveredImages));
    410   const int kSearchButtonPressedImages[] =
    411       IMAGE_GRID(IDR_OMNIBOX_SEARCH_BUTTON_PRESSED);
    412   search_button_border->SetPainter(
    413       false, views::Button::STATE_PRESSED,
    414       views::Painter::CreateImageGridPainter(kSearchButtonPressedImages));
    415   search_button_border->SetPainter(false, views::Button::STATE_DISABLED, NULL);
    416   search_button_border->SetPainter(true, views::Button::STATE_NORMAL, NULL);
    417   search_button_border->SetPainter(true, views::Button::STATE_HOVERED, NULL);
    418   search_button_border->SetPainter(true, views::Button::STATE_PRESSED, NULL);
    419   search_button_border->SetPainter(true, views::Button::STATE_DISABLED, NULL);
    420   const int kSearchButtonWidth = 56;
    421   search_button_->set_min_size(gfx::Size(kSearchButtonWidth, 0));
    422   search_button_->SetVisible(false);
    423   AddChildView(search_button_);
    424 
    425   content::Source<Profile> profile_source = content::Source<Profile>(profile_);
    426   registrar_.Add(this,
    427                  chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
    428                  profile_source);
    429   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, profile_source);
    430   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, profile_source);
    431 
    432   // Initialize the location entry. We do this to avoid a black flash which is
    433   // visible when the location entry has just been initialized.
    434   Update(NULL);
    435 }
    436 
    437 bool LocationBarView::IsInitialized() const {
    438   return omnibox_view_ != NULL;
    439 }
    440 
    441 SkColor LocationBarView::GetColor(ToolbarModel::SecurityLevel security_level,
    442                                   ColorKind kind) const {
    443   const ui::NativeTheme* native_theme = GetNativeTheme();
    444   switch (kind) {
    445     case BACKGROUND:
    446 #if defined(OS_CHROMEOS)
    447       // Chrome OS requires a transparent omnibox background color.
    448       return SkColorSetARGB(0, 255, 255, 255);
    449 #else
    450       return native_theme->GetSystemColor(
    451           ui::NativeTheme::kColorId_TextfieldDefaultBackground);
    452 #endif
    453 
    454     case TEXT:
    455       return native_theme->GetSystemColor(
    456           ui::NativeTheme::kColorId_TextfieldDefaultColor);
    457 
    458     case SELECTED_TEXT:
    459       return native_theme->GetSystemColor(
    460           ui::NativeTheme::kColorId_TextfieldSelectionColor);
    461 
    462     case DEEMPHASIZED_TEXT:
    463       return color_utils::AlphaBlend(
    464           GetColor(security_level, TEXT),
    465           GetColor(security_level, BACKGROUND),
    466           128);
    467 
    468     case SECURITY_TEXT: {
    469       SkColor color;
    470       switch (security_level) {
    471         case ToolbarModel::EV_SECURE:
    472         case ToolbarModel::SECURE:
    473           color = SkColorSetRGB(7, 149, 0);
    474           break;
    475 
    476         case ToolbarModel::SECURITY_WARNING:
    477         case ToolbarModel::SECURITY_POLICY_WARNING:
    478           return GetColor(security_level, DEEMPHASIZED_TEXT);
    479           break;
    480 
    481         case ToolbarModel::SECURITY_ERROR:
    482           color = SkColorSetRGB(162, 0, 0);
    483           break;
    484 
    485         default:
    486           NOTREACHED();
    487           return GetColor(security_level, TEXT);
    488       }
    489       return color_utils::GetReadableColor(
    490           color, GetColor(security_level, BACKGROUND));
    491     }
    492 
    493     default:
    494       NOTREACHED();
    495       return GetColor(security_level, TEXT);
    496   }
    497 }
    498 
    499 void LocationBarView::GetOmniboxPopupPositioningInfo(
    500     gfx::Point* top_left_screen_coord,
    501     int* popup_width,
    502     int* left_margin,
    503     int* right_margin) {
    504   // Because the popup might appear atop the attached bookmark bar, there won't
    505   // necessarily be a client edge separating it from the rest of the toolbar.
    506   // Therefore we position the popup high enough so it can draw its own client
    507   // edge at the top, in the same place the toolbar would normally draw the
    508   // client edge.
    509   *top_left_screen_coord = gfx::Point(
    510       0,
    511       parent()->height() - views::NonClientFrameView::kClientEdgeThickness);
    512   views::View::ConvertPointToScreen(parent(), top_left_screen_coord);
    513   *popup_width = parent()->width();
    514 
    515   gfx::Rect location_bar_bounds(bounds());
    516   location_bar_bounds.Inset(kNormalEdgeThickness, 0);
    517   *left_margin = location_bar_bounds.x();
    518   *right_margin = *popup_width - location_bar_bounds.right();
    519 }
    520 
    521 // static
    522 int LocationBarView::GetItemPadding() {
    523   const int kTouchItemPadding = 8;
    524   if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH)
    525     return kTouchItemPadding;
    526 
    527   const int kDesktopScriptBadgeItemPadding = 9;
    528   const int kDesktopItemPadding = 3;
    529   return extensions::FeatureSwitch::script_badges()->IsEnabled() ?
    530       kDesktopScriptBadgeItemPadding : kDesktopItemPadding;
    531 }
    532 
    533 // DropdownBarHostDelegate
    534 void LocationBarView::SetFocusAndSelection(bool select_all) {
    535   FocusLocation(select_all);
    536 }
    537 
    538 void LocationBarView::SetAnimationOffset(int offset) {
    539   animation_offset_ = offset;
    540 }
    541 
    542 void LocationBarView::UpdateContentSettingsIcons() {
    543   if (RefreshContentSettingViews()) {
    544     Layout();
    545     SchedulePaint();
    546   }
    547 }
    548 
    549 void LocationBarView::UpdateManagePasswordsIconAndBubble() {
    550   if (RefreshManagePasswordsIconView()) {
    551     Layout();
    552     SchedulePaint();
    553   }
    554   ShowManagePasswordsBubbleIfNeeded();
    555 }
    556 
    557 void LocationBarView::UpdatePageActions() {
    558   size_t count_before = page_action_views_.size();
    559   bool changed = RefreshPageActionViews();
    560   changed |= RefreshScriptBubble();
    561   if (page_action_views_.size() != count_before) {
    562     content::NotificationService::current()->Notify(
    563         chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
    564         content::Source<LocationBar>(this),
    565         content::NotificationService::NoDetails());
    566   }
    567 
    568   if (changed) {
    569     Layout();
    570     SchedulePaint();
    571   }
    572 }
    573 
    574 void LocationBarView::InvalidatePageActions() {
    575   size_t count_before = page_action_views_.size();
    576   DeletePageActionViews();
    577   if (page_action_views_.size() != count_before) {
    578     content::NotificationService::current()->Notify(
    579         chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
    580         content::Source<LocationBar>(this),
    581         content::NotificationService::NoDetails());
    582   }
    583 }
    584 
    585 void LocationBarView::UpdateOpenPDFInReaderPrompt() {
    586   open_pdf_in_reader_view_->Update(
    587       GetToolbarModel()->input_in_progress() ? NULL : GetWebContents());
    588   Layout();
    589   SchedulePaint();
    590 }
    591 
    592 void LocationBarView::UpdateGeneratedCreditCardView() {
    593   generated_credit_card_view_->Update();
    594   Layout();
    595   SchedulePaint();
    596 }
    597 
    598 void LocationBarView::OnFocus() {
    599   // Focus the view widget first which implements accessibility for
    600   // Chrome OS.  It is noop on Win. This should be removed once
    601   // Chrome OS migrates to aura, which uses Views' textfield that receives
    602   // focus. See crbug.com/106428.
    603   NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_FOCUS, false);
    604 
    605   // Then focus the native location view which implements accessibility for
    606   // Windows.
    607   omnibox_view_->SetFocus();
    608 }
    609 
    610 void LocationBarView::SetPreviewEnabledPageAction(ExtensionAction* page_action,
    611                                                   bool preview_enabled) {
    612   if (is_popup_mode_)
    613     return;
    614 
    615   DCHECK(page_action);
    616   WebContents* contents = delegate_->GetWebContents();
    617 
    618   RefreshPageActionViews();
    619   PageActionWithBadgeView* page_action_view =
    620       static_cast<PageActionWithBadgeView*>(GetPageActionView(page_action));
    621   DCHECK(page_action_view);
    622   if (!page_action_view)
    623     return;
    624 
    625   page_action_view->image_view()->set_preview_enabled(preview_enabled);
    626   page_action_view->UpdateVisibility(contents, GetToolbarModel()->GetURL());
    627   Layout();
    628   SchedulePaint();
    629 }
    630 
    631 views::View* LocationBarView::GetPageActionView(ExtensionAction *page_action) {
    632   DCHECK(page_action);
    633   for (PageActionViews::const_iterator i(page_action_views_.begin());
    634        i != page_action_views_.end(); ++i) {
    635     if ((*i)->image_view()->page_action() == page_action)
    636       return *i;
    637   }
    638   return NULL;
    639 }
    640 
    641 void LocationBarView::SetStarToggled(bool on) {
    642   if (star_view_)
    643     star_view_->SetToggled(on);
    644 }
    645 
    646 void LocationBarView::SetTranslateIconToggled(bool on) {
    647   translate_icon_view_->SetToggled(on);
    648 }
    649 
    650 void LocationBarView::ShowBookmarkPrompt() {
    651   if (star_view_ && star_view_->visible())
    652     BookmarkPromptView::ShowPrompt(star_view_, profile_->GetPrefs());
    653 }
    654 
    655 void LocationBarView::ZoomChangedForActiveTab(bool can_show_bubble) {
    656   DCHECK(zoom_view_);
    657   if (RefreshZoomView()) {
    658     Layout();
    659     SchedulePaint();
    660   }
    661 
    662   if (can_show_bubble && zoom_view_->visible() && delegate_->GetWebContents())
    663     ZoomBubbleView::ShowBubble(delegate_->GetWebContents(), true);
    664 }
    665 
    666 gfx::Point LocationBarView::GetOmniboxViewOrigin() const {
    667   gfx::Point origin(omnibox_view_->bounds().origin());
    668   // If the UI layout is RTL, the coordinate system is not transformed and
    669   // therefore we need to adjust the X coordinate so that bubble appears on the
    670   // right hand side of the location bar.
    671   if (base::i18n::IsRTL())
    672     origin.set_x(width() - origin.x());
    673   views::View::ConvertPointToScreen(this, &origin);
    674   return origin;
    675 }
    676 
    677 void LocationBarView::SetImeInlineAutocompletion(const base::string16& text) {
    678   ime_inline_autocomplete_view_->SetText(text);
    679   ime_inline_autocomplete_view_->SetVisible(!text.empty());
    680 }
    681 
    682 void LocationBarView::SetGrayTextAutocompletion(const base::string16& text) {
    683   if (suggested_text_view_->text() != text) {
    684     suggested_text_view_->SetText(text);
    685     suggested_text_view_->SetVisible(!text.empty());
    686     Layout();
    687     SchedulePaint();
    688   }
    689 }
    690 
    691 base::string16 LocationBarView::GetGrayTextAutocompletion() const {
    692   return HasValidSuggestText() ? suggested_text_view_->text()
    693                                : base::string16();
    694 }
    695 
    696 gfx::Size LocationBarView::GetPreferredSize() {
    697   gfx::Size background_min_size(background_border_painter_->GetMinimumSize());
    698   if (!IsInitialized())
    699     return background_min_size;
    700   gfx::Size search_button_min_size(search_button_->GetMinimumSize());
    701   gfx::Size min_size(background_min_size);
    702   min_size.SetToMax(search_button_min_size);
    703   min_size.set_width(
    704       background_min_size.width() + search_button_min_size.width());
    705   return min_size;
    706 }
    707 
    708 void LocationBarView::Layout() {
    709   if (!IsInitialized())
    710     return;
    711 
    712   selected_keyword_view_->SetVisible(false);
    713   location_icon_view_->SetVisible(false);
    714   ev_bubble_view_->SetVisible(false);
    715   keyword_hint_view_->SetVisible(false);
    716 
    717   const int item_padding = GetItemPadding();
    718   // The textfield has 1 px of whitespace before the text in the RTL case only.
    719   const int kEditLeadingInternalSpace = base::i18n::IsRTL() ? 1 : 0;
    720   LocationBarLayout leading_decorations(
    721       LocationBarLayout::LEFT_EDGE, item_padding - kEditLeadingInternalSpace);
    722   LocationBarLayout trailing_decorations(LocationBarLayout::RIGHT_EDGE,
    723                                          item_padding);
    724 
    725   const base::string16 keyword(omnibox_view_->model()->keyword());
    726   const bool is_keyword_hint(omnibox_view_->model()->is_keyword_hint());
    727   const int bubble_location_y = vertical_edge_thickness() + kBubblePadding;
    728   // In some cases (e.g. fullscreen mode) we may have 0 height.  We still want
    729   // to position our child views in this case, because other things may be
    730   // positioned relative to them (e.g. the "bookmark added" bubble if the user
    731   // hits ctrl-d).
    732   const int location_height = GetInternalHeight(false);
    733   const int bubble_height = std::max(location_height - (kBubblePadding * 2), 0);
    734   if (!keyword.empty() && !is_keyword_hint) {
    735     leading_decorations.AddDecoration(bubble_location_y, bubble_height, true, 0,
    736                                       kBubblePadding, item_padding, 0,
    737                                       selected_keyword_view_);
    738     if (selected_keyword_view_->keyword() != keyword) {
    739       selected_keyword_view_->SetKeyword(keyword);
    740       const TemplateURL* template_url =
    741           TemplateURLServiceFactory::GetForProfile(profile_)->
    742           GetTemplateURLForKeyword(keyword);
    743       if (template_url &&
    744           (template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION)) {
    745         gfx::Image image = extensions::OmniboxAPI::Get(profile_)->
    746             GetOmniboxIcon(template_url->GetExtensionId());
    747         selected_keyword_view_->SetImage(image.AsImageSkia());
    748         selected_keyword_view_->set_is_extension_icon(true);
    749       } else {
    750         selected_keyword_view_->SetImage(
    751             *(GetThemeProvider()->GetImageSkiaNamed(IDR_OMNIBOX_SEARCH)));
    752         selected_keyword_view_->set_is_extension_icon(false);
    753       }
    754     }
    755   } else if (!site_chip_view_ &&
    756       (GetToolbarModel()->GetSecurityLevel(false) == ToolbarModel::EV_SECURE)) {
    757     ev_bubble_view_->SetLabel(GetToolbarModel()->GetEVCertName());
    758     // The largest fraction of the omnibox that can be taken by the EV bubble.
    759     const double kMaxBubbleFraction = 0.5;
    760     leading_decorations.AddDecoration(bubble_location_y, bubble_height, false,
    761                                       kMaxBubbleFraction, kBubblePadding,
    762                                       item_padding, 0, ev_bubble_view_);
    763   } else {
    764     leading_decorations.AddDecoration(
    765         vertical_edge_thickness(), location_height,
    766         GetBuiltInHorizontalPaddingForChildViews(),
    767         location_icon_view_);
    768   }
    769 
    770   if (star_view_->visible()) {
    771     trailing_decorations.AddDecoration(
    772         vertical_edge_thickness(), location_height,
    773         GetBuiltInHorizontalPaddingForChildViews(), star_view_);
    774   }
    775   if (translate_icon_view_->visible()) {
    776     trailing_decorations.AddDecoration(
    777         vertical_edge_thickness(), location_height,
    778         GetBuiltInHorizontalPaddingForChildViews(),
    779         translate_icon_view_);
    780   }
    781   if (script_bubble_icon_view_->visible()) {
    782     trailing_decorations.AddDecoration(
    783         vertical_edge_thickness(), location_height,
    784         GetBuiltInHorizontalPaddingForChildViews(),
    785         script_bubble_icon_view_);
    786   }
    787   if (open_pdf_in_reader_view_->visible()) {
    788     trailing_decorations.AddDecoration(
    789         vertical_edge_thickness(), location_height,
    790         GetBuiltInHorizontalPaddingForChildViews(),
    791         open_pdf_in_reader_view_);
    792   }
    793   if (manage_passwords_icon_view_->visible()) {
    794     trailing_decorations.AddDecoration(vertical_edge_thickness(),
    795                                        location_height, 0,
    796                                        manage_passwords_icon_view_);
    797   }
    798   for (PageActionViews::const_iterator i(page_action_views_.begin());
    799        i != page_action_views_.end(); ++i) {
    800     if ((*i)->visible()) {
    801       trailing_decorations.AddDecoration(
    802           vertical_edge_thickness(), location_height,
    803           GetBuiltInHorizontalPaddingForChildViews(), (*i));
    804     }
    805   }
    806   if (zoom_view_->visible()) {
    807     trailing_decorations.AddDecoration(vertical_edge_thickness(),
    808                                        location_height, 0, zoom_view_);
    809   }
    810   for (ContentSettingViews::const_reverse_iterator i(
    811            content_setting_views_.rbegin()); i != content_setting_views_.rend();
    812        ++i) {
    813     if ((*i)->visible()) {
    814       trailing_decorations.AddDecoration(
    815           bubble_location_y, bubble_height, false, 0, item_padding,
    816           item_padding, GetBuiltInHorizontalPaddingForChildViews(), (*i));
    817     }
    818   }
    819   if (generated_credit_card_view_->visible()) {
    820     trailing_decorations.AddDecoration(vertical_edge_thickness(),
    821                                        location_height, 0,
    822                                        generated_credit_card_view_);
    823   }
    824   if (mic_search_view_->visible()) {
    825     trailing_decorations.AddDecoration(vertical_edge_thickness(),
    826                                        location_height, 0, mic_search_view_);
    827   }
    828   // Because IMEs may eat the tab key, we don't show "press tab to search" while
    829   // IME composition is in progress.
    830   if (!keyword.empty() && is_keyword_hint && !omnibox_view_->IsImeComposing()) {
    831     trailing_decorations.AddDecoration(vertical_edge_thickness(),
    832                                        location_height, true, 0, item_padding,
    833                                        item_padding, 0, keyword_hint_view_);
    834     if (keyword_hint_view_->keyword() != keyword)
    835       keyword_hint_view_->SetKeyword(keyword);
    836   }
    837 
    838   // Perform layout.
    839   const int horizontal_edge_thickness = GetHorizontalEdgeThickness();
    840   int full_width = width() - horizontal_edge_thickness;
    841   // The search button images are made to look as if they overlay the normal
    842   // edge images, but to align things, the search button needs to be inset
    843   // horizontally by 1 px.
    844   const int kSearchButtonInset = 1;
    845   const gfx::Size search_button_size(search_button_->GetPreferredSize());
    846   const int search_button_reserved_width =
    847       search_button_size.width() + kSearchButtonInset;
    848   full_width -= search_button_->visible() ?
    849       search_button_reserved_width : horizontal_edge_thickness;
    850   int entry_width = full_width;
    851   leading_decorations.LayoutPass1(&entry_width);
    852   trailing_decorations.LayoutPass1(&entry_width);
    853   leading_decorations.LayoutPass2(&entry_width);
    854   trailing_decorations.LayoutPass2(&entry_width);
    855 
    856   int location_needed_width = omnibox_view_->GetTextWidth();
    857   int available_width = entry_width - location_needed_width;
    858   // The bounds must be wide enough for all the decorations to fit.
    859   gfx::Rect location_bounds(
    860       horizontal_edge_thickness, vertical_edge_thickness(),
    861       std::max(full_width, full_width - entry_width), location_height);
    862   leading_decorations.LayoutPass3(&location_bounds, &available_width);
    863   trailing_decorations.LayoutPass3(&location_bounds, &available_width);
    864 
    865   // Layout out the suggested text view right aligned to the location
    866   // entry. Only show the suggested text if we can fit the text from one
    867   // character before the end of the selection to the end of the text and the
    868   // suggested text. If we can't it means either the suggested text is too big,
    869   // or the user has scrolled.
    870 
    871   // TODO(sky): We could potentially adjust this to take into account suggested
    872   // text to force using minimum size if necessary, but currently the chance of
    873   // showing keyword hints and suggested text is minimal and we're not confident
    874   // this is the right approach for suggested text.
    875 
    876   int omnibox_view_margin = 0;
    877   if (suggested_text_view_->visible()) {
    878     // We do not display the suggested text when it contains a mix of RTL and
    879     // LTR characters since this could mean the suggestion should be displayed
    880     // in the middle of the string.
    881     base::i18n::TextDirection text_direction =
    882         base::i18n::GetStringDirection(omnibox_view_->GetText());
    883     if (text_direction !=
    884         base::i18n::GetStringDirection(suggested_text_view_->text()))
    885       text_direction = base::i18n::UNKNOWN_DIRECTION;
    886 
    887     // TODO(sky): need to layout when the user changes caret position.
    888     gfx::Size suggested_text_size(suggested_text_view_->GetPreferredSize());
    889     if (suggested_text_size.width() > available_width ||
    890         text_direction == base::i18n::UNKNOWN_DIRECTION) {
    891       // Hide the suggested text if the user has scrolled or we can't fit all
    892       // the suggested text, or we have a mix of RTL and LTR characters.
    893       suggested_text_view_->SetBounds(0, 0, 0, 0);
    894     } else {
    895       location_needed_width =
    896           std::min(location_needed_width,
    897                    location_bounds.width() - suggested_text_size.width());
    898       gfx::Rect suggested_text_bounds(location_bounds.x(), location_bounds.y(),
    899                                       suggested_text_size.width(),
    900                                       location_bounds.height());
    901       // TODO(sky): figure out why this needs the -1.
    902       suggested_text_bounds.Offset(location_needed_width - 1, 0);
    903 
    904       // We reverse the order of the location entry and suggested text if:
    905       // - Chrome is RTL but the text is fully LTR, or
    906       // - Chrome is LTR but the text is fully RTL.
    907       // This ensures the suggested text is correctly displayed to the right
    908       // (or left) of the user text.
    909       if (text_direction == (base::i18n::IsRTL() ?
    910           base::i18n::LEFT_TO_RIGHT : base::i18n::RIGHT_TO_LEFT)) {
    911         // TODO(sky): Figure out why we need the +1.
    912         suggested_text_bounds.set_x(location_bounds.x() + 1);
    913         // Use a margin to prevent omnibox text from overlapping suggest text.
    914         omnibox_view_margin = suggested_text_bounds.width();
    915       }
    916       suggested_text_view_->SetBoundsRect(suggested_text_bounds);
    917     }
    918   }
    919 
    920   omnibox_view_->SetHorizontalMargins(0, omnibox_view_margin);
    921 
    922   // Layout |ime_inline_autocomplete_view_| next to the user input.
    923   if (ime_inline_autocomplete_view_->visible()) {
    924     int width =
    925         ime_inline_autocomplete_view_->font().GetStringWidth(
    926             ime_inline_autocomplete_view_->text()) +
    927         ime_inline_autocomplete_view_->GetInsets().width();
    928     // All the target languages (IMEs) are LTR, and we do not need to support
    929     // RTL so far.  In other words, no testable RTL environment so far.
    930     int x = location_needed_width;
    931     if (width > entry_width)
    932       x = 0;
    933     else if (location_needed_width + width > entry_width)
    934       x = entry_width - width;
    935     location_bounds.set_width(x);
    936     ime_inline_autocomplete_view_->SetBounds(
    937         location_bounds.right(), location_bounds.y(),
    938         std::min(width, entry_width), location_bounds.height());
    939   }
    940 
    941   omnibox_view_->SetBoundsRect(location_bounds);
    942 
    943   search_button_->SetBoundsRect(gfx::Rect(
    944       gfx::Point(width() - search_button_reserved_width, 0),
    945       search_button_size));
    946 }
    947 
    948 void LocationBarView::PaintChildren(gfx::Canvas* canvas) {
    949   View::PaintChildren(canvas);
    950 
    951   // For non-InstantExtendedAPI cases, if necessary, show focus rect. As we need
    952   // the focus rect to appear on top of children we paint here rather than
    953   // OnPaint().
    954   // Note: |Canvas::DrawFocusRect| paints a dashed rect with gray color.
    955   if (show_focus_rect_ && HasFocus())
    956     canvas->DrawFocusRect(omnibox_view_->bounds());
    957 }
    958 
    959 void LocationBarView::OnPaint(gfx::Canvas* canvas) {
    960   View::OnPaint(canvas);
    961 
    962   // Fill the location bar background color behind the border.  Parts of the
    963   // border images are meant to rest atop the toolbar background and parts atop
    964   // the omnibox background, so we can't just blindly fill our entire bounds.
    965   const int horizontal_edge_thickness = GetHorizontalEdgeThickness();
    966   if (!background_filling_painter_) {
    967     gfx::Rect bounds(GetContentsBounds());
    968     bounds.Inset(horizontal_edge_thickness, vertical_edge_thickness());
    969     SkColor color(GetColor(ToolbarModel::NONE, BACKGROUND));
    970     if (is_popup_mode_) {
    971       canvas->FillRect(bounds, color);
    972     } else {
    973       SkPaint paint;
    974       paint.setStyle(SkPaint::kFill_Style);
    975       paint.setColor(color);
    976       const int kBorderCornerRadius = 2;
    977       canvas->DrawRoundRect(bounds, kBorderCornerRadius, paint);
    978     }
    979   }
    980 
    981   // Maximized popup windows don't draw the horizontal edges.  We implement this
    982   // by simply expanding the paint area outside the view by the edge thickness.
    983   gfx::Rect background_rect(GetContentsBounds());
    984   if (is_popup_mode_ && (horizontal_edge_thickness == 0))
    985     background_rect.Inset(-kPopupEdgeThickness, 0);
    986   views::Painter::PaintPainterAt(canvas, background_border_painter_.get(),
    987                                  background_rect);
    988   if (background_filling_painter_)
    989     background_filling_painter_->Paint(canvas, size());
    990 
    991   if (!is_popup_mode_)
    992     PaintPageActionBackgrounds(canvas);
    993 }
    994 
    995 void LocationBarView::SetShowFocusRect(bool show) {
    996   show_focus_rect_ = show;
    997   SchedulePaint();
    998 }
    999 
   1000 void LocationBarView::SelectAll() {
   1001   omnibox_view_->SelectAll(true);
   1002 }
   1003 
   1004 views::ImageView* LocationBarView::GetLocationIconView() {
   1005   return site_chip_view_ ?
   1006       site_chip_view_->location_icon_view() : location_icon_view_;
   1007 }
   1008 
   1009 const views::ImageView* LocationBarView::GetLocationIconView() const {
   1010   return site_chip_view_ ?
   1011       site_chip_view_->location_icon_view() : location_icon_view_;
   1012 }
   1013 
   1014 views::View* LocationBarView::GetLocationBarAnchor() {
   1015   return GetLocationIconView();
   1016 }
   1017 
   1018 gfx::Point LocationBarView::GetLocationBarAnchorPoint() const {
   1019   // The +1 in the next line creates a 1-px gap between icon and arrow tip.
   1020   gfx::Point icon_bottom(0, GetLocationIconView()->GetImageBounds().bottom() -
   1021       LocationBarView::kIconInternalPadding + 1);
   1022   gfx::Point icon_center(GetLocationIconView()->GetImageBounds().CenterPoint());
   1023   gfx::Point point(icon_center.x(), icon_bottom.y());
   1024   ConvertPointToTarget(GetLocationIconView(), this, &point);
   1025   return point;
   1026 }
   1027 
   1028 views::View* LocationBarView::generated_credit_card_view() {
   1029   return generated_credit_card_view_;
   1030 }
   1031 
   1032 void LocationBarView::Update(const WebContents* contents) {
   1033   mic_search_view_->SetVisible(
   1034       !GetToolbarModel()->input_in_progress() && browser_ &&
   1035       browser_->search_model()->voice_search_supported());
   1036   RefreshContentSettingViews();
   1037   generated_credit_card_view_->Update();
   1038   ZoomBubbleView::CloseBubble();
   1039   RefreshZoomView();
   1040   RefreshPageActionViews();
   1041   RefreshScriptBubble();
   1042   RefreshTranslateIcon();
   1043   RefreshManagePasswordsIconView();
   1044   open_pdf_in_reader_view_->Update(
   1045       GetToolbarModel()->input_in_progress() ? NULL : GetWebContents());
   1046 
   1047   bool star_enabled = browser_defaults::bookmarks_enabled && !is_popup_mode_ &&
   1048       star_view_ && !GetToolbarModel()->input_in_progress() &&
   1049       edit_bookmarks_enabled_.GetValue() && !IsBookmarkStarHiddenByExtension();
   1050 
   1051   command_updater()->UpdateCommandEnabled(IDC_BOOKMARK_PAGE, star_enabled);
   1052   command_updater()->UpdateCommandEnabled(IDC_BOOKMARK_PAGE_FROM_STAR,
   1053                                           star_enabled);
   1054   if (star_view_)
   1055     star_view_->SetVisible(star_enabled);
   1056 
   1057   if (contents)
   1058     omnibox_view_->OnTabChanged(contents);
   1059   else
   1060     omnibox_view_->Update();
   1061 
   1062   OnChanged();  // NOTE: Calls Layout().
   1063 }
   1064 
   1065 void LocationBarView::OnChanged() {
   1066   int icon_id = omnibox_view_->GetIcon();
   1067   location_icon_view_->SetImage(GetThemeProvider()->GetImageSkiaNamed(icon_id));
   1068   location_icon_view_->ShowTooltip(!GetOmniboxView()->IsEditingOrEmpty());
   1069 
   1070   ToolbarModel* toolbar_model = GetToolbarModel();
   1071   chrome::DisplaySearchButtonConditions conditions =
   1072       chrome::GetDisplaySearchButtonConditions();
   1073   bool meets_conditions =
   1074       (conditions == chrome::DISPLAY_SEARCH_BUTTON_ALWAYS) ||
   1075       ((conditions != chrome::DISPLAY_SEARCH_BUTTON_NEVER) &&
   1076        (toolbar_model->WouldPerformSearchTermReplacement(true) ||
   1077         ((conditions == chrome::DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP) &&
   1078          toolbar_model->input_in_progress())));
   1079   search_button_->SetVisible(!is_popup_mode_ && meets_conditions);
   1080   search_button_->SetImage(
   1081       views::Button::STATE_NORMAL,
   1082       *GetThemeProvider()->GetImageSkiaNamed((icon_id == IDR_OMNIBOX_SEARCH) ?
   1083           IDR_OMNIBOX_SEARCH_BUTTON_LOUPE : IDR_OMNIBOX_SEARCH_BUTTON_ARROW));
   1084 
   1085   if (site_chip_view_)
   1086     site_chip_view_->OnChanged();
   1087 
   1088   Layout();
   1089   SchedulePaint();
   1090 }
   1091 
   1092 void LocationBarView::OnSetFocus() {
   1093   GetFocusManager()->SetFocusedView(this);
   1094 }
   1095 
   1096 InstantController* LocationBarView::GetInstant() {
   1097   return delegate_->GetInstant();
   1098 }
   1099 
   1100 WebContents* LocationBarView::GetWebContents() {
   1101   return delegate_->GetWebContents();
   1102 }
   1103 
   1104 ToolbarModel* LocationBarView::GetToolbarModel() {
   1105   return delegate_->GetToolbarModel();
   1106 }
   1107 
   1108 const ToolbarModel* LocationBarView::GetToolbarModel() const {
   1109   return delegate_->GetToolbarModel();
   1110 }
   1111 
   1112 const char* LocationBarView::GetClassName() const {
   1113   return kViewClassName;
   1114 }
   1115 
   1116 bool LocationBarView::HasFocus() const {
   1117   return omnibox_view_->model()->has_focus();
   1118 }
   1119 
   1120 void LocationBarView::GetAccessibleState(ui::AccessibleViewState* state) {
   1121   if (!IsInitialized())
   1122     return;
   1123 
   1124   state->role = ui::AccessibilityTypes::ROLE_LOCATION_BAR;
   1125   state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION);
   1126   state->value = omnibox_view_->GetText();
   1127 
   1128   base::string16::size_type entry_start;
   1129   base::string16::size_type entry_end;
   1130   omnibox_view_->GetSelectionBounds(&entry_start, &entry_end);
   1131   state->selection_start = entry_start;
   1132   state->selection_end = entry_end;
   1133 
   1134   if (is_popup_mode_) {
   1135     state->state |= ui::AccessibilityTypes::STATE_READONLY;
   1136   } else {
   1137     state->set_value_callback =
   1138         base::Bind(&LocationBarView::AccessibilitySetValue,
   1139                    weak_ptr_factory_.GetWeakPtr());
   1140   }
   1141 }
   1142 
   1143 void LocationBarView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
   1144   if (browser_ && browser_->instant_controller() && parent())
   1145     browser_->instant_controller()->SetOmniboxBounds(bounds());
   1146   OmniboxPopupView* popup = omnibox_view_->model()->popup_model()->view();
   1147   if (popup->IsOpen())
   1148     popup->UpdatePopupAppearance();
   1149 }
   1150 
   1151 void LocationBarView::ButtonPressed(views::Button* sender,
   1152                                     const ui::Event& event) {
   1153   if (sender == mic_search_view_) {
   1154     command_updater()->ExecuteCommand(IDC_TOGGLE_SPEECH_INPUT);
   1155     return;
   1156   }
   1157 
   1158   DCHECK_EQ(search_button_, sender);
   1159   // TODO(pkasting): When macourteau adds UMA stats for this, wire them up here.
   1160   omnibox_view_->model()->AcceptInput(
   1161       ui::DispositionFromEventFlags(event.flags()), false);
   1162 }
   1163 
   1164 void LocationBarView::WriteDragDataForView(views::View* sender,
   1165                                            const gfx::Point& press_pt,
   1166                                            OSExchangeData* data) {
   1167   DCHECK_NE(GetDragOperationsForView(sender, press_pt),
   1168             ui::DragDropTypes::DRAG_NONE);
   1169 
   1170   WebContents* web_contents = GetWebContents();
   1171   FaviconTabHelper* favicon_tab_helper =
   1172       FaviconTabHelper::FromWebContents(web_contents);
   1173   gfx::ImageSkia favicon = favicon_tab_helper->GetFavicon().AsImageSkia();
   1174   button_drag_utils::SetURLAndDragImage(web_contents->GetURL(),
   1175                                         web_contents->GetTitle(),
   1176                                         favicon,
   1177                                         data,
   1178                                         sender->GetWidget());
   1179 }
   1180 
   1181 int LocationBarView::GetDragOperationsForView(views::View* sender,
   1182                                               const gfx::Point& p) {
   1183   DCHECK((sender == location_icon_view_) || (sender == ev_bubble_view_));
   1184   WebContents* web_contents = delegate_->GetWebContents();
   1185   return (web_contents && web_contents->GetURL().is_valid() &&
   1186           !GetOmniboxView()->IsEditingOrEmpty()) ?
   1187       (ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK) :
   1188       ui::DragDropTypes::DRAG_NONE;
   1189 }
   1190 
   1191 bool LocationBarView::CanStartDragForView(View* sender,
   1192                                           const gfx::Point& press_pt,
   1193                                           const gfx::Point& p) {
   1194   return true;
   1195 }
   1196 
   1197 ////////////////////////////////////////////////////////////////////////////////
   1198 // LocationBarView, LocationBar implementation:
   1199 
   1200 void LocationBarView::ShowFirstRunBubble() {
   1201   // Wait until search engines have loaded to show the first run bubble.
   1202   TemplateURLService* url_service =
   1203       TemplateURLServiceFactory::GetForProfile(profile_);
   1204   if (!url_service->loaded()) {
   1205     template_url_service_ = url_service;
   1206     template_url_service_->AddObserver(this);
   1207     template_url_service_->Load();
   1208     return;
   1209   }
   1210   ShowFirstRunBubbleInternal();
   1211 }
   1212 
   1213 GURL LocationBarView::GetDestinationURL() const {
   1214   return destination_url();
   1215 }
   1216 
   1217 WindowOpenDisposition LocationBarView::GetWindowOpenDisposition() const {
   1218   return disposition();
   1219 }
   1220 
   1221 content::PageTransition LocationBarView::GetPageTransition() const {
   1222   return transition();
   1223 }
   1224 
   1225 void LocationBarView::AcceptInput() {
   1226   omnibox_view_->model()->AcceptInput(CURRENT_TAB, false);
   1227 }
   1228 
   1229 void LocationBarView::FocusLocation(bool select_all) {
   1230   omnibox_view_->SetFocus();
   1231   if (select_all)
   1232     omnibox_view_->SelectAll(true);
   1233 }
   1234 
   1235 void LocationBarView::FocusSearch() {
   1236   omnibox_view_->SetFocus();
   1237   omnibox_view_->SetForcedQuery();
   1238 }
   1239 
   1240 void LocationBarView::SaveStateToContents(WebContents* contents) {
   1241   omnibox_view_->SaveStateToTab(contents);
   1242 }
   1243 
   1244 void LocationBarView::Revert() {
   1245   omnibox_view_->RevertAll();
   1246 }
   1247 
   1248 const OmniboxView* LocationBarView::GetOmniboxView() const {
   1249   return omnibox_view_;
   1250 }
   1251 
   1252 OmniboxView* LocationBarView::GetOmniboxView() {
   1253   return omnibox_view_;
   1254 }
   1255 
   1256 LocationBarTesting* LocationBarView::GetLocationBarForTesting() {
   1257   return this;
   1258 }
   1259 
   1260 int LocationBarView::PageActionCount() {
   1261   return page_action_views_.size();
   1262 }
   1263 
   1264 int LocationBarView::PageActionVisibleCount() {
   1265   int result = 0;
   1266   for (size_t i = 0; i < page_action_views_.size(); i++) {
   1267     if (page_action_views_[i]->visible())
   1268       ++result;
   1269   }
   1270   return result;
   1271 }
   1272 
   1273 ExtensionAction* LocationBarView::GetPageAction(size_t index) {
   1274   if (index < page_action_views_.size())
   1275     return page_action_views_[index]->image_view()->page_action();
   1276 
   1277   NOTREACHED();
   1278   return NULL;
   1279 }
   1280 
   1281 ExtensionAction* LocationBarView::GetVisiblePageAction(size_t index) {
   1282   size_t current = 0;
   1283   for (size_t i = 0; i < page_action_views_.size(); ++i) {
   1284     if (page_action_views_[i]->visible()) {
   1285       if (current == index)
   1286         return page_action_views_[i]->image_view()->page_action();
   1287 
   1288       ++current;
   1289     }
   1290   }
   1291 
   1292   NOTREACHED();
   1293   return NULL;
   1294 }
   1295 
   1296 void LocationBarView::TestPageActionPressed(size_t index) {
   1297   size_t current = 0;
   1298   for (size_t i = 0; i < page_action_views_.size(); ++i) {
   1299     if (page_action_views_[i]->visible()) {
   1300       if (current == index) {
   1301         page_action_views_[i]->image_view()->ExecuteAction(
   1302             ExtensionPopup::SHOW);
   1303         return;
   1304       }
   1305       ++current;
   1306     }
   1307   }
   1308 
   1309   NOTREACHED();
   1310 }
   1311 
   1312 bool LocationBarView::GetBookmarkStarVisibility() {
   1313   DCHECK(star_view_);
   1314   return star_view_->visible();
   1315 }
   1316 
   1317 void LocationBarView::OnTemplateURLServiceChanged() {
   1318   template_url_service_->RemoveObserver(this);
   1319   template_url_service_ = NULL;
   1320   // If the browser is no longer active, let's not show the info bubble, as this
   1321   // would make the browser the active window again.
   1322   if (omnibox_view_ && omnibox_view_->GetWidget()->IsActive())
   1323     ShowFirstRunBubble();
   1324 }
   1325 
   1326 void LocationBarView::Observe(int type,
   1327                               const content::NotificationSource& source,
   1328                               const content::NotificationDetails& details) {
   1329   switch (type) {
   1330     case chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED: {
   1331       // Only update if the updated action box was for the active tab contents.
   1332       WebContents* target_tab = content::Details<WebContents>(details).ptr();
   1333       if (target_tab == GetWebContents())
   1334         UpdatePageActions();
   1335       break;
   1336     }
   1337 
   1338     case chrome::NOTIFICATION_EXTENSION_LOADED:
   1339     case chrome::NOTIFICATION_EXTENSION_UNLOADED:
   1340       Update(NULL);
   1341       break;
   1342 
   1343     default:
   1344       NOTREACHED() << "Unexpected notification.";
   1345   }
   1346 }
   1347 
   1348 void LocationBarView::ModelChanged(const SearchModel::State& old_state,
   1349                                    const SearchModel::State& new_state) {
   1350   const bool visible = !GetToolbarModel()->input_in_progress() &&
   1351       new_state.voice_search_supported;
   1352   if (mic_search_view_->visible() != visible) {
   1353     mic_search_view_->SetVisible(visible);
   1354     Layout();
   1355   }
   1356 }
   1357 
   1358 int LocationBarView::GetInternalHeight(bool use_preferred_size) {
   1359   int total_height =
   1360       use_preferred_size ? GetPreferredSize().height() : height();
   1361   return std::max(total_height - (vertical_edge_thickness() * 2), 0);
   1362 }
   1363 
   1364 ////////////////////////////////////////////////////////////////////////////////
   1365 // LocationBarView, private:
   1366 
   1367 // static
   1368 int LocationBarView::GetBuiltInHorizontalPaddingForChildViews() {
   1369   return (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) ?
   1370       GetItemPadding() / 2 : 0;
   1371 }
   1372 
   1373 int LocationBarView::GetHorizontalEdgeThickness() const {
   1374   // In maximized popup mode, there isn't any edge.
   1375   return (is_popup_mode_ && browser_ && browser_->window() &&
   1376       browser_->window()->IsMaximized()) ? 0 : vertical_edge_thickness();
   1377 }
   1378 
   1379 bool LocationBarView::RefreshContentSettingViews() {
   1380   bool visibility_changed = false;
   1381   for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
   1382        i != content_setting_views_.end(); ++i) {
   1383     const bool was_visible = (*i)->visible();
   1384     (*i)->Update(GetToolbarModel()->input_in_progress() ?
   1385         NULL : GetWebContents());
   1386     if (was_visible != (*i)->visible())
   1387       visibility_changed = true;
   1388   }
   1389   return visibility_changed;
   1390 }
   1391 
   1392 void LocationBarView::DeletePageActionViews() {
   1393   for (PageActionViews::const_iterator i(page_action_views_.begin());
   1394        i != page_action_views_.end(); ++i)
   1395     RemoveChildView(*i);
   1396   STLDeleteElements(&page_action_views_);
   1397 }
   1398 
   1399 bool LocationBarView::RefreshPageActionViews() {
   1400   if (is_popup_mode_)
   1401     return false;
   1402 
   1403   bool changed = false;
   1404 
   1405   // Remember the previous visibility of the page actions so that we can
   1406   // notify when this changes.
   1407   std::map<ExtensionAction*, bool> old_visibility;
   1408   for (PageActionViews::const_iterator i(page_action_views_.begin());
   1409        i != page_action_views_.end(); ++i) {
   1410     old_visibility[(*i)->image_view()->page_action()] = (*i)->visible();
   1411   }
   1412 
   1413   PageActions new_page_actions;
   1414 
   1415   WebContents* contents = delegate_->GetWebContents();
   1416   if (contents) {
   1417     extensions::TabHelper* extensions_tab_helper =
   1418         extensions::TabHelper::FromWebContents(contents);
   1419     extensions::LocationBarController* controller =
   1420         extensions_tab_helper->location_bar_controller();
   1421     new_page_actions = controller->GetCurrentActions();
   1422   }
   1423 
   1424   // On startup we sometimes haven't loaded any extensions. This makes sure
   1425   // we catch up when the extensions (and any page actions) load.
   1426   if (page_actions_ != new_page_actions) {
   1427     changed = true;
   1428 
   1429     page_actions_.swap(new_page_actions);
   1430     DeletePageActionViews();  // Delete the old views (if any).
   1431 
   1432     page_action_views_.resize(page_actions_.size());
   1433     // Create the page action views.
   1434     PageActionViews::iterator dest = page_action_views_.begin();
   1435     for (PageActions::const_iterator i = page_actions_.begin();
   1436          i != page_actions_.end(); ++i, ++dest) {
   1437       PageActionWithBadgeView* page_action_view = new PageActionWithBadgeView(
   1438           delegate_->CreatePageActionImageView(this, *i));
   1439       page_action_view->SetVisible(false);
   1440       *dest = page_action_view;
   1441     }
   1442 
   1443     // Move rightmost extensions to the start.
   1444     std::stable_partition(
   1445         page_action_views_.begin(),
   1446         page_action_views_.end(),
   1447         IsPageActionViewRightAligned(
   1448             extensions::ExtensionSystem::Get(profile_)->extension_service()));
   1449 
   1450     View* right_anchor = open_pdf_in_reader_view_;
   1451     if (!right_anchor)
   1452       right_anchor = star_view_;
   1453     if (!right_anchor)
   1454       right_anchor = script_bubble_icon_view_;
   1455     DCHECK(right_anchor);
   1456 
   1457     // Use reverse (i.e. left-right) ordering for the page action views for
   1458     // accessibility.
   1459     for (PageActionViews::reverse_iterator i = page_action_views_.rbegin();
   1460          i != page_action_views_.rend(); ++i) {
   1461       AddChildViewAt(*i, GetIndexOf(right_anchor));
   1462     }
   1463   }
   1464 
   1465   if (!page_action_views_.empty() && contents) {
   1466     Browser* browser = chrome::FindBrowserWithWebContents(contents);
   1467     GURL url = browser->tab_strip_model()->GetActiveWebContents()->GetURL();
   1468 
   1469     for (PageActionViews::const_iterator i(page_action_views_.begin());
   1470          i != page_action_views_.end(); ++i) {
   1471       (*i)->UpdateVisibility(
   1472           GetToolbarModel()->input_in_progress() ? NULL : contents, url);
   1473 
   1474       // Check if the visibility of the action changed and notify if it did.
   1475       ExtensionAction* action = (*i)->image_view()->page_action();
   1476       if (old_visibility.find(action) == old_visibility.end() ||
   1477           old_visibility[action] != (*i)->visible()) {
   1478         changed = true;
   1479         content::NotificationService::current()->Notify(
   1480             chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
   1481             content::Source<ExtensionAction>(action),
   1482             content::Details<WebContents>(contents));
   1483       }
   1484     }
   1485   }
   1486   return changed;
   1487 }
   1488 
   1489 size_t LocationBarView::ScriptBubbleScriptsRunning() {
   1490   WebContents* contents = delegate_->GetWebContents();
   1491   if (!contents)
   1492     return false;
   1493   extensions::TabHelper* extensions_tab_helper =
   1494       extensions::TabHelper::FromWebContents(contents);
   1495   if (!extensions_tab_helper)
   1496     return false;
   1497   extensions::ScriptBubbleController* script_bubble_controller =
   1498       extensions_tab_helper->script_bubble_controller();
   1499   if (!script_bubble_controller)
   1500     return false;
   1501   size_t script_count =
   1502       script_bubble_controller->extensions_running_scripts().size();
   1503   return script_count;
   1504 }
   1505 
   1506 bool LocationBarView::RefreshScriptBubble() {
   1507   if (!script_bubble_icon_view_)
   1508     return false;
   1509   size_t script_count = ScriptBubbleScriptsRunning();
   1510   const bool was_visible = script_bubble_icon_view_->visible();
   1511   script_bubble_icon_view_->SetVisible(script_count > 0);
   1512   if (script_count > 0)
   1513     script_bubble_icon_view_->SetScriptCount(script_count);
   1514   return was_visible != script_bubble_icon_view_->visible();
   1515 }
   1516 
   1517 bool LocationBarView::RefreshZoomView() {
   1518   DCHECK(zoom_view_);
   1519   WebContents* web_contents = GetWebContents();
   1520   if (!web_contents)
   1521     return false;
   1522   const bool was_visible = zoom_view_->visible();
   1523   zoom_view_->Update(ZoomController::FromWebContents(web_contents));
   1524   return was_visible != zoom_view_->visible();
   1525 }
   1526 
   1527 bool LocationBarView::RefreshManagePasswordsIconView() {
   1528   DCHECK(manage_passwords_icon_view_);
   1529   WebContents* web_contents = GetWebContents();
   1530   if (!web_contents)
   1531     return false;
   1532   const bool was_visible = manage_passwords_icon_view_->visible();
   1533   manage_passwords_icon_view_->Update(
   1534       ManagePasswordsBubbleUIController::FromWebContents(web_contents));
   1535   return was_visible != manage_passwords_icon_view_->visible();
   1536 }
   1537 
   1538 void LocationBarView::RefreshTranslateIcon() {
   1539   if (!TranslateManager::IsTranslateBubbleEnabled())
   1540     return;
   1541 
   1542   WebContents* web_contents = GetWebContents();
   1543   if (!web_contents)
   1544     return;
   1545   LanguageState& language_state = TranslateTabHelper::FromWebContents(
   1546       web_contents)->language_state();
   1547   bool enabled = language_state.translate_enabled();
   1548   command_updater()->UpdateCommandEnabled(IDC_TRANSLATE_PAGE, enabled);
   1549   translate_icon_view_->SetVisible(enabled);
   1550   translate_icon_view_->SetToggled(language_state.IsPageTranslated());
   1551 }
   1552 
   1553 void LocationBarView::ShowManagePasswordsBubbleIfNeeded() {
   1554   DCHECK(manage_passwords_icon_view_);
   1555   WebContents* web_contents = GetWebContents();
   1556   if (!web_contents)
   1557     return;
   1558   manage_passwords_icon_view_->ShowBubbleIfNeeded(
   1559       ManagePasswordsBubbleUIController::FromWebContents(web_contents));
   1560 }
   1561 
   1562 bool LocationBarView::HasValidSuggestText() const {
   1563   return suggested_text_view_->visible() &&
   1564       !suggested_text_view_->size().IsEmpty();
   1565 }
   1566 
   1567 void LocationBarView::ShowFirstRunBubbleInternal() {
   1568 #if !defined(OS_CHROMEOS)
   1569   // First run bubble doesn't make sense for Chrome OS.
   1570   Browser* browser = GetBrowserFromDelegate(delegate_);
   1571   if (!browser)
   1572     return; // Possible when browser is shutting down.
   1573 
   1574   FirstRunBubble::ShowBubble(browser, GetLocationBarAnchor());
   1575 #endif
   1576 }
   1577 
   1578 void LocationBarView::PaintPageActionBackgrounds(gfx::Canvas* canvas) {
   1579   WebContents* web_contents = GetWebContents();
   1580   // web_contents may be NULL while the browser is shutting down.
   1581   if (!web_contents)
   1582     return;
   1583 
   1584   const int32 tab_id = SessionID::IdForTab(web_contents);
   1585   const ToolbarModel::SecurityLevel security_level =
   1586       GetToolbarModel()->GetSecurityLevel(false);
   1587   const SkColor text_color = GetColor(security_level, TEXT);
   1588   const SkColor background_color = GetColor(security_level, BACKGROUND);
   1589 
   1590   for (PageActionViews::const_iterator
   1591            page_action_view = page_action_views_.begin();
   1592        page_action_view != page_action_views_.end();
   1593        ++page_action_view) {
   1594     gfx::Rect bounds = (*page_action_view)->bounds();
   1595     int horizontal_padding =
   1596         GetItemPadding() - GetBuiltInHorizontalPaddingForChildViews();
   1597     // Make the bounding rectangle include the whole vertical range of the
   1598     // location bar, and the mid-point pixels between adjacent page actions.
   1599     //
   1600     // For odd horizontal_paddings, "horizontal_padding + 1" includes the
   1601     // mid-point between two page actions in the bounding rectangle.  For even
   1602     // paddings, the +1 is dropped, which is right since there is no pixel at
   1603     // the mid-point.
   1604     bounds.Inset(-(horizontal_padding + 1) / 2, 0);
   1605     location_bar_util::PaintExtensionActionBackground(
   1606         *(*page_action_view)->image_view()->page_action(),
   1607         tab_id, canvas, bounds, text_color, background_color);
   1608   }
   1609 }
   1610 
   1611 void LocationBarView::AccessibilitySetValue(const base::string16& new_value) {
   1612   omnibox_view_->SetUserText(new_value, new_value, true);
   1613 }
   1614 
   1615 bool LocationBarView::IsBookmarkStarHiddenByExtension() {
   1616   ExtensionService* extension_service =
   1617       extensions::ExtensionSystem::GetForBrowserContext(profile_)
   1618           ->extension_service();
   1619   // Extension service may be NULL during unit test execution.
   1620   if (!extension_service)
   1621     return false;
   1622 
   1623   const ExtensionSet* extension_set =
   1624       extension_service->extensions();
   1625   for (ExtensionSet::const_iterator i = extension_set->begin();
   1626        i != extension_set->end(); ++i) {
   1627     const extensions::SettingsOverrides* settings_overrides =
   1628         extensions::SettingsOverrides::Get(i->get());
   1629     const bool manifest_hides_bookmark_button = settings_overrides &&
   1630         settings_overrides->RequiresHideBookmarkButtonPermission();
   1631 
   1632     if (!manifest_hides_bookmark_button)
   1633       continue;
   1634 
   1635     if (extensions::PermissionsData::HasAPIPermission(
   1636             *i,
   1637             extensions::APIPermission::kBookmarkManagerPrivate))
   1638       return true;
   1639 
   1640     if (extensions::FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled())
   1641       return true;
   1642   }
   1643 
   1644   return false;
   1645 }
   1646