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

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 avi's comments and wei'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
« 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.
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 &notification_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
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