Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / system_indicator / system_indicator_manager.cc
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/extensions/api/system_indicator/system_indicator_manager.h"
6
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"
20
21 namespace extensions {
22
23 namespace system_indicator = api::system_indicator;
24
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                                         const ExtensionAction* action,
34                                         Profile* profile,
35                                         StatusTray* status_tray);
36   ~ExtensionIndicatorIcon() override;
37
38   // StatusIconObserver implementation.
39   void OnStatusIconClicked() override;
40
41   // ExtensionActionIconFactory::Observer implementation.
42   void OnIconUpdated() override;
43
44  private:
45   ExtensionIndicatorIcon(const Extension* extension,
46                          const ExtensionAction* action,
47                          Profile* profile,
48                          StatusTray* status_tray);
49
50   const extensions::Extension* extension_;
51   StatusTray* status_tray_;
52   StatusIcon* icon_;
53   Profile* profile_;
54   ExtensionActionIconFactory icon_factory_;
55 };
56
57 ExtensionIndicatorIcon* ExtensionIndicatorIcon::Create(
58     const Extension* extension,
59     const ExtensionAction* action,
60     Profile* profile,
61     StatusTray* status_tray) {
62   scoped_ptr<ExtensionIndicatorIcon> extension_icon(
63       new ExtensionIndicatorIcon(extension, action, profile, status_tray));
64
65   // Check if a status icon was successfully created.
66   if (extension_icon->icon_)
67     return extension_icon.release();
68
69   // We could not create a status icon.
70   return NULL;
71 }
72
73 ExtensionIndicatorIcon::~ExtensionIndicatorIcon() {
74   if (icon_) {
75     icon_->RemoveObserver(this);
76     status_tray_->RemoveStatusIcon(icon_);
77   }
78 }
79
80 void ExtensionIndicatorIcon::OnStatusIconClicked() {
81   scoped_ptr<base::ListValue> params(
82       api::system_indicator::OnClicked::Create());
83
84   EventRouter* event_router = EventRouter::Get(profile_);
85   scoped_ptr<Event> event(new Event(
86       system_indicator::OnClicked::kEventName,
87       params.Pass(),
88       profile_));
89   event_router->DispatchEventToExtension(
90       extension_->id(), event.Pass());
91 }
92
93 void ExtensionIndicatorIcon::OnIconUpdated() {
94   icon_->SetImage(
95       icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia());
96 }
97
98 ExtensionIndicatorIcon::ExtensionIndicatorIcon(const Extension* extension,
99                                                const ExtensionAction* action,
100                                                Profile* profile,
101                                                StatusTray* status_tray)
102     : extension_(extension),
103       status_tray_(status_tray),
104       icon_(NULL),
105       profile_(profile),
106       icon_factory_(profile, extension, action, this) {
107   // Get the icon image and tool tip for the status icon. The extension name is
108   // used as the tool tip.
109   gfx::ImageSkia icon_image =
110       icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia();
111   base::string16 tool_tip = base::UTF8ToUTF16(extension_->name());
112
113   icon_ = status_tray_->CreateStatusIcon(
114       StatusTray::OTHER_ICON, icon_image, tool_tip);
115   if (icon_)
116     icon_->AddObserver(this);
117 }
118
119 SystemIndicatorManager::SystemIndicatorManager(Profile* profile,
120                                                StatusTray* status_tray)
121     : profile_(profile),
122       status_tray_(status_tray),
123       extension_action_observer_(this),
124       extension_registry_observer_(this) {
125   extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
126   extension_action_observer_.Add(ExtensionActionAPI::Get(profile_));
127 }
128
129 SystemIndicatorManager::~SystemIndicatorManager() {
130   DCHECK(thread_checker_.CalledOnValidThread());
131 }
132
133 void SystemIndicatorManager::Shutdown() {
134   DCHECK(thread_checker_.CalledOnValidThread());
135 }
136
137 void SystemIndicatorManager::OnExtensionUnloaded(
138     content::BrowserContext* browser_context,
139     const Extension* extension,
140     UnloadedExtensionInfo::Reason reason) {
141   RemoveIndicator(extension->id());
142 }
143
144 void SystemIndicatorManager::OnExtensionActionUpdated(
145     ExtensionAction* extension_action,
146     content::WebContents* web_contents,
147     content::BrowserContext* browser_context) {
148   DCHECK(thread_checker_.CalledOnValidThread());
149   if (profile_->GetOriginalProfile() != browser_context ||
150       extension_action->action_type() != ActionInfo::TYPE_SYSTEM_INDICATOR)
151     return;
152
153   std::string extension_id = extension_action->extension_id();
154   if (extension_action->GetIsVisible(ExtensionAction::kDefaultTabId)) {
155     CreateOrUpdateIndicator(
156         ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
157             extension_id),
158         extension_action);
159   } else {
160     RemoveIndicator(extension_id);
161   }
162 }
163
164 bool SystemIndicatorManager::SendClickEventToExtensionForTest(
165     const std::string extension_id) {
166
167     extensions::SystemIndicatorManager::SystemIndicatorMap::iterator it =
168         system_indicators_.find(extension_id);
169
170     if (it == system_indicators_.end())
171       return false;
172
173     it->second->OnStatusIconClicked();
174     return true;
175 }
176
177 void SystemIndicatorManager::CreateOrUpdateIndicator(
178     const Extension* extension,
179     const ExtensionAction* extension_action) {
180   DCHECK(thread_checker_.CalledOnValidThread());
181   SystemIndicatorMap::iterator it = system_indicators_.find(extension->id());
182   if (it != system_indicators_.end()) {
183     it->second->OnIconUpdated();
184     return;
185   }
186
187   ExtensionIndicatorIcon* extension_icon = ExtensionIndicatorIcon::Create(
188       extension, extension_action, profile_, status_tray_);
189   if (extension_icon)
190     system_indicators_[extension->id()] = make_linked_ptr(extension_icon);
191 }
192
193 void SystemIndicatorManager::RemoveIndicator(const std::string& extension_id) {
194   DCHECK(thread_checker_.CalledOnValidThread());
195   system_indicators_.erase(extension_id);
196 }
197
198 }  // namespace extensions