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