OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // MediaDeviceNotificationsLinux implementation. | 5 // MediaDeviceNotificationsLinux implementation. |
6 | 6 |
7 #include "chrome/browser/media_gallery/media_device_notifications_linux.h" | 7 #include "chrome/browser/media_gallery/media_device_notifications_linux.h" |
8 | 8 |
9 #include <mntent.h> | 9 #include <mntent.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 | 11 |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/file_path.h" | 15 #include "base/file_path.h" |
| 16 #include "base/stl_util.h" |
| 17 #include "base/string_number_conversions.h" |
16 #include "base/system_monitor/system_monitor.h" | 18 #include "base/system_monitor/system_monitor.h" |
| 19 #include "base/utf_string_conversions.h" |
17 #include "chrome/browser/media_gallery/media_device_notifications_utils.h" | 20 #include "chrome/browser/media_gallery/media_device_notifications_utils.h" |
18 | 21 |
19 namespace { | 22 namespace { |
20 | 23 |
21 // List of file systems we care about. | 24 // List of file systems we care about. |
22 const char* const kKnownFileSystems[] = { | 25 const char* const kKnownFileSystems[] = { |
23 "ext2", | 26 "ext2", |
24 "ext3", | 27 "ext3", |
25 "ext4", | 28 "ext4", |
26 "fat", | 29 "fat", |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 106 |
104 MountMap new_mtab; | 107 MountMap new_mtab; |
105 ReadMtab(&new_mtab); | 108 ReadMtab(&new_mtab); |
106 | 109 |
107 // Check existing mtab entries for unaccounted mount points. | 110 // Check existing mtab entries for unaccounted mount points. |
108 // These mount points must have been removed in the new mtab. | 111 // These mount points must have been removed in the new mtab. |
109 std::vector<std::string> mount_points_to_erase; | 112 std::vector<std::string> mount_points_to_erase; |
110 for (MountMap::const_iterator it = mtab_.begin(); it != mtab_.end(); ++it) { | 113 for (MountMap::const_iterator it = mtab_.begin(); it != mtab_.end(); ++it) { |
111 const std::string& mount_point = it->first; | 114 const std::string& mount_point = it->first; |
112 // |mount_point| not in |new_mtab|. | 115 // |mount_point| not in |new_mtab|. |
113 if (new_mtab.find(mount_point) == new_mtab.end()) { | 116 if (!ContainsKey(new_mtab, mount_point)) { |
114 const SystemMonitor::DeviceIdType& device_id = it->second.second; | 117 const std::string& device_id = it->second.second; |
115 RemoveOldDevice(device_id); | 118 RemoveOldDevice(device_id); |
116 mount_points_to_erase.push_back(mount_point); | 119 mount_points_to_erase.push_back(mount_point); |
117 } | 120 } |
118 } | 121 } |
119 // Erase the |mtab_| entries afterwards. Erasing in the loop above using the | 122 // Erase the |mtab_| entries afterwards. Erasing in the loop above using the |
120 // iterator is slightly more efficient, but more tricky, since calling | 123 // iterator is slightly more efficient, but more tricky, since calling |
121 // std::map::erase() on an iterator invalidates it. | 124 // std::map::erase() on an iterator invalidates it. |
122 for (size_t i = 0; i < mount_points_to_erase.size(); ++i) | 125 for (size_t i = 0; i < mount_points_to_erase.size(); ++i) |
123 mtab_.erase(mount_points_to_erase[i]); | 126 mtab_.erase(mount_points_to_erase[i]); |
124 | 127 |
125 // Check new mtab entries against existing ones. | 128 // Check new mtab entries against existing ones. |
126 for (MountMap::iterator newiter = new_mtab.begin(); | 129 for (MountMap::iterator newiter = new_mtab.begin(); |
127 newiter != new_mtab.end(); | 130 newiter != new_mtab.end(); |
128 ++newiter) { | 131 ++newiter) { |
129 const std::string& mount_point = newiter->first; | 132 const std::string& mount_point = newiter->first; |
130 const MountDeviceAndId& mount_device_and_id = newiter->second; | 133 const MountDeviceAndId& mount_device_and_id = newiter->second; |
131 const std::string& mount_device = mount_device_and_id.first; | 134 const std::string& mount_device = mount_device_and_id.first; |
132 SystemMonitor::DeviceIdType& id = newiter->second.second; | 135 std::string& id = newiter->second.second; |
133 MountMap::iterator olditer = mtab_.find(mount_point); | 136 MountMap::iterator olditer = mtab_.find(mount_point); |
134 // Check to see if it is a new mount point. | 137 // Check to see if it is a new mount point. |
135 if (olditer == mtab_.end()) { | 138 if (olditer == mtab_.end()) { |
136 if (IsMediaDevice(mount_point)) { | 139 if (IsMediaDevice(mount_point)) { |
137 AddNewDevice(mount_device, mount_point, &id); | 140 AddNewDevice(mount_device, mount_point, &id); |
138 mtab_.insert(std::make_pair(mount_point, mount_device_and_id)); | 141 mtab_.insert(std::make_pair(mount_point, mount_device_and_id)); |
139 } | 142 } |
140 continue; | 143 continue; |
141 } | 144 } |
142 | 145 |
(...skipping 12 matching lines...) Expand all Loading... |
155 } | 158 } |
156 | 159 |
157 void MediaDeviceNotificationsLinux::ReadMtab(MountMap* mtab) { | 160 void MediaDeviceNotificationsLinux::ReadMtab(MountMap* mtab) { |
158 FILE* fp = setmntent(mtab_path_.value().c_str(), "r"); | 161 FILE* fp = setmntent(mtab_path_.value().c_str(), "r"); |
159 if (!fp) | 162 if (!fp) |
160 return; | 163 return; |
161 | 164 |
162 MountMap& new_mtab = *mtab; | 165 MountMap& new_mtab = *mtab; |
163 mntent entry; | 166 mntent entry; |
164 char buf[512]; | 167 char buf[512]; |
165 SystemMonitor::DeviceIdType mount_position = 0; | 168 int mount_position = 0; |
166 typedef std::pair<std::string, SystemMonitor::DeviceIdType> MountPointAndId; | 169 typedef std::pair<std::string, std::string> MountPointAndId; |
167 typedef std::map<std::string, MountPointAndId> DeviceMap; | 170 typedef std::map<std::string, MountPointAndId> DeviceMap; |
168 DeviceMap device_map; | 171 DeviceMap device_map; |
169 while (getmntent_r(fp, &entry, buf, sizeof(buf))) { | 172 while (getmntent_r(fp, &entry, buf, sizeof(buf))) { |
170 // We only care about real file systems. | 173 // We only care about real file systems. |
171 if (known_file_systems_.find(entry.mnt_type) == known_file_systems_.end()) | 174 if (!ContainsKey(known_file_systems_, entry.mnt_type)) |
172 continue; | 175 continue; |
173 // Add entries, but overwrite entries for the same mount device. Keep track | 176 // Add entries, but overwrite entries for the same mount device. Keep track |
174 // of the entry positions in the device id field and use that below to | 177 // of the entry positions in the device id field and use that below to |
175 // resolve multiple devices mounted at the same mount point. | 178 // resolve multiple devices mounted at the same mount point. |
176 MountPointAndId mount_point_and_id = | 179 MountPointAndId mount_point_and_id = |
177 std::make_pair(entry.mnt_dir, mount_position++); | 180 std::make_pair(entry.mnt_dir, base::IntToString(mount_position++)); |
178 DeviceMap::iterator it = device_map.find(entry.mnt_fsname); | 181 DeviceMap::iterator it = device_map.find(entry.mnt_fsname); |
179 if (it == device_map.end()) { | 182 if (it == device_map.end()) { |
180 device_map.insert(it, | 183 device_map.insert(std::make_pair(entry.mnt_fsname, mount_point_and_id)); |
181 std::make_pair(entry.mnt_fsname, mount_point_and_id)); | |
182 } else { | 184 } else { |
183 it->second = mount_point_and_id; | 185 it->second = mount_point_and_id; |
184 } | 186 } |
185 } | 187 } |
186 endmntent(fp); | 188 endmntent(fp); |
187 | 189 |
188 for (DeviceMap::const_iterator device_it = device_map.begin(); | 190 for (DeviceMap::const_iterator device_it = device_map.begin(); |
189 device_it != device_map.end(); | 191 device_it != device_map.end(); |
190 ++device_it) { | 192 ++device_it) { |
191 const std::string& device = device_it->first; | 193 const std::string& device = device_it->first; |
192 const std::string& mount_point = device_it->second.first; | 194 const std::string& mount_point = device_it->second.first; |
193 const SystemMonitor::DeviceIdType& position = device_it->second.second; | 195 const std::string& position = device_it->second.second; |
194 | 196 |
195 // No device at |mount_point|, save |device| to it. | 197 // No device at |mount_point|, save |device| to it. |
196 MountMap::iterator mount_it = new_mtab.find(mount_point); | 198 MountMap::iterator mount_it = new_mtab.find(mount_point); |
197 if (mount_it == new_mtab.end()) { | 199 if (mount_it == new_mtab.end()) { |
198 new_mtab.insert(std::make_pair(mount_point, | 200 new_mtab.insert(std::make_pair(mount_point, |
199 std::make_pair(device, position))); | 201 std::make_pair(device, position))); |
200 continue; | 202 continue; |
201 } | 203 } |
202 | 204 |
203 // There is already a device mounted at |mount_point|. Check to see if | 205 // There is already a device mounted at |mount_point|. Check to see if |
204 // the existing mount entry is newer than the current one. | 206 // the existing mount entry is newer than the current one. |
205 std::string& existing_device = mount_it->second.first; | 207 std::string& existing_device = mount_it->second.first; |
206 SystemMonitor::DeviceIdType& existing_position = mount_it->second.second; | 208 std::string& existing_position = mount_it->second.second; |
207 if (existing_position > position) | 209 if (existing_position > position) |
208 continue; | 210 continue; |
209 | 211 |
210 // The current entry is newer, update the mount point entry. | 212 // The current entry is newer, update the mount point entry. |
211 existing_device = device; | 213 existing_device = device; |
212 existing_position = position; | 214 existing_position = position; |
213 } | 215 } |
214 } | 216 } |
215 | 217 |
216 void MediaDeviceNotificationsLinux::AddNewDevice( | 218 void MediaDeviceNotificationsLinux::AddNewDevice( |
217 const std::string& mount_device, | 219 const std::string& mount_device, |
218 const std::string& mount_point, | 220 const std::string& mount_point, |
219 base::SystemMonitor::DeviceIdType* device_id) { | 221 std::string* device_id) { |
220 *device_id = current_device_id_++; | 222 *device_id = base::IntToString(current_device_id_++); |
221 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | 223 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); |
222 system_monitor->ProcessMediaDeviceAttached(*device_id, | 224 system_monitor->ProcessMediaDeviceAttached(*device_id, |
223 mount_device, | 225 UTF8ToUTF16(mount_device), |
224 FilePath(mount_point)); | 226 SystemMonitor::TYPE_PATH, |
| 227 mount_point); |
225 } | 228 } |
226 | 229 |
227 void MediaDeviceNotificationsLinux::RemoveOldDevice( | 230 void MediaDeviceNotificationsLinux::RemoveOldDevice( |
228 const base::SystemMonitor::DeviceIdType& device_id) { | 231 const std::string& device_id) { |
229 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | 232 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); |
230 system_monitor->ProcessMediaDeviceDetached(device_id); | 233 system_monitor->ProcessMediaDeviceDetached(device_id); |
231 } | 234 } |
232 | 235 |
233 } // namespace chrome | 236 } // namespace chrome |
OLD | NEW |