| 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 |