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

Side by Side Diff: content/browser/mac/media_device_notifications.mm

Issue 9363008: Add Media device notification to SystemMonitor and Mac impl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Type Created 8 years, 9 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/mac/media_device_notifications.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/mac/media_device_notifications.h"
6
7 #include <Carbon/Carbon.h>
8 #include <CoreFoundation/CoreFoundation.h>
9
10 #include "base/file_path.h"
11 #include "base/mac/foundation_util.h"
12 #include "base/mac/scoped_cftyperef.h"
13 #include "base/sys_string_conversions.h"
14 #include "base/system_monitor/system_monitor.h"
15
16 namespace content {
17
18 namespace {
19
20 const CFStringRef kICAUserAssignedDeviceNameKey =
21 CFSTR("ICAUserAssignedDeviceNameKey");
22 const CFStringRef kICDeviceNameKey = CFSTR("ifil");
23 const CFStringRef kICDeviceBSDNameKey = CFSTR("bsdName");
24
25 CFStringRef CopyMountPointFromBSDName(CFStringRef bsd_name) {
26 base::mac::ScopedCFTypeRef<DASessionRef> session(
27 DASessionCreate(kCFAllocatorDefault));
28 if (!session.get())
29 return NULL;
30
31 base::mac::ScopedCFTypeRef<DADiskRef> disk(
32 DADiskCreateFromBSDName(kCFAllocatorDefault, session.get(),
33 base::SysCFStringRefToUTF8(bsd_name).c_str()));
34 if (!disk.get())
35 return NULL;
36
37 base::mac::ScopedCFTypeRef<CFDictionaryRef> description(
38 DADiskCopyDescription(disk));
39 if (!description.get())
40 return NULL;
41
42 CFURLRef mount_point = base::mac::GetValueFromDictionary<CFURLRef>(
43 description, kDADiskDescriptionVolumePathKey);
44 if (!mount_point)
45 return NULL;
46
47 return CFURLCopyFileSystemPath(mount_point, kCFURLPOSIXPathStyle);
48 }
49
50 bool GetDeviceInfo(unsigned long device_number, std::string* name,
51 FilePath* location) {
52 ICACopyObjectPropertyDictionaryPB properties_request;
53 properties_request.object = device_number;
54 CFDictionaryRef device_properties;
55 properties_request.theDict = &device_properties;
56 if (ICACopyObjectPropertyDictionary(&properties_request, NULL) != noErr)
57 return false;
58 base::mac::ScopedCFTypeRef<CFDictionaryRef> scoped_device_properties(
59 device_properties);
60
61 CFStringRef device_name = base::mac::GetValueFromDictionary<CFStringRef>(
62 device_properties, kICAUserAssignedDeviceNameKey);
63 if (device_name == NULL) {
64 device_name = base::mac::GetValueFromDictionary<CFStringRef>(
65 device_properties, kICDeviceNameKey);
66 }
67 if (device_name == NULL)
68 return false;
69 *name = base::SysCFStringRefToUTF8(device_name);
70
71 // TODO(vandebo) Support all media device, for now we only support mass
72 // storage media devices.
73 CFStringRef device = base::mac::GetValueFromDictionary<CFStringRef>(
74 device_properties, kICDeviceBSDNameKey);
75 if (device == NULL)
76 return false;
77 base::mac::ScopedCFTypeRef<CFStringRef>
78 path(CopyMountPointFromBSDName(device));
79 if (path.get() == NULL)
80 return false;
81
82 *location = FilePath(base::SysCFStringRefToUTF8(path).c_str());
83
84 return true;
85 }
86
87 void MediaDeviceNotificationCallback(CFStringRef notification_type,
88 CFDictionaryRef notification_dictionary) {
89 bool attach = false;
90 if (CFEqual(notification_type, kICANotificationTypeDeviceAdded)) {
91 attach = true;
92 } else if (!CFEqual(notification_type, kICANotificationTypeDeviceRemoved)) {
93 return;
94 }
95
96 base::SystemMonitor* system_monitor = base::SystemMonitor::Get();
97
98 CFNumberRef device_number_object =
99 base::mac::GetValueFromDictionary<CFNumberRef>(
100 notification_dictionary, kICANotificationDeviceICAObjectKey);
101 unsigned long device_number =
102 [base::mac::CFToNSCast(device_number_object) unsignedLongValue];
103 if (attach) {
104 std::string device_name;
105 FilePath location;
106 if (GetDeviceInfo(device_number, &device_name, &location)) {
107 system_monitor->ProcessMediaDeviceAttached(device_number, device_name,
108 location);
109 }
110 } else {
111 system_monitor->ProcessMediaDeviceDetached(device_number);
112 }
113 }
114
115 } // namespace
116
117 void StartMediaDeviceNotifications() {
118 NSArray* events_of_interest = [NSArray arrayWithObjects:
119 (id)kICANotificationTypeDeviceAdded,
120 (id)kICANotificationTypeDeviceRemoved,
121 nil];
122
123 ICARegisterForEventNotificationPB notification_request;
124 notification_request.objectOfInterest = 0; // Zero means all objects
125 notification_request.eventsOfInterest =
126 base::mac::NSToCFCast(events_of_interest);
127 notification_request.notificationProc = &MediaDeviceNotificationCallback;
128 notification_request.options = NULL;
129 OSErr err = ICARegisterForEventNotification(&notification_request, NULL);
130 CHECK_EQ(err, noErr);
131 }
132
133 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/mac/media_device_notifications.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698