Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/system_message_window_win.h" | 5 #include "content/browser/system_message_window_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | |
| 8 #include <dbt.h> | 7 #include <dbt.h> |
| 8 #include <ks.h> | |
| 9 #include <ksmedia.h> | |
| 9 | 10 |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/system_monitor/system_monitor.h" | 12 #include "base/system_monitor/system_monitor.h" |
| 12 #include "base/win/wrapped_window_proc.h" | 13 #include "base/win/wrapped_window_proc.h" |
| 13 | 14 |
| 14 static const wchar_t* const WindowClassName = L"Chrome_SystemMessageWindow"; | 15 namespace { |
| 16 const wchar_t kWindowClassName[] = L"Chrome_SystemMessageWindow"; | |
| 17 | |
| 18 // A static map from a device category guid to base::SystemMonitor::DeviceType. | |
| 19 struct { | |
| 20 const GUID device_category; | |
| 21 const base::SystemMonitor::DeviceType device_type; | |
| 22 } const kDeviceCategoryMap[] = { | |
| 23 { KSCATEGORY_AUDIO, base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE }, | |
| 24 { KSCATEGORY_VIDEO, base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE }, | |
| 25 }; | |
| 26 } | |
|
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.
| |
| 27 | |
| 28 // Manages the device notification handles for SystemMessageWindowWin. | |
| 29 class SystemMessageWindowWin::DeviceNotifications { | |
| 30 public: | |
| 31 explicit DeviceNotifications(HWND hwnd) : notifications_() { | |
| 32 Register(hwnd); | |
| 33 } | |
| 34 | |
| 35 ~DeviceNotifications() { | |
| 36 Unregister(); | |
| 37 } | |
| 38 | |
| 39 void Register(HWND hwnd) { | |
| 40 // Request to receive device notifications. All applications receive basic | |
| 41 // notifications via WM_DEVICECHANGE but in order to receive detailed device | |
| 42 // arrival and removal messages, we need to register. | |
| 43 DEV_BROADCAST_DEVICEINTERFACE filter = {0}; | |
| 44 filter.dbcc_size = sizeof(filter); | |
| 45 filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; | |
| 46 for (int i = 0; i < arraysize(kDeviceCategoryMap); ++i) { | |
| 47 filter.dbcc_classguid = kDeviceCategoryMap[i].device_category; | |
| 48 DCHECK_EQ(notifications_[i], static_cast<HDEVNOTIFY>(NULL)); | |
| 49 notifications_[i] = RegisterDeviceNotification(hwnd, &filter, | |
| 50 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
| |
| 51 DPLOG_IF(ERROR, !notifications_[i]) | |
| 52 << "RegisterDeviceNotification failed"; | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 void Unregister() { | |
| 57 for (int i = 0; i < arraysize(notifications_); ++i) { | |
| 58 if (notifications_[i]) { | |
| 59 UnregisterDeviceNotification(notifications_[i]); | |
| 60 notifications_[i] = NULL; | |
| 61 } | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 private: | |
| 66 HDEVNOTIFY notifications_[arraysize(kDeviceCategoryMap)]; | |
| 67 | |
| 68 DISALLOW_IMPLICIT_CONSTRUCTORS(DeviceNotifications); | |
| 69 }; | |
| 15 | 70 |
| 16 | 71 |
| 17 SystemMessageWindowWin::SystemMessageWindowWin() { | 72 SystemMessageWindowWin::SystemMessageWindowWin() { |
| 18 WNDCLASSEX window_class; | 73 WNDCLASSEX window_class; |
| 19 base::win::InitializeWindowClass( | 74 base::win::InitializeWindowClass( |
| 20 WindowClassName, | 75 kWindowClassName, |
| 21 &base::win::WrappedWindowProc<SystemMessageWindowWin::WndProcThunk>, | 76 &base::win::WrappedWindowProc<SystemMessageWindowWin::WndProcThunk>, |
| 22 0, 0, 0, NULL, NULL, NULL, NULL, NULL, | 77 0, 0, 0, NULL, NULL, NULL, NULL, NULL, |
| 23 &window_class); | 78 &window_class); |
| 24 instance_ = window_class.hInstance; | 79 instance_ = window_class.hInstance; |
| 25 ATOM clazz = RegisterClassEx(&window_class); | 80 ATOM clazz = RegisterClassEx(&window_class); |
| 26 DCHECK(clazz); | 81 DCHECK(clazz); |
| 27 | 82 |
| 28 window_ = CreateWindow(WindowClassName, | 83 window_ = CreateWindow(kWindowClassName, |
| 29 0, 0, 0, 0, 0, 0, 0, 0, instance_, 0); | 84 0, 0, 0, 0, 0, 0, 0, 0, instance_, 0); |
| 30 SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); | 85 SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); |
| 86 device_notifications_.reset(new DeviceNotifications(window_)); | |
| 31 } | 87 } |
| 32 | 88 |
| 33 SystemMessageWindowWin::~SystemMessageWindowWin() { | 89 SystemMessageWindowWin::~SystemMessageWindowWin() { |
| 34 if (window_) { | 90 if (window_) { |
| 35 DestroyWindow(window_); | 91 DestroyWindow(window_); |
| 36 UnregisterClass(WindowClassName, instance_); | 92 UnregisterClass(kWindowClassName, instance_); |
| 37 } | 93 } |
| 38 } | 94 } |
| 39 | 95 |
| 40 LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, DWORD data) { | 96 LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, |
| 97 DWORD_PTR data) { | |
| 41 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | 98 base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| 99 base::SystemMonitor::DeviceType device_type = | |
| 100 base::SystemMonitor::DEVTYPE_UNKNOWN; | |
| 42 switch (event_type) { | 101 switch (event_type) { |
| 43 case DBT_DEVNODES_CHANGED: | 102 case DBT_DEVNODES_CHANGED: |
| 44 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_UNKNOWN); | 103 // For this notification, we're happy with the default DEVTYPE_UNKNOWN. |
| 45 break; | 104 break; |
| 105 | |
| 106 case DBT_DEVICEREMOVECOMPLETE: | |
| 107 case DBT_DEVICEARRIVAL: { | |
| 108 // This notification has more details about the specific device that | |
| 109 // was added or removed. See if this is a category we're interested | |
| 110 // in monitoring and if so report the specific device type. If we don't | |
| 111 // find the category in our map, ignore the notification and do not | |
| 112 // notify the system monitor. | |
| 113 DEV_BROADCAST_DEVICEINTERFACE* device_interface = | |
| 114 reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(data); | |
| 115 DCHECK_EQ(device_interface->dbcc_devicetype, | |
| 116 static_cast<DWORD>(DBT_DEVTYP_DEVICEINTERFACE)); | |
| 117 for (int i = 0; i < arraysize(kDeviceCategoryMap); ++i) { | |
| 118 if (kDeviceCategoryMap[i].device_category == | |
| 119 device_interface->dbcc_classguid) { | |
| 120 device_type = kDeviceCategoryMap[i].device_type; | |
| 121 break; | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 // Devices that we do not have a DEVTYPE_ for, get detected via | |
| 126 // DBT_DEVNODES_CHANGED, so we avoid sending additional notifications | |
| 127 // for those here. | |
| 128 if (device_type == base::SystemMonitor::DEVTYPE_UNKNOWN) | |
| 129 return TRUE; | |
| 130 break; | |
| 131 } | |
| 132 | |
| 133 default: | |
| 134 return TRUE; | |
| 46 } | 135 } |
| 136 | |
| 137 monitor->ProcessDevicesChanged(device_type); | |
| 138 | |
| 47 return TRUE; | 139 return TRUE; |
| 48 } | 140 } |
| 49 | 141 |
| 50 LRESULT CALLBACK SystemMessageWindowWin::WndProc(HWND hwnd, UINT message, | 142 LRESULT CALLBACK SystemMessageWindowWin::WndProc(HWND hwnd, UINT message, |
| 51 WPARAM wparam, LPARAM lparam) { | 143 WPARAM wparam, LPARAM lparam) { |
| 52 switch (message) { | 144 switch (message) { |
| 53 case WM_DEVICECHANGE: | 145 case WM_DEVICECHANGE: |
| 54 return OnDeviceChange(static_cast<UINT>(wparam), | 146 return OnDeviceChange(static_cast<UINT>(wparam), |
| 55 static_cast<DWORD>(lparam)); | 147 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).
| |
| 56 default: | 148 default: |
| 57 break; | 149 break; |
| 58 } | 150 } |
| 59 | 151 |
| 60 return ::DefWindowProc(hwnd, message, wparam, lparam); | 152 return ::DefWindowProc(hwnd, message, wparam, lparam); |
| 61 } | 153 } |
| OLD | NEW |