OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
Mark Mentovai
2012/08/07 18:39:10
Why is this a .mm file? You haven’t used any Objec
no longer working on chromium
2012/08/08 08:42:42
It is a following design from gamepad/platform_dat
| |
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 <IOKit/usb/IOUSBLib.h> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/mac/scoped_cftyperef.h" | |
11 #include "base/mac/scoped_ioobject.h" | |
12 | |
13 namespace content { | |
14 | |
15 namespace { | |
16 | |
17 struct { | |
Mark Mentovai
2012/08/07 18:39:10
const?
no longer working on chromium
2012/08/08 08:42:42
Done.
| |
18 base::SystemMonitor::DeviceType device_type; | |
19 const io_name_t service_type; | |
Mark Mentovai
2012/08/07 18:39:10
…but this doesn’t really need to be const
no longer working on chromium
2012/08/08 08:42:42
I think it is a c_string, isn't it better to put i
| |
20 } kDeviceServices[] = { | |
21 // Add new services here if needed. | |
22 { base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE, kIOMatchedNotification }, | |
23 { base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE, kIOTerminatedNotification }, | |
24 { base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE, kIOMatchedNotification }, | |
25 { base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE, kIOTerminatedNotification }, | |
26 }; | |
27 | |
28 CFMutableDictionaryRef CreateMatchingDictionary( | |
29 SInt32 interface_class_code, SInt32 interface_subclass_code) { | |
30 CFMutableDictionaryRef matching_dictionary = IOServiceMatching( | |
31 kIOUSBInterfaceClassName); | |
32 base::mac::ScopedCFTypeRef<CFNumberRef> number_ref(CFNumberCreate( | |
33 kCFAllocatorDefault, kCFNumberSInt32Type, &interface_class_code)); | |
34 DCHECK(number_ref); | |
35 CFDictionaryAddValue(matching_dictionary, CFSTR(kUSBInterfaceClass), | |
36 number_ref); | |
37 | |
38 number_ref.reset(CFNumberCreate(kCFAllocatorDefault, | |
39 kCFNumberSInt32Type, | |
40 &interface_subclass_code)); | |
41 DCHECK(number_ref); | |
42 CFDictionaryAddValue(matching_dictionary, CFSTR(kUSBInterfaceSubClass), | |
43 number_ref); | |
44 | |
45 return matching_dictionary; | |
46 } | |
47 | |
48 void AddCallbackToIOService(IONotificationPortRef port, | |
49 const io_name_t type, | |
50 CFMutableDictionaryRef dictionary, | |
51 IOServiceMatchingCallback callback, | |
52 void* context, | |
53 io_iterator_t* notification) { | |
54 kern_return_t err = IOServiceAddMatchingNotification(port, | |
Mark Mentovai
2012/08/07 18:39:10
Weird indentation.
no longer working on chromium
2012/08/08 08:42:42
thanks.
| |
55 type, | |
56 dictionary, | |
57 callback, | |
58 context, | |
59 notification); | |
60 if (err) { | |
61 NOTREACHED() << "Failed to register the IO matched notification for type " | |
62 << type; | |
63 return; | |
64 } | |
65 DCHECK(*notification); | |
66 | |
67 // Iterate over set of matching devices to access already-present devices | |
68 // and to arm the notification. | |
69 base::mac::ScopedIOObject<io_service_t> this_object( | |
70 IOIteratorNext(*notification)); | |
71 for (; this_object; this_object.reset(IOIteratorNext(*notification))); | |
Mark Mentovai
2012/08/07 18:39:10
Use {} to show an empty body. Also see the comment
no longer working on chromium
2012/08/08 08:42:42
Done.
I replied the comment at line 136.
| |
72 } | |
73 | |
74 } // namespace | |
75 | |
76 DeviceMonitorMac::DeviceMonitorMac() { | |
77 CFRunLoopRef runloop = CFRunLoopGetCurrent(); | |
Mark Mentovai
2012/08/07 18:39:10
You can save doing this until you’re ready to add
no longer working on chromium
2012/08/08 08:42:42
Done.
| |
78 | |
79 // Add the notification port to the run loop. | |
80 notification_port_ = IONotificationPortCreate(kIOMasterPortDefault); | |
81 DCHECK(notification_port_); | |
82 CFRunLoopSourceRef notification_cfsource = | |
83 IONotificationPortGetRunLoopSource(notification_port_); | |
84 | |
85 RegisterServices(); | |
86 | |
87 CFRunLoopAddSource(runloop, notification_cfsource, kCFRunLoopCommonModes); | |
88 } | |
89 | |
90 DeviceMonitorMac::~DeviceMonitorMac() { | |
91 // Stop the notifications and free the objects. | |
92 for (size_t i = 0; i < arraysize(kDeviceServices); ++i) { | |
Mark Mentovai
2012/08/07 18:39:10
This looks a little freaky. Why don’t you use a st
no longer working on chromium
2012/08/08 08:42:42
a scoped_array is much more suitable here because
Mark Mentovai
2012/08/08 12:32:57
Aside from the ability to resize a std::vector (wh
| |
93 IOObjectRelease(notification_iterators_[i]); | |
Avi (use Gerrit)
2012/08/06 20:29:47
Aha, cool.
| |
94 } | |
95 | |
96 // Remove the sleep notification port from the application runloop. | |
97 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), | |
98 IONotificationPortGetRunLoopSource(notification_port_), | |
99 kCFRunLoopCommonModes); | |
100 | |
101 // Destroy the notification port allocated by IONotificationPortCreate. | |
102 IONotificationPortDestroy(notification_port_); | |
103 } | |
104 | |
105 void DeviceMonitorMac::RegisterServices() { | |
106 notification_iterators_.reset(new io_iterator_t[arraysize(kDeviceServices)]); | |
107 CFMutableDictionaryRef matching_dictionary; | |
108 for (size_t i = 0; i < arraysize(kDeviceServices); ++i) { | |
109 switch (kDeviceServices[i].device_type) { | |
wjia(left Chromium)
2012/08/07 20:57:27
After chatting with mmentovai@, my understanding i
no longer working on chromium
2012/08/08 08:42:42
NO.
I thought I had already explained clearly abou
| |
110 case base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE: | |
111 matching_dictionary = CreateMatchingDictionary( | |
112 kUSBAudioInterfaceClass, kUSBAudioControlSubClass); | |
113 break; | |
114 case base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE: | |
115 matching_dictionary = CreateMatchingDictionary( | |
116 kUSBVideoInterfaceClass, kUSBVideoControlSubClass); | |
117 break; | |
118 default: | |
119 NOTREACHED(); | |
120 return; | |
121 } | |
122 | |
123 // Add callback to the service. | |
124 AddCallbackToIOService(notification_port_, | |
125 kDeviceServices[i].service_type, | |
126 matching_dictionary, | |
127 &DeviceChangedCallback, | |
128 static_cast<void*>(&kDeviceServices[i].device_type), | |
129 ¬ification_iterators_[i]); | |
130 } | |
131 } | |
132 | |
133 void DeviceMonitorMac::DeviceChangedCallback(void *context, | |
134 io_iterator_t iterator) { | |
135 base::mac::ScopedIOObject<io_service_t> this_object(IOIteratorNext(iterator)); | |
136 for (; this_object; this_object.reset(IOIteratorNext(iterator))) { | |
Mark Mentovai
2012/08/07 18:39:10
I’d write the initialization inside the body of th
no longer working on chromium
2012/08/08 08:42:42
:) I think I have got different opinions on this s
Mark Mentovai
2012/08/08 12:32:57
Whoever’s opinion you got in the past on this was
| |
137 if (context) { | |
138 base::SystemMonitor::DeviceType device_type = | |
139 *reinterpret_cast<base::SystemMonitor::DeviceType*>(context); | |
140 DCHECK(device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE || | |
141 device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE); | |
142 // TODO(xians): Remove the global variable for SystemMonitor. | |
143 base::SystemMonitor::Get()->ProcessDevicesChanged(device_type); | |
144 } | |
145 } | |
146 } | |
147 | |
148 } // namespace content | |
OLD | NEW |