Switch from MountLibrary to DiskMountManager and CrosDisksLibrary

This patch is 2nd part of 3 splitted patches made from http://codereview.chromium.org/8386031


BUG=chromium-os:16556
TEST=Confirm that removable disk is correctly mounted


Review URL: http://codereview.chromium.org/8497007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110469 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 856660f94..b09aa5d 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
 #include "chrome/browser/chromeos/dbus/power_manager_client.h"
 #include "chrome/browser/chromeos/dbus/session_manager_client.h"
+#include "chrome/browser/chromeos/disks/disk_mount_manager.h"
 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
 #include "chrome/browser/chromeos/login/session_manager_observer.h"
@@ -93,6 +94,8 @@
   if (chromeos::CrosNetworkChangeNotifierFactory::GetInstance())
     chromeos::CrosNetworkChangeNotifierFactory::GetInstance()->Shutdown();
 
+  chromeos::disks::DiskMountManager::Shutdown();
+
   chromeos::BluetoothManager::Shutdown();
 
   // We should remove observers attached to D-Bus clients before
@@ -181,6 +184,9 @@
   chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
       AddObserver(session_manager_observer_.get());
 
+  // Initialize the disk mount manager.
+  chromeos::disks::DiskMountManager::Initialize();
+
   // Initialize the network change notifier for Chrome OS. The network
   // change notifier starts to monitor changes from the power manager and
   // the network manager.
diff --git a/chrome/browser/chromeos/cros/burn_library.cc b/chrome/browser/chromeos/cros/burn_library.cc
index 007005c..c5e83323 100644
--- a/chrome/browser/chromeos/cros/burn_library.cc
+++ b/chrome/browser/chromeos/cros/burn_library.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/memory/linked_ptr.h"
 #include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/disks/disk_mount_manager.h"
 #include "chrome/common/zip.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -185,9 +186,10 @@
 
   burning_ = true;
 
-  chromeos::CrosLibrary::Get()->GetMountLibrary()->UnmountDeviceRecursive(
-      target_device_path_.c_str(), &BurnLibraryImpl::DevicesUnmountedCallback,
-      this);
+  chromeos::disks::DiskMountManager::GetInstance()->
+      UnmountDeviceRecursive(target_device_path_,
+                             &BurnLibraryImpl::DevicesUnmountedCallback,
+                             this);
 }
 
 void BurnLibraryImpl::DevicesUnmountedCallback(void* object, bool success) {
diff --git a/chrome/browser/chromeos/cros/burn_library.h b/chrome/browser/chromeos/cros/burn_library.h
index 838a63fb..5f0ed58 100644
--- a/chrome/browser/chromeos/cros/burn_library.h
+++ b/chrome/browser/chromeos/cros/burn_library.h
@@ -13,7 +13,6 @@
 #include "base/file_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "chrome/browser/chromeos/cros/mount_library.h"
 #include "third_party/cros/chromeos_imageburn.h"
 
 struct ImageBurnStatus {
diff --git a/chrome/browser/chromeos/dbus/cros_disks_client.cc b/chrome/browser/chromeos/dbus/cros_disks_client.cc
index b5c92b0..e6b01c4 100644
--- a/chrome/browser/chromeos/dbus/cros_disks_client.cc
+++ b/chrome/browser/chromeos/dbus/cros_disks_client.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/chromeos/dbus/cros_disks_client.h"
 
 #include "base/bind.h"
-#include "base/memory/scoped_vector.h"
+#include "base/stl_util.h"
 #include "chrome/browser/chromeos/system/runtime_environment.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
@@ -476,12 +476,11 @@
     return;
   }
   // TODO(satorux): Rework this code using Protocol Buffers. crosbug.com/22626
-  ScopedVector<dbus::MessageReader> value_readers_owner;
-  std::map<std::string, dbus::MessageReader*> properties;
+  typedef std::map<std::string, dbus::MessageReader*> PropertiesMap;
+  PropertiesMap properties;
+  STLValueDeleter<PropertiesMap> properties_value_deleter(&properties);
   while (array_reader.HasMoreData()) {
-    // |value_readers_owner| is responsible to delete |value_reader|.
     dbus::MessageReader* value_reader = new dbus::MessageReader(response);
-    value_readers_owner.push_back(value_reader);
     dbus::MessageReader dict_entry_reader(response);
     std::string key;
     if (!array_reader.PopDictEntry(&dict_entry_reader) ||
diff --git a/chrome/browser/chromeos/disks/disk_mount_manager.cc b/chrome/browser/chromeos/disks/disk_mount_manager.cc
index 0e2a26b..5e10c58 100644
--- a/chrome/browser/chromeos/disks/disk_mount_manager.cc
+++ b/chrome/browser/chromeos/disks/disk_mount_manager.cc
@@ -328,7 +328,8 @@
     // Check if there is a formatting scheduled.
     PathMap::iterator it = formatting_pending_.find(disk->device_path());
     if (it != formatting_pending_.end()) {
-      const std::string& file_path = it->second;
+      // Copy the string before it gets erased.
+      const std::string file_path = it->second;
       formatting_pending_.erase(it);
       FormatUnmountedDevice(file_path);
     }
@@ -632,19 +633,34 @@
 
 // static
 void DiskMountManager::Initialize() {
-  VLOG(1) << "DiskMountManager::Initialize";
-  DCHECK(!g_disk_mount_manager);
+  if (g_disk_mount_manager) {
+    LOG(WARNING) << "DiskMountManager was already initialized";
+    return;
+  }
   g_disk_mount_manager = new DiskMountManagerImpl();
-  DCHECK(g_disk_mount_manager);
+  VLOG(1) << "DiskMountManager initialized";
+}
+
+// static
+void DiskMountManager::InitializeForTesting(
+    DiskMountManager* disk_mount_manager) {
+  if (g_disk_mount_manager) {
+    LOG(WARNING) << "DiskMountManager was already initialized";
+    return;
+  }
+  g_disk_mount_manager = disk_mount_manager;
+  VLOG(1) << "DiskMountManager initialized";
 }
 
 // static
 void DiskMountManager::Shutdown() {
-  VLOG(1) << "DiskMountManager::Shutdown";
-  if (g_disk_mount_manager) {
-    delete g_disk_mount_manager;
-    g_disk_mount_manager = NULL;
+  if (!g_disk_mount_manager) {
+    LOG(WARNING) << "DiskMountManager::Shutdown() called with NULL manager";
+    return;
   }
+  delete g_disk_mount_manager;
+  g_disk_mount_manager = NULL;
+  VLOG(1) << "DiskMountManager Shutdown completed";
 }
 
 // static
diff --git a/chrome/browser/chromeos/disks/disk_mount_manager.h b/chrome/browser/chromeos/disks/disk_mount_manager.h
index 4dbb3eb..c5c9da9 100644
--- a/chrome/browser/chromeos/disks/disk_mount_manager.h
+++ b/chrome/browser/chromeos/disks/disk_mount_manager.h
@@ -236,6 +236,12 @@
   // Creates the global DiskMountManager instance.
   static void Initialize();
 
+  // Similar to Initialize(), but can inject an alternative
+  // DiskMountManager such as MockDiskMountManager for testing.
+  // The injected object will be owned by the internal pointer and deleted
+  // by Shutdown().
+  static void InitializeForTesting(DiskMountManager* disk_mount_manager);
+
   // Destroys the global DiskMountManager instance if it exists.
   static void Shutdown();
 
diff --git a/chrome/browser/chromeos/extensions/file_browser_event_router.cc b/chrome/browser/chromeos/extensions/file_browser_event_router.cc
index 3e164a9..997e8473 100644
--- a/chrome/browser/chromeos/extensions/file_browser_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_browser_event_router.cc
@@ -9,7 +9,6 @@
 #include "base/message_loop.h"
 #include "base/stl_util.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/extensions/file_browser_notifications.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/extensions/extension_event_names.h"
@@ -45,13 +44,13 @@
   }
 
   DictionaryValue* DiskToDictionaryValue(
-      const chromeos::MountLibrary::Disk* disk) {
+      const chromeos::disks::DiskMountManager::Disk* disk) {
     DictionaryValue* result = new DictionaryValue();
     result->SetString("mountPath", disk->mount_path());
     result->SetString("devicePath", disk->device_path());
     result->SetString("label", disk->device_label());
     result->SetString("deviceType", DeviceTypeToString(disk->device_type()));
-    result->SetInteger("totalSizeKB", disk->total_size() / 1024);
+    result->SetInteger("totalSizeKB", disk->total_size_in_bytes() / 1024);
     result->SetBoolean("readOnly", disk->is_read_only());
     return result;
   }
@@ -95,11 +94,7 @@
     return;
   }
   profile_ = NULL;
-  if (!chromeos::CrosLibrary::Get()->EnsureLoaded())
-    return;
-  chromeos::MountLibrary* lib =
-      chromeos::CrosLibrary::Get()->GetMountLibrary();
-  lib->RemoveObserver(this);
+  chromeos::disks::DiskMountManager::GetInstance()->RemoveObserver(this);
 }
 
 void ExtensionFileBrowserEventRouter::ObserveFileSystemEvents() {
@@ -107,14 +102,12 @@
     NOTREACHED();
     return;
   }
-  if (!chromeos::CrosLibrary::Get()->EnsureLoaded())
-    return;
   if (chromeos::UserManager::Get()->user_is_logged_in()) {
-    chromeos::MountLibrary* lib =
-        chromeos::CrosLibrary::Get()->GetMountLibrary();
-    lib->RemoveObserver(this);
-    lib->AddObserver(this);
-    lib->RequestMountInfoRefresh();
+    chromeos::disks::DiskMountManager* disk_mount_manager =
+        chromeos::disks::DiskMountManager::GetInstance();
+    disk_mount_manager->RemoveObserver(this);
+    disk_mount_manager->AddObserver(this);
+    disk_mount_manager->RequestMountInfoRefresh();
   }
 }
 
@@ -155,35 +148,35 @@
 }
 
 void ExtensionFileBrowserEventRouter::DiskChanged(
-    chromeos::MountLibraryEventType event,
-    const chromeos::MountLibrary::Disk* disk) {
+    chromeos::disks::DiskMountManagerEventType event,
+    const chromeos::disks::DiskMountManager::Disk* disk) {
   // Disregard hidden devices.
   if (disk->is_hidden())
     return;
-  if (event == chromeos::MOUNT_DISK_ADDED) {
+  if (event == chromeos::disks::MOUNT_DISK_ADDED) {
     OnDiskAdded(disk);
-  } else if (event == chromeos::MOUNT_DISK_REMOVED) {
+  } else if (event == chromeos::disks::MOUNT_DISK_REMOVED) {
     OnDiskRemoved(disk);
   }
 }
 
 void ExtensionFileBrowserEventRouter::DeviceChanged(
-    chromeos::MountLibraryEventType event,
+    chromeos::disks::DiskMountManagerEventType event,
     const std::string& device_path) {
-  if (event == chromeos::MOUNT_DEVICE_ADDED) {
+  if (event == chromeos::disks::MOUNT_DEVICE_ADDED) {
     OnDeviceAdded(device_path);
-  } else if (event == chromeos::MOUNT_DEVICE_REMOVED) {
+  } else if (event == chromeos::disks::MOUNT_DEVICE_REMOVED) {
     OnDeviceRemoved(device_path);
-  } else if (event == chromeos::MOUNT_DEVICE_SCANNED) {
+  } else if (event == chromeos::disks::MOUNT_DEVICE_SCANNED) {
     OnDeviceScanned(device_path);
-  } else if (event == chromeos::MOUNT_FORMATTING_STARTED) {
+  } else if (event == chromeos::disks::MOUNT_FORMATTING_STARTED) {
   // TODO(tbarzic): get rid of '!'.
     if (device_path[0] == '!') {
       OnFormattingStarted(device_path.substr(1), false);
     } else {
       OnFormattingStarted(device_path, true);
     }
-  } else if (event == chromeos::MOUNT_FORMATTING_FINISHED) {
+  } else if (event == chromeos::disks::MOUNT_FORMATTING_FINISHED) {
     if (device_path[0] == '!') {
       OnFormattingFinished(device_path.substr(1), false);
     } else {
@@ -193,21 +186,21 @@
 }
 
 void ExtensionFileBrowserEventRouter::MountCompleted(
-    chromeos::MountLibrary::MountEvent event_type,
+    chromeos::disks::DiskMountManager::MountEvent event_type,
     chromeos::MountError error_code,
-    const chromeos::MountLibrary::MountPointInfo& mount_info) {
+    const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) {
   DispatchMountCompletedEvent(event_type, error_code, mount_info);
 
   if (mount_info.mount_type == chromeos::MOUNT_TYPE_DEVICE &&
-      event_type == chromeos::MountLibrary::MOUNTING) {
-    chromeos::MountLibrary* mount_lib =
-        chromeos::CrosLibrary::Get()->GetMountLibrary();
-    chromeos::MountLibrary::DiskMap::const_iterator disk_it =
-        mount_lib->disks().find(mount_info.source_path);
-    if (disk_it == mount_lib->disks().end()) {
+      event_type == chromeos::disks::DiskMountManager::MOUNTING) {
+    chromeos::disks::DiskMountManager* disk_mount_manager =
+        chromeos::disks::DiskMountManager::GetInstance();
+    chromeos::disks::DiskMountManager::DiskMap::const_iterator disk_it =
+        disk_mount_manager->disks().find(mount_info.source_path);
+    if (disk_it == disk_mount_manager->disks().end()) {
       return;
     }
-    chromeos::MountLibrary::Disk* disk = disk_it->second;
+    chromeos::disks::DiskMountManager::Disk* disk = disk_it->second;
 
      notifications_->ManageNotificationsOnMountCompleted(
         disk->system_path_prefix(), disk->drive_label(), disk->is_parent(),
@@ -260,7 +253,7 @@
 }
 
 void ExtensionFileBrowserEventRouter::DispatchDiskEvent(
-    const chromeos::MountLibrary::Disk* disk, bool added) {
+    const chromeos::disks::DiskMountManager::Disk* disk, bool added) {
   if (!profile_) {
     NOTREACHED();
     return;
@@ -282,9 +275,9 @@
 }
 
 void ExtensionFileBrowserEventRouter::DispatchMountCompletedEvent(
-    chromeos::MountLibrary::MountEvent event,
+    chromeos::disks::DiskMountManager::MountEvent event,
     chromeos::MountError error_code,
-    const chromeos::MountLibrary::MountPointInfo& mount_info) {
+    const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) {
   if (!profile_ || mount_info.mount_type == chromeos::MOUNT_TYPE_INVALID) {
     NOTREACHED();
     return;
@@ -293,14 +286,16 @@
   ListValue args;
   DictionaryValue* mount_info_value = new DictionaryValue();
   args.Append(mount_info_value);
-  if (event == chromeos::MountLibrary::MOUNTING) {
+  if (event == chromeos::disks::DiskMountManager::MOUNTING) {
     mount_info_value->SetString("eventType", "mount");
   } else {
     mount_info_value->SetString("eventType", "unmount");
   }
   mount_info_value->SetString("status", MountErrorToString(error_code));
-  mount_info_value->SetString("mountType",
-      chromeos::MountLibrary::MountTypeToString(mount_info.mount_type));
+  mount_info_value->SetString(
+      "mountType",
+      chromeos::disks::DiskMountManager::MountTypeToString(
+          mount_info.mount_type));
 
   if (mount_info.mount_type == chromeos::MOUNT_TYPE_ARCHIVE) {
     GURL source_url;
@@ -341,13 +336,13 @@
   if (relative_mount_path_set &&
       mount_info.mount_type == chromeos::MOUNT_TYPE_DEVICE &&
       !mount_info.mount_condition &&
-      event == chromeos::MountLibrary::MOUNTING) {
+      event == chromeos::disks::DiskMountManager::MOUNTING) {
     FileManagerUtil::ViewFolder(FilePath(mount_info.mount_path));
   }
 }
 
 void ExtensionFileBrowserEventRouter::OnDiskAdded(
-    const chromeos::MountLibrary::Disk* disk) {
+    const chromeos::disks::DiskMountManager::Disk* disk) {
   VLOG(1) << "Disk added: " << disk->device_path();
   if (disk->device_path().empty()) {
     VLOG(1) << "Empty system path for " << disk->device_path();
@@ -357,23 +352,19 @@
   // If disk is not mounted yet, give it a try.
   if (disk->mount_path().empty()) {
     // Initiate disk mount operation.
-    chromeos::MountLibrary* lib =
-        chromeos::CrosLibrary::Get()->GetMountLibrary();
-    lib->MountPath(disk->device_path().c_str(),
-                   chromeos::MOUNT_TYPE_DEVICE,
-                   chromeos::MountPathOptions());  // Unused.
+    chromeos::disks::DiskMountManager::GetInstance()->MountPath(
+        disk->device_path(), chromeos::MOUNT_TYPE_DEVICE);
   }
   DispatchDiskEvent(disk, true);
 }
 
 void ExtensionFileBrowserEventRouter::OnDiskRemoved(
-    const chromeos::MountLibrary::Disk* disk) {
+    const chromeos::disks::DiskMountManager::Disk* disk) {
   VLOG(1) << "Disk removed: " << disk->device_path();
 
   if (!disk->mount_path().empty()) {
-    chromeos::MountLibrary* lib =
-       chromeos::CrosLibrary::Get()->GetMountLibrary();
-    lib->UnmountPath(disk->mount_path().c_str());
+    chromeos::disks::DiskMountManager::GetInstance()->UnmountPath(
+        disk->mount_path());
   }
   DispatchDiskEvent(disk, false);
 }
@@ -425,11 +416,8 @@
     notifications_->HideNotificationDelayed(
         FileBrowserNotifications::FORMAT_SUCCESS, device_path, 4000);
 
-    chromeos::MountLibrary* lib =
-        chromeos::CrosLibrary::Get()->GetMountLibrary();
-    lib->MountPath(device_path.c_str(),
-                   chromeos::MOUNT_TYPE_DEVICE,
-                   chromeos::MountPathOptions());  // Unused.
+    chromeos::disks::DiskMountManager::GetInstance()->MountPath(
+        device_path, chromeos::MOUNT_TYPE_DEVICE);
   } else {
     notifications_->HideNotification(FileBrowserNotifications::FORMAT_START,
                                      device_path);
diff --git a/chrome/browser/chromeos/extensions/file_browser_event_router.h b/chrome/browser/chromeos/extensions/file_browser_event_router.h
index b9d2b23..e5464557 100644
--- a/chrome/browser/chromeos/extensions/file_browser_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_browser_event_router.h
@@ -15,7 +15,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/string16.h"
 #include "base/synchronization/lock.h"
-#include "chrome/browser/chromeos/cros/mount_library.h"
+#include "chrome/browser/chromeos/disks/disk_mount_manager.h"
 
 class FileBrowserNotifications;
 class Profile;
@@ -23,12 +23,12 @@
 // Used to monitor disk mount changes and signal when new mounted usb device is
 // found.
 class ExtensionFileBrowserEventRouter
-    : public chromeos::MountLibrary::Observer {
+    : public chromeos::disks::DiskMountManager::Observer {
  public:
   explicit ExtensionFileBrowserEventRouter(Profile* profile);
   virtual ~ExtensionFileBrowserEventRouter();
   // Starts observing file system change events. Currently only
-  // MountLibrary events are being observed.
+  // CrosDisksClient events are being observed.
   void ObserveFileSystemEvents();
 
   // File watch setup routines.
@@ -38,14 +38,17 @@
   void RemoveFileWatch(const FilePath& file_path,
                        const std::string& extension_id);
 
-  // MountLibrary::Observer overrides.
-  virtual void DiskChanged(chromeos::MountLibraryEventType event,
-                           const chromeos::MountLibrary::Disk* disk) OVERRIDE;
-  virtual void DeviceChanged(chromeos::MountLibraryEventType event,
+  // CrosDisksClient::Observer overrides.
+  virtual void DiskChanged(chromeos::disks::DiskMountManagerEventType event,
+                           const chromeos::disks::DiskMountManager::Disk* disk)
+      OVERRIDE;
+  virtual void DeviceChanged(chromeos::disks::DiskMountManagerEventType event,
                              const std::string& device_path) OVERRIDE;
-  virtual void MountCompleted(chromeos::MountLibrary::MountEvent event_type,
+  virtual void MountCompleted(
+      chromeos::disks::DiskMountManager::MountEvent event_type,
       chromeos::MountError error_code,
-      const chromeos::MountLibrary::MountPointInfo& mount_info) OVERRIDE;
+      const chromeos::disks::DiskMountManager::MountPointInfo& mount_info)
+      OVERRIDE;
 
  private:
   // Helper class for passing through file watch notification events.
@@ -95,10 +98,10 @@
   typedef std::map<FilePath, FileWatcherExtensions*> WatcherMap;
 
   // USB mount event handlers.
-  void OnDiskAdded(const chromeos::MountLibrary::Disk* disk);
-  void OnDiskRemoved(const chromeos::MountLibrary::Disk* disk);
-  void OnDiskMounted(const chromeos::MountLibrary::Disk* disk);
-  void OnDiskUnmounted(const chromeos::MountLibrary::Disk* disk);
+  void OnDiskAdded(const chromeos::disks::DiskMountManager::Disk* disk);
+  void OnDiskRemoved(const chromeos::disks::DiskMountManager::Disk* disk);
+  void OnDiskMounted(const chromeos::disks::DiskMountManager::Disk* disk);
+  void OnDiskUnmounted(const chromeos::disks::DiskMountManager::Disk* disk);
   void OnDeviceAdded(const std::string& device_path);
   void OnDeviceRemoved(const std::string& device_path);
   void OnDeviceScanned(const std::string& device_path);
@@ -114,11 +117,13 @@
                                  const ExtensionUsageRegistry& extensions);
 
   // Sends filesystem changed extension message to all renderers.
-  void DispatchDiskEvent(const chromeos::MountLibrary::Disk* disk, bool added);
+  void DispatchDiskEvent(const chromeos::disks::DiskMountManager::Disk* disk,
+                         bool added);
 
-  void DispatchMountCompletedEvent(chromeos::MountLibrary::MountEvent event,
+  void DispatchMountCompletedEvent(
+      chromeos::disks::DiskMountManager::MountEvent event,
       chromeos::MountError error_code,
-      const chromeos::MountLibrary::MountPointInfo& mount_info);
+      const chromeos::disks::DiskMountManager::MountPointInfo& mount_info);
 
   void RemoveBrowserFromVector(const std::string& path);