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 3 // found in the LICENSE file. 4 5 #ifndef CHROMEOS_DISKS_DISK_MOUNT_MANAGER_H_ 6 #define CHROMEOS_DISKS_DISK_MOUNT_MANAGER_H_ 7 8 #include <map> 9 10 #include "base/callback_forward.h" 11 #include "chromeos/chromeos_export.h" 12 #include "chromeos/dbus/cros_disks_client.h" 13 14 namespace chromeos { 15 namespace disks { 16 17 // Condition of mounted filesystem. 18 enum MountCondition { 19 MOUNT_CONDITION_NONE, 20 MOUNT_CONDITION_UNKNOWN_FILESYSTEM, 21 MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM, 22 }; 23 24 // This class handles the interaction with cros-disks. 25 // Other classes can add themselves as observers. 26 class CHROMEOS_EXPORT DiskMountManager { 27 public: 28 // Event types passed to the observers. 29 enum DiskEvent { 30 DISK_ADDED, 31 DISK_REMOVED, 32 DISK_CHANGED, 33 }; 34 35 enum DeviceEvent { 36 DEVICE_ADDED, 37 DEVICE_REMOVED, 38 DEVICE_SCANNED, 39 }; 40 41 enum MountEvent { 42 MOUNTING, 43 UNMOUNTING, 44 }; 45 46 enum FormatEvent { 47 FORMAT_STARTED, 48 FORMAT_COMPLETED 49 }; 50 51 // Used to house an instance of each found mount device. 52 class Disk { 53 public: 54 Disk(const std::string& device_path, 55 const std::string& mount_path, 56 const std::string& system_path, 57 const std::string& file_path, 58 const std::string& device_label, 59 const std::string& drive_label, 60 const std::string& vendor_id, 61 const std::string& vendor_name, 62 const std::string& product_id, 63 const std::string& product_name, 64 const std::string& fs_uuid, 65 const std::string& system_path_prefix, 66 DeviceType device_type, 67 uint64 total_size_in_bytes, 68 bool is_parent, 69 bool is_read_only, 70 bool has_media, 71 bool on_boot_device, 72 bool on_removable_device, 73 bool is_hidden); 74 ~Disk(); 75 76 // The path of the device, used by devicekit-disks. 77 // (e.g. /sys/devices/pci0000:00/.../8:0:0:0/block/sdb/sdb1) device_path()78 const std::string& device_path() const { return device_path_; } 79 80 // The path to the mount point of this device. Will be empty if not mounted. 81 // (e.g. /media/removable/VOLUME) mount_path()82 const std::string& mount_path() const { return mount_path_; } 83 84 // The path of the device according to the udev system. 85 // (e.g. /sys/devices/pci0000:00/.../8:0:0:0/block/sdb/sdb1) system_path()86 const std::string& system_path() const { return system_path_; } 87 88 // The path of the device according to filesystem. 89 // (e.g. /dev/sdb) file_path()90 const std::string& file_path() const { return file_path_; } 91 92 // Device's label. device_label()93 const std::string& device_label() const { return device_label_; } 94 95 // If disk is a parent, then its label, else parents label. 96 // (e.g. "TransMemory") drive_label()97 const std::string& drive_label() const { return drive_label_; } 98 99 // Vendor ID of the device (e.g. "18d1"). vendor_id()100 const std::string& vendor_id() const { return vendor_id_; } 101 102 // Vendor name of the device (e.g. "Google Inc."). vendor_name()103 const std::string& vendor_name() const { return vendor_name_; } 104 105 // Product ID of the device (e.g. "4e11"). product_id()106 const std::string& product_id() const { return product_id_; } 107 108 // Product name of the device (e.g. "Nexus One"). product_name()109 const std::string& product_name() const { return product_name_; } 110 111 // Returns the file system uuid string. fs_uuid()112 const std::string& fs_uuid() const { return fs_uuid_; } 113 114 // Path of the system device this device's block is a part of. 115 // (e.g. /sys/devices/pci0000:00/.../8:0:0:0/) system_path_prefix()116 const std::string& system_path_prefix() const { 117 return system_path_prefix_; 118 } 119 120 // Device type. device_type()121 DeviceType device_type() const { return device_type_; } 122 123 // Total size of the device in bytes. total_size_in_bytes()124 uint64 total_size_in_bytes() const { return total_size_in_bytes_; } 125 126 // Is the device is a parent device (i.e. sdb rather than sdb1). is_parent()127 bool is_parent() const { return is_parent_; } 128 129 // Is the device read only. is_read_only()130 bool is_read_only() const { return is_read_only_; } 131 132 // Does the device contains media. has_media()133 bool has_media() const { return has_media_; } 134 135 // Is the device on the boot device. on_boot_device()136 bool on_boot_device() const { return on_boot_device_; } 137 138 // Is the device on the removable device. on_removable_device()139 bool on_removable_device() const { return on_removable_device_; } 140 141 // Shoud the device be shown in the UI, or automounted. is_hidden()142 bool is_hidden() const { return is_hidden_; } 143 set_mount_path(const std::string & mount_path)144 void set_mount_path(const std::string& mount_path) { 145 mount_path_ = mount_path; 146 } 147 clear_mount_path()148 void clear_mount_path() { mount_path_.clear(); } 149 150 private: 151 std::string device_path_; 152 std::string mount_path_; 153 std::string system_path_; 154 std::string file_path_; 155 std::string device_label_; 156 std::string drive_label_; 157 std::string vendor_id_; 158 std::string vendor_name_; 159 std::string product_id_; 160 std::string product_name_; 161 std::string fs_uuid_; 162 std::string system_path_prefix_; 163 DeviceType device_type_; 164 uint64 total_size_in_bytes_; 165 bool is_parent_; 166 bool is_read_only_; 167 bool has_media_; 168 bool on_boot_device_; 169 bool on_removable_device_; 170 bool is_hidden_; 171 }; 172 typedef std::map<std::string, Disk*> DiskMap; 173 174 // A struct to store information about mount point. 175 struct MountPointInfo { 176 // Device's path. 177 std::string source_path; 178 // Mounted path. 179 std::string mount_path; 180 // Type of mount. 181 MountType mount_type; 182 // Condition of mount. 183 MountCondition mount_condition; 184 MountPointInfoMountPointInfo185 MountPointInfo(const std::string& source, 186 const std::string& mount, 187 const MountType type, 188 MountCondition condition) 189 : source_path(source), 190 mount_path(mount), 191 mount_type(type), 192 mount_condition(condition) { 193 } 194 }; 195 196 // MountPointMap key is mount_path. 197 typedef std::map<std::string, MountPointInfo> MountPointMap; 198 199 // A callback function type which is called after UnmountDeviceRecursively 200 // finishes. 201 typedef base::Callback<void(bool)> UnmountDeviceRecursivelyCallbackType; 202 203 // A callback type for UnmountPath method. 204 typedef base::Callback<void(MountError error_code)> UnmountPathCallback; 205 206 // A callback type for EnsureMountInfoRefreshed method. 207 typedef base::Callback<void(bool success)> EnsureMountInfoRefreshedCallback; 208 209 // Implement this interface to be notified about disk/mount related events. 210 class Observer { 211 public: ~Observer()212 virtual ~Observer() {} 213 214 // Called when disk mount status is changed. 215 virtual void OnDiskEvent(DiskEvent event, const Disk* disk) = 0; 216 // Called when device status is changed. 217 virtual void OnDeviceEvent(DeviceEvent event, 218 const std::string& device_path) = 0; 219 // Called after a mount point has been mounted or unmounted. 220 virtual void OnMountEvent(MountEvent event, 221 MountError error_code, 222 const MountPointInfo& mount_info) = 0; 223 // Called on format process events. 224 virtual void OnFormatEvent(FormatEvent event, 225 FormatError error_code, 226 const std::string& device_path) = 0; 227 }; 228 ~DiskMountManager()229 virtual ~DiskMountManager() {} 230 231 // Adds an observer. 232 virtual void AddObserver(Observer* observer) = 0; 233 234 // Removes an observer. 235 virtual void RemoveObserver(Observer* observer) = 0; 236 237 // Gets the list of disks found. 238 virtual const DiskMap& disks() const = 0; 239 240 // Returns Disk object corresponding to |source_path| or NULL on failure. 241 virtual const Disk* FindDiskBySourcePath( 242 const std::string& source_path) const = 0; 243 244 // Gets the list of mount points. 245 virtual const MountPointMap& mount_points() const = 0; 246 247 // Refreshes all the information about mounting if it is not yet done and 248 // invokes |callback| when finished. If the information is already refreshed 249 // It just runs |callback| immediately. 250 virtual void EnsureMountInfoRefreshed( 251 const EnsureMountInfoRefreshedCallback& callback) = 0; 252 253 // Mounts a device. 254 // Note that the mount operation may fail. To find out the result, one should 255 // observe DiskMountManager for |Observer::OnMountEvent| event, which will be 256 // raised upon the mount operation completion. 257 virtual void MountPath(const std::string& source_path, 258 const std::string& source_format, 259 const std::string& mount_label, 260 MountType type) = 0; 261 262 // Unmounts a mounted disk. 263 // |UnmountOptions| enum defined in chromeos/dbus/cros_disks_client.h. 264 // When the method is complete, |callback| will be called and observers' 265 // |OnMountEvent| will be raised. 266 // 267 // |callback| may be empty, in which case it gets ignored. 268 virtual void UnmountPath(const std::string& mount_path, 269 UnmountOptions options, 270 const UnmountPathCallback& callback) = 0; 271 272 // Formats Device given its mount path. Unmounts the device. 273 // Example: mount_path: /media/VOLUME_LABEL 274 virtual void FormatMountedDevice(const std::string& mount_path) = 0; 275 276 // Unmounts device_path and all of its known children. 277 virtual void UnmountDeviceRecursively( 278 const std::string& device_path, 279 const UnmountDeviceRecursivelyCallbackType& callback) = 0; 280 281 // Used in tests to initialize the manager's disk and mount point sets. 282 // Default implementation does noting. It just fails. 283 virtual bool AddDiskForTest(Disk* disk); 284 virtual bool AddMountPointForTest(const MountPointInfo& mount_point); 285 286 // Returns corresponding string to |type| like "unknown_filesystem". 287 static std::string MountConditionToString(MountCondition type); 288 289 // Returns corresponding string to |type|, like "sd", "usb". 290 static std::string DeviceTypeToString(DeviceType type); 291 292 // Creates the global DiskMountManager instance. 293 static void Initialize(); 294 295 // Similar to Initialize(), but can inject an alternative 296 // DiskMountManager such as MockDiskMountManager for testing. 297 // The injected object will be owned by the internal pointer and deleted 298 // by Shutdown(). 299 static void InitializeForTesting(DiskMountManager* disk_mount_manager); 300 301 // Destroys the global DiskMountManager instance if it exists. 302 static void Shutdown(); 303 304 // Returns a pointer to the global DiskMountManager instance. 305 // Initialize() should already have been called. 306 static DiskMountManager* GetInstance(); 307 }; 308 309 } // namespace disks 310 } // namespace chromeos 311 312 #endif // CHROMEOS_DISKS_DISK_MOUNT_MANAGER_H_ 313