Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: content/browser/device_monitor_mac.cc

Issue 11106013: Fix a M23 stable crash issue for device enumeration on Mac (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/device_monitor_mac.h" 5 #include "content/browser/device_monitor_mac.h"
6 6
7 #include <IOKit/audio/IOAudioDefines.h>
8 #include <IOKit/usb/IOUSBLib.h> 7 #include <IOKit/usb/IOUSBLib.h>
9 8
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #include "base/mac/scoped_cftyperef.h" 10 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/scoped_ioobject.h" 11 #include "base/mac/scoped_ioobject.h"
13 12
14 namespace content { 13 namespace content {
15 14
16 namespace { 15 namespace {
17 16
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 // Remove the notification port from the message runloop. 90 // Remove the notification port from the message runloop.
92 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), 91 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
93 IONotificationPortGetRunLoopSource(notification_port_), 92 IONotificationPortGetRunLoopSource(notification_port_),
94 kCFRunLoopCommonModes); 93 kCFRunLoopCommonModes);
95 94
96 // Destroy the notification port allocated by IONotificationPortCreate. 95 // Destroy the notification port allocated by IONotificationPortCreate.
97 IONotificationPortDestroy(notification_port_); 96 IONotificationPortDestroy(notification_port_);
98 } 97 }
99 98
100 void DeviceMonitorMac::RegisterAudioServices() { 99 void DeviceMonitorMac::RegisterAudioServices() {
101 CFMutableDictionaryRef dictionary = 100 // We can't use IOService for audio since IOKit notification will come prior
102 IOServiceMatching(kIOAudioDeviceClassName); 101 // to the driver is actually fully initialized, and this has two issues:
103 RegisterServices(dictionary, &AudioDeviceCallback); 102 // 1, device enumeration is not correct.
103 // 2, it might crash if the device is being enumerated at the same time as
104 // as being initialized. See issue 153411 for details.
105 AudioObjectPropertyAddress property = {
106 kAudioHardwarePropertyDevices,
107 kAudioObjectPropertyScopeGlobal,
108 kAudioObjectPropertyElementMaster
109 };
110 AudioObjectAddPropertyListener(kAudioObjectSystemObject, &property,
111 &AudioDeviceCallback, this);
104 } 112 }
105 113
106 void DeviceMonitorMac::RegisterVideoServices() { 114 void DeviceMonitorMac::RegisterVideoServices() {
107 CFMutableDictionaryRef dictionary = CreateMatchingDictionaryForUSBDevices( 115 CFMutableDictionaryRef dictionary = CreateMatchingDictionaryForUSBDevices(
108 kUSBVideoInterfaceClass, kUSBVideoControlSubClass); 116 kUSBVideoInterfaceClass, kUSBVideoControlSubClass);
109 RegisterServices(dictionary, &VideoDeviceCallback); 117 RegisterServices(dictionary, &VideoDeviceCallback);
110 } 118 }
111 119
112 void DeviceMonitorMac::RegisterServices(CFMutableDictionaryRef dictionary, 120 void DeviceMonitorMac::RegisterServices(CFMutableDictionaryRef dictionary,
113 IOServiceMatchingCallback callback) { 121 IOServiceMatchingCallback callback) {
(...skipping 13 matching lines...) Expand all
127 callback, 135 callback,
128 this, 136 this,
129 &service); 137 &service);
130 138
131 // Store the pointer of the object to release the memory when shutting 139 // Store the pointer of the object to release the memory when shutting
132 // down the services. 140 // down the services.
133 notification_iterators_.push_back(&service); 141 notification_iterators_.push_back(&service);
134 } 142 }
135 } 143 }
136 144
137 void DeviceMonitorMac::AudioDeviceCallback(void *context, 145 OSStatus DeviceMonitorMac::AudioDeviceCallback(
138 io_iterator_t iterator) { 146 AudioObjectID object, UInt32 size,
139 for (base::mac::ScopedIOObject<io_service_t> object(IOIteratorNext(iterator)); 147 const AudioObjectPropertyAddress addresses[], void* context) {
140 object; 148 for (UInt32 i = 0; i < size; ++i) {
141 object.reset(IOIteratorNext(iterator))) { 149 if (addresses[i].mSelector == kAudioHardwarePropertyDevices) {
142 if (context) { 150 if (context) {
143 reinterpret_cast<DeviceMonitorMac*>(context)->NotifyDeviceChanged( 151 reinterpret_cast<DeviceMonitorMac*>(context)->NotifyDeviceChanged(
144 base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); 152 base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
153 break;
154 }
145 } 155 }
146 } 156 }
157
158 return noErr;
147 } 159 }
148 160
149 void DeviceMonitorMac::VideoDeviceCallback(void *context, 161 void DeviceMonitorMac::VideoDeviceCallback(void *context,
150 io_iterator_t iterator) { 162 io_iterator_t iterator) {
151 for (base::mac::ScopedIOObject<io_service_t> object(IOIteratorNext(iterator)); 163 for (base::mac::ScopedIOObject<io_service_t> object(IOIteratorNext(iterator));
152 object; 164 object;
153 object.reset(IOIteratorNext(iterator))) { 165 object.reset(IOIteratorNext(iterator))) {
154 if (context) { 166 if (context) {
155 reinterpret_cast<DeviceMonitorMac*>(context)->NotifyDeviceChanged( 167 reinterpret_cast<DeviceMonitorMac*>(context)->NotifyDeviceChanged(
156 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE); 168 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
157 } 169 }
158 } 170 }
159 } 171 }
160 172
161 void DeviceMonitorMac::NotifyDeviceChanged( 173 void DeviceMonitorMac::NotifyDeviceChanged(
162 base::SystemMonitor::DeviceType type) { 174 base::SystemMonitor::DeviceType type) {
163 // TODO(xians): Remove the global variable for SystemMonitor. 175 // TODO(xians): Remove the global variable for SystemMonitor.
164 base::SystemMonitor::Get()->ProcessDevicesChanged(type); 176 base::SystemMonitor::Get()->ProcessDevicesChanged(type);
165 } 177 }
166 178
167 } // namespace content 179 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698