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 // RemovableDeviceNotificationsLinux implementation. | 5 // StorageMonitorLinux implementation. |
6 | 6 |
7 #include "chrome/browser/storage_monitor/removable_device_notifications_linux.h" | 7 #include "chrome/browser/storage_monitor/storage_monitor_linux.h" |
8 | 8 |
9 #include <mntent.h> | 9 #include <mntent.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 | 11 |
12 #include <list> | 12 #include <list> |
13 | 13 |
14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 *removable = (value && atoi(value) == 1); | 217 *removable = (value && atoi(value) == 1); |
218 } | 218 } |
219 | 219 |
220 if (partition_size_in_bytes) | 220 if (partition_size_in_bytes) |
221 *partition_size_in_bytes = GetDeviceStorageSize(device_path, device); | 221 *partition_size_in_bytes = GetDeviceStorageSize(device_path, device); |
222 RecordGetDeviceInfoResult(true); | 222 RecordGetDeviceInfoResult(true); |
223 } | 223 } |
224 | 224 |
225 } // namespace | 225 } // namespace |
226 | 226 |
227 RemovableDeviceNotificationsLinux::RemovableDeviceNotificationsLinux( | 227 StorageMonitorLinux::StorageMonitorLinux(const base::FilePath& path) |
228 const base::FilePath& path) | |
229 : initialized_(false), | 228 : initialized_(false), |
230 mtab_path_(path), | 229 mtab_path_(path), |
231 get_device_info_func_(&GetDeviceInfo) { | 230 get_device_info_func_(&GetDeviceInfo) { |
232 } | 231 } |
233 | 232 |
234 RemovableDeviceNotificationsLinux::RemovableDeviceNotificationsLinux( | 233 StorageMonitorLinux::StorageMonitorLinux(const base::FilePath& path, |
235 const base::FilePath& path, | 234 GetDeviceInfoFunc get_device_info_func) |
236 GetDeviceInfoFunc get_device_info_func) | |
237 : initialized_(false), | 235 : initialized_(false), |
238 mtab_path_(path), | 236 mtab_path_(path), |
239 get_device_info_func_(get_device_info_func) { | 237 get_device_info_func_(get_device_info_func) { |
240 } | 238 } |
241 | 239 |
242 RemovableDeviceNotificationsLinux::~RemovableDeviceNotificationsLinux() { | 240 StorageMonitorLinux::~StorageMonitorLinux() { |
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
244 } | 242 } |
245 | 243 |
246 void RemovableDeviceNotificationsLinux::Init() { | 244 void StorageMonitorLinux::Init() { |
247 DCHECK(!mtab_path_.empty()); | 245 DCHECK(!mtab_path_.empty()); |
248 | 246 |
249 // Put |kKnownFileSystems| in std::set to get O(log N) access time. | 247 // Put |kKnownFileSystems| in std::set to get O(log N) access time. |
250 for (size_t i = 0; i < arraysize(kKnownFileSystems); ++i) | 248 for (size_t i = 0; i < arraysize(kKnownFileSystems); ++i) |
251 known_file_systems_.insert(kKnownFileSystems[i]); | 249 known_file_systems_.insert(kKnownFileSystems[i]); |
252 | 250 |
253 BrowserThread::PostTask( | 251 BrowserThread::PostTask( |
254 BrowserThread::FILE, FROM_HERE, | 252 BrowserThread::FILE, FROM_HERE, |
255 base::Bind(&RemovableDeviceNotificationsLinux::InitOnFileThread, this)); | 253 base::Bind(&StorageMonitorLinux::InitOnFileThread, this)); |
256 } | 254 } |
257 | 255 |
258 bool RemovableDeviceNotificationsLinux::GetStorageInfoForPath( | 256 bool StorageMonitorLinux::GetStorageInfoForPath( |
259 const base::FilePath& path, | 257 const base::FilePath& path, |
260 StorageInfo* device_info) const { | 258 StorageInfo* device_info) const { |
261 if (!path.IsAbsolute()) | 259 if (!path.IsAbsolute()) |
262 return false; | 260 return false; |
263 | 261 |
264 base::FilePath current = path; | 262 base::FilePath current = path; |
265 while (!ContainsKey(mount_info_map_, current) && current != current.DirName()) | 263 while (!ContainsKey(mount_info_map_, current) && current != current.DirName()) |
266 current = current.DirName(); | 264 current = current.DirName(); |
267 | 265 |
268 MountMap::const_iterator mount_info = mount_info_map_.find(current); | 266 MountMap::const_iterator mount_info = mount_info_map_.find(current); |
269 if (mount_info == mount_info_map_.end()) | 267 if (mount_info == mount_info_map_.end()) |
270 return false; | 268 return false; |
271 | 269 |
272 if (device_info) { | 270 if (device_info) { |
273 device_info->device_id = mount_info->second.device_id; | 271 device_info->device_id = mount_info->second.device_id; |
274 device_info->name = mount_info->second.device_name; | 272 device_info->name = mount_info->second.device_name; |
275 device_info->location = current.value(); | 273 device_info->location = current.value(); |
276 } | 274 } |
277 return true; | 275 return true; |
278 } | 276 } |
279 | 277 |
280 uint64 RemovableDeviceNotificationsLinux::GetStorageSize( | 278 uint64 StorageMonitorLinux::GetStorageSize(const std::string& location) const { |
281 const std::string& location) const { | |
282 MountMap::const_iterator mount_info = mount_info_map_.find( | 279 MountMap::const_iterator mount_info = mount_info_map_.find( |
283 base::FilePath(location)); | 280 base::FilePath(location)); |
284 return (mount_info != mount_info_map_.end()) ? | 281 return (mount_info != mount_info_map_.end()) ? |
285 mount_info->second.partition_size_in_bytes : 0; | 282 mount_info->second.partition_size_in_bytes : 0; |
286 } | 283 } |
287 | 284 |
288 void RemovableDeviceNotificationsLinux::OnFilePathChanged( | 285 void StorageMonitorLinux::OnFilePathChanged(const base::FilePath& path, |
289 const base::FilePath& path, | 286 bool error) { |
290 bool error) { | |
291 if (path != mtab_path_) { | 287 if (path != mtab_path_) { |
292 // This cannot happen unless FilePathWatcher is buggy. Just ignore this | 288 // This cannot happen unless FilePathWatcher is buggy. Just ignore this |
293 // notification and do nothing. | 289 // notification and do nothing. |
294 NOTREACHED(); | 290 NOTREACHED(); |
295 return; | 291 return; |
296 } | 292 } |
297 if (error) { | 293 if (error) { |
298 LOG(ERROR) << "Error watching " << mtab_path_.value(); | 294 LOG(ERROR) << "Error watching " << mtab_path_.value(); |
299 return; | 295 return; |
300 } | 296 } |
301 | 297 |
302 UpdateMtab(); | 298 UpdateMtab(); |
303 } | 299 } |
304 | 300 |
305 RemovableDeviceNotificationsLinux::MountPointInfo::MountPointInfo() | 301 StorageMonitorLinux::MountPointInfo::MountPointInfo() |
306 : partition_size_in_bytes(0) { | 302 : partition_size_in_bytes(0) { |
307 } | 303 } |
308 | 304 |
309 void RemovableDeviceNotificationsLinux::InitOnFileThread() { | 305 void StorageMonitorLinux::InitOnFileThread() { |
310 DCHECK(!initialized_); | 306 DCHECK(!initialized_); |
311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
312 initialized_ = true; | 308 initialized_ = true; |
313 | 309 |
314 // The callback passed to Watch() has to be unretained. Otherwise | 310 // The callback passed to Watch() has to be unretained. Otherwise |
315 // RemovableDeviceNotificationsLinux will live longer than expected, and | 311 // StorageMonitorLinux will live longer than expected, and FilePathWatcher |
316 // FilePathWatcher will get in trouble at shutdown time. | 312 // will get in trouble at shutdown time. |
317 bool ret = file_watcher_.Watch( | 313 bool ret = file_watcher_.Watch( |
318 mtab_path_, false, | 314 mtab_path_, false, |
319 base::Bind(&RemovableDeviceNotificationsLinux::OnFilePathChanged, | 315 base::Bind(&StorageMonitorLinux::OnFilePathChanged, |
320 base::Unretained(this))); | 316 base::Unretained(this))); |
321 if (!ret) { | 317 if (!ret) { |
322 LOG(ERROR) << "Adding watch for " << mtab_path_.value() << " failed"; | 318 LOG(ERROR) << "Adding watch for " << mtab_path_.value() << " failed"; |
323 return; | 319 return; |
324 } | 320 } |
325 | 321 |
326 UpdateMtab(); | 322 UpdateMtab(); |
327 } | 323 } |
328 | 324 |
329 void RemovableDeviceNotificationsLinux::UpdateMtab() { | 325 void StorageMonitorLinux::UpdateMtab() { |
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
331 | 327 |
332 MountPointDeviceMap new_mtab; | 328 MountPointDeviceMap new_mtab; |
333 ReadMtab(mtab_path_, known_file_systems_, &new_mtab); | 329 ReadMtab(mtab_path_, known_file_systems_, &new_mtab); |
334 | 330 |
335 // Check existing mtab entries for unaccounted mount points. | 331 // Check existing mtab entries for unaccounted mount points. |
336 // These mount points must have been removed in the new mtab. | 332 // These mount points must have been removed in the new mtab. |
337 std::list<base::FilePath> mount_points_to_erase; | 333 std::list<base::FilePath> mount_points_to_erase; |
338 std::list<base::FilePath> multiple_mounted_devices_needing_reattachment; | 334 std::list<base::FilePath> multiple_mounted_devices_needing_reattachment; |
339 for (MountMap::const_iterator old_iter = mount_info_map_.begin(); | 335 for (MountMap::const_iterator old_iter = mount_info_map_.begin(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 MountMap::iterator old_iter = mount_info_map_.find(mount_point); | 397 MountMap::iterator old_iter = mount_info_map_.find(mount_point); |
402 if (old_iter == mount_info_map_.end() || | 398 if (old_iter == mount_info_map_.end() || |
403 old_iter->second.mount_device != mount_device) { | 399 old_iter->second.mount_device != mount_device) { |
404 // New mount point found or an existing mount point found with a new | 400 // New mount point found or an existing mount point found with a new |
405 // device. | 401 // device. |
406 AddNewMount(mount_device, mount_point); | 402 AddNewMount(mount_device, mount_point); |
407 } | 403 } |
408 } | 404 } |
409 } | 405 } |
410 | 406 |
411 void RemovableDeviceNotificationsLinux::AddNewMount( | 407 void StorageMonitorLinux::AddNewMount(const base::FilePath& mount_device, |
412 const base::FilePath& mount_device, const base::FilePath& mount_point) { | 408 const base::FilePath& mount_point) { |
413 MountPriorityMap::iterator priority = | 409 MountPriorityMap::iterator priority = |
414 mount_priority_map_.find(mount_device); | 410 mount_priority_map_.find(mount_device); |
415 if (priority != mount_priority_map_.end()) { | 411 if (priority != mount_priority_map_.end()) { |
416 const base::FilePath& other_mount_point = priority->second.begin()->first; | 412 const base::FilePath& other_mount_point = priority->second.begin()->first; |
417 priority->second[mount_point] = false; | 413 priority->second[mount_point] = false; |
418 mount_info_map_[mount_point] = | 414 mount_info_map_[mount_point] = |
419 mount_info_map_.find(other_mount_point)->second; | 415 mount_info_map_.find(other_mount_point)->second; |
420 return; | 416 return; |
421 } | 417 } |
422 | 418 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 mount_priority_map_[mount_device][mount_point] = removable; | 451 mount_priority_map_[mount_device][mount_point] = removable; |
456 | 452 |
457 if (removable) { | 453 if (removable) { |
458 receiver()->ProcessAttach(StorageInfo( | 454 receiver()->ProcessAttach(StorageInfo( |
459 device_id, GetDisplayNameForDevice(partition_size_in_bytes, name), | 455 device_id, GetDisplayNameForDevice(partition_size_in_bytes, name), |
460 mount_point.value())); | 456 mount_point.value())); |
461 } | 457 } |
462 } | 458 } |
463 | 459 |
464 } // namespace chrome | 460 } // namespace chrome |
OLD | NEW |