Do lazy unmount only when the disk has been physically removed.

Also, wire up unmount failure event to file manager so error message
for unmount failure can e displayed.

TEST=manual
    (try unmounting USB while copying a file to the device ->
         unmount should fail and error message should be displayed;
     remove USB while copying a file to it in progress ->
         the device should be unmounted)
BUG=154403


Review URL: https://chromiumcodereview.appspot.com/11099004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161072 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chromeos/dbus/cros_disks_client.cc b/chromeos/dbus/cros_disks_client.cc
index 1688b8d..edafb18e 100644
--- a/chromeos/dbus/cros_disks_client.cc
+++ b/chromeos/dbus/cros_disks_client.cc
@@ -28,9 +28,10 @@
 
 const char* kDefaultUnmountOptions[] = {
   "force",
-  "lazy",
 };
 
+const char kLazyUnmountOption[] = "lazy";
+
 const char kMountLabelOption[] = "mountlabel";
 
 // Checks if retrieved media type is in boundaries of DeviceMediaType.
@@ -150,15 +151,20 @@
 
   // CrosDisksClient override.
   virtual void Unmount(const std::string& device_path,
+                       UnmountOptions options,
                        const UnmountCallback& callback,
-                       const ErrorCallback& error_callback) OVERRIDE {
+                       const UnmountCallback& error_callback) OVERRIDE {
     dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
                                  cros_disks::kUnmount);
     dbus::MessageWriter writer(&method_call);
     writer.AppendString(device_path);
-    std::vector<std::string> unmount_options(kDefaultUnmountOptions,
-                                             kDefaultUnmountOptions +
-                                             arraysize(kDefaultUnmountOptions));
+
+    std::vector<std::string> unmount_options(
+        kDefaultUnmountOptions,
+        kDefaultUnmountOptions + arraysize(kDefaultUnmountOptions));
+    if (options == UNMOUNT_OPTIONS_LAZY)
+      unmount_options.push_back(kLazyUnmountOption);
+
     writer.AppendArrayOfStrings(unmount_options);
     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
                        base::Bind(&CrosDisksClientImpl::OnUnmount,
@@ -276,10 +282,10 @@
   // Handles the result of Unount and calls |callback| or |error_callback|.
   void OnUnmount(const std::string& device_path,
                  const UnmountCallback& callback,
-                 const ErrorCallback& error_callback,
+                 const UnmountCallback& error_callback,
                  dbus::Response* response) {
     if (!response) {
-      error_callback.Run();
+      error_callback.Run(device_path);
       return;
     }
     callback.Run(device_path);
@@ -400,8 +406,9 @@
                      const MountCallback& callback,
                      const ErrorCallback& error_callback) OVERRIDE {}
   virtual void Unmount(const std::string& device_path,
+                       UnmountOptions options,
                        const UnmountCallback& callback,
-                       const ErrorCallback& error_callback) OVERRIDE {}
+                       const UnmountCallback& error_callback) OVERRIDE {}
   virtual void EnumerateAutoMountableDevices(
       const EnumerateAutoMountableDevicesCallback& callback,
       const ErrorCallback& error_callback) OVERRIDE {}
diff --git a/chromeos/dbus/cros_disks_client.h b/chromeos/dbus/cros_disks_client.h
index 3590ca6..62cc67b9 100644
--- a/chromeos/dbus/cros_disks_client.h
+++ b/chromeos/dbus/cros_disks_client.h
@@ -18,6 +18,8 @@
 class Response;
 }
 
+// TODO(tbarzic): We should probably move these enums inside CrosDisksClient,
+// to be clearer where they come from.
 namespace chromeos {
 
 // Enum describing types of mount used by cros-disks.
@@ -64,6 +66,12 @@
   FORMATTING_FINISHED,
 };
 
+// Additional unmount flags to be added to unmount request.
+enum UnmountOptions {
+  UNMOUNT_OPTIONS_NONE,
+  UNMOUNT_OPTIONS_LAZY,  // Do lazy unmount.
+};
+
 // A class to represent information about a disk sent from cros-disks.
 class DiskInfo {
  public:
@@ -219,8 +227,9 @@
   // Calls Unmount method.  |callback| is called after the method call succeeds,
   // otherwise, |error_callback| is called.
   virtual void Unmount(const std::string& device_path,
+                       UnmountOptions options,
                        const UnmountCallback& callback,
-                       const ErrorCallback& error_callback) = 0;
+                       const UnmountCallback& error_callback) = 0;
 
   // Calls EnumerateAutoMountableDevices method.  |callback| is called after the
   // method call succeeds, otherwise, |error_callback| is called.
diff --git a/chromeos/dbus/mock_cros_disks_client.h b/chromeos/dbus/mock_cros_disks_client.h
index c237d90..9b594001 100644
--- a/chromeos/dbus/mock_cros_disks_client.h
+++ b/chromeos/dbus/mock_cros_disks_client.h
@@ -23,9 +23,10 @@
                            MountType,
                            const MountCallback&,
                            const ErrorCallback&));
-  MOCK_METHOD3(Unmount, void(const std::string&,
+  MOCK_METHOD4(Unmount, void(const std::string&,
+                             UnmountOptions,
                              const UnmountCallback&,
-                             const ErrorCallback&));
+                             const UnmountCallback&));
   MOCK_METHOD2(EnumerateAutoMountableDevices,
                void(const EnumerateAutoMountableDevicesCallback&,
                     const ErrorCallback&));