Home | History | Annotate | Download | only in storage_monitor
      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 {
     73     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