OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/device_monitor_mac.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/system_monitor/system_monitor.h" | |
9 | |
10 #include <CoreFoundation/CFNumber.h> | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
shouldn't these be above the chrome includes?
no longer working on chromium
2012/08/03 13:07:07
done.
| |
11 #include <CoreFoundation/CoreFoundation.h> | |
12 #include <IOKit/usb/IOUSBLib.h> | |
13 | |
14 namespace content { | |
15 | |
16 namespace { | |
17 | |
18 DeviceMonitorMac* InstanceFromContext(void* context) { | |
19 return reinterpret_cast<DeviceMonitorMac*>(context); | |
20 } | |
21 | |
22 void AddValueToDictionary(CFMutableDictionaryRef dictionary, | |
23 SInt32 code, | |
24 const void *key) { | |
25 CFNumberRef number_ref = CFNumberCreate(kCFAllocatorDefault, | |
26 kCFNumberSInt32Type, | |
27 &code); | |
28 if (!number_ref) { | |
29 NOTREACHED() << "failed to create CFNumberRef for " << code; | |
30 return; | |
31 } | |
32 | |
33 CFDictionaryAddValue(dictionary, key, number_ref); | |
34 CFRelease(number_ref); | |
35 | |
36 dictionary = (CFMutableDictionaryRef)(CFRetain(dictionary)); | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
fix cast or is this how things are done in mm land
no longer working on chromium
2012/08/03 13:07:07
neither static_cast nor reinterpret_cast passes th
| |
37 } | |
38 | |
39 void VideoDeviceChangedCallback(void *context, io_iterator_t devices) { | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
void* context.
In order to allow this method to c
no longer working on chromium
2012/08/03 13:07:07
Done.
| |
40 io_object_t thisObject; | |
41 while ((thisObject = IOIteratorNext(devices))) { | |
42 if (context) | |
43 InstanceFromContext(context)->NotifyVideoDeviceChanged(); | |
44 | |
45 IOObjectRelease(thisObject); | |
46 } | |
47 } | |
48 | |
49 void AudioDeviceChangedCallback(void *context, io_iterator_t devices) { | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
same as above.
no longer working on chromium
2012/08/03 13:07:07
Done.
| |
50 io_object_t thisObject; | |
51 while ((thisObject = IOIteratorNext(devices))) { | |
52 if (context) | |
53 InstanceFromContext(context)->NotifyAudioDeviceChanged(); | |
54 | |
55 IOObjectRelease(thisObject); | |
56 } | |
57 } | |
58 | |
59 } // namespace | |
60 | |
61 DeviceMonitorMac::DeviceMonitorMac() { | |
62 CFRunLoopRef runloop = CFRunLoopGetCurrent (); | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
no space before ()
no longer working on chromium
2012/08/03 13:07:07
Done.
| |
63 CFRetain (runloop); | |
64 | |
65 // Add the notification port to the run loop. | |
66 IONotificationPortRef notification_port = | |
67 IONotificationPortCreate (kIOMasterPortDefault); | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
same here. please fix throughout
no longer working on chromium
2012/08/03 13:07:07
Done.
| |
68 CFRunLoopSourceRef notification_cfsource = | |
69 IONotificationPortGetRunLoopSource (notification_port); | |
70 | |
71 RegisterVideoCallbacks(notification_port); | |
72 RegisterAudioCallbacks(notification_port); | |
73 CFRunLoopAddSource(runloop, notification_cfsource, kCFRunLoopCommonModes); | |
74 } | |
75 | |
76 void DeviceMonitorMac::RegisterVideoCallbacks(IONotificationPortRef port) { | |
77 SInt32 interface_class_code = kUSBVideoInterfaceClass; | |
78 SInt32 interface_subclass_code = kUSBVideoControlSubClass; | |
79 CFMutableDictionaryRef matching_dictionary = IOServiceMatching( | |
80 kIOUSBInterfaceClassName); | |
81 AddValueToDictionary(matching_dictionary, interface_class_code, | |
82 CFSTR(kUSBInterfaceClass)); | |
83 AddValueToDictionary(matching_dictionary, interface_subclass_code, | |
84 CFSTR(kUSBInterfaceSubClass)); | |
85 | |
86 // Add a callback which will be called when a video device is plugged in. | |
87 io_iterator_t new_devices_iterator = 0; | |
88 kern_return_t err = IOServiceAddMatchingNotification( | |
89 port, | |
90 kIOMatchedNotification, | |
91 matching_dictionary, | |
92 &VideoDeviceChangedCallback, | |
93 this, | |
94 &new_devices_iterator); | |
95 if (err) { | |
96 NOTREACHED() << "Failed to register the video IO mached notification"; | |
97 return; | |
98 } | |
99 VideoDeviceChangedCallback(NULL, new_devices_iterator); | |
100 | |
101 // Add a callback which will be called when a video device is terminated. | |
102 io_iterator_t lost_devices_iterator = 0; | |
103 err = IOServiceAddMatchingNotification( | |
104 port, | |
105 kIOTerminatedNotification, | |
106 matching_dictionary, | |
107 &VideoDeviceChangedCallback, | |
108 this, | |
109 &lost_devices_iterator); | |
110 if (err) { | |
111 NOTREACHED() << "Failed to register the video IO terminated notification"; | |
112 return; | |
113 } | |
114 VideoDeviceChangedCallback(NULL, lost_devices_iterator); | |
115 } | |
116 | |
117 void DeviceMonitorMac::RegisterAudioCallbacks(IONotificationPortRef port) { | |
118 SInt32 interface_class_code = kUSBAudioInterfaceClass; | |
119 SInt32 interface_subclass_code = kUSBAudioControlSubClass; | |
120 CFMutableDictionaryRef matching_dictionary = IOServiceMatching( | |
121 kIOUSBInterfaceClassName); | |
122 AddValueToDictionary(matching_dictionary, interface_class_code, | |
123 CFSTR(kUSBInterfaceClass)); | |
124 AddValueToDictionary(matching_dictionary, interface_subclass_code, | |
125 CFSTR(kUSBInterfaceSubClass)); | |
126 | |
127 // Add a callback which will be called when a audio device is plugged in. | |
128 io_iterator_t added_devices_iterator = 0; | |
129 kern_return_t err = IOServiceAddMatchingNotification( | |
130 port, | |
131 kIOMatchedNotification, | |
132 matching_dictionary, | |
133 &AudioDeviceChangedCallback, | |
134 this, | |
135 &added_devices_iterator); | |
136 if (err) { | |
137 NOTREACHED() << "Failed to register the audio IO mached notification"; | |
138 return; | |
139 } | |
140 // Iterate over set of matching devices to access already-present devices | |
141 // and to arm the notification. | |
142 AudioDeviceChangedCallback(NULL, added_devices_iterator); | |
143 | |
144 // Add a callback which will be called when a audio device is terminated. | |
145 io_iterator_t removed_devices_iterator = 0; | |
146 err = IOServiceAddMatchingNotification( | |
147 port, | |
148 kIOTerminatedNotification, | |
149 matching_dictionary, | |
150 &AudioDeviceChangedCallback, | |
151 this, | |
152 &removed_devices_iterator); | |
153 if (err) { | |
154 NOTREACHED() << "Failed to register the audio IO terminated notification"; | |
tommi (sloooow) - chröme
2012/08/03 11:24:29
fix indent
no longer working on chromium
2012/08/03 13:07:07
Done.
| |
155 return; | |
156 } | |
157 // Iterate over set of matching devices to release each one and to | |
158 // arm the notification. | |
159 AudioDeviceChangedCallback(NULL, removed_devices_iterator); | |
160 } | |
161 | |
162 void DeviceMonitorMac::NotifyAudioDeviceChanged() { | |
163 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | |
164 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); | |
165 } | |
166 | |
167 void DeviceMonitorMac::NotifyVideoDeviceChanged() { | |
168 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | |
169 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE); | |
170 } | |
171 | |
172 DeviceMonitorMac::~DeviceMonitorMac() {} | |
173 | |
174 } // namespace content | |
OLD | NEW |