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

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

Powered by Google App Engine
This is Rietveld 408576698