• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
8 // StorageMonitorLinux lives on the UI thread, and uses a MtabWatcherLinux on
9 // the FILE thread to get mount point change events.
10 
11 #ifndef COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
12 #define COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
13 
14 #if defined(OS_CHROMEOS)
15 #error "Use the ChromeOS-specific implementation instead."
16 #endif
17 
18 #include <map>
19 #include <string>
20 
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"
30 
31 namespace storage_monitor {
32 
33 class MediaTransferProtocolDeviceObserverLinux;
34 
35 class StorageMonitorLinux : public StorageMonitor,
36                             public MtabWatcherLinux::Delegate {
37  public:
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();
43 
44   // Must be called for StorageMonitorLinux to work.
45   virtual void Init() OVERRIDE;
46 
47  protected:
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;
52 
53   void SetGetDeviceInfoCallbackForTest(
54       const GetDeviceInfoCallback& get_device_info_callback);
55 
56   void SetMediaTransferProtocolManagerForTest(
57       device::MediaTransferProtocolManager* test_manager);
58 
59   // MtabWatcherLinux::Delegate implementation.
60   virtual void UpdateMtab(
61       const MtabWatcherLinux::MountPointDeviceMap& new_mtab) OVERRIDE;
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   // For use with scoped_ptr.
72   struct MtabWatcherLinuxDeleter {
operatorMtabWatcherLinuxDeleter73     void operator()(MtabWatcherLinux* mtab_watcher) {
74       content::BrowserThread::DeleteSoon(content::BrowserThread::FILE,
75                                          FROM_HERE, mtab_watcher);
76     }
77   };
78 
79   // Mapping of mount points to MountPointInfo.
80   typedef std::map<base::FilePath, MountPointInfo> MountMap;
81 
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;
86 
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;
91 
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;
99 
100   // Called when the MtabWatcher has been created.
101   void OnMtabWatcherCreated(MtabWatcherLinux* watcher);
102 
103   bool IsDeviceAlreadyMounted(const base::FilePath& mount_device) const;
104 
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);
109 
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);
113 
114   // Mtab file that lists the mount points.
115   const base::FilePath mtab_path_;
116 
117   // Callback to get device information. Set this to a custom callback for
118   // testing.
119   GetDeviceInfoCallback get_device_info_callback_;
120 
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_;
125 
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
129   // points.
130   MountPriorityMap mount_priority_map_;
131 
132   scoped_ptr<device::MediaTransferProtocolManager>
133       media_transfer_protocol_manager_;
134   scoped_ptr<MediaTransferProtocolDeviceObserverLinux>
135       media_transfer_protocol_device_observer_;
136 
137   scoped_ptr<MtabWatcherLinux, MtabWatcherLinuxDeleter> mtab_watcher_;
138 
139   base::WeakPtrFactory<StorageMonitorLinux> weak_ptr_factory_;
140 
141   DISALLOW_COPY_AND_ASSIGN(StorageMonitorLinux);
142 };
143 
144 }  // namespace storage_monitor
145 
146 #endif  // COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
147