summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/system_monitor/system_monitor.cc37
-rw-r--r--base/system_monitor/system_monitor.h23
-rw-r--r--base/system_monitor/system_monitor_unittest.cc47
-rw-r--r--content/browser/browser_main_loop.cc5
-rw-r--r--content/browser/browser_main_loop.h4
-rw-r--r--content/browser/system_message_window_win.cc57
-rw-r--r--content/browser/system_message_window_win.h43
-rw-r--r--content/common/hi_res_timer_manager_win.cc4
-rw-r--r--content/content_browser.gypi2
-rw-r--r--net/url_request/url_request_job.cc4
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(