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

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

Issue 10824162: add device notification to Mac (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed Tommi's comments Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
(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 <CoreFoundation/CFNumber.h>
8 #include <CoreFoundation/CoreFoundation.h>
9 #include <IOKit/usb/IOUSBLib.h>
10
11 #include "base/logging.h"
12 #include "base/system_monitor/system_monitor.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));
37 }
38
39 } // namespace
40
41 DeviceMonitorMac::DeviceMonitorMac() {
42 CFRunLoopRef runloop = CFRunLoopGetCurrent();
43 CFRetain(runloop);
44
45 // Add the notification port to the run loop.
46 IONotificationPortRef notification_port =
47 IONotificationPortCreate(kIOMasterPortDefault);
48 CFRunLoopSourceRef notification_cfsource =
49 IONotificationPortGetRunLoopSource(notification_port);
50
51 RegisterVideoCallbacks(notification_port);
52 RegisterAudioCallbacks(notification_port);
53 CFRunLoopAddSource(runloop, notification_cfsource, kCFRunLoopCommonModes);
54 }
55
56 void DeviceMonitorMac::RegisterVideoCallbacks(IONotificationPortRef port) {
57 SInt32 interface_class_code = kUSBVideoInterfaceClass;
58 SInt32 interface_subclass_code = kUSBVideoControlSubClass;
59 CFMutableDictionaryRef matching_dictionary = IOServiceMatching(
60 kIOUSBInterfaceClassName);
61 AddValueToDictionary(matching_dictionary, interface_class_code,
62 CFSTR(kUSBInterfaceClass));
63 AddValueToDictionary(matching_dictionary, interface_subclass_code,
64 CFSTR(kUSBInterfaceSubClass));
65
66 // Add a callback which will be called when a video device is plugged in.
67 io_iterator_t new_devices_iterator = 0;
68 kern_return_t err = IOServiceAddMatchingNotification(
69 port,
70 kIOMatchedNotification,
71 matching_dictionary,
72 &VideoDeviceChangedCallback,
73 this,
74 &new_devices_iterator);
75 if (err) {
76 NOTREACHED() << "Failed to register the video IO mached notification";
77 return;
78 }
79 VideoDeviceChangedCallback(NULL, new_devices_iterator);
80
81 // Add a callback which will be called when a video device is terminated.
82 io_iterator_t lost_devices_iterator = 0;
83 err = IOServiceAddMatchingNotification(
84 port,
85 kIOTerminatedNotification,
86 matching_dictionary,
87 &VideoDeviceChangedCallback,
88 this,
89 &lost_devices_iterator);
90 if (err) {
91 NOTREACHED() << "Failed to register the video IO terminated notification";
92 return;
93 }
94 VideoDeviceChangedCallback(NULL, lost_devices_iterator);
95 }
96
97 void DeviceMonitorMac::RegisterAudioCallbacks(IONotificationPortRef port) {
wjia(left Chromium) 2012/08/03 13:50:08 It seems this function is very similar to Register
no longer working on chromium 2012/08/03 16:10:15 Done.
98 SInt32 interface_class_code = kUSBAudioInterfaceClass;
99 SInt32 interface_subclass_code = kUSBAudioControlSubClass;
100 CFMutableDictionaryRef matching_dictionary = IOServiceMatching(
101 kIOUSBInterfaceClassName);
102 AddValueToDictionary(matching_dictionary, interface_class_code,
103 CFSTR(kUSBInterfaceClass));
104 AddValueToDictionary(matching_dictionary, interface_subclass_code,
105 CFSTR(kUSBInterfaceSubClass));
106
107 // Add a callback which will be called when a audio device is plugged in.
108 io_iterator_t added_devices_iterator = 0;
109 kern_return_t err = IOServiceAddMatchingNotification(
110 port,
111 kIOMatchedNotification,
112 matching_dictionary,
113 &AudioDeviceChangedCallback,
114 this,
115 &added_devices_iterator);
116 if (err) {
117 NOTREACHED() << "Failed to register the audio IO mached notification";
118 return;
119 }
120 // Iterate over set of matching devices to access already-present devices
121 // and to arm the notification.
122 AudioDeviceChangedCallback(NULL, added_devices_iterator);
123
124 // Add a callback which will be called when a audio device is terminated.
125 io_iterator_t removed_devices_iterator = 0;
126 err = IOServiceAddMatchingNotification(
127 port,
128 kIOTerminatedNotification,
129 matching_dictionary,
130 &AudioDeviceChangedCallback,
131 this,
wjia(left Chromium) 2012/08/03 15:21:05 if the type, instead of |this|, is used here, you
no longer working on chromium 2012/08/03 16:10:15 In this case, we can't access to member functions.
132 &removed_devices_iterator);
133 if (err) {
134 NOTREACHED() << "Failed to register the audio IO terminated notification";
135 return;
136 }
137 // Iterate over set of matching devices to release each one and to
138 // arm the notification.
139 AudioDeviceChangedCallback(NULL, removed_devices_iterator);
140 }
141
142 void DeviceMonitorMac::VideoDeviceChangedCallback(void *context,
143 io_iterator_t devices) {
144 io_object_t thisObject;
145 while ((thisObject = IOIteratorNext(devices))) {
146 if (context)
147 InstanceFromContext(context)->NotifyVideoDeviceChanged();
wjia(left Chromium) 2012/08/03 13:50:08 At this point, the type is known. It seems you nee
no longer working on chromium 2012/08/03 16:10:15 Done.
148
149 IOObjectRelease(thisObject);
150 }
151 }
152
153 void DeviceMonitorMac::AudioDeviceChangedCallback(void *context,
154 io_iterator_t devices) {
155 io_object_t thisObject;
156 while ((thisObject = IOIteratorNext(devices))) {
157 if (context)
158 InstanceFromContext(context)->NotifyAudioDeviceChanged();
159
160 IOObjectRelease(thisObject);
161 }
162 }
163
164 void DeviceMonitorMac::NotifyAudioDeviceChanged() {
165 base::SystemMonitor* monitor = base::SystemMonitor::Get();
wjia(left Chromium) 2012/08/03 13:50:08 no need to have intermediate variable.
no longer working on chromium 2012/08/03 16:10:15 Done.
166 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
167 }
168
169 void DeviceMonitorMac::NotifyVideoDeviceChanged() {
170 base::SystemMonitor* monitor = base::SystemMonitor::Get();
171 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
172 }
173
174 DeviceMonitorMac::~DeviceMonitorMac() {}
175
176 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698