1 // Copyright 2014 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 // 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. 9 10 #ifndef COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_ 11 #define COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_ 12 13 #if defined(OS_CHROMEOS) 14 #error "Use the ChromeOS-specific implementation instead." 15 #endif 16 17 #include <map> 18 #include <memory> 19 #include <string> 20 21 #include "base/compiler_specific.h" 22 #include "base/files/file_path.h" 23 #include "base/files/file_path_watcher.h" 24 #include "base/macros.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" 31 32 namespace base { 33 class SequencedTaskRunner; 34 } 35 36 namespace storage_monitor { 37 38 class StorageMonitorLinux : public StorageMonitor { 39 public: 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); 44 ~StorageMonitorLinux() override; 45 46 // Must be called for StorageMonitorLinux to work. 47 void Init() override; 48 49 protected: 50 // Gets device information given a |device_path| and |mount_point|. 51 using GetDeviceInfoCallback = 52 base::RepeatingCallback<std::unique_ptr<StorageInfo>( 53 const base::FilePath& device_path, 54 const base::FilePath& mount_point)>; 55 56 void SetGetDeviceInfoCallbackForTest( 57 const GetDeviceInfoCallback& get_device_info_callback); 58 59 // Parses |new_mtab| and find all changes. 60 virtual void UpdateMtab( 61 const MtabWatcherLinux::MountPointDeviceMap& new_mtab); 62 63 private: 64 // Structure to save mounted device information such as device path, unique 65 // identifier, device name and partition size. 66 struct MountPointInfo { 67 base::FilePath mount_device; 68 StorageInfo storage_info; 69 }; 70 71 // Mapping of mount points to MountPointInfo. 72 using MountMap = std::map<base::FilePath, MountPointInfo>; 73 74 // (mount point, priority) 75 // For devices that are mounted to multiple mount points, this helps us track 76 // which one we've notified system monitor about. 77 using ReferencedMountPoint = std::map<base::FilePath, bool>; 78 79 // (mount device, map of known mount points) 80 // For each mount device, track the places it is mounted and which one (if 81 // any) we have notified system monitor about. 82 using MountPriorityMap = std::map<base::FilePath, ReferencedMountPoint>; 83 84 // StorageMonitor implementation. 85 bool GetStorageInfoForPath(const base::FilePath& path, 86 StorageInfo* device_info) const override; 87 void EjectDevice(const std::string& device_id, 88 base::OnceCallback<void(EjectStatus)> callback) override; 89 90 // Called when the MtabWatcher has been created. 91 void OnMtabWatcherCreated(std::unique_ptr<MtabWatcherLinux> watcher); 92 93 bool IsDeviceAlreadyMounted(const base::FilePath& mount_device) const; 94 95 // Assuming |mount_device| is already mounted, and it gets mounted again at 96 // |mount_point|, update the mappings. 97 void HandleDeviceMountedMultipleTimes(const base::FilePath& mount_device, 98 const base::FilePath& mount_point); 99 100 // Adds |mount_device| to the mappings and notify listeners, if any. 101 void AddNewMount(const base::FilePath& mount_device, 102 std::unique_ptr<StorageInfo> storage_info); 103 104 // Mtab file that lists the mount points. 105 const base::FilePath mtab_path_; 106 107 // Callback to get device information. Set this to a custom callback for 108 // testing. 109 GetDeviceInfoCallback get_device_info_callback_; 110 111 // Mapping of relevant mount points and their corresponding mount devices. 112 // Keep in mind on Linux, a device can be mounted at multiple mount points, 113 // and multiple devices can be mounted at a mount point. 114 MountMap mount_info_map_; 115 116 // Because a device can be mounted to multiple places, we only want to 117 // notify about one of them. If (and only if) that one is unmounted, we need 118 // to notify about it's departure and notify about another one of it's mount 119 // points. 120 MountPriorityMap mount_priority_map_; 121 122 // Must be created and destroyed on |mtab_watcher_task_runner_|. 123 std::unique_ptr<MtabWatcherLinux> mtab_watcher_; 124 125 scoped_refptr<base::SequencedTaskRunner> mtab_watcher_task_runner_; 126 127 SEQUENCE_CHECKER(sequence_checker_); 128 129 base::WeakPtrFactory<StorageMonitorLinux> weak_ptr_factory_{this}; 130 131 DISALLOW_COPY_AND_ASSIGN(StorageMonitorLinux); 132 }; 133 134 } // namespace storage_monitor 135 136 #endif // COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_ 137