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