Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / system_indicator / system_indicator_manager.cc
blob07cc8c024b316a4fcb0cc88c05cc72856ccc6075
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h"
7 #include "base/memory/linked_ptr.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/status_icons/status_icon.h"
12 #include "chrome/browser/status_icons/status_icon_observer.h"
13 #include "chrome/browser/status_icons/status_tray.h"
14 #include "chrome/common/extensions/api/system_indicator.h"
15 #include "content/public/browser/web_contents.h"
16 #include "extensions/browser/event_router.h"
17 #include "extensions/browser/extension_registry.h"
18 #include "extensions/common/extension.h"
19 #include "ui/gfx/image/image.h"
21 namespace extensions {
23 namespace system_indicator = api::system_indicator;
25 // Observes clicks on a given status icon and forwards the event to the
26 // appropriate extension. Handles icon updates, and responsible for creating
27 // and removing the icon from the notification area during construction and
28 // destruction.
29 class ExtensionIndicatorIcon : public StatusIconObserver,
30 public ExtensionActionIconFactory::Observer {
31 public:
32 static ExtensionIndicatorIcon* Create(const Extension* extension,
33 ExtensionAction* action,
34 Profile* profile,
35 StatusTray* status_tray);
36 ~ExtensionIndicatorIcon() override;
38 // StatusIconObserver implementation.
39 void OnStatusIconClicked() override;
41 // ExtensionActionIconFactory::Observer implementation.
42 void OnIconUpdated() override;
44 private:
45 ExtensionIndicatorIcon(const Extension* extension,
46 ExtensionAction* action,
47 Profile* profile,
48 StatusTray* status_tray);
50 const extensions::Extension* extension_;
51 StatusTray* status_tray_;
52 StatusIcon* icon_;
53 Profile* profile_;
54 ExtensionActionIconFactory icon_factory_;
57 ExtensionIndicatorIcon* ExtensionIndicatorIcon::Create(
58 const Extension* extension,
59 ExtensionAction* action,
60 Profile* profile,
61 StatusTray* status_tray) {
62 scoped_ptr<ExtensionIndicatorIcon> extension_icon(
63 new ExtensionIndicatorIcon(extension, action, profile, status_tray));
65 // Check if a status icon was successfully created.
66 if (extension_icon->icon_)
67 return extension_icon.release();
69 // We could not create a status icon.
70 return NULL;
73 ExtensionIndicatorIcon::~ExtensionIndicatorIcon() {
74 if (icon_) {
75 icon_->RemoveObserver(this);
76 status_tray_->RemoveStatusIcon(icon_);
80 void ExtensionIndicatorIcon::OnStatusIconClicked() {
81 scoped_ptr<base::ListValue> params(
82 api::system_indicator::OnClicked::Create());
84 EventRouter* event_router = EventRouter::Get(profile_);
85 scoped_ptr<Event> event(new Event(events::SYSTEM_INDICATOR_ON_CLICKED,
86 system_indicator::OnClicked::kEventName,
87 params.Pass(), profile_));
88 event_router->DispatchEventToExtension(
89 extension_->id(), event.Pass());
92 void ExtensionIndicatorIcon::OnIconUpdated() {
93 icon_->SetImage(
94 icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia());
97 ExtensionIndicatorIcon::ExtensionIndicatorIcon(const Extension* extension,
98 ExtensionAction* action,
99 Profile* profile,
100 StatusTray* status_tray)
101 : extension_(extension),
102 status_tray_(status_tray),
103 icon_(NULL),
104 profile_(profile),
105 icon_factory_(profile, extension, action, this) {
106 // Get the icon image and tool tip for the status icon. The extension name is
107 // used as the tool tip.
108 gfx::ImageSkia icon_image =
109 icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia();
110 base::string16 tool_tip = base::UTF8ToUTF16(extension_->name());
112 icon_ = status_tray_->CreateStatusIcon(
113 StatusTray::OTHER_ICON, icon_image, tool_tip);
114 if (icon_)
115 icon_->AddObserver(this);
118 SystemIndicatorManager::SystemIndicatorManager(Profile* profile,
119 StatusTray* status_tray)
120 : profile_(profile),
121 status_tray_(status_tray),
122 extension_action_observer_(this),
123 extension_registry_observer_(this) {
124 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
125 extension_action_observer_.Add(ExtensionActionAPI::Get(profile_));
128 SystemIndicatorManager::~SystemIndicatorManager() {
129 DCHECK(thread_checker_.CalledOnValidThread());
132 void SystemIndicatorManager::Shutdown() {
133 DCHECK(thread_checker_.CalledOnValidThread());
136 void SystemIndicatorManager::OnExtensionUnloaded(
137 content::BrowserContext* browser_context,
138 const Extension* extension,
139 UnloadedExtensionInfo::Reason reason) {
140 RemoveIndicator(extension->id());
143 void SystemIndicatorManager::OnExtensionActionUpdated(
144 ExtensionAction* extension_action,
145 content::WebContents* web_contents,
146 content::BrowserContext* browser_context) {
147 DCHECK(thread_checker_.CalledOnValidThread());
148 if (profile_->GetOriginalProfile() != browser_context ||
149 extension_action->action_type() != ActionInfo::TYPE_SYSTEM_INDICATOR)
150 return;
152 std::string extension_id = extension_action->extension_id();
153 if (extension_action->GetIsVisible(ExtensionAction::kDefaultTabId)) {
154 CreateOrUpdateIndicator(
155 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
156 extension_id),
157 extension_action);
158 } else {
159 RemoveIndicator(extension_id);
163 bool SystemIndicatorManager::SendClickEventToExtensionForTest(
164 const std::string extension_id) {
166 extensions::SystemIndicatorManager::SystemIndicatorMap::iterator it =
167 system_indicators_.find(extension_id);
169 if (it == system_indicators_.end())
170 return false;
172 it->second->OnStatusIconClicked();
173 return true;
176 void SystemIndicatorManager::CreateOrUpdateIndicator(
177 const Extension* extension,
178 ExtensionAction* extension_action) {
179 DCHECK(thread_checker_.CalledOnValidThread());
180 SystemIndicatorMap::iterator it = system_indicators_.find(extension->id());
181 if (it != system_indicators_.end()) {
182 it->second->OnIconUpdated();
183 return;
186 ExtensionIndicatorIcon* extension_icon = ExtensionIndicatorIcon::Create(
187 extension, extension_action, profile_, status_tray_);
188 if (extension_icon)
189 system_indicators_[extension->id()] = make_linked_ptr(extension_icon);
192 void SystemIndicatorManager::RemoveIndicator(const std::string& extension_id) {
193 DCHECK(thread_checker_.CalledOnValidThread());
194 system_indicators_.erase(extension_id);
197 } // namespace extensions