1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // StorageMonitorLinux processes mount point change events, notifies listeners
6 // about the addition and deletion of media devices, and answers queries about
7 // mounted devices. StorageMonitorLinux uses a MtabWatcherLinux on a separate
8 // background sequence that is file IO capable.
10 #ifndef COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
11 #define COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
13 #include "build/chromeos_buildflags.h"
15 #if BUILDFLAG(IS_CHROMEOS_ASH)
16 #error "Use the ChromeOS-specific implementation instead."
23 #include "base/compiler_specific.h"
24 #include "base/files/file_path.h"
25 #include "base/memory/ref_counted.h"
26 #include "base/memory/weak_ptr.h"
27 #include "base/sequence_checker.h"
28 #include "build/build_config.h"
29 #include "components/storage_monitor/mtab_watcher_linux.h"
30 #include "components/storage_monitor/storage_monitor.h"
33 class SequencedTaskRunner;
36 namespace storage_monitor {
38 class StorageMonitorLinux : public StorageMonitor {
40 // Should only be called by browser start up code.
41 // Use StorageMonitor::GetInstance() instead.
42 // |mtab_file_path| is the path to a mtab file to watch for mount points.
43 explicit StorageMonitorLinux(const base::FilePath& mtab_file_path);
45 StorageMonitorLinux(const StorageMonitorLinux&) = delete;
46 StorageMonitorLinux& operator=(const StorageMonitorLinux&) = delete;
48 ~StorageMonitorLinux() override;
50 // Must be called for StorageMonitorLinux to work.
54 // Gets device information given a |device_path| and |mount_point|.
55 using GetDeviceInfoCallback =
56 base::RepeatingCallback<std::unique_ptr<StorageInfo>(
57 const base::FilePath& device_path,
58 const base::FilePath& mount_point)>;
60 void SetGetDeviceInfoCallbackForTest(
61 const GetDeviceInfoCallback& get_device_info_callback);
63 // Parses |new_mtab| and find all changes.
64 virtual void UpdateMtab(
65 const MtabWatcherLinux::MountPointDeviceMap& new_mtab);
68 // Structure to save mounted device information such as device path, unique
69 // identifier, device name and partition size.
70 struct MountPointInfo {
71 base::FilePath mount_device;
72 StorageInfo storage_info;
75 // Mapping of mount points to MountPointInfo.
76 using MountMap = std::map<base::FilePath, MountPointInfo>;
78 // (mount point, priority)
79 // For devices that are mounted to multiple mount points, this helps us track
80 // which one we've notified system monitor about.
81 using ReferencedMountPoint = std::map<base::FilePath, bool>;
83 // (mount device, map of known mount points)
84 // For each mount device, track the places it is mounted and which one (if
85 // any) we have notified system monitor about.
86 using MountPriorityMap = std::map<base::FilePath, ReferencedMountPoint>;
88 // StorageMonitor implementation.
89 bool GetStorageInfoForPath(const base::FilePath& path,
90 StorageInfo* device_info) const override;
91 void EjectDevice(const std::string& device_id,
92 base::OnceCallback<void(EjectStatus)> callback) override;
94 // Called when the MtabWatcher has been created.
95 void OnMtabWatcherCreated(std::unique_ptr<MtabWatcherLinux> watcher);
97 bool IsDeviceAlreadyMounted(const base::FilePath& mount_device) const;
99 // Assuming |mount_device| is already mounted, and it gets mounted again at
100 // |mount_point|, update the mappings.
101 void HandleDeviceMountedMultipleTimes(const base::FilePath& mount_device,
102 const base::FilePath& mount_point);
104 // Adds |mount_device| to the mappings and notify listeners, if any.
105 void AddNewMount(const base::FilePath& mount_device,
106 std::unique_ptr<StorageInfo> storage_info);
108 // Mtab file that lists the mount points.
109 const base::FilePath mtab_path_;
111 // Callback to get device information. Set this to a custom callback for
113 GetDeviceInfoCallback get_device_info_callback_;
115 // Mapping of relevant mount points and their corresponding mount devices.
116 // Keep in mind on Linux, a device can be mounted at multiple mount points,
117 // and multiple devices can be mounted at a mount point.
118 MountMap mount_info_map_;
120 // Because a device can be mounted to multiple places, we only want to
121 // notify about one of them. If (and only if) that one is unmounted, we need
122 // to notify about it's departure and notify about another one of it's mount
124 MountPriorityMap mount_priority_map_;
126 // Must be created and destroyed on |mtab_watcher_task_runner_|.
127 std::unique_ptr<MtabWatcherLinux> mtab_watcher_;
129 scoped_refptr<base::SequencedTaskRunner> mtab_watcher_task_runner_;
131 SEQUENCE_CHECKER(sequence_checker_);
133 base::WeakPtrFactory<StorageMonitorLinux> weak_ptr_factory_{this};
136 } // namespace storage_monitor
138 #endif // COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_