Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: chrome/browser/extensions/api/system_info/system_info_api.cc

Issue 389633002: Move system.* family of APIs to extensions/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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_info/system_info_api.h"
6
7 #include <set>
8
9 #include "base/bind.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/singleton.h"
13 #include "base/strings/string_util.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/extensions/api/system_display/display_info_provider.h"
17 #include "chrome/browser/extensions/api/system_storage/storage_info_provider.h"
18 #include "chrome/browser/extensions/event_router_forwarder.h"
19 #include "chrome/common/extensions/api/system_display.h"
20 #include "chrome/common/extensions/api/system_storage.h"
21 #include "components/storage_monitor/removable_storage_observer.h"
22 #include "components/storage_monitor/storage_info.h"
23 #include "components/storage_monitor/storage_monitor.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "ui/gfx/display_observer.h"
26 #include "ui/gfx/screen.h"
27
28 namespace extensions {
29
30 using api::system_storage::StorageUnitInfo;
31 using content::BrowserThread;
32 using storage_monitor::StorageMonitor;
33
34 namespace system_display = api::system_display;
35 namespace system_storage = api::system_storage;
36
37 namespace {
38
39 bool IsDisplayChangedEvent(const std::string& event_name) {
40 return event_name == system_display::OnDisplayChanged::kEventName;
41 }
42
43 bool IsSystemStorageEvent(const std::string& event_name) {
44 return (event_name == system_storage::OnAttached::kEventName ||
45 event_name == system_storage::OnDetached::kEventName);
46 }
47
48 // Event router for systemInfo API. It is a singleton instance shared by
49 // multiple profiles.
50 class SystemInfoEventRouter : public gfx::DisplayObserver,
51 public storage_monitor::RemovableStorageObserver {
52 public:
53 static SystemInfoEventRouter* GetInstance();
54
55 SystemInfoEventRouter();
56 virtual ~SystemInfoEventRouter();
57
58 // Add/remove event listener for the |event_name| event.
59 void AddEventListener(const std::string& event_name);
60 void RemoveEventListener(const std::string& event_name);
61
62 private:
63 // gfx::DisplayObserver:
64 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE;
65 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE;
66 virtual void OnDisplayMetricsChanged(const gfx::Display& display,
67 uint32_t metrics) OVERRIDE;
68
69 // RemovableStorageObserver implementation.
70 virtual void OnRemovableStorageAttached(
71 const storage_monitor::StorageInfo& info) OVERRIDE;
72 virtual void OnRemovableStorageDetached(
73 const storage_monitor::StorageInfo& info) OVERRIDE;
74
75 // Called from any thread to dispatch the systemInfo event to all extension
76 // processes cross multiple profiles.
77 void DispatchEvent(const std::string& event_name,
78 scoped_ptr<base::ListValue> args);
79
80 // Called to dispatch the systemInfo.display.onDisplayChanged event.
81 void OnDisplayChanged();
82
83 // Used to record the event names being watched.
84 std::multiset<std::string> watching_event_set_;
85
86 bool has_storage_monitor_observer_;
87
88 DISALLOW_COPY_AND_ASSIGN(SystemInfoEventRouter);
89 };
90
91 static base::LazyInstance<SystemInfoEventRouter>::Leaky
92 g_system_info_event_router = LAZY_INSTANCE_INITIALIZER;
93
94 // static
95 SystemInfoEventRouter* SystemInfoEventRouter::GetInstance() {
96 return g_system_info_event_router.Pointer();
97 }
98
99 SystemInfoEventRouter::SystemInfoEventRouter()
100 : has_storage_monitor_observer_(false) {
101 }
102
103 SystemInfoEventRouter::~SystemInfoEventRouter() {
104 if (has_storage_monitor_observer_) {
105 StorageMonitor* storage_monitor = StorageMonitor::GetInstance();
106 if (storage_monitor)
107 storage_monitor->RemoveObserver(this);
108 }
109 }
110
111 void SystemInfoEventRouter::AddEventListener(const std::string& event_name) {
112 DCHECK_CURRENTLY_ON(BrowserThread::UI);
113
114 watching_event_set_.insert(event_name);
115 if (watching_event_set_.count(event_name) > 1)
116 return;
117
118 if (IsDisplayChangedEvent(event_name)) {
119 gfx::Screen* screen = DisplayInfoProvider::Get()->GetActiveScreen();
120 if (screen)
121 screen->AddObserver(this);
122 }
123
124 if (IsSystemStorageEvent(event_name)) {
125 if (!has_storage_monitor_observer_) {
126 has_storage_monitor_observer_ = true;
127 DCHECK(StorageMonitor::GetInstance()->IsInitialized());
128 StorageMonitor::GetInstance()->AddObserver(this);
129 }
130 }
131 }
132
133 void SystemInfoEventRouter::RemoveEventListener(const std::string& event_name) {
134 DCHECK_CURRENTLY_ON(BrowserThread::UI);
135
136 std::multiset<std::string>::iterator it =
137 watching_event_set_.find(event_name);
138 if (it != watching_event_set_.end()) {
139 watching_event_set_.erase(it);
140 if (watching_event_set_.count(event_name) > 0)
141 return;
142 }
143
144 if (IsDisplayChangedEvent(event_name)) {
145 gfx::Screen* screen = DisplayInfoProvider::Get()->GetActiveScreen();
146 if (screen)
147 screen->RemoveObserver(this);
148 }
149
150 if (IsSystemStorageEvent(event_name)) {
151 const std::string& other_event_name =
152 (event_name == system_storage::OnDetached::kEventName) ?
153 system_storage::OnAttached::kEventName :
154 system_storage::OnDetached::kEventName;
155 if (watching_event_set_.count(other_event_name) == 0) {
156 StorageMonitor::GetInstance()->RemoveObserver(this);
157 has_storage_monitor_observer_ = false;
158 }
159 }
160 }
161
162 void SystemInfoEventRouter::OnRemovableStorageAttached(
163 const storage_monitor::StorageInfo& info) {
164 StorageUnitInfo unit;
165 systeminfo::BuildStorageUnitInfo(info, &unit);
166 scoped_ptr<base::ListValue> args(new base::ListValue);
167 args->Append(unit.ToValue().release());
168 DispatchEvent(system_storage::OnAttached::kEventName, args.Pass());
169 }
170
171 void SystemInfoEventRouter::OnRemovableStorageDetached(
172 const storage_monitor::StorageInfo& info) {
173 scoped_ptr<base::ListValue> args(new base::ListValue);
174 std::string transient_id =
175 StorageMonitor::GetInstance()->GetTransientIdForDeviceId(
176 info.device_id());
177 args->AppendString(transient_id);
178
179 DispatchEvent(system_storage::OnDetached::kEventName, args.Pass());
180 }
181
182 void SystemInfoEventRouter::OnDisplayAdded(const gfx::Display& new_display) {
183 OnDisplayChanged();
184 }
185
186 void SystemInfoEventRouter::OnDisplayRemoved(const gfx::Display& old_display) {
187 OnDisplayChanged();
188 }
189
190 void SystemInfoEventRouter::OnDisplayMetricsChanged(const gfx::Display& display,
191 uint32_t metrics) {
192 OnDisplayChanged();
193 }
194
195 void SystemInfoEventRouter::OnDisplayChanged() {
196 scoped_ptr<base::ListValue> args(new base::ListValue());
197 DispatchEvent(system_display::OnDisplayChanged::kEventName, args.Pass());
198 }
199
200 void SystemInfoEventRouter::DispatchEvent(const std::string& event_name,
201 scoped_ptr<base::ListValue> args) {
202 g_browser_process->extension_event_router_forwarder()->
203 BroadcastEventToRenderers(event_name, args.Pass(), GURL());
204 }
205
206 void AddEventListener(const std::string& event_name) {
207 SystemInfoEventRouter::GetInstance()->AddEventListener(event_name);
208 }
209
210 void RemoveEventListener(const std::string& event_name) {
211 SystemInfoEventRouter::GetInstance()->RemoveEventListener(event_name);
212 }
213
214 } // namespace
215
216 static base::LazyInstance<BrowserContextKeyedAPIFactory<SystemInfoAPI> >
217 g_factory = LAZY_INSTANCE_INITIALIZER;
218
219 // static
220 BrowserContextKeyedAPIFactory<SystemInfoAPI>*
221 SystemInfoAPI::GetFactoryInstance() {
222 return g_factory.Pointer();
223 }
224
225 SystemInfoAPI::SystemInfoAPI(content::BrowserContext* context)
226 : browser_context_(context) {
227 EventRouter* router = EventRouter::Get(browser_context_);
228 router->RegisterObserver(this, system_storage::OnAttached::kEventName);
229 router->RegisterObserver(this, system_storage::OnDetached::kEventName);
230 router->RegisterObserver(this, system_display::OnDisplayChanged::kEventName);
231 }
232
233 SystemInfoAPI::~SystemInfoAPI() {
234 }
235
236 void SystemInfoAPI::Shutdown() {
237 EventRouter::Get(browser_context_)->UnregisterObserver(this);
238 }
239
240 void SystemInfoAPI::OnListenerAdded(const EventListenerInfo& details) {
241 if (IsSystemStorageEvent(details.event_name)) {
242 StorageMonitor::GetInstance()->EnsureInitialized(
243 base::Bind(&AddEventListener, details.event_name));
244 } else {
245 AddEventListener(details.event_name);
246 }
247 }
248
249 void SystemInfoAPI::OnListenerRemoved(const EventListenerInfo& details) {
250 if (IsSystemStorageEvent(details.event_name)) {
251 StorageMonitor::GetInstance()->EnsureInitialized(
252 base::Bind(&RemoveEventListener, details.event_name));
253 } else {
254 RemoveEventListener(details.event_name);
255 }
256 }
257
258 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698