Chromium Code Reviews| Index: chrome/browser/system_monitor/removable_device_notifications_mac.mm |
| diff --git a/chrome/browser/system_monitor/removable_device_notifications_mac.mm b/chrome/browser/system_monitor/removable_device_notifications_mac.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b1595803df24b903ab2f511b67e84ef1842def72 |
| --- /dev/null |
| +++ b/chrome/browser/system_monitor/removable_device_notifications_mac.mm |
| @@ -0,0 +1,150 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/system_monitor/removable_device_notifications_mac.h" |
| + |
| +#include "base/system_monitor/system_monitor.h" |
| +#include "content/public/browser/browser_thread.h" |
| + |
| +namespace chrome { |
| + |
| +namespace { |
| + |
| +void GetDiskInfoAndUpdateOnFileThread( |
| + const base::WeakPtr<RemovableDeviceNotificationsMac>& notifications, |
| + base::mac::ScopedCFTypeRef<CFDictionaryRef> dict, |
| + RemovableDeviceNotificationsMac::UpdateAction update_action) { |
| + DiskInfoMac info = DiskInfoMac::BuildDiskInfoOnFileThread(dict); |
| + if (info.device_id().empty()) |
| + return; |
| + |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&RemovableDeviceNotificationsMac::UpdateDisk, |
| + notifications, |
| + info, |
| + update_action)); |
| +} |
| + |
| +void GetDiskInfoAndUpdate( |
| + const base::WeakPtr<RemovableDeviceNotificationsMac>& notifications, |
| + DADiskRef disk, |
| + RemovableDeviceNotificationsMac::UpdateAction update_action) { |
| + base::mac::ScopedCFTypeRef<CFDictionaryRef> dict(DADiskCopyDescription(disk)); |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::FILE, |
| + FROM_HERE, |
| + base::Bind(GetDiskInfoAndUpdateOnFileThread, |
| + notifications, |
| + dict, |
| + update_action)); |
| +} |
| + |
| +} // namespace |
| + |
| +RemovableDeviceNotificationsMac::RemovableDeviceNotificationsMac() { |
| + session_.reset(DASessionCreate(NULL)); |
| + DASessionScheduleWithRunLoop( |
| + session_, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); |
| + |
| + // Register for callbacks for attached, changed, and removed devices. |
| + // This will send notifications for existing devices too. |
| + DARegisterDiskAppearedCallback( |
| + session_, |
| + kDADiskDescriptionMatchVolumeMountable, |
| + DiskAppearedCallback, |
| + this); |
| + DARegisterDiskDisappearedCallback( |
| + session_, |
| + kDADiskDescriptionMatchVolumeMountable, |
| + DiskDisappearedCallback, |
| + this); |
| + DARegisterDiskDescriptionChangedCallback( |
| + session_, |
| + kDADiskDescriptionMatchVolumeMountable, |
| + kDADiskDescriptionWatchVolumePath, |
| + DiskDescriptionChangedCallback, |
| + this); |
| +} |
| + |
| +RemovableDeviceNotificationsMac::~RemovableDeviceNotificationsMac() { |
| + DASessionUnscheduleFromRunLoop( |
| + session_, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); |
| +} |
| + |
| +void RemovableDeviceNotificationsMac::UpdateDisk( |
| + const DiskInfoMac& info, |
| + UpdateAction update_action) { |
| + if (info.bsd_name().empty()) |
| + return; |
| + |
| + std::map<std::string, DiskInfoMac>::iterator it = |
| + disk_info_map_.find(info.bsd_name()); |
| + if (it != disk_info_map_.end()) { |
| + if (ShouldPostNotificationForDisk(it->second)) { |
|
vandebo (ex-Chrome)
2012/09/11 00:45:50
Should we check to see that one of the properties
sail
2012/09/11 03:02:00
Currently the DescriptionChanged event is fired fo
|
| + base::SystemMonitor::Get()->ProcessRemovableStorageDetached( |
| + it->second.device_id()); |
| + } |
| + } |
| + |
| + if (update_action == UPDATE_SHOULD_REMOVE) { |
| + if (it != disk_info_map_.end()) |
| + disk_info_map_.erase(it); |
| + } else { |
| + disk_info_map_[info.bsd_name()] = info; |
| + if (ShouldPostNotificationForDisk(info)) { |
| + base::SystemMonitor::Get()->ProcessRemovableStorageAttached( |
| + info.device_id(), info.display_name(), info.mount_point().value()); |
| + } |
| + } |
| +} |
| + |
| +// static |
| +void RemovableDeviceNotificationsMac::DiskAppearedCallback( |
| + DADiskRef disk, |
| + void* context) { |
| + RemovableDeviceNotificationsMac* notifications = |
| + static_cast<RemovableDeviceNotificationsMac*>(context); |
| + GetDiskInfoAndUpdate(notifications->AsWeakPtr(), |
| + disk, |
| + UPDATE_SHOULD_NOT_REMOVE); |
| +} |
| + |
| +// static |
| +void RemovableDeviceNotificationsMac::DiskDisappearedCallback( |
| + DADiskRef disk, |
| + void* context) { |
| + RemovableDeviceNotificationsMac* notifications = |
| + static_cast<RemovableDeviceNotificationsMac*>(context); |
| + GetDiskInfoAndUpdate(notifications->AsWeakPtr(), |
| + disk, |
| + UPDATE_SHOULD_REMOVE); |
| +} |
| + |
| +// static |
| +void RemovableDeviceNotificationsMac::DiskDescriptionChangedCallback( |
| + DADiskRef disk, |
| + CFArrayRef keys, |
| + void *context) { |
| + RemovableDeviceNotificationsMac* notifications = |
| + static_cast<RemovableDeviceNotificationsMac*>(context); |
| + GetDiskInfoAndUpdate(notifications->AsWeakPtr(), |
| + disk, |
| + UPDATE_SHOULD_NOT_REMOVE); |
|
vandebo (ex-Chrome)
2012/09/11 00:45:50
Since you're using an enum, it might make things c
sail
2012/09/11 03:02:00
Done.
|
| +} |
| + |
| +bool RemovableDeviceNotificationsMac::ShouldPostNotificationForDisk( |
| + const DiskInfoMac& info) const { |
| + // Only post notifications about disks that have no empty fields and |
| + // are removable. |
| + return !info.bsd_name().empty() && |
| + !info.device_id().empty() && |
| + !info.display_name().empty() && |
| + !info.mount_point().empty() && |
| + (info.type() == MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM || |
| + info.type() == MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM); |
| +} |
| + |
| +} // namespace chrome |