Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/system_info/system_info_api.h" | 5 #include "chrome/browser/extensions/api/system_info/system_info_api.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/extensions/api/system_info_storage/storage_info_provide r.h" | 17 #include "chrome/browser/extensions/api/system_info_storage/storage_info_provide r.h" |
| 18 #include "chrome/browser/extensions/event_names.h" | 18 #include "chrome/browser/extensions/event_names.h" |
| 19 #include "chrome/browser/extensions/event_router_forwarder.h" | 19 #include "chrome/browser/extensions/event_router_forwarder.h" |
| 20 #include "chrome/browser/storage_monitor/removable_storage_observer.h" | |
| 21 #include "chrome/browser/storage_monitor/storage_info.h" | |
| 22 #include "chrome/browser/storage_monitor/storage_monitor.h" | |
| 20 #include "chrome/common/extensions/api/experimental_system_info_storage.h" | 23 #include "chrome/common/extensions/api/experimental_system_info_storage.h" |
| 21 #include "ui/gfx/display_observer.h" | 24 #include "ui/gfx/display_observer.h" |
| 22 | 25 |
| 23 #if defined(USE_ASH) | 26 #if defined(USE_ASH) |
| 24 #include "ash/screen_ash.h" | 27 #include "ash/screen_ash.h" |
| 25 #include "ash/shell.h" | 28 #include "ash/shell.h" |
| 26 #endif | 29 #endif |
| 27 | 30 |
| 28 namespace extensions { | 31 namespace extensions { |
| 29 | 32 |
| 33 using api::experimental_system_info_storage::StorageCapacityChangeInfo; | |
| 30 using api::experimental_system_info_storage::StorageUnitInfo; | 34 using api::experimental_system_info_storage::StorageUnitInfo; |
| 31 using api::experimental_system_info_storage::StorageUnitType; | 35 using api::experimental_system_info_storage::StorageUnitType; |
| 32 using api::experimental_system_info_storage::StorageChangeInfo; | |
| 33 using content::BrowserThread; | 36 using content::BrowserThread; |
| 34 | 37 |
| 35 namespace { | 38 namespace { |
| 36 | 39 |
| 37 // The display events use the "systemInfo" prefix. | 40 // The display events use the "systemInfo" prefix. |
| 38 const char kSystemInfoEventPrefix[] = "systemInfo"; | 41 const char kSystemInfoEventPrefix[] = "systemInfo"; |
| 39 // The storage events still use the "experimental.systemInfo" prefix. | 42 // The storage events still use the "experimental.systemInfo" prefix. |
| 40 const char kExperimentalSystemInfoEventPrefix[] = "experimental.systemInfo"; | 43 const char kExperimentalSystemInfoEventPrefix[] = "experimental.systemInfo"; |
| 41 | 44 |
| 42 bool IsDisplayChangedEvent(const std::string& event_name) { | 45 bool IsDisplayChangedEvent(const std::string& event_name) { |
| 43 return event_name == event_names::kOnDisplayChanged; | 46 return event_name == event_names::kOnDisplayChanged; |
| 44 } | 47 } |
| 45 | 48 |
| 46 bool IsAvailableCapacityChangedEvent(const std::string& event_name) { | 49 bool IsAvailableCapacityChangedEvent(const std::string& event_name) { |
| 47 return event_name == event_names::kOnStorageAvailableCapacityChanged; | 50 return event_name == event_names::kOnStorageAvailableCapacityChanged; |
| 48 } | 51 } |
| 49 | 52 |
| 50 // Event router for systemInfo API. It is a singleton instance shared by | 53 // Event router for systemInfo API. It is a singleton instance shared by |
| 51 // multiple profiles. | 54 // multiple profiles. |
| 52 class SystemInfoEventRouter | 55 class SystemInfoEventRouter : public gfx::DisplayObserver, |
| 53 : public gfx::DisplayObserver, public StorageInfoObserver { | 56 public StorageFreeSpaceObserver, |
| 57 public chrome::RemovableStorageObserver { | |
| 54 public: | 58 public: |
| 55 static SystemInfoEventRouter* GetInstance(); | 59 static SystemInfoEventRouter* GetInstance(); |
| 56 | 60 |
| 57 SystemInfoEventRouter(); | 61 SystemInfoEventRouter(); |
| 58 virtual ~SystemInfoEventRouter(); | 62 virtual ~SystemInfoEventRouter(); |
| 59 | 63 |
| 60 // Add/remove event listener for the |event_name| event. | 64 // Add/remove event listener for the |event_name| event. |
| 61 void AddEventListener(const std::string& event_name); | 65 void AddEventListener(const std::string& event_name); |
| 62 void RemoveEventListener(const std::string& event_name); | 66 void RemoveEventListener(const std::string& event_name); |
| 63 | 67 |
| 64 // Return true if the |event_name| is an event from systemInfo namespace. | 68 // Return true if the |event_name| is an event from systemInfo namespace. |
| 65 static bool IsSystemInfoEvent(const std::string& event_name); | 69 static bool IsSystemInfoEvent(const std::string& event_name); |
| 66 | 70 |
| 67 private: | 71 private: |
| 68 // StorageInfoObserver: | 72 // StorageFreeSpaceObserver: |
| 69 virtual void OnStorageFreeSpaceChanged(const std::string& id, | 73 virtual void OnFreeSpaceChanged(const std::string& id, |
| 70 double new_value, | 74 double new_value, |
| 71 double old_value) OVERRIDE; | 75 double old_value) OVERRIDE; |
| 72 virtual void OnStorageAttached( | |
| 73 const std::string& id, | |
| 74 api::experimental_system_info_storage::StorageUnitType type, | |
| 75 double capacity, | |
| 76 double available_capacity) OVERRIDE; | |
| 77 virtual void OnStorageDetached(const std::string& id) OVERRIDE; | |
| 78 | 76 |
| 79 // gfx::DisplayObserver: | 77 // gfx::DisplayObserver: |
| 80 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; | 78 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; |
| 81 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; | 79 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; |
| 82 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; | 80 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; |
| 83 | 81 |
| 82 // chrome::RemovableStorageObserver implementation. | |
| 83 virtual void OnRemovableStorageAttached( | |
| 84 const chrome::StorageInfo& info) OVERRIDE; | |
| 85 virtual void OnRemovableStorageDetached( | |
| 86 const chrome::StorageInfo& info) OVERRIDE; | |
| 87 | |
| 88 void DispatchStorageAttachedEvent(const chrome::StorageInfo& info, | |
| 89 int64 avail_bytes); | |
| 90 | |
| 84 // Called from any thread to dispatch the systemInfo event to all extension | 91 // Called from any thread to dispatch the systemInfo event to all extension |
| 85 // processes cross multiple profiles. | 92 // processes cross multiple profiles. |
| 86 void DispatchEvent(const std::string& event_name, | 93 void DispatchEvent(const std::string& event_name, |
| 87 scoped_ptr<base::ListValue> args); | 94 scoped_ptr<base::ListValue> args); |
| 88 | 95 |
| 89 // The callbacks of querying storage info to start and stop watching the | 96 // The callbacks of querying storage info to start and stop watching the |
| 90 // storages. Called from UI thread. | 97 // storages. Called from UI thread. |
| 91 void StartWatchingStorages(const StorageInfo& info, bool success); | 98 void StartWatchingStorages(const StorageInfo& info, bool success); |
| 92 void StopWatchingStorages(const StorageInfo& info, bool success); | 99 void StopWatchingStorages(const StorageInfo& info, bool success); |
| 93 | 100 |
| 94 // Called to dispatch the systemInfo.display.onDisplayChanged event. | 101 // Called to dispatch the systemInfo.display.onDisplayChanged event. |
| 95 void OnDisplayChanged(); | 102 void OnDisplayChanged(); |
| 96 | 103 |
| 97 // Used to record the event names being watched. | 104 // Used to record the event names being watched. |
| 98 std::multiset<std::string> watching_event_set_; | 105 std::multiset<std::string> watching_event_set_; |
| 99 | 106 |
| 100 DISALLOW_COPY_AND_ASSIGN(SystemInfoEventRouter); | 107 DISALLOW_COPY_AND_ASSIGN(SystemInfoEventRouter); |
| 101 }; | 108 }; |
| 102 | 109 |
| 103 static base::LazyInstance<SystemInfoEventRouter>::Leaky | 110 static base::LazyInstance<SystemInfoEventRouter>::Leaky |
| 104 g_system_info_event_router = LAZY_INSTANCE_INITIALIZER; | 111 g_system_info_event_router = LAZY_INSTANCE_INITIALIZER; |
| 105 | 112 |
| 106 // static | 113 // static |
| 107 SystemInfoEventRouter* SystemInfoEventRouter::GetInstance() { | 114 SystemInfoEventRouter* SystemInfoEventRouter::GetInstance() { |
| 108 return g_system_info_event_router.Pointer(); | 115 return g_system_info_event_router.Pointer(); |
| 109 } | 116 } |
| 110 | 117 |
| 111 SystemInfoEventRouter::SystemInfoEventRouter() { | 118 SystemInfoEventRouter::SystemInfoEventRouter() { |
| 112 StorageInfoProvider::Get()->AddObserver(this); | 119 StorageInfoProvider::Get()->AddObserver(this); |
| 120 chrome::StorageMonitor::GetInstance()->AddObserver(this); | |
| 113 } | 121 } |
| 114 | 122 |
| 115 SystemInfoEventRouter::~SystemInfoEventRouter() { | 123 SystemInfoEventRouter::~SystemInfoEventRouter() { |
| 116 StorageInfoProvider::Get()->RemoveObserver(this); | 124 StorageInfoProvider::Get()->RemoveObserver(this); |
| 125 if (chrome::StorageMonitor::GetInstance()) | |
|
Jeffrey Yasskin
2013/07/02 23:00:50
You can avoid calling GetInstance twice by writing
Haojian Wu
2013/07/03 16:23:49
Done.
| |
| 126 chrome::StorageMonitor::GetInstance()->RemoveObserver(this); | |
| 117 } | 127 } |
| 118 | 128 |
| 119 void SystemInfoEventRouter::StartWatchingStorages( | 129 void SystemInfoEventRouter::StartWatchingStorages( |
| 120 const StorageInfo& info, bool success) { | 130 const StorageInfo& info, bool success) { |
| 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 122 if (!success) | 132 if (!success) |
| 123 return; | 133 return; |
| 124 | 134 |
| 125 for (StorageInfo::const_iterator it = info.begin(); it != info.end(); ++it) { | 135 for (StorageInfo::const_iterator it = info.begin(); it != info.end(); ++it) { |
| 126 StorageInfoProvider::Get()->StartWatching((*it)->id); | 136 StorageInfoProvider::Get()->StartWatching((*it)->id); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 | 201 |
| 192 // static | 202 // static |
| 193 bool SystemInfoEventRouter::IsSystemInfoEvent(const std::string& event_name) { | 203 bool SystemInfoEventRouter::IsSystemInfoEvent(const std::string& event_name) { |
| 194 // TODO(hshi): simplify this once all systemInfo APIs are out of experimental. | 204 // TODO(hshi): simplify this once all systemInfo APIs are out of experimental. |
| 195 return (StartsWithASCII(event_name, kSystemInfoEventPrefix, true) || | 205 return (StartsWithASCII(event_name, kSystemInfoEventPrefix, true) || |
| 196 StartsWithASCII(event_name, kExperimentalSystemInfoEventPrefix, | 206 StartsWithASCII(event_name, kExperimentalSystemInfoEventPrefix, |
| 197 true)); | 207 true)); |
| 198 } | 208 } |
| 199 | 209 |
| 200 // Called on UI thread since the observer is added from UI thread. | 210 // Called on UI thread since the observer is added from UI thread. |
| 201 void SystemInfoEventRouter::OnStorageFreeSpaceChanged( | 211 void SystemInfoEventRouter::OnFreeSpaceChanged( |
| 202 const std::string& id, double new_value, double old_value) { | 212 const std::string& transient_id, double new_value, double old_value) { |
| 203 StorageChangeInfo info; | 213 StorageCapacityChangeInfo info; |
| 204 info.id = id; | 214 info.id = transient_id; |
| 205 info.available_capacity = static_cast<double>(new_value); | 215 info.available_capacity = static_cast<double>(new_value); |
| 206 | 216 |
| 207 scoped_ptr<base::ListValue> args(new base::ListValue()); | 217 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 208 args->Append(info.ToValue().release()); | 218 args->Append(info.ToValue().release()); |
| 209 | 219 |
| 210 DispatchEvent(event_names::kOnStorageAvailableCapacityChanged, args.Pass()); | 220 DispatchEvent(event_names::kOnStorageAvailableCapacityChanged, args.Pass()); |
| 211 } | 221 } |
| 212 | 222 |
| 213 void SystemInfoEventRouter::OnStorageAttached(const std::string& id, | 223 void SystemInfoEventRouter::OnRemovableStorageAttached( |
| 214 StorageUnitType type, | 224 const chrome::StorageInfo& info) { |
| 215 double capacity, | 225 base::PostTaskAndReplyWithResult( |
| 216 double available_capacity) { | 226 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( |
| 217 StorageUnitInfo info; | 227 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN), |
| 218 info.id = id; | 228 FROM_HERE, |
| 219 info.type = type; | 229 base::Bind(&StorageInfoProvider::GetStorageFreeSpaceFromTransientId, |
| 220 info.capacity = capacity; | 230 StorageInfoProvider::Get(), |
| 221 info.available_capacity = available_capacity; | 231 StorageInfoProvider::Get()->GetTransientIdForDeviceId( |
| 232 info.device_id())), | |
| 233 base::Bind(&SystemInfoEventRouter::DispatchStorageAttachedEvent, | |
| 234 base::Unretained(this), info)); | |
|
Jeffrey Yasskin
2013/07/02 23:00:50
What makes sure that *this is still alive when the
Hongbo Min
2013/07/03 04:59:40
OK. It is because SystemInfoProvider instance is a
Jeffrey Yasskin
2013/07/03 21:44:48
Please comment that.
Haojian Wu
2013/07/04 00:41:17
Done.
| |
| 235 } | |
| 236 | |
| 237 void SystemInfoEventRouter::DispatchStorageAttachedEvent( | |
| 238 const chrome::StorageInfo& info, int64 avail_bytes) { | |
| 239 StorageUnitInfo unit; | |
| 240 systeminfo::BuildStorageUnitInfo(info, &unit); | |
| 241 | |
| 242 unit.available_capacity = | |
| 243 avail_bytes > 0 ? static_cast<double>(avail_bytes) : 0; | |
| 222 | 244 |
| 223 scoped_ptr<base::ListValue> args(new base::ListValue); | 245 scoped_ptr<base::ListValue> args(new base::ListValue); |
| 224 args->Append(info.ToValue().release()); | 246 args->Append(unit.ToValue().release()); |
| 225 | |
| 226 DispatchEvent(event_names::kOnStorageAttached, args.Pass()); | 247 DispatchEvent(event_names::kOnStorageAttached, args.Pass()); |
| 227 } | 248 } |
| 228 | 249 |
| 229 void SystemInfoEventRouter::OnStorageDetached(const std::string& id) { | 250 void SystemInfoEventRouter::OnRemovableStorageDetached( |
| 251 const chrome::StorageInfo& info) { | |
| 230 scoped_ptr<base::ListValue> args(new base::ListValue); | 252 scoped_ptr<base::ListValue> args(new base::ListValue); |
| 231 args->Append(new base::StringValue(id)); | 253 args->Append(new base::StringValue(StorageInfoProvider::Get()-> |
| 254 GetTransientIdForDeviceId(info.device_id()))); | |
| 232 | 255 |
| 233 DispatchEvent(event_names::kOnStorageDetached, args.Pass()); | 256 DispatchEvent(event_names::kOnStorageDetached, args.Pass()); |
| 234 } | 257 } |
| 235 | 258 |
| 236 void SystemInfoEventRouter::OnDisplayBoundsChanged( | 259 void SystemInfoEventRouter::OnDisplayBoundsChanged( |
| 237 const gfx::Display& display) { | 260 const gfx::Display& display) { |
| 238 OnDisplayChanged(); | 261 OnDisplayChanged(); |
| 239 } | 262 } |
| 240 | 263 |
| 241 void SystemInfoEventRouter::OnDisplayAdded(const gfx::Display& new_display) { | 264 void SystemInfoEventRouter::OnDisplayAdded(const gfx::Display& new_display) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 | 308 |
| 286 void SystemInfoAPI::OnListenerAdded(const EventListenerInfo& details) { | 309 void SystemInfoAPI::OnListenerAdded(const EventListenerInfo& details) { |
| 287 SystemInfoEventRouter::GetInstance()->AddEventListener(details.event_name); | 310 SystemInfoEventRouter::GetInstance()->AddEventListener(details.event_name); |
| 288 } | 311 } |
| 289 | 312 |
| 290 void SystemInfoAPI::OnListenerRemoved(const EventListenerInfo& details) { | 313 void SystemInfoAPI::OnListenerRemoved(const EventListenerInfo& details) { |
| 291 SystemInfoEventRouter::GetInstance()->RemoveEventListener(details.event_name); | 314 SystemInfoEventRouter::GetInstance()->RemoveEventListener(details.event_name); |
| 292 } | 315 } |
| 293 | 316 |
| 294 } // namespace extensions | 317 } // namespace extensions |
| OLD | NEW |