Chromium Code Reviews| Index: content/browser/system_message_window_win.cc |
| diff --git a/content/browser/system_message_window_win.cc b/content/browser/system_message_window_win.cc |
| index ca31feb21f7a1358d25b51e42f5f052a9e844db6..2e9db8803c0c978f6de310d12d1212038f71690b 100644 |
| --- a/content/browser/system_message_window_win.cc |
| +++ b/content/browser/system_message_window_win.cc |
| @@ -4,20 +4,75 @@ |
| #include "content/browser/system_message_window_win.h" |
| -#include <windows.h> |
| #include <dbt.h> |
| +#include <ks.h> |
| +#include <ksmedia.h> |
| #include "base/logging.h" |
| #include "base/system_monitor/system_monitor.h" |
| #include "base/win/wrapped_window_proc.h" |
| -static const wchar_t* const WindowClassName = L"Chrome_SystemMessageWindow"; |
| +namespace { |
| +const wchar_t kWindowClassName[] = L"Chrome_SystemMessageWindow"; |
| + |
| +// A static map from a device category guid to base::SystemMonitor::DeviceType. |
| +struct { |
| + const GUID device_category; |
| + const base::SystemMonitor::DeviceType device_type; |
| +} const kDeviceCategoryMap[] = { |
| + { KSCATEGORY_AUDIO, base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE }, |
| + { KSCATEGORY_VIDEO, base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE }, |
| +}; |
| +} |
|
piman
2012/07/31 18:24:55
nit: // anonymous namespace
tommi (sloooow) - chröme
2012/07/31 18:50:09
Done.
Lei Zhang
2012/07/31 19:46:46
You need to upload a new patchset.
|
| + |
| +// Manages the device notification handles for SystemMessageWindowWin. |
| +class SystemMessageWindowWin::DeviceNotifications { |
| + public: |
| + explicit DeviceNotifications(HWND hwnd) : notifications_() { |
| + Register(hwnd); |
| + } |
| + |
| + ~DeviceNotifications() { |
| + Unregister(); |
| + } |
| + |
| + void Register(HWND hwnd) { |
| + // Request to receive device notifications. All applications receive basic |
| + // notifications via WM_DEVICECHANGE but in order to receive detailed device |
| + // arrival and removal messages, we need to register. |
| + DEV_BROADCAST_DEVICEINTERFACE filter = {0}; |
| + filter.dbcc_size = sizeof(filter); |
| + filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; |
| + for (int i = 0; i < arraysize(kDeviceCategoryMap); ++i) { |
| + filter.dbcc_classguid = kDeviceCategoryMap[i].device_category; |
| + DCHECK_EQ(notifications_[i], static_cast<HDEVNOTIFY>(NULL)); |
| + notifications_[i] = RegisterDeviceNotification(hwnd, &filter, |
| + DEVICE_NOTIFY_WINDOW_HANDLE); |
|
piman
2012/07/31 18:24:55
nit: correct style is either:
LongFuntionName(a,
tommi (sloooow) - chröme
2012/07/31 18:50:09
Fixed.
However, I've seen this style elsewhere in
|
| + DPLOG_IF(ERROR, !notifications_[i]) |
| + << "RegisterDeviceNotification failed"; |
| + } |
| + } |
| + |
| + void Unregister() { |
| + for (int i = 0; i < arraysize(notifications_); ++i) { |
| + if (notifications_[i]) { |
| + UnregisterDeviceNotification(notifications_[i]); |
| + notifications_[i] = NULL; |
| + } |
| + } |
| + } |
| + |
| + private: |
| + HDEVNOTIFY notifications_[arraysize(kDeviceCategoryMap)]; |
| + |
| + DISALLOW_IMPLICIT_CONSTRUCTORS(DeviceNotifications); |
| +}; |
| SystemMessageWindowWin::SystemMessageWindowWin() { |
| WNDCLASSEX window_class; |
| base::win::InitializeWindowClass( |
| - WindowClassName, |
| + kWindowClassName, |
| &base::win::WrappedWindowProc<SystemMessageWindowWin::WndProcThunk>, |
| 0, 0, 0, NULL, NULL, NULL, NULL, NULL, |
| &window_class); |
| @@ -25,25 +80,62 @@ SystemMessageWindowWin::SystemMessageWindowWin() { |
| ATOM clazz = RegisterClassEx(&window_class); |
| DCHECK(clazz); |
| - window_ = CreateWindow(WindowClassName, |
| + window_ = CreateWindow(kWindowClassName, |
| 0, 0, 0, 0, 0, 0, 0, 0, instance_, 0); |
| SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); |
| + device_notifications_.reset(new DeviceNotifications(window_)); |
| } |
| SystemMessageWindowWin::~SystemMessageWindowWin() { |
| if (window_) { |
| DestroyWindow(window_); |
| - UnregisterClass(WindowClassName, instance_); |
| + UnregisterClass(kWindowClassName, instance_); |
| } |
| } |
| -LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, DWORD data) { |
| +LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, |
| + DWORD_PTR data) { |
| base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| + base::SystemMonitor::DeviceType device_type = |
| + base::SystemMonitor::DEVTYPE_UNKNOWN; |
| switch (event_type) { |
| case DBT_DEVNODES_CHANGED: |
| - monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_UNKNOWN); |
| + // For this notification, we're happy with the default DEVTYPE_UNKNOWN. |
| + break; |
| + |
| + case DBT_DEVICEREMOVECOMPLETE: |
| + case DBT_DEVICEARRIVAL: { |
| + // This notification has more details about the specific device that |
| + // was added or removed. See if this is a category we're interested |
| + // in monitoring and if so report the specific device type. If we don't |
| + // find the category in our map, ignore the notification and do not |
| + // notify the system monitor. |
| + DEV_BROADCAST_DEVICEINTERFACE* device_interface = |
| + reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(data); |
| + DCHECK_EQ(device_interface->dbcc_devicetype, |
| + static_cast<DWORD>(DBT_DEVTYP_DEVICEINTERFACE)); |
| + for (int i = 0; i < arraysize(kDeviceCategoryMap); ++i) { |
| + if (kDeviceCategoryMap[i].device_category == |
| + device_interface->dbcc_classguid) { |
| + device_type = kDeviceCategoryMap[i].device_type; |
| + break; |
| + } |
| + } |
| + |
| + // Devices that we do not have a DEVTYPE_ for, get detected via |
| + // DBT_DEVNODES_CHANGED, so we avoid sending additional notifications |
| + // for those here. |
| + if (device_type == base::SystemMonitor::DEVTYPE_UNKNOWN) |
| + return TRUE; |
| break; |
| + } |
| + |
| + default: |
| + return TRUE; |
| } |
| + |
| + monitor->ProcessDevicesChanged(device_type); |
| + |
| return TRUE; |
| } |
| @@ -52,7 +144,7 @@ LRESULT CALLBACK SystemMessageWindowWin::WndProc(HWND hwnd, UINT message, |
| switch (message) { |
| case WM_DEVICECHANGE: |
| return OnDeviceChange(static_cast<UINT>(wparam), |
| - static_cast<DWORD>(lparam)); |
| + static_cast<DWORD_PTR>(lparam)); |
|
piman
2012/07/31 18:24:55
why the need for 2 casts, one here and one in OnDe
tommi (sloooow) - chröme
2012/07/31 18:50:09
Good point. Done (did the former).
|
| default: |
| break; |
| } |