Chromium Code Reviews| 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 |