13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_browser_event_router.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/platform_util.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_action.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_resource.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/accessibility/accessible_view_state.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_2.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPageActionImageView::PageActionImageView(LocationBarView* owner,
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         Profile* profile,
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         ExtensionAction* page_action)
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : owner_(owner),
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_(profile),
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      page_action_(page_action),
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      current_tab_id_(-1),
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      preview_enabled_(false),
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      popup_(NULL) {
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const Extension* extension = profile->GetExtensionService()->
31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetExtensionById(page_action->extension_id(), false);
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Load all the icons declared in the manifest. This is the contents of the
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // icons array, plus the default_icon property, if any.
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> icon_paths(*page_action->icon_paths());
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!page_action_->default_icon_path().empty())
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    icon_paths.push_back(page_action_->default_icon_path());
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<std::string>::iterator iter = icon_paths.begin();
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != icon_paths.end(); ++iter) {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tracker_.LoadImage(extension, extension->GetResource(*iter),
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       gfx::Size(Extension::kPageActionIconMaxSize,
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 Extension::kPageActionIconMaxSize),
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       ImageLoadingTracker::DONT_CACHE);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_accessibility_focusable(true);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPageActionImageView::~PageActionImageView() {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (popup_)
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HidePopup();
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::ExecuteAction(int button,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        bool inspect_with_devtools) {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_tab_id_ < 0) {
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "No current tab.";
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (page_action_->HasPopup(current_tab_id_)) {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // In tests, GetLastActive could return NULL, so we need to have
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // a fallback.
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(erikkay): Find a better way to get the Browser that this
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // button is in.
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!browser)
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser = BrowserList::FindBrowserWithProfile(profile_);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(browser);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool popup_showing = popup_ != NULL;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Always hide the current popup. Only one popup at a time.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HidePopup();
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If we were already showing, then treat this click as a dismiss.
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (popup_showing)
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Rect screen_bounds(GetImageBounds());
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Point origin(screen_bounds.origin());
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    View::ConvertPointToScreen(this, &origin);
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    screen_bounds.set_origin(origin);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ?
883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    popup_ = ExtensionPopup::Show(
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        page_action_->GetPopupUrl(current_tab_id_),
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        browser,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        screen_bounds,
943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        arrow_location,
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        inspect_with_devtools,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        this);  // ExtensionPopup::Observer
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ExtensionService* service = profile_->GetExtensionService();
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service->browser_event_router()->PageActionExecuted(
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        profile_, page_action_->extension_id(), page_action_->id(),
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        current_tab_id_, current_url_.spec(), button);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PageActionImageView::GetAccessibleState(ui::AccessibleViewState* state) {
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool PageActionImageView::OnMousePressed(const views::MouseEvent& event) {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We want to show the bubble on mouse release; that is the standard behavior
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for buttons.  (Also, triggering on mouse press causes bugs like
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // http://crbug.com/33155.)
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PageActionImageView::OnMouseReleased(const views::MouseEvent& event) {
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!HitTest(event.location()))
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int button = -1;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (event.IsLeftMouseButton()) {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    button = 1;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (event.IsMiddleMouseButton()) {
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    button = 2;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (event.IsRightMouseButton()) {
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Get the top left point of this button in screen coordinates.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Point menu_origin;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConvertPointToScreen(this, &menu_origin);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make the menu appear below the button.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    menu_origin.Offset(0, height());
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ShowContextMenu(menu_origin, true);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExecuteAction(button, false);  // inspect_with_devtools
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool PageActionImageView::OnKeyPressed(const views::KeyEvent& event) {
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (event.key_code() == ui::VKEY_SPACE ||
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      event.key_code() == ui::VKEY_RETURN) {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExecuteAction(1, false);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::ShowContextMenu(const gfx::Point& p,
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          bool is_mouse_gesture) {
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const Extension* extension = profile_->GetExtensionService()->
150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetExtensionById(page_action()->extension_id(), false);
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!extension->ShowConfigureContextMenus())
15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = BrowserView::GetBrowserViewForNativeWindow(
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      platform_util::GetTopLevel(GetWidget()->GetNativeView()))->browser();
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_menu_contents_ =
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new ExtensionContextMenuModel(extension, browser, this);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_menu_menu_->RunContextMenuAt(p);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::OnImageLoaded(
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SkBitmap* image, const ExtensionResource& resource, int index) {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We loaded icons()->size() icons, plus one extra if the page action had
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a default icon.
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int total_icons = static_cast<int>(page_action_->icon_paths()->size());
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!page_action_->default_icon_path().empty())
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    total_icons++;
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(index < total_icons);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Map the index of the loaded image back to its name. If we ever get an
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // index greater than the number of icons, it must be the default icon.
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (image) {
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (index < static_cast<int>(page_action_->icon_paths()->size()))
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      page_action_icons_[page_action_->icon_paths()->at(index)] = *image;
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      page_action_icons_[page_action_->default_icon_path()] = *image;
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // During object construction (before the parent has been set) we are already
181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // in a UpdatePageActions call, so we don't need to start another one (and
182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // doing so causes crash described in http://crbug.com/57333).
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (parent())
184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    owner_->UpdatePageActions();
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::UpdateVisibility(TabContents* contents,
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const GURL& url) {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Save this off so we can pass it back to the extension when the action gets
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // executed. See PageActionImageView::OnMousePressed.
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  current_tab_id_ = contents ? ExtensionTabUtil::GetTabId(contents) : -1;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_url_ = url;
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!contents ||
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      (!preview_enabled_ && !page_action_->GetIsVisible(current_tab_id_))) {
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SetVisible(false);
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the tooltip.
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tooltip_ = page_action_->GetTitle(current_tab_id_);
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SetTooltipText(UTF8ToWide(tooltip_));
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the image.
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // It can come from three places. In descending order of priority:
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - The developer can set it dynamically by path or bitmap. It will be in
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   page_action_->GetIcon().
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - The developer can set it dynamically by index. It will be in
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   page_action_->GetIconIndex().
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - It can be set in the manifest by path. It will be in
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   page_action_->default_icon_path().
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // First look for a dynamically set bitmap.
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SkBitmap icon = page_action_->GetIcon(current_tab_id_);
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (icon.isNull()) {
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    int icon_index = page_action_->GetIconIndex(current_tab_id_);
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string icon_path = (icon_index < 0) ?
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        page_action_->default_icon_path() :
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        page_action_->icon_paths()->at(icon_index);
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!icon_path.empty()) {
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      PageActionMap::iterator iter = page_action_icons_.find(icon_path);
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (iter != page_action_icons_.end())
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        icon = iter->second;
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!icon.isNull())
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SetImage(&icon);
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SetVisible(true);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::InspectPopup(ExtensionAction* action) {
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExecuteAction(1,  // left-click
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                true);  // inspect_with_devtools
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::ExtensionPopupIsClosing(ExtensionPopup* popup) {
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(popup_, popup);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ExtensionPopup is ref-counted, so we don't need to delete it.
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  popup_ = NULL;
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PageActionImageView::HidePopup() {
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (popup_)
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    popup_->Close();
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
247