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

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: delete the monitors before system_monitor_ in browser_main_loop_. 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
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>
Avi (use Gerrit) 2012/08/06 13:54:37 You don't need to include this; the include below
no longer working on chromium 2012/08/06 19:53:12 Done.
8 #include <CoreFoundation/CoreFoundation.h>
9 #include <IOKit/usb/IOUSBLib.h>
10
11 #include "base/logging.h"
12 #include "base/mac/scoped_cftyperef.h"
13 #include "base/mac/scoped_ioobject.h"
14
15 namespace content {
16
17 namespace {
18
19 CFMutableDictionaryRef CreateMatchingDictionary(
20 SInt32 interface_class_code, SInt32 interface_subclass_code) {
21 CFMutableDictionaryRef matching_dictionary = IOServiceMatching(
22 kIOUSBInterfaceClassName);
23 base::mac::ScopedCFTypeRef<CFNumberRef> number_ref(CFNumberCreate(
24 kCFAllocatorDefault, kCFNumberSInt32Type, &interface_class_code));
25 DCHECK(number_ref);
26 CFDictionaryAddValue(matching_dictionary, CFSTR(kUSBInterfaceClass),
27 number_ref);
28
29 number_ref.reset(CFNumberCreate(kCFAllocatorDefault,
30 kCFNumberSInt32Type,
31 &interface_subclass_code));
32 DCHECK(number_ref);
33 CFDictionaryAddValue(matching_dictionary, CFSTR(kUSBInterfaceSubClass),
34 number_ref);
35
36 return matching_dictionary;
37 }
38
39 void AddCallbackToIOService(IONotificationPortRef port,
40 const io_name_t type,
41 CFMutableDictionaryRef dictionary,
42 IOServiceMatchingCallback callback,
43 void* context) {
44 // Retain additional dictionary references because each call to
45 // IOServiceAddMatchingNotification consumes one reference.
46 dictionary = (CFMutableDictionaryRef)(CFRetain(dictionary));
Avi (use Gerrit) 2012/08/06 13:54:37 I already commented on this. Why do you feel you n
no longer working on chromium 2012/08/06 19:53:12 I should have removed it from the previous set of
47
48 io_iterator_t devices_iterator = 0;
Avi (use Gerrit) 2012/08/06 13:54:37 The iterator itself needs to be a base::mac::Scope
no longer working on chromium 2012/08/06 19:53:12 Thanks for pointing out, this does leak. I have to
49 kern_return_t err = IOServiceAddMatchingNotification(port,
50 type,
51 dictionary,
52 callback,
53 context,
54 &devices_iterator);
55 if (err) {
56 NOTREACHED() << "Failed to register the IO mached notification for type "
Avi (use Gerrit) 2012/08/06 13:54:37 s/mached/matched/
no longer working on chromium 2012/08/06 19:53:12 Done.
57 << type;
58 return;
59 }
60
61 // Iterate over set of matching devices to access already-present devices
62 // and to arm the notification.
63 base::mac::ScopedIOObject<io_service_t> this_object(
64 IOIteratorNext(devices_iterator));
65 for (; this_object; this_object.reset(IOIteratorNext(devices_iterator)));
Avi (use Gerrit) 2012/08/06 13:54:37 Do we want to do something with the objects we're
no longer working on chromium 2012/08/06 19:53:12 My understanding here is simply loop through the e
Avi (use Gerrit) 2012/08/06 20:29:47 Do we need to fire a first-time changed callback?
no longer working on chromium 2012/08/06 22:01:10 This for loop does the same as calling a first-tim
66 }
67
68 void RegisterCallbacks(IONotificationPortRef port,
69 CFMutableDictionaryRef dictionary,
70 IOServiceMatchingCallback callback,
71 void* context) {
72 // Add a callback which will be called when a video device is plugged in.
73 AddCallbackToIOService(port,
74 kIOMatchedNotification,
75 dictionary,
76 callback,
77 context);
78
79 // Add a callback which will be called when a video device is terminated.
80 AddCallbackToIOService(port,
81 kIOTerminatedNotification,
82 dictionary,
83 callback,
84 context);
85 }
86
87 } // namespace
88
89 DeviceMonitorMac::DeviceMonitorMac() {
90 CFRunLoopRef runloop = CFRunLoopGetCurrent();
91 CFRetain(runloop);
Avi (use Gerrit) 2012/08/06 13:54:37 Why are you retaining this? Please address my earl
no longer working on chromium 2012/08/06 19:53:12 This should have been removed too. Sorry.
92
93 // Add the notification port to the run loop.
94 notification_port_ = IONotificationPortCreate(kIOMasterPortDefault);
95 DCHECK(notification_port_);
96 CFRunLoopSourceRef notification_cfsource =
97 IONotificationPortGetRunLoopSource(notification_port_);
98
99 RegisterVideoCallbacks();
100 RegisterAudioCallbacks();
101 CFRunLoopAddSource(runloop, notification_cfsource, kCFRunLoopCommonModes);
102 }
103
104 DeviceMonitorMac::~DeviceMonitorMac() {
105 // Remove the sleep notification port from the application runloop.
106 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
107 IONotificationPortGetRunLoopSource(notification_port_),
108 kCFRunLoopCommonModes);
109
110 // Destroy the notification port allocated by IONotificationPortCreate.
111 IONotificationPortDestroy(notification_port_);
112 }
113
114 void DeviceMonitorMac::RegisterVideoCallbacks() {
115 CFMutableDictionaryRef matching_dictionary = CreateMatchingDictionary(
116 kUSBVideoInterfaceClass, kUSBVideoControlSubClass);
117
118 RegisterCallbacks(notification_port_,
119 matching_dictionary,
120 &VideoDeviceChangedCallback,
121 this);
122 }
123
124 void DeviceMonitorMac::RegisterAudioCallbacks() {
125 CFMutableDictionaryRef matching_dictionary = CreateMatchingDictionary(
126 kUSBAudioInterfaceClass, kUSBAudioControlSubClass);
127
128 RegisterCallbacks(notification_port_,
129 matching_dictionary,
130 &AudioDeviceChangedCallback,
131 this);
132 }
133
134 void DeviceMonitorMac::VideoDeviceChangedCallback(void *context,
135 io_iterator_t devices) {
136 base::mac::ScopedIOObject<io_service_t> this_object(IOIteratorNext(devices));
137 for (; this_object; this_object.reset(IOIteratorNext(devices))) {
138 if (context) {
139 reinterpret_cast<DeviceMonitorMac*>(context)->NotifyDeviceChanged(
140 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
141 }
142 IOObjectRelease(this_object);
Avi (use Gerrit) 2012/08/06 13:54:37 Wha? No, the ScopedIOObject releases.
no longer working on chromium 2012/08/06 19:53:12 Done.
143 }
144 }
145
146 void DeviceMonitorMac::AudioDeviceChangedCallback(void *context,
147 io_iterator_t devices) {
148 base::mac::ScopedIOObject<io_service_t> this_object(IOIteratorNext(devices));
149 for (; this_object; this_object.reset(IOIteratorNext(devices))) {
150 if (context) {
151 reinterpret_cast<DeviceMonitorMac*>(context)->NotifyDeviceChanged(
152 base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
153 }
154 IOObjectRelease(this_object);
Avi (use Gerrit) 2012/08/06 13:54:37 Ditto.
no longer working on chromium 2012/08/06 19:53:12 Done.
155 }
156 }
157
158 void DeviceMonitorMac::NotifyDeviceChanged(
159 base::SystemMonitor::DeviceType type) {
160 base::SystemMonitor::Get()->ProcessDevicesChanged(type);
161 }
162
163 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698