diff options
-rw-r--r-- | base/system_monitor/system_monitor.cc | 37 | ||||
-rw-r--r-- | base/system_monitor/system_monitor.h | 23 | ||||
-rw-r--r-- | base/system_monitor/system_monitor_unittest.cc | 47 | ||||
-rw-r--r-- | content/browser/browser_main_loop.cc | 5 | ||||
-rw-r--r-- | content/browser/browser_main_loop.h | 4 | ||||
-rw-r--r-- | content/browser/system_message_window_win.cc | 57 | ||||
-rw-r--r-- | content/browser/system_message_window_win.h | 43 | ||||
-rw-r--r-- | content/common/hi_res_timer_manager_win.cc | 4 | ||||
-rw-r--r-- | content/content_browser.gypi | 2 | ||||
-rw-r--r-- | net/url_request/url_request_job.cc | 4 |
10 files changed, 210 insertions, 16 deletions
diff --git a/base/system_monitor/system_monitor.cc b/base/system_monitor/system_monitor.cc index 5131fbf..28fc70b 100644 --- a/base/system_monitor/system_monitor.cc +++ b/base/system_monitor/system_monitor.cc @@ -19,7 +19,9 @@ static int kDelayedBatteryCheckMs = 10 * 1000; #endif // defined(ENABLE_BATTERY_MONITORING) SystemMonitor::SystemMonitor() - : observer_list_(new ObserverListThreadSafe<PowerObserver>()), + : power_observer_list_(new ObserverListThreadSafe<PowerObserver>()), + devices_changed_observer_list_( + new ObserverListThreadSafe<DevicesChangedObserver>()), battery_in_use_(false), suspended_(false) { DCHECK(!g_system_monitor); @@ -77,28 +79,47 @@ void SystemMonitor::ProcessPowerMessage(PowerEvent event_id) { } } -void SystemMonitor::AddObserver(PowerObserver* obs) { - observer_list_->AddObserver(obs); +void SystemMonitor::ProcessDevicesChanged() { + NotifyDevicesChanged(); } -void SystemMonitor::RemoveObserver(PowerObserver* obs) { - observer_list_->RemoveObserver(obs); +void SystemMonitor::AddPowerObserver(PowerObserver* obs) { + power_observer_list_->AddObserver(obs); +} + +void SystemMonitor::RemovePowerObserver(PowerObserver* obs) { + power_observer_list_->RemoveObserver(obs); +} + +void SystemMonitor::AddDevicesChangedObserver(DevicesChangedObserver* obs) { + devices_changed_observer_list_->AddObserver(obs); +} + +void SystemMonitor::RemoveDevicesChangedObserver(DevicesChangedObserver* obs) { + devices_changed_observer_list_->RemoveObserver(obs); +} + +void SystemMonitor::NotifyDevicesChanged() { + DVLOG(1) << "DevicesChanged"; + devices_changed_observer_list_->Notify( + &DevicesChangedObserver::OnDevicesChanged); } void SystemMonitor::NotifyPowerStateChange() { DVLOG(1) << "PowerStateChange: " << (BatteryPower() ? "On" : "Off") << " battery"; - observer_list_->Notify(&PowerObserver::OnPowerStateChange, BatteryPower()); + power_observer_list_->Notify(&PowerObserver::OnPowerStateChange, + BatteryPower()); } void SystemMonitor::NotifySuspend() { DVLOG(1) << "Power Suspending"; - observer_list_->Notify(&PowerObserver::OnSuspend); + power_observer_list_->Notify(&PowerObserver::OnSuspend); } void SystemMonitor::NotifyResume() { DVLOG(1) << "Power Resuming"; - observer_list_->Notify(&PowerObserver::OnResume); + power_observer_list_->Notify(&PowerObserver::OnResume); } void SystemMonitor::BatteryCheck() { diff --git a/base/system_monitor/system_monitor.h b/base/system_monitor/system_monitor.h index c779994..7684523 100644 --- a/base/system_monitor/system_monitor.h +++ b/base/system_monitor/system_monitor.h @@ -90,15 +90,26 @@ class BASE_EXPORT SystemMonitor { virtual ~PowerObserver() {} }; + class BASE_EXPORT DevicesChangedObserver { + public: + // Notification that the devices connected to the system have changed. + virtual void OnDevicesChanged() {} + + protected: + virtual ~DevicesChangedObserver() {} + }; + // Add a new observer. // Can be called from any thread. // Must not be called from within a notification callback. - void AddObserver(PowerObserver* obs); + void AddPowerObserver(PowerObserver* obs); + void AddDevicesChangedObserver(DevicesChangedObserver* obs); // Remove an existing observer. // Can be called from any thread. // Must not be called from within a notification callback. - void RemoveObserver(PowerObserver* obs); + void RemovePowerObserver(PowerObserver* obs); + void RemoveDevicesChangedObserver(DevicesChangedObserver* obs); #if defined(OS_WIN) // Windows-specific handling of a WM_POWERBROADCAST message. @@ -110,6 +121,9 @@ class BASE_EXPORT SystemMonitor { // Cross-platform handling of a power event. void ProcessPowerMessage(PowerEvent event_id); + // Cross-platform handling of a device change event. + void ProcessDevicesChanged(); + private: #if defined(OS_MACOSX) void PlatformInit(); @@ -126,11 +140,14 @@ class BASE_EXPORT SystemMonitor { void BatteryCheck(); // Functions to trigger notifications. + void NotifyDevicesChanged(); void NotifyPowerStateChange(); void NotifySuspend(); void NotifyResume(); - scoped_refptr<ObserverListThreadSafe<PowerObserver> > observer_list_; + scoped_refptr<ObserverListThreadSafe<PowerObserver> > power_observer_list_; + scoped_refptr<ObserverListThreadSafe<DevicesChangedObserver> > + devices_changed_observer_list_; bool battery_in_use_; bool suspended_; diff --git a/base/system_monitor/system_monitor_unittest.cc b/base/system_monitor/system_monitor_unittest.cc index f4a4e73..1d5d6af 100644 --- a/base/system_monitor/system_monitor_unittest.cc +++ b/base/system_monitor/system_monitor_unittest.cc @@ -55,7 +55,7 @@ TEST(SystemMonitor, PowerNotifications) { SystemMonitor system_monitor; PowerTest test[kObservers]; for (int index = 0; index < kObservers; ++index) - system_monitor.AddObserver(&test[index]); + system_monitor.AddPowerObserver(&test[index]); // Send a bunch of power changes. Since the battery power hasn't // actually changed, we shouldn't get notifications. @@ -90,4 +90,49 @@ TEST(SystemMonitor, PowerNotifications) { EXPECT_EQ(test[0].resumes(), 1); } +class DevicesChangedTest : public SystemMonitor::DevicesChangedObserver { + public: + DevicesChangedTest() + : changes_(0) { + } + + // DevicesChangedObserver callbacks. + virtual void OnDevicesChanged() OVERRIDE { + changes_++; + } + + // Test status counts. + int changes() const { return changes_; } + + private: + int changes_; // Count of OnDevicesChanged notifications. + + DISALLOW_COPY_AND_ASSIGN(DevicesChangedTest); +}; + +TEST(SystemMonitor, DeviceChangeNotifications) { + const int kObservers = 5; + + // Initialize a message loop for this to run on. + MessageLoop loop; + +#if defined(OS_MACOSX) + SystemMonitor::AllocateSystemIOPorts(); +#endif + + SystemMonitor system_monitor; + DevicesChangedTest test[kObservers]; + for (int index = 0; index < kObservers; ++index) + system_monitor.AddDevicesChangedObserver(&test[index]); + + system_monitor.ProcessDevicesChanged(); + loop.RunAllPending(); + EXPECT_EQ(1, test[0].changes()); + + system_monitor.ProcessDevicesChanged(); + system_monitor.ProcessDevicesChanged(); + loop.RunAllPending(); + EXPECT_EQ(3, test[0].changes()); +} + } // namespace base diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index d722637..2059d2a 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -32,6 +32,7 @@ #include <ole2.h> #include <shellapi.h> +#include "content/browser/system_message_window_win.h" #include "ui/base/l10n/l10n_util_win.h" #include "net/base/winsock_init.h" #endif @@ -255,6 +256,10 @@ void BrowserMainLoop::MainMessageLoopStart() { network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); +#if defined(OS_WIN) + system_message_window_.reset(new SystemMessageWindowWin); +#endif + for (size_t i = 0; i < parts_list_.size(); ++i) parts_list_[i]->PostMainMessageLoopStart(); } diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 8642e4f..0abe7e1 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -14,6 +14,7 @@ class CommandLine; class HighResolutionTimerManager; class MessageLoop; +class SystemMessageWindowWin; namespace base { class SystemMonitor; @@ -64,6 +65,9 @@ class BrowserMainLoop { scoped_ptr<base::SystemMonitor> system_monitor_; scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_; scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; +#if defined(OS_WIN) + scoped_ptr<SystemMessageWindowWin> system_message_window_; +#endif scoped_ptr<BrowserThreadImpl> main_thread_; DISALLOW_COPY_AND_ASSIGN(BrowserMainLoop); diff --git a/content/browser/system_message_window_win.cc b/content/browser/system_message_window_win.cc new file mode 100644 index 0000000..c5a7633 --- /dev/null +++ b/content/browser/system_message_window_win.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/system_message_window_win.h" + +#include <windows.h> +#include <dbt.h> + +#include "base/system_monitor/system_monitor.h" +#include "base/win/wrapped_window_proc.h" + +static const wchar_t* const WindowClassName = L"Chrome_SystemMessageWindow"; + +SystemMessageWindowWin::SystemMessageWindowWin() { + HINSTANCE hinst = GetModuleHandle(NULL); + + WNDCLASSEX wc = {0}; + wc.cbSize = sizeof(wc); + wc.lpfnWndProc = + base::win::WrappedWindowProc<&SystemMessageWindowWin::WndProcThunk>; + wc.hInstance = hinst; + wc.lpszClassName = WindowClassName; + ATOM clazz = RegisterClassEx(&wc); + DCHECK(clazz); + + window_ = CreateWindow(WindowClassName, + 0, 0, 0, 0, 0, 0, 0, 0, hinst, 0); + SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); +} + +SystemMessageWindowWin::~SystemMessageWindowWin() { + if (window_) { + DestroyWindow(window_); + UnregisterClass(WindowClassName, GetModuleHandle(NULL)); + } +} + +LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, DWORD data) { + base::SystemMonitor* monitor = base::SystemMonitor::Get(); + if (monitor && event_type == DBT_DEVNODES_CHANGED) + monitor->ProcessDevicesChanged(); + return TRUE; +} + +LRESULT CALLBACK SystemMessageWindowWin::WndProc(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) { + switch (message) { + case WM_DEVICECHANGE: + return OnDeviceChange(static_cast<UINT>(wparam), + static_cast<DWORD>(lparam)); + default: + break; + } + + return ::DefWindowProc(hwnd, message, wparam, lparam); +} diff --git a/content/browser/system_message_window_win.h b/content/browser/system_message_window_win.h new file mode 100644 index 0000000..184aaa3 --- /dev/null +++ b/content/browser/system_message_window_win.h @@ -0,0 +1,43 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SYSTEM_MESSAGE_WINDOW_WIN_H_ +#define CONTENT_BROWSER_SYSTEM_MESSAGE_WINDOW_WIN_H_ +#pragma once + +#include "build/build_config.h" + +#include <windows.h> + +#include "base/basictypes.h" +#include "content/common/content_export.h" + +class CONTENT_EXPORT SystemMessageWindowWin { + public: + SystemMessageWindowWin(); + virtual ~SystemMessageWindowWin(); + + virtual LRESULT OnDeviceChange(UINT event_type, DWORD data); + + private: + LRESULT CALLBACK WndProc(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam); + + static LRESULT CALLBACK WndProcThunk(HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) { + SystemMessageWindowWin* msg_wnd = reinterpret_cast<SystemMessageWindowWin*>( + GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (msg_wnd) + return msg_wnd->WndProc(hwnd, message, wparam, lparam); + return ::DefWindowProc(hwnd, message, wparam, lparam); + } + + HWND window_; + + DISALLOW_COPY_AND_ASSIGN(SystemMessageWindowWin); +}; + +#endif // CONTENT_BROWSER_SYSTEM_MESSAGE_WINDOW_WIN_H_ diff --git a/content/common/hi_res_timer_manager_win.cc b/content/common/hi_res_timer_manager_win.cc index 45f22ba..62664b5 100644 --- a/content/common/hi_res_timer_manager_win.cc +++ b/content/common/hi_res_timer_manager_win.cc @@ -9,12 +9,12 @@ HighResolutionTimerManager::HighResolutionTimerManager() : hi_res_clock_available_(false) { base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); - system_monitor->AddObserver(this); + system_monitor->AddPowerObserver(this); UseHiResClock(!system_monitor->BatteryPower()); } HighResolutionTimerManager::~HighResolutionTimerManager() { - base::SystemMonitor::Get()->RemoveObserver(this); + base::SystemMonitor::Get()->RemovePowerObserver(this); UseHiResClock(false); } diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 11c1121..4a4a97e 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -511,6 +511,8 @@ 'browser/ssl/ssl_policy_backend.h', 'browser/ssl/ssl_request_info.cc', 'browser/ssl/ssl_request_info.h', + 'browser/system_message_window_win.cc', + 'browser/system_message_window_win.h', 'browser/tab_contents/drag_utils_gtk.cc', 'browser/tab_contents/drag_utils_gtk.h', 'browser/tab_contents/interstitial_page.cc', diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index a9e9627..ff6299a 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc @@ -34,7 +34,7 @@ URLRequestJob::URLRequestJob(URLRequest* request) ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); if (system_monitor) - base::SystemMonitor::Get()->AddObserver(this); + base::SystemMonitor::Get()->AddPowerObserver(this); } void URLRequestJob::SetUpload(UploadData* upload) { @@ -219,7 +219,7 @@ void URLRequestJob::NotifyURLRequestDestroyed() { URLRequestJob::~URLRequestJob() { base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); if (system_monitor) - base::SystemMonitor::Get()->RemoveObserver(this); + base::SystemMonitor::Get()->RemovePowerObserver(this); } void URLRequestJob::NotifyCertificateRequested( |