Prevent formatting a device being mounted in read-only mode.
The change adds a double check before starting unmount-for-format
operation to ensure that the read-only devices cannot be formatted even
when the UI issues that command.
It will also apply for devices mounted in read-only mode by the policy after
https://codereview.chromium.org/2230713003/ ,
in addition to HW write-protected device.

The UI issue (crbug.com/636373) will also be fixed separately.

TEST=unittest and manual test utilizing the repro steps noted in crbug.com/636373 to see formatting a writable device results in an error. The manual test requires to merge 2230713003 and 2248033003 locally.
BUG=629945,636373

Review-Url: https://codereview.chromium.org/2247263002
Cr-Commit-Position: refs/heads/master@{#412461}
diff --git a/chromeos/disks/disk_mount_manager_unittest.cc b/chromeos/disks/disk_mount_manager_unittest.cc
index bc9d1f6..3e9cdfe 100644
--- a/chromeos/disks/disk_mount_manager_unittest.cc
+++ b/chromeos/disks/disk_mount_manager_unittest.cc
@@ -23,6 +23,9 @@
 
 namespace {
 
+const char kReadOnlyMountpath[] = "/device/read_only_mount_path";
+const char kReadOnlyDeviceSource[] = "/device/read_only_source_path";
+
 // Holds information needed to create a DiskMountManager::Disk instance.
 struct TestDiskInfo {
   const char* source_path;
@@ -74,6 +77,28 @@
     1073741824,  // size in bytes
     false,  // is parent
     false,  // is read only
+    true,   // has media
+    false,  // is on boot device
+    true,  // is on removable device
+    false  // is hidden
+  },
+  {
+    kReadOnlyDeviceSource,
+    kReadOnlyMountpath,
+    "/device/prefix/system_path_2",
+    "/device/file_path_2",
+    "/device/device_label_2",
+    "/device/drive_label_2",
+    "/device/vendor_id_2",
+    "/device/vendor_name_2",
+    "/device/product_id_2",
+    "/device/product_name_2",
+    "/device/fs_uuid_2",
+    "/device/prefix",
+    chromeos::DEVICE_TYPE_USB,
+    1073741824,  // size in bytes
+    false,  // is parent
+    true,  // is read only
     true,  // has media
     false,  // is on boot device
     true,  // is on removable device
@@ -95,6 +120,12 @@
     chromeos::MOUNT_TYPE_DEVICE,
     chromeos::disks::MOUNT_CONDITION_NONE
   },
+  {
+    kReadOnlyDeviceSource,
+    kReadOnlyMountpath,
+    chromeos::MOUNT_TYPE_DEVICE,
+    chromeos::disks::MOUNT_CONDITION_NONE
+  },
 };
 
 // Mocks DiskMountManager observer.
@@ -216,6 +247,17 @@
   DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent");
 }
 
+// Tests that the observer gets notified on attempt to format read-only mount
+// point.
+TEST_F(DiskMountManagerTest, Format_ReadOnly) {
+  EXPECT_CALL(observer_,
+              OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
+                            chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED,
+                            kReadOnlyMountpath))
+      .Times(1);
+  DiskMountManager::GetInstance()->FormatMountedDevice(kReadOnlyMountpath);
+}
+
 // Tests that it is not possible to format archive mount point.
 TEST_F(DiskMountManagerTest, Format_Archive) {
   EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,