• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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