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

Unified Diff: base/system_monitor/system_monitor_mac.mm

Issue 9363008: Add Media device notification to SystemMonitor and Mac impl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 8 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: base/system_monitor/system_monitor_mac.mm
diff --git a/base/system_monitor/system_monitor_mac.mm b/base/system_monitor/system_monitor_mac.mm
index baaadf052db913eb7f3c548f81c545901f6192e8..f9a92cc911208b11cceff20040633e92636d7e60 100644
--- a/base/system_monitor/system_monitor_mac.mm
+++ b/base/system_monitor/system_monitor_mac.mm
@@ -7,9 +7,14 @@
#include "base/system_monitor/system_monitor.h"
+#include <Carbon/Carbon.h>
+#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
+#include "base/mac/foundation_util.h"
+#include "base/sys_string_conversions.h"
+
namespace base {
namespace {
@@ -37,6 +42,73 @@ void SystemPowerEventCallback(void*,
}
}
+bool GetDeviceInfo(unsigned long device_number, std::string* name,
+ FilePath* location) {
+ ICACopyObjectPropertyDictionaryPB properties_request;
+ properties_request.object = device_number;
+ CFDictionaryRef device_properties;
+ properties_request.theDict = &device_properties;
+ OSErr ret = ICACopyObjectPropertyDictionary(&properties_request, NULL);
+ CHECK_EQ(ret, noErr);
+
+ // For now, we only support mass storage media devices.
+ CFStringRef volume = mac::GetValueFromDictionary<CFStringRef>(
+ device_properties, CFSTR("volume"));
+ if (volume == NULL) {
+ CFRelease(device_properties);
+ return false;
+ }
+ *location = FilePath("/Volumes/").Append(SysCFStringRefToUTF8(volume));
+
+ CFStringRef device_name = mac::GetValueFromDictionary<CFStringRef>(
+ device_properties, CFSTR("ICAUserAssignedDeviceNameKey"));
+ if (device_name == NULL) {
+ device_name = mac::GetValueFromDictionary<CFStringRef>(
+ device_properties, CFSTR("ifil"));
+ }
+ if (device_name == NULL) {
+ CFRelease(device_properties);
+ return false;
+ }
+ *name = SysCFStringRefToUTF8(device_name);
+
+ CFRelease(device_properties);
+ return true;
+}
+
+void MediaDeviceNotificationCallback(CFStringRef notification_type,
+ CFDictionaryRef notification_dictionary) {
+ bool attach = false;
+ if (CFStringCompare(notification_type, kICANotificationTypeDeviceAdded, 0) ==
+ kCFCompareEqualTo) {
+ attach = true;
+ } else if (CFStringCompare(notification_type,
+ kICANotificationTypeDeviceRemoved, 0) !=
+ kCFCompareEqualTo) {
+ return;
+ }
+ CFNumberRef refcon_object = mac::GetValueFromDictionary<CFNumberRef>(
+ notification_dictionary, kICARefconKey);
+ unsigned long refcon;
+ CFNumberGetValue(refcon_object, kCFNumberLongType, &refcon);
+ SystemMonitor* system_monitor = reinterpret_cast<SystemMonitor*>(refcon);
+
+ CFNumberRef device_number_object = mac::GetValueFromDictionary<CFNumberRef>(
+ notification_dictionary, kICANotificationDeviceICAObjectKey);
+ unsigned long device_number;
+ CFNumberGetValue(device_number_object, kCFNumberIntType, &device_number);
+ if (attach) {
+ std::string device_name;
+ FilePath location;
+ if (GetDeviceInfo(device_number, &device_name, &location)) {
+ system_monitor->ProcessMediaDeviceAttached(device_number, device_name,
+ location);
+ }
+ } else {
+ system_monitor->ProcessMediaDeviceDetached(device_number);
+ }
+}
+
} // namespace
// The reason we can't include this code in the constructor is because
@@ -69,6 +141,20 @@ void SystemMonitor::PlatformInit() {
CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(g_notification_port_ref),
kCFRunLoopCommonModes);
+
+ ICARegisterForEventNotificationPB notification_request;
+ notification_request.header.refcon = reinterpret_cast<unsigned long>(this);
+ notification_request.objectOfInterest = 0; // Zero means all objects
+ CFStringRef events_of_interest_array[] = {kICANotificationTypeDeviceAdded,
+ kICANotificationTypeDeviceRemoved};
+ CFArrayRef events_of_interest =
+ CFArrayCreate(NULL, (const void**)&events_of_interest_array, 2,
+ &kCFTypeArrayCallBacks);
+ notification_request.eventsOfInterest = events_of_interest;
+ notification_request.notificationProc = &MediaDeviceNotificationCallback;
+ notification_request.options = NULL;
+ OSErr err = ICARegisterForEventNotification(&notification_request, NULL);
+ CHECK_EQ(err, noErr);
}
void SystemMonitor::PlatformDestroy() {

Powered by Google App Engine
This is Rietveld 408576698