Home | History | Annotate | Download | only in disks
      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)
     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)
     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)
     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)
     90     const std::string& file_path() const { return file_path_; }
     91 
     92     // Device's 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")
     97     const std::string& drive_label() const { return drive_label_; }
     98 
     99     // Vendor ID of the device (e.g. "18d1").
    100     const std::string& vendor_id() const { return vendor_id_; }
    101 
    102     // Vendor name of the device (e.g. "Google Inc.").
    103     const std::string& vendor_name() const { return vendor_name_; }
    104 
    105     // Product ID of the device (e.g. "4e11").
    106     const std::string& product_id() const { return product_id_; }
    107 
    108     // Product name of the device (e.g. "Nexus One").
    109     const std::string& product_name() const { return product_name_; }
    110 
    111     // Returns the file system uuid string.
    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/)
    116     const std::string& system_path_prefix() const {
    117       return system_path_prefix_;
    118     }
    119 
    120     // Device type.
    121     DeviceType device_type() const { return device_type_; }
    122 
    123     // Total size of the device 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).
    127     bool is_parent() const { return is_parent_; }
    128 
    129     // Is the device read only.
    130     bool is_read_only() const { return is_read_only_; }
    131 
    132     // Does the device contains media.
    133     bool has_media() const { return has_media_; }
    134 
    135     // Is the device on the boot device.
    136     bool on_boot_device() const { return on_boot_device_; }
    137 
    138     // Is the device on the removable device.
    139     bool on_removable_device() const { return on_removable_device_; }
    140 
    141     // Shoud the device be shown in the UI, or automounted.
    142     bool is_hidden() const { return is_hidden_; }
    143 
    144     void set_mount_path(const std::string& mount_path) {
    145       mount_path_ = mount_path;
    146     }
    147 
    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 
    185     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:
    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 
    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