OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 // StorageMonitorLinux implementation. | 5 // StorageMonitorLinux implementation. |
6 | 6 |
7 #include "components/storage_monitor/storage_monitor_linux.h" | 7 #include "components/storage_monitor/storage_monitor_linux.h" |
8 | 8 |
9 #include <mntent.h> | 9 #include <mntent.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 uint64 total_size_in_bytes = 0; | 112 uint64 total_size_in_bytes = 0; |
113 if (!base::StringToUint64(partition_size, &total_size_in_bytes)) | 113 if (!base::StringToUint64(partition_size, &total_size_in_bytes)) |
114 return 0; | 114 return 0; |
115 return (total_size_in_bytes <= kuint64max / 512) ? | 115 return (total_size_in_bytes <= kuint64max / 512) ? |
116 total_size_in_bytes * 512 : 0; | 116 total_size_in_bytes * 512 : 0; |
117 } | 117 } |
118 | 118 |
119 // Gets the device information using udev library. | 119 // Gets the device information using udev library. |
120 scoped_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path, | 120 scoped_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path, |
121 const base::FilePath& mount_point) { | 121 const base::FilePath& mount_point) { |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 122 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
123 DCHECK(!device_path.empty()); | 123 DCHECK(!device_path.empty()); |
124 | 124 |
125 scoped_ptr<StorageInfo> storage_info; | 125 scoped_ptr<StorageInfo> storage_info; |
126 | 126 |
127 ScopedGetDeviceInfoResultRecorder results_recorder; | 127 ScopedGetDeviceInfoResultRecorder results_recorder; |
128 | 128 |
129 device::ScopedUdevPtr udev_obj(device::udev_new()); | 129 device::ScopedUdevPtr udev_obj(device::udev_new()); |
130 if (!udev_obj.get()) | 130 if (!udev_obj.get()) |
131 return storage_info.Pass(); | 131 return storage_info.Pass(); |
132 | 132 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 volume_label, | 191 volume_label, |
192 vendor_name, | 192 vendor_name, |
193 model_name, | 193 model_name, |
194 GetDeviceStorageSize(device_path, device.get()))); | 194 GetDeviceStorageSize(device_path, device.get()))); |
195 return storage_info.Pass(); | 195 return storage_info.Pass(); |
196 } | 196 } |
197 | 197 |
198 MtabWatcherLinux* CreateMtabWatcherLinuxOnFileThread( | 198 MtabWatcherLinux* CreateMtabWatcherLinuxOnFileThread( |
199 const base::FilePath& mtab_path, | 199 const base::FilePath& mtab_path, |
200 base::WeakPtr<MtabWatcherLinux::Delegate> delegate) { | 200 base::WeakPtr<MtabWatcherLinux::Delegate> delegate) { |
201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 201 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
202 // Owned by caller. | 202 // Owned by caller. |
203 return new MtabWatcherLinux(mtab_path, delegate); | 203 return new MtabWatcherLinux(mtab_path, delegate); |
204 } | 204 } |
205 | 205 |
206 StorageMonitor::EjectStatus EjectPathOnFileThread( | 206 StorageMonitor::EjectStatus EjectPathOnFileThread( |
207 const base::FilePath& path, | 207 const base::FilePath& path, |
208 const base::FilePath& device) { | 208 const base::FilePath& device) { |
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 209 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
210 | 210 |
211 // Note: Linux LSB says umount should exist in /bin. | 211 // Note: Linux LSB says umount should exist in /bin. |
212 static const char kUmountBinary[] = "/bin/umount"; | 212 static const char kUmountBinary[] = "/bin/umount"; |
213 std::vector<std::string> command; | 213 std::vector<std::string> command; |
214 command.push_back(kUmountBinary); | 214 command.push_back(kUmountBinary); |
215 command.push_back(path.value()); | 215 command.push_back(path.value()); |
216 | 216 |
217 base::LaunchOptions options; | 217 base::LaunchOptions options; |
218 base::Process process = base::LaunchProcess(command, options); | 218 base::Process process = base::LaunchProcess(command, options); |
219 if (!process.IsValid()) | 219 if (!process.IsValid()) |
(...skipping 17 matching lines...) Expand all Loading... |
237 | 237 |
238 return StorageMonitor::EJECT_OK; | 238 return StorageMonitor::EJECT_OK; |
239 } | 239 } |
240 | 240 |
241 } // namespace | 241 } // namespace |
242 | 242 |
243 StorageMonitorLinux::StorageMonitorLinux(const base::FilePath& path) | 243 StorageMonitorLinux::StorageMonitorLinux(const base::FilePath& path) |
244 : mtab_path_(path), | 244 : mtab_path_(path), |
245 get_device_info_callback_(base::Bind(&GetDeviceInfo)), | 245 get_device_info_callback_(base::Bind(&GetDeviceInfo)), |
246 weak_ptr_factory_(this) { | 246 weak_ptr_factory_(this) { |
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 247 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
248 } | 248 } |
249 | 249 |
250 StorageMonitorLinux::~StorageMonitorLinux() { | 250 StorageMonitorLinux::~StorageMonitorLinux() { |
251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 251 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
252 } | 252 } |
253 | 253 |
254 void StorageMonitorLinux::Init() { | 254 void StorageMonitorLinux::Init() { |
255 DCHECK(!mtab_path_.empty()); | 255 DCHECK(!mtab_path_.empty()); |
256 | 256 |
257 BrowserThread::PostTaskAndReplyWithResult( | 257 BrowserThread::PostTaskAndReplyWithResult( |
258 BrowserThread::FILE, FROM_HERE, | 258 BrowserThread::FILE, FROM_HERE, |
259 base::Bind(&CreateMtabWatcherLinuxOnFileThread, | 259 base::Bind(&CreateMtabWatcherLinuxOnFileThread, |
260 mtab_path_, | 260 mtab_path_, |
261 weak_ptr_factory_.GetWeakPtr()), | 261 weak_ptr_factory_.GetWeakPtr()), |
262 base::Bind(&StorageMonitorLinux::OnMtabWatcherCreated, | 262 base::Bind(&StorageMonitorLinux::OnMtabWatcherCreated, |
263 weak_ptr_factory_.GetWeakPtr())); | 263 weak_ptr_factory_.GetWeakPtr())); |
264 | 264 |
265 if (!media_transfer_protocol_manager_) { | 265 if (!media_transfer_protocol_manager_) { |
266 scoped_refptr<base::MessageLoopProxy> loop_proxy = | 266 scoped_refptr<base::MessageLoopProxy> loop_proxy = |
267 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE); | 267 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE); |
268 media_transfer_protocol_manager_.reset( | 268 media_transfer_protocol_manager_.reset( |
269 device::MediaTransferProtocolManager::Initialize(loop_proxy)); | 269 device::MediaTransferProtocolManager::Initialize(loop_proxy)); |
270 } | 270 } |
271 | 271 |
272 media_transfer_protocol_device_observer_.reset( | 272 media_transfer_protocol_device_observer_.reset( |
273 new MediaTransferProtocolDeviceObserverLinux( | 273 new MediaTransferProtocolDeviceObserverLinux( |
274 receiver(), media_transfer_protocol_manager_.get())); | 274 receiver(), media_transfer_protocol_manager_.get())); |
275 } | 275 } |
276 | 276 |
277 bool StorageMonitorLinux::GetStorageInfoForPath( | 277 bool StorageMonitorLinux::GetStorageInfoForPath( |
278 const base::FilePath& path, | 278 const base::FilePath& path, |
279 StorageInfo* device_info) const { | 279 StorageInfo* device_info) const { |
280 DCHECK(device_info); | 280 DCHECK(device_info); |
281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 281 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
282 | 282 |
283 // TODO(thestig) |media_transfer_protocol_device_observer_| should always be | 283 // TODO(thestig) |media_transfer_protocol_device_observer_| should always be |
284 // valid. | 284 // valid. |
285 if (media_transfer_protocol_device_observer_ && | 285 if (media_transfer_protocol_device_observer_ && |
286 media_transfer_protocol_device_observer_->GetStorageInfoForPath( | 286 media_transfer_protocol_device_observer_->GetStorageInfoForPath( |
287 path, device_info)) { | 287 path, device_info)) { |
288 return true; | 288 return true; |
289 } | 289 } |
290 | 290 |
291 if (!path.IsAbsolute()) | 291 if (!path.IsAbsolute()) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 352 |
353 receiver()->ProcessDetach(device_id); | 353 receiver()->ProcessDetach(device_id); |
354 | 354 |
355 BrowserThread::PostTaskAndReplyWithResult( | 355 BrowserThread::PostTaskAndReplyWithResult( |
356 BrowserThread::FILE, FROM_HERE, | 356 BrowserThread::FILE, FROM_HERE, |
357 base::Bind(&EjectPathOnFileThread, path, device), | 357 base::Bind(&EjectPathOnFileThread, path, device), |
358 callback); | 358 callback); |
359 } | 359 } |
360 | 360 |
361 void StorageMonitorLinux::OnMtabWatcherCreated(MtabWatcherLinux* watcher) { | 361 void StorageMonitorLinux::OnMtabWatcherCreated(MtabWatcherLinux* watcher) { |
362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 362 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
363 mtab_watcher_.reset(watcher); | 363 mtab_watcher_.reset(watcher); |
364 } | 364 } |
365 | 365 |
366 void StorageMonitorLinux::UpdateMtab(const MountPointDeviceMap& new_mtab) { | 366 void StorageMonitorLinux::UpdateMtab(const MountPointDeviceMap& new_mtab) { |
367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 367 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
368 | 368 |
369 // Check existing mtab entries for unaccounted mount points. | 369 // Check existing mtab entries for unaccounted mount points. |
370 // These mount points must have been removed in the new mtab. | 370 // These mount points must have been removed in the new mtab. |
371 std::list<base::FilePath> mount_points_to_erase; | 371 std::list<base::FilePath> mount_points_to_erase; |
372 std::list<base::FilePath> multiple_mounted_devices_needing_reattachment; | 372 std::list<base::FilePath> multiple_mounted_devices_needing_reattachment; |
373 for (MountMap::const_iterator old_iter = mount_info_map_.begin(); | 373 for (MountMap::const_iterator old_iter = mount_info_map_.begin(); |
374 old_iter != mount_info_map_.end(); ++old_iter) { | 374 old_iter != mount_info_map_.end(); ++old_iter) { |
375 const base::FilePath& mount_point = old_iter->first; | 375 const base::FilePath& mount_point = old_iter->first; |
376 const base::FilePath& mount_device = old_iter->second.mount_device; | 376 const base::FilePath& mount_device = old_iter->second.mount_device; |
377 MountPointDeviceMap::const_iterator new_iter = new_mtab.find(mount_point); | 377 MountPointDeviceMap::const_iterator new_iter = new_mtab.find(mount_point); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 BrowserThread::PostTaskAndReply( | 458 BrowserThread::PostTaskAndReply( |
459 BrowserThread::FILE, FROM_HERE, | 459 BrowserThread::FILE, FROM_HERE, |
460 base::Bind(&base::DoNothing), | 460 base::Bind(&base::DoNothing), |
461 base::Bind(&StorageMonitorLinux::MarkInitialized, | 461 base::Bind(&StorageMonitorLinux::MarkInitialized, |
462 weak_ptr_factory_.GetWeakPtr())); | 462 weak_ptr_factory_.GetWeakPtr())); |
463 } | 463 } |
464 } | 464 } |
465 | 465 |
466 bool StorageMonitorLinux::IsDeviceAlreadyMounted( | 466 bool StorageMonitorLinux::IsDeviceAlreadyMounted( |
467 const base::FilePath& mount_device) const { | 467 const base::FilePath& mount_device) const { |
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 468 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
469 return ContainsKey(mount_priority_map_, mount_device); | 469 return ContainsKey(mount_priority_map_, mount_device); |
470 } | 470 } |
471 | 471 |
472 void StorageMonitorLinux::HandleDeviceMountedMultipleTimes( | 472 void StorageMonitorLinux::HandleDeviceMountedMultipleTimes( |
473 const base::FilePath& mount_device, | 473 const base::FilePath& mount_device, |
474 const base::FilePath& mount_point) { | 474 const base::FilePath& mount_point) { |
475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 475 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
476 | 476 |
477 MountPriorityMap::iterator priority = mount_priority_map_.find(mount_device); | 477 MountPriorityMap::iterator priority = mount_priority_map_.find(mount_device); |
478 DCHECK(priority != mount_priority_map_.end()); | 478 DCHECK(priority != mount_priority_map_.end()); |
479 const base::FilePath& other_mount_point = priority->second.begin()->first; | 479 const base::FilePath& other_mount_point = priority->second.begin()->first; |
480 priority->second[mount_point] = false; | 480 priority->second[mount_point] = false; |
481 mount_info_map_[mount_point] = | 481 mount_info_map_[mount_point] = |
482 mount_info_map_.find(other_mount_point)->second; | 482 mount_info_map_.find(other_mount_point)->second; |
483 } | 483 } |
484 | 484 |
485 void StorageMonitorLinux::AddNewMount(const base::FilePath& mount_device, | 485 void StorageMonitorLinux::AddNewMount(const base::FilePath& mount_device, |
486 scoped_ptr<StorageInfo> storage_info) { | 486 scoped_ptr<StorageInfo> storage_info) { |
487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 487 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
488 | 488 |
489 if (!storage_info) | 489 if (!storage_info) |
490 return; | 490 return; |
491 | 491 |
492 DCHECK(!storage_info->device_id().empty()); | 492 DCHECK(!storage_info->device_id().empty()); |
493 | 493 |
494 bool removable = StorageInfo::IsRemovableDevice(storage_info->device_id()); | 494 bool removable = StorageInfo::IsRemovableDevice(storage_info->device_id()); |
495 const base::FilePath mount_point(storage_info->location()); | 495 const base::FilePath mount_point(storage_info->location()); |
496 | 496 |
497 MountPointInfo mount_point_info; | 497 MountPointInfo mount_point_info; |
498 mount_point_info.mount_device = mount_device; | 498 mount_point_info.mount_device = mount_device; |
499 mount_point_info.storage_info = *storage_info; | 499 mount_point_info.storage_info = *storage_info; |
500 mount_info_map_[mount_point] = mount_point_info; | 500 mount_info_map_[mount_point] = mount_point_info; |
501 mount_priority_map_[mount_device][mount_point] = removable; | 501 mount_priority_map_[mount_device][mount_point] = removable; |
502 receiver()->ProcessAttach(*storage_info); | 502 receiver()->ProcessAttach(*storage_info); |
503 } | 503 } |
504 | 504 |
505 StorageMonitor* StorageMonitor::CreateInternal() { | 505 StorageMonitor* StorageMonitor::CreateInternal() { |
506 const base::FilePath kDefaultMtabPath("/etc/mtab"); | 506 const base::FilePath kDefaultMtabPath("/etc/mtab"); |
507 return new StorageMonitorLinux(kDefaultMtabPath); | 507 return new StorageMonitorLinux(kDefaultMtabPath); |
508 } | 508 } |
509 | 509 |
510 } // namespace storage_monitor | 510 } // namespace storage_monitor |
OLD | NEW |