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

Side by Side Diff: chromeos/disks/disk_mount_manager.cc

Issue 379743004: Add a method in DiskMountManager to refresh mount entries in addition to devices. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed review comments + Fix up MockDiskMountManager. Created 6 years, 5 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
« no previous file with comments | « chromeos/disks/disk_mount_manager.h ('k') | chromeos/disks/mock_disk_mount_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "chromeos/disks/disk_mount_manager.h" 5 #include "chromeos/disks/disk_mount_manager.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
12 #include "base/observer_list.h" 12 #include "base/observer_list.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "chromeos/dbus/dbus_thread_manager.h" 15 #include "chromeos/dbus/dbus_thread_manager.h"
16 16
17 namespace chromeos { 17 namespace chromeos {
18 namespace disks { 18 namespace disks {
19 19
20 namespace { 20 namespace {
21 21
22 const char kDeviceNotFound[] = "Device could not be found"; 22 const char kDeviceNotFound[] = "Device could not be found";
23 23
24 DiskMountManager* g_disk_mount_manager = NULL; 24 DiskMountManager* g_disk_mount_manager = NULL;
25 25
26 // The DiskMountManager implementation. 26 // The DiskMountManager implementation.
27 class DiskMountManagerImpl : public DiskMountManager { 27 class DiskMountManagerImpl : public DiskMountManager {
28 public: 28 public:
29 DiskMountManagerImpl() : weak_ptr_factory_(this) { 29 DiskMountManagerImpl() :
30 already_refreshed_(false),
31 weak_ptr_factory_(this) {
30 DBusThreadManager* dbus_thread_manager = DBusThreadManager::Get(); 32 DBusThreadManager* dbus_thread_manager = DBusThreadManager::Get();
31 DCHECK(dbus_thread_manager); 33 DCHECK(dbus_thread_manager);
32 cros_disks_client_ = dbus_thread_manager->GetCrosDisksClient(); 34 cros_disks_client_ = dbus_thread_manager->GetCrosDisksClient();
33 DCHECK(cros_disks_client_); 35 DCHECK(cros_disks_client_);
34 cros_disks_client_->SetMountEventHandler( 36 cros_disks_client_->SetMountEventHandler(
35 base::Bind(&DiskMountManagerImpl::OnMountEvent, 37 base::Bind(&DiskMountManagerImpl::OnMountEvent,
36 weak_ptr_factory_.GetWeakPtr())); 38 weak_ptr_factory_.GetWeakPtr()));
37 cros_disks_client_->SetMountCompletedHandler( 39 cros_disks_client_->SetMountCompletedHandler(
38 base::Bind(&DiskMountManagerImpl::OnMountCompleted, 40 base::Bind(&DiskMountManagerImpl::OnMountCompleted,
39 weak_ptr_factory_.GetWeakPtr())); 41 weak_ptr_factory_.GetWeakPtr()));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 callback.Run(false); 150 callback.Run(false);
149 return; 151 return;
150 } 152 }
151 153
152 // Nothing to unmount. 154 // Nothing to unmount.
153 callback.Run(true); 155 callback.Run(true);
154 return; 156 return;
155 } 157 }
156 158
157 // We will send the same callback data object to all Unmount calls and use 159 // We will send the same callback data object to all Unmount calls and use
158 // it to syncronize callbacks. 160 // it to synchronize callbacks.
159 // Note: this implementation has a potential memory leak issue. For 161 // Note: this implementation has a potential memory leak issue. For
160 // example if this instance is destructed before all the callbacks for 162 // example if this instance is destructed before all the callbacks for
161 // Unmount are invoked, the memory pointed by |cb_data| will be leaked. 163 // Unmount are invoked, the memory pointed by |cb_data| will be leaked.
162 // It is because the UnmountDeviceRecursivelyCallbackData keeps how 164 // It is because the UnmountDeviceRecursivelyCallbackData keeps how
163 // many times OnUnmountDeviceRecursively callback is called and when 165 // many times OnUnmountDeviceRecursively callback is called and when
164 // all the callbacks are called, |cb_data| will be deleted in the method. 166 // all the callbacks are called, |cb_data| will be deleted in the method.
165 // However destructing the instance before all callback invocations will 167 // However destructing the instance before all callback invocations will
166 // cancel all pending callbacks, so that the |cb_data| would never be 168 // cancel all pending callbacks, so that the |cb_data| would never be
167 // deleted. 169 // deleted.
168 // Fortunately, in the real scenario, the instance will be destructed 170 // Fortunately, in the real scenario, the instance will be destructed
(...skipping 13 matching lines...) Expand all
182 devices_to_unmount[i]), 184 devices_to_unmount[i]),
183 base::Bind(&DiskMountManagerImpl::OnUnmountDeviceRecursively, 185 base::Bind(&DiskMountManagerImpl::OnUnmountDeviceRecursively,
184 weak_ptr_factory_.GetWeakPtr(), 186 weak_ptr_factory_.GetWeakPtr(),
185 cb_data, 187 cb_data,
186 false, 188 false,
187 devices_to_unmount[i])); 189 devices_to_unmount[i]));
188 } 190 }
189 } 191 }
190 192
191 // DiskMountManager override. 193 // DiskMountManager override.
192 virtual void RequestMountInfoRefresh() OVERRIDE { 194 virtual void EnsureMountInfoRefreshed(
193 cros_disks_client_->EnumerateAutoMountableDevices( 195 const EnsureMountInfoRefreshedCallback& callback) OVERRIDE {
194 base::Bind(&DiskMountManagerImpl::OnRequestMountInfo, 196 if (already_refreshed_) {
195 weak_ptr_factory_.GetWeakPtr()), 197 callback.Run(true);
196 base::Bind(&base::DoNothing)); 198 return;
199 }
200
201 refresh_callbacks_.push_back(callback);
202 if (refresh_callbacks_.size() == 1) {
203 // If there's no in-flight refreshing task, start it.
204 cros_disks_client_->EnumerateAutoMountableDevices(
205 base::Bind(&DiskMountManagerImpl::RefreshAfterEnumerateDevices,
206 weak_ptr_factory_.GetWeakPtr()),
207 base::Bind(&DiskMountManagerImpl::RefreshCompleted,
208 weak_ptr_factory_.GetWeakPtr(), false));
209 }
197 } 210 }
198 211
199 // DiskMountManager override. 212 // DiskMountManager override.
200 virtual const DiskMap& disks() const OVERRIDE { return disks_; } 213 virtual const DiskMap& disks() const OVERRIDE { return disks_; }
201 214
202 // DiskMountManager override. 215 // DiskMountManager override.
203 virtual const Disk* FindDiskBySourcePath(const std::string& source_path) 216 virtual const Disk* FindDiskBySourcePath(const std::string& source_path)
204 const OVERRIDE { 217 const OVERRIDE {
205 DiskMap::const_iterator disk_it = disks_.find(source_path); 218 DiskMap::const_iterator disk_it = disks_.find(source_path);
206 return disk_it == disks_.end() ? NULL : disk_it->second; 219 return disk_it == disks_.end() ? NULL : disk_it->second;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 void OnFormatStarted(const std::string& device_path) { 420 void OnFormatStarted(const std::string& device_path) {
408 NotifyFormatStatusUpdate(FORMAT_STARTED, FORMAT_ERROR_NONE, device_path); 421 NotifyFormatStatusUpdate(FORMAT_STARTED, FORMAT_ERROR_NONE, device_path);
409 } 422 }
410 423
411 // Callback to handle FormatCompleted signal and Format method call failure. 424 // Callback to handle FormatCompleted signal and Format method call failure.
412 void OnFormatCompleted(FormatError error_code, 425 void OnFormatCompleted(FormatError error_code,
413 const std::string& device_path) { 426 const std::string& device_path) {
414 NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, device_path); 427 NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, device_path);
415 } 428 }
416 429
417 // Callbcak for GetDeviceProperties. 430 // Callback for GetDeviceProperties.
418 void OnGetDeviceProperties(const DiskInfo& disk_info) { 431 void OnGetDeviceProperties(const DiskInfo& disk_info) {
419 // TODO(zelidrag): Find a better way to filter these out before we 432 // TODO(zelidrag): Find a better way to filter these out before we
420 // fetch the properties: 433 // fetch the properties:
421 // Ignore disks coming from the device we booted the system from. 434 // Ignore disks coming from the device we booted the system from.
422 if (disk_info.on_boot_device()) 435 if (disk_info.on_boot_device())
423 return; 436 return;
424 437
425 LOG(WARNING) << "Found disk " << disk_info.device_path(); 438 LOG(WARNING) << "Found disk " << disk_info.device_path();
426 // Delete previous disk info for this path: 439 // Delete previous disk info for this path:
427 bool is_new = true; 440 bool is_new = true;
(...skipping 19 matching lines...) Expand all
447 disk_info.total_size_in_bytes(), 460 disk_info.total_size_in_bytes(),
448 disk_info.is_drive(), 461 disk_info.is_drive(),
449 disk_info.is_read_only(), 462 disk_info.is_read_only(),
450 disk_info.has_media(), 463 disk_info.has_media(),
451 disk_info.on_boot_device(), 464 disk_info.on_boot_device(),
452 disk_info.is_hidden()); 465 disk_info.is_hidden());
453 disks_.insert(std::make_pair(disk_info.device_path(), disk)); 466 disks_.insert(std::make_pair(disk_info.device_path(), disk));
454 NotifyDiskStatusUpdate(is_new ? DISK_ADDED : DISK_CHANGED, disk); 467 NotifyDiskStatusUpdate(is_new ? DISK_ADDED : DISK_CHANGED, disk);
455 } 468 }
456 469
457 // Callbcak for RequestMountInfo. 470 // Part of EnsureMountInfoRefreshed(). Called after the list of devices are
458 void OnRequestMountInfo(const std::vector<std::string>& devices) { 471 // enumerated.
459 std::set<std::string> current_device_set; 472 void RefreshAfterEnumerateDevices(const std::vector<std::string>& devices) {
460 if (!devices.empty()) { 473 std::set<std::string> current_device_set(devices.begin(), devices.end());
461 // Initiate properties fetch for all removable disks,
462 for (size_t i = 0; i < devices.size(); i++) {
463 current_device_set.insert(devices[i]);
464 // Initiate disk property retrieval for each relevant device path.
465 cros_disks_client_->GetDeviceProperties(
466 devices[i],
467 base::Bind(&DiskMountManagerImpl::OnGetDeviceProperties,
468 weak_ptr_factory_.GetWeakPtr()),
469 base::Bind(&base::DoNothing));
470 }
471 }
472 // Search and remove disks that are no longer present.
473 for (DiskMap::iterator iter = disks_.begin(); iter != disks_.end(); ) { 474 for (DiskMap::iterator iter = disks_.begin(); iter != disks_.end(); ) {
474 if (current_device_set.find(iter->first) == current_device_set.end()) { 475 if (current_device_set.find(iter->first) == current_device_set.end()) {
475 Disk* disk = iter->second;
476 NotifyDiskStatusUpdate(DISK_REMOVED, disk);
477 delete iter->second; 476 delete iter->second;
478 disks_.erase(iter++); 477 disks_.erase(iter++);
479 } else { 478 } else {
480 ++iter; 479 ++iter;
481 } 480 }
482 } 481 }
482 RefreshDeviceAtIndex(devices, 0);
483 }
484
485 // Part of EnsureMountInfoRefreshed(). Called for each device to refresh info.
486 void RefreshDeviceAtIndex(const std::vector<std::string>& devices,
487 size_t index) {
488 if (index == devices.size()) {
489 // All devices info retrieved. Proceed to enumerate mount point info.
490 cros_disks_client_->EnumerateMountEntries(
491 base::Bind(&DiskMountManagerImpl::RefreshAfterEnumerateMountEntries,
492 weak_ptr_factory_.GetWeakPtr()),
493 base::Bind(&DiskMountManagerImpl::RefreshCompleted,
494 weak_ptr_factory_.GetWeakPtr(), false));
495 return;
496 }
497
498 cros_disks_client_->GetDeviceProperties(
499 devices[index],
500 base::Bind(&DiskMountManagerImpl::RefreshAfterGetDeviceProperties,
501 weak_ptr_factory_.GetWeakPtr(), devices, index + 1),
502 base::Bind(&DiskMountManagerImpl::RefreshCompleted,
503 weak_ptr_factory_.GetWeakPtr(), false));
504 }
505
506 // Part of EnsureMountInfoRefreshed().
507 void RefreshAfterGetDeviceProperties(const std::vector<std::string>& devices,
508 size_t next_index,
509 const DiskInfo& disk_info) {
510 OnGetDeviceProperties(disk_info);
511 RefreshDeviceAtIndex(devices, next_index);
512 }
513
514 // Part of EnsureMountInfoRefreshed(). Called after mount entries are listed.
515 void RefreshAfterEnumerateMountEntries(
516 const std::vector<MountEntry>& entries) {
517 for (size_t i = 0; i < entries.size(); ++i)
518 OnMountCompleted(entries[i]);
519 RefreshCompleted(true);
520 }
521
522 // Part of EnsureMountInfoRefreshed(). Called when the refreshing is done.
523 void RefreshCompleted(bool success) {
524 already_refreshed_ = true;
525 for (size_t i = 0; i < refresh_callbacks_.size(); ++i)
526 refresh_callbacks_[i].Run(success);
527 refresh_callbacks_.clear();
483 } 528 }
484 529
485 // Callback to handle mount event signals. 530 // Callback to handle mount event signals.
486 void OnMountEvent(MountEventType event, const std::string& device_path_arg) { 531 void OnMountEvent(MountEventType event, const std::string& device_path_arg) {
487 // Take a copy of the argument so we can modify it below. 532 // Take a copy of the argument so we can modify it below.
488 std::string device_path = device_path_arg; 533 std::string device_path = device_path_arg;
489 switch (event) { 534 switch (event) {
490 case CROS_DISKS_DISK_ADDED: { 535 case CROS_DISKS_DISK_ADDED: {
491 cros_disks_client_->GetDeviceProperties( 536 cros_disks_client_->GetDeviceProperties(
492 device_path, 537 device_path,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 CrosDisksClient* cros_disks_client_; 618 CrosDisksClient* cros_disks_client_;
574 619
575 // The list of disks found. 620 // The list of disks found.
576 DiskMountManager::DiskMap disks_; 621 DiskMountManager::DiskMap disks_;
577 622
578 DiskMountManager::MountPointMap mount_points_; 623 DiskMountManager::MountPointMap mount_points_;
579 624
580 typedef std::set<std::string> SystemPathPrefixSet; 625 typedef std::set<std::string> SystemPathPrefixSet;
581 SystemPathPrefixSet system_path_prefixes_; 626 SystemPathPrefixSet system_path_prefixes_;
582 627
628 bool already_refreshed_;
629 std::vector<EnsureMountInfoRefreshedCallback> refresh_callbacks_;
630
583 base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_; 631 base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_;
584 632
585 DISALLOW_COPY_AND_ASSIGN(DiskMountManagerImpl); 633 DISALLOW_COPY_AND_ASSIGN(DiskMountManagerImpl);
586 }; 634 };
587 635
588 } // namespace 636 } // namespace
589 637
590 DiskMountManager::Disk::Disk(const std::string& device_path, 638 DiskMountManager::Disk::Disk(const std::string& device_path,
591 const std::string& mount_path, 639 const std::string& mount_path,
592 const std::string& system_path, 640 const std::string& system_path,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 VLOG(1) << "DiskMountManager Shutdown completed"; 748 VLOG(1) << "DiskMountManager Shutdown completed";
701 } 749 }
702 750
703 // static 751 // static
704 DiskMountManager* DiskMountManager::GetInstance() { 752 DiskMountManager* DiskMountManager::GetInstance() {
705 return g_disk_mount_manager; 753 return g_disk_mount_manager;
706 } 754 }
707 755
708 } // namespace disks 756 } // namespace disks
709 } // namespace chromeos 757 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/disks/disk_mount_manager.h ('k') | chromeos/disks/mock_disk_mount_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698