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.
5 // StorageMonitorLinux processes mount point change events, notifies listeners
6 // about the addition and deletion of media devices, and answers queries about
8 // StorageMonitorLinux lives on the UI thread, and uses a MtabWatcherLinux on
9 // the FILE thread to get mount point change events.
11 #ifndef COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
12 #define COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
14 #if defined(OS_CHROMEOS)
15 #error "Use the ChromeOS-specific implementation instead."
21 #include "base/basictypes.h"
22 #include "base/compiler_specific.h"
23 #include "base/files/file_path.h"
24 #include "base/files/file_path_watcher.h"
25 #include "base/memory/scoped_ptr.h"
26 #include "base/memory/weak_ptr.h"
27 #include "components/storage_monitor/mtab_watcher_linux.h"
28 #include "components/storage_monitor/storage_monitor.h"
29 #include "content/public/browser/browser_thread.h"
31 namespace storage_monitor
{
33 class MediaTransferProtocolDeviceObserverLinux
;
35 class StorageMonitorLinux
: public StorageMonitor
,
36 public MtabWatcherLinux::Delegate
{
38 // Should only be called by browser start up code.
39 // Use StorageMonitor::GetInstance() instead.
40 // |mtab_file_path| is the path to a mtab file to watch for mount points.
41 explicit StorageMonitorLinux(const base::FilePath
& mtab_file_path
);
42 virtual ~StorageMonitorLinux();
44 // Must be called for StorageMonitorLinux to work.
45 virtual void Init() OVERRIDE
;
48 // Gets device information given a |device_path| and |mount_point|.
49 typedef base::Callback
<scoped_ptr
<StorageInfo
>(
50 const base::FilePath
& device_path
,
51 const base::FilePath
& mount_point
)> GetDeviceInfoCallback
;
53 void SetGetDeviceInfoCallbackForTest(
54 const GetDeviceInfoCallback
& get_device_info_callback
);
56 void SetMediaTransferProtocolManagerForTest(
57 device::MediaTransferProtocolManager
* test_manager
);
59 // MtabWatcherLinux::Delegate implementation.
60 virtual void UpdateMtab(
61 const MtabWatcherLinux::MountPointDeviceMap
& new_mtab
) OVERRIDE
;
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
;
71 // For use with scoped_ptr.
72 struct MtabWatcherLinuxDeleter
{
73 void operator()(MtabWatcherLinux
* mtab_watcher
) {
74 content::BrowserThread::DeleteSoon(content::BrowserThread::FILE,
75 FROM_HERE
, mtab_watcher
);
79 // Mapping of mount points to MountPointInfo.
80 typedef std::map
<base::FilePath
, MountPointInfo
> MountMap
;
82 // (mount point, priority)
83 // For devices that are mounted to multiple mount points, this helps us track
84 // which one we've notified system monitor about.
85 typedef std::map
<base::FilePath
, bool> ReferencedMountPoint
;
87 // (mount device, map of known mount points)
88 // For each mount device, track the places it is mounted and which one (if
89 // any) we have notified system monitor about.
90 typedef std::map
<base::FilePath
, ReferencedMountPoint
> MountPriorityMap
;
92 // StorageMonitor implementation.
93 virtual bool GetStorageInfoForPath(const base::FilePath
& path
,
94 StorageInfo
* device_info
) const OVERRIDE
;
95 virtual void EjectDevice(const std::string
& device_id
,
96 base::Callback
<void(EjectStatus
)> callback
) OVERRIDE
;
97 virtual device::MediaTransferProtocolManager
*
98 media_transfer_protocol_manager() OVERRIDE
;
100 // Called when the MtabWatcher has been created.
101 void OnMtabWatcherCreated(MtabWatcherLinux
* watcher
);
103 bool IsDeviceAlreadyMounted(const base::FilePath
& mount_device
) const;
105 // Assuming |mount_device| is already mounted, and it gets mounted again at
106 // |mount_point|, update the mappings.
107 void HandleDeviceMountedMultipleTimes(const base::FilePath
& mount_device
,
108 const base::FilePath
& mount_point
);
110 // Adds |mount_device| to the mappings and notify listeners, if any.
111 void AddNewMount(const base::FilePath
& mount_device
,
112 scoped_ptr
<StorageInfo
> storage_info
);
114 // Mtab file that lists the mount points.
115 const base::FilePath mtab_path_
;
117 // Callback to get device information. Set this to a custom callback for
119 GetDeviceInfoCallback get_device_info_callback_
;
121 // Mapping of relevant mount points and their corresponding mount devices.
122 // Keep in mind on Linux, a device can be mounted at multiple mount points,
123 // and multiple devices can be mounted at a mount point.
124 MountMap mount_info_map_
;
126 // Because a device can be mounted to multiple places, we only want to
127 // notify about one of them. If (and only if) that one is unmounted, we need
128 // to notify about it's departure and notify about another one of it's mount
130 MountPriorityMap mount_priority_map_
;
132 scoped_ptr
<device::MediaTransferProtocolManager
>
133 media_transfer_protocol_manager_
;
134 scoped_ptr
<MediaTransferProtocolDeviceObserverLinux
>
135 media_transfer_protocol_device_observer_
;
137 scoped_ptr
<MtabWatcherLinux
, MtabWatcherLinuxDeleter
> mtab_watcher_
;
139 base::WeakPtrFactory
<StorageMonitorLinux
> weak_ptr_factory_
;
141 DISALLOW_COPY_AND_ASSIGN(StorageMonitorLinux
);
144 } // namespace storage_monitor
146 #endif // COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_