summaryrefslogtreecommitdiffstats
path: root/chromeos/disks/disk_mount_manager.h
blob: dfe80c367f82101dcf22bf18b7b504f8423cf10f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_DISKS_DISK_MOUNT_MANAGER_H_
#define CHROMEOS_DISKS_DISK_MOUNT_MANAGER_H_

#include <map>

#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/cros_disks_client.h"

namespace chromeos {
namespace disks {

// Types of events DiskMountManager sends to its observers.
enum DiskMountManagerEventType {
  MOUNT_DISK_ADDED,
  MOUNT_DISK_REMOVED,
  MOUNT_DISK_CHANGED,
  MOUNT_DISK_MOUNTED,
  MOUNT_DISK_UNMOUNTED,
  MOUNT_DEVICE_ADDED,
  MOUNT_DEVICE_REMOVED,
  MOUNT_DEVICE_SCANNED,
  MOUNT_FORMATTING_STARTED,
  MOUNT_FORMATTING_FINISHED,
};

// Condition of mounted filesystem.
enum MountCondition {
  MOUNT_CONDITION_NONE,
  MOUNT_CONDITION_UNKNOWN_FILESYSTEM,
  MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM,
};

// This class handles the interaction with cros-disks.
// Other classes can add themselves as observers.
class CHROMEOS_EXPORT DiskMountManager {
 public:
  // Event type given to observers' MountCompleted method.
  enum MountEvent {
    MOUNTING,
    UNMOUNTING,
  };

  // Used to house an instance of each found mount device.
  class Disk {
   public:
    Disk(const std::string& device_path,
         const std::string& mount_path,
         const std::string& system_path,
         const std::string& file_path,
         const std::string& device_label,
         const std::string& drive_label,
         const std::string& fs_uuid,
         const std::string& system_path_prefix,
         DeviceType device_type,
         uint64 total_size_in_bytes,
         bool is_parent,
         bool is_read_only,
         bool has_media,
         bool on_boot_device,
         bool is_hidden);
    ~Disk();

    // The path of the device, used by devicekit-disks.
    // (e.g. /sys/devices/pci0000:00/.../8:0:0:0/block/sdb/sdb1)
    const std::string& device_path() const { return device_path_; }

    // The path to the mount point of this device. Will be empty if not mounted.
    // (e.g. /media/removable/VOLUME)
    const std::string&  mount_path() const { return mount_path_; }

    // The path of the device according to the udev system.
    // (e.g. /sys/devices/pci0000:00/.../8:0:0:0/block/sdb/sdb1)
    const std::string& system_path() const { return system_path_; }

    // The path of the device according to filesystem.
    // (e.g. /dev/sdb)
    const std::string& file_path() const { return file_path_; }

    // Device's label.
    const std::string& device_label() const { return device_label_; }

    // If disk is a parent, then its label, else parents label.
    // (e.g. "TransMemory")
    const std::string& drive_label() const { return drive_label_; }

    // Returns the file system uuid string.
    const std::string& fs_uuid() const { return fs_uuid_; }

    // Path of the system device this device's block is a part of.
    // (e.g. /sys/devices/pci0000:00/.../8:0:0:0/)
    const std::string& system_path_prefix() const {
      return system_path_prefix_;
    }

    // Device type.
    DeviceType device_type() const { return device_type_; }

    // Total size of the device in bytes.
    uint64 total_size_in_bytes() const { return total_size_in_bytes_; }

    // Is the device is a parent device (i.e. sdb rather than sdb1).
    bool is_parent() const { return is_parent_; }

    // Is the device read only.
    bool is_read_only() const { return is_read_only_; }

    // Does the device contains media.
    bool has_media() const { return has_media_; }

    // Is the device on the boot device.
    bool on_boot_device() const { return on_boot_device_; }

    // Shoud the device be shown in the UI, or automounted.
    bool is_hidden() const { return is_hidden_; }

    void set_mount_path(const std::string& mount_path) {
      mount_path_ = mount_path;
    }

    void clear_mount_path() { mount_path_.clear(); }

   private:
    std::string device_path_;
    std::string mount_path_;
    std::string system_path_;
    std::string file_path_;
    std::string device_label_;
    std::string drive_label_;
    std::string fs_uuid_;
    std::string system_path_prefix_;
    DeviceType device_type_;
    uint64 total_size_in_bytes_;
    bool is_parent_;
    bool is_read_only_;
    bool has_media_;
    bool on_boot_device_;
    bool is_hidden_;
  };
  typedef std::map<std::string, Disk*> DiskMap;

  // A struct to store information about mount point.
  struct MountPointInfo {
    // Device's path.
    std::string source_path;
    // Mounted path.
    std::string mount_path;
    // Type of mount.
    MountType mount_type;
    // Condition of mount.
    MountCondition mount_condition;

    MountPointInfo(const std::string& source,
                   const std::string& mount,
                   const MountType type,
                   MountCondition condition)
        : source_path(source),
          mount_path(mount),
          mount_type(type),
          mount_condition(condition) {
    }
  };

  // MountPointMap key is mount_path.
  typedef std::map<std::string, MountPointInfo> MountPointMap;

  // A callback function type which is called after UnmountDeviceRecursive
  // finishes.
  typedef void(*UnmountDeviceRecursiveCallbackType)(void*, bool);

  // Implement this interface to be notified about disk/mount related events.
  class Observer {
   public:
    virtual ~Observer() {}

    // A function called when disk mount status is changed.
    virtual void DiskChanged(DiskMountManagerEventType event,
                             const Disk* disk) = 0;
    // A function called when device status is changed.
    virtual void DeviceChanged(DiskMountManagerEventType event,
                               const std::string& device_path) = 0;
    // A function called after mount is completed.
    virtual void MountCompleted(MountEvent event_type,
                                MountError error_code,
                                const MountPointInfo& mount_info) = 0;
  };

  virtual ~DiskMountManager() {}

  // Adds an observer.
  virtual void AddObserver(Observer* observer) = 0;

  // Removes an observer.
  virtual void RemoveObserver(Observer* observer) = 0;

  // Gets the list of disks found.
  virtual const DiskMap& disks() const = 0;

  // Returns Disk object corresponding to |source_path| or NULL on failure.
  virtual const Disk* FindDiskBySourcePath(
      const std::string& source_path) const = 0;

  // Gets the list of mount points.
  virtual const MountPointMap& mount_points() const = 0;

  // Requests refreshing all the information about mounted disks.
  virtual void RequestMountInfoRefresh() = 0;

  // Mounts a device.
  virtual void MountPath(const std::string& source_path,
                         const std::string& source_format,
                         const std::string& mount_label,
                         MountType type) = 0;

  // Unmounts a mounted disk.
  virtual void UnmountPath(const std::string& mount_path) = 0;

  // Formats device given its file path.
  // Example: file_path: /dev/sdb1
  virtual void FormatUnmountedDevice(const std::string& file_path) = 0;

  // Formats Device given its mount path. Unmounts the device.
  // Example: mount_path: /media/VOLUME_LABEL
  virtual void FormatMountedDevice(const std::string& mount_path) = 0;

  // Unmounts device_path and all of its known children.
  virtual void UnmountDeviceRecursive(
      const std::string& device_path,
      UnmountDeviceRecursiveCallbackType callback,
      void* user_data) = 0;

  // Returns corresponding string to |type| like "device" or "file".
  static std::string MountTypeToString(MountType type);

  // The inverse function of MountTypeToString.
  static MountType MountTypeFromString(const std::string& type_str);

  // Returns corresponding string to |type| like "unknown_filesystem".
  static std::string MountConditionToString(MountCondition type);

  // Returns corresponding string to |type|, like "sd", "usb".
  static std::string DeviceTypeToString(DeviceType type);

  // Creates the global DiskMountManager instance.
  static void Initialize();

  // Similar to Initialize(), but can inject an alternative
  // DiskMountManager such as MockDiskMountManager for testing.
  // The injected object will be owned by the internal pointer and deleted
  // by Shutdown().
  static void InitializeForTesting(DiskMountManager* disk_mount_manager);

  // Destroys the global DiskMountManager instance if it exists.
  static void Shutdown();

  // Returns a pointer to the global DiskMountManager instance.
  // Initialize() should already have been called.
  static DiskMountManager* GetInstance();
};

}  // namespace disks
}  // namespace chromeos

#endif  // CHROMEOS_DISKS_DISK_MOUNT_MANAGER_H_