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

Side by Side Diff: chrome/browser/system_monitor/removable_device_notifications_mac.mm

Issue 10919185: Implement RemovableDeviceNotifications for Mac (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address review comments Created 8 years, 3 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
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 "chrome/browser/system_monitor/removable_device_notifications_mac.h"
6
7 #include "content/public/browser/browser_thread.h"
8
9 namespace chrome {
10
11 namespace {
12
13 void GetDiskInfoAndUpdateOnFileThread(
14 const base::WeakPtr<RemovableDeviceNotificationsMac>& notifications,
15 base::mac::ScopedCFTypeRef<CFDictionaryRef> dict,
16 RemovableDeviceNotificationsMac::UpdateType update_type) {
17 DiskInfoMac info = DiskInfoMac::BuildDiskInfoOnFileThread(dict);
18 if (info.device_id().empty())
19 return;
20
21 content::BrowserThread::PostTask(
22 content::BrowserThread::UI,
23 FROM_HERE,
24 base::Bind(&RemovableDeviceNotificationsMac::UpdateDisk,
25 notifications,
26 info,
27 update_type));
28 }
29
30 void GetDiskInfoAndUpdate(
31 const base::WeakPtr<RemovableDeviceNotificationsMac>& notifications,
32 DADiskRef disk,
33 RemovableDeviceNotificationsMac::UpdateType update_type) {
34 base::mac::ScopedCFTypeRef<CFDictionaryRef> dict(DADiskCopyDescription(disk));
35 content::BrowserThread::PostTask(
36 content::BrowserThread::FILE,
37 FROM_HERE,
38 base::Bind(GetDiskInfoAndUpdateOnFileThread,
39 notifications,
40 dict,
41 update_type));
42 }
43
44 } // namespace
45
46 RemovableDeviceNotificationsMac::RemovableDeviceNotificationsMac() {
47 session_.reset(DASessionCreate(NULL));
48 DASessionScheduleWithRunLoop(
49 session_, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
50
51 // Register for callbacks for attached, changed, and removed devices.
52 // This will send notifications for existing devices too.
53 DARegisterDiskAppearedCallback(
54 session_,
55 kDADiskDescriptionMatchVolumeMountable,
56 DiskAppearedCallback,
57 this);
58 DARegisterDiskDisappearedCallback(
59 session_,
60 kDADiskDescriptionMatchVolumeMountable,
61 DiskDisappearedCallback,
62 this);
63 DARegisterDiskDescriptionChangedCallback(
64 session_,
65 kDADiskDescriptionMatchVolumeMountable,
66 kDADiskDescriptionWatchVolumePath,
67 DiskDescriptionChangedCallback,
68 this);
69 }
70
71 RemovableDeviceNotificationsMac::~RemovableDeviceNotificationsMac() {
72 DASessionUnscheduleFromRunLoop(
73 session_, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
74 }
75
76 void RemovableDeviceNotificationsMac::UpdateDisk(
77 const DiskInfoMac& info,
78 UpdateType update_type) {
79 if (info.bsd_name().empty())
80 return;
81
82 std::map<std::string, DiskInfoMac>::iterator it =
83 disk_info_map_.find(info.bsd_name());
84 if (it != disk_info_map_.end()) {
85 if (ShouldPostNotificationForDisk(it->second)) {
vandebo (ex-Chrome) 2012/09/11 17:08:17 nit: DCHECK(update_type == UPDATE_DEVICE_REMOVED |
sail 2012/09/12 20:56:32 Done. Added comment explaining that this for remov
86 base::SystemMonitor::Get()->ProcessRemovableStorageDetached(
87 it->second.device_id());
88 }
89 }
90
91 if (update_type == UPDATE_DEVICE_REMOVED) {
92 if (it != disk_info_map_.end())
93 disk_info_map_.erase(it);
94 } else {
95 disk_info_map_[info.bsd_name()] = info;
96 if (ShouldPostNotificationForDisk(info)) {
97 base::SystemMonitor::Get()->ProcessRemovableStorageAttached(
98 info.device_id(), info.display_name(), info.mount_point().value());
99 }
100 }
101 }
102
103 bool RemovableDeviceNotificationsMac::GetDeviceInfoForPath(
104 const FilePath& path,
105 base::SystemMonitor::RemovableStorageInfo* device_info) const {
106 if (!path.IsAbsolute())
107 return false;
108
109 FilePath current = path;
110 const FilePath root(FilePath::kSeparators);
111 while (current != root) {
112 DiskInfoMac info;
113 if (FindDiskWithMountPoint(current, &info)) {
114 device_info->device_id = info.device_id();
115 device_info->name = info.display_name();
116 device_info->location = info.mount_point().value();
117 return true;
118 }
119 current = current.DirName();
120 }
121
122 return false;
123 }
124
125 // static
126 void RemovableDeviceNotificationsMac::DiskAppearedCallback(
127 DADiskRef disk,
128 void* context) {
129 RemovableDeviceNotificationsMac* notifications =
130 static_cast<RemovableDeviceNotificationsMac*>(context);
131 GetDiskInfoAndUpdate(notifications->AsWeakPtr(),
132 disk,
133 UPDATE_DEVICE_ADDED);
134 }
135
136 // static
137 void RemovableDeviceNotificationsMac::DiskDisappearedCallback(
138 DADiskRef disk,
139 void* context) {
140 RemovableDeviceNotificationsMac* notifications =
141 static_cast<RemovableDeviceNotificationsMac*>(context);
142 GetDiskInfoAndUpdate(notifications->AsWeakPtr(),
143 disk,
144 UPDATE_DEVICE_REMOVED);
145 }
146
147 // static
148 void RemovableDeviceNotificationsMac::DiskDescriptionChangedCallback(
149 DADiskRef disk,
150 CFArrayRef keys,
151 void *context) {
152 RemovableDeviceNotificationsMac* notifications =
153 static_cast<RemovableDeviceNotificationsMac*>(context);
154 GetDiskInfoAndUpdate(notifications->AsWeakPtr(),
155 disk,
156 UPDATE_DEVICE_CHANGED);
157 }
158
159 bool RemovableDeviceNotificationsMac::ShouldPostNotificationForDisk(
160 const DiskInfoMac& info) const {
161 // Only post notifications about disks that have no empty fields and
162 // are removable.
163 return !info.bsd_name().empty() &&
164 !info.device_id().empty() &&
165 !info.display_name().empty() &&
166 !info.mount_point().empty() &&
167 (info.type() == MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM ||
168 info.type() == MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM);
169 }
170
171 bool RemovableDeviceNotificationsMac::FindDiskWithMountPoint(
172 const FilePath& mount_point,
173 DiskInfoMac* info) const {
174 for (std::map<std::string, DiskInfoMac>::const_iterator
175 it = disk_info_map_.begin(); it != disk_info_map_.end(); ++it) {
176 if (it->second.mount_point() == mount_point) {
177 *info = it->second;
178 return true;
179 }
180 }
181 return false;
182 }
183
184 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698