Home | History | Annotate | Download | only in storage_monitor
      1 // Copyright (c) 2012 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 CHROME_BROWSER_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
     12 #define CHROME_BROWSER_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 "chrome/browser/storage_monitor/mtab_watcher_linux.h"
     28 #include "chrome/browser/storage_monitor/storage_monitor.h"
     29 #include "content/public/browser/browser_thread.h"
     30 
     31 class MediaTransferProtocolDeviceObserverLinux;
     32 
     33 class StorageMonitorLinux : public StorageMonitor,
     34                             public MtabWatcherLinux::Delegate {
     35  public:
     36   // Should only be called by browser start up code.
     37   // Use StorageMonitor::GetInstance() instead.
     38   // |mtab_file_path| is the path to a mtab file to watch for mount points.
     39   explicit StorageMonitorLinux(const base::FilePath& mtab_file_path);
     40   virtual ~StorageMonitorLinux();
     41 
     42   // Must be called for StorageMonitorLinux to work.
     43   virtual void Init() OVERRIDE;
     44 
     45  protected:
     46   // Gets device information given a |device_path| and |mount_point|.
     47   typedef base::Callback<scoped_ptr<StorageInfo>(
     48       const base::FilePath& device_path,
     49       const base::FilePath& mount_point)> GetDeviceInfoCallback;
     50 
     51   void SetGetDeviceInfoCallbackForTest(
     52       const GetDeviceInfoCallback& get_device_info_callback);
     53 
     54   void SetMediaTransferProtocolManagerForTest(
     55       device::MediaTransferProtocolManager* test_manager);
     56 
     57   // MtabWatcherLinux::Delegate implementation.
     58   virtual void UpdateMtab(
     59       const MtabWatcherLinux::MountPointDeviceMap& new_mtab) OVERRIDE;
     60 
     61  private:
     62   // Structure to save mounted device information such as device path, unique
     63   // identifier, device name and partition size.
     64   struct MountPointInfo {
     65     base::FilePath mount_device;
     66     StorageInfo storage_info;
     67   };
     68 
     69   // For use with scoped_ptr.
     70   struct MtabWatcherLinuxDeleter {
     71     void operator()(MtabWatcherLinux* mtab_watcher) {
     72       content::BrowserThread::DeleteSoon(content::BrowserThread::FILE,
     73                                          FROM_HERE, mtab_watcher);
     74     }
     75   };
     76 
     77   // Mapping of mount points to MountPointInfo.
     78   typedef std::map<base::FilePath, MountPointInfo> MountMap;
     79 
     80   // (mount point, priority)
     81   // For devices that are mounted to multiple mount points, this helps us track
     82   // which one we've notified system monitor about.
     83   typedef std::map<base::FilePath, bool> ReferencedMountPoint;
     84 
     85   // (mount device, map of known mount points)
     86   // For each mount device, track the places it is mounted and which one (if
     87   // any) we have notified system monitor about.
     88   typedef std::map<base::FilePath, ReferencedMountPoint> MountPriorityMap;
     89 
     90   // StorageMonitor implementation.
     91   virtual bool GetStorageInfoForPath(const base::FilePath& path,
     92                                      StorageInfo* device_info) const OVERRIDE;
     93   virtual void EjectDevice(const std::string& device_id,
     94                            base::Callback<void(EjectStatus)> callback) OVERRIDE;
     95   virtual device::MediaTransferProtocolManager*
     96       media_transfer_protocol_manager() OVERRIDE;
     97 
     98   // Called when the MtabWatcher has been created.
     99   void OnMtabWatcherCreated(MtabWatcherLinux* watcher);
    100 
    101   bool IsDeviceAlreadyMounted(const base::FilePath& mount_device) const;
    102 
    103   // Assuming |mount_device| is already mounted, and it gets mounted again at
    104   // |mount_point|, update the mappings.
    105   void HandleDeviceMountedMultipleTimes(const base::FilePath& mount_device,
    106                                         const base::FilePath& mount_point);
    107 
    108   // Adds |mount_device| to the mappings and notify listeners, if any.
    109   void AddNewMount(const base::FilePath& mount_device,
    110                    scoped_ptr<StorageInfo> storage_info);
    111 
    112   // Mtab file that lists the mount points.
    113   const base::FilePath mtab_path_;
    114 
    115   // Callback to get device information. Set this to a custom callback for
    116   // testing.
    117   GetDeviceInfoCallback get_device_info_callback_;
    118 
    119   // Mapping of relevant mount points and their corresponding mount devices.
    120   // Keep in mind on Linux, a device can be mounted at multiple mount points,
    121   // and multiple devices can be mounted at a mount point.
    122   MountMap mount_info_map_;
    123 
    124   // Because a device can be mounted to multiple places, we only want to
    125   // notify about one of them. If (and only if) that one is unmounted, we need
    126   // to notify about it's departure and notify about another one of it's mount
    127   // points.
    128   MountPriorityMap mount_priority_map_;
    129 
    130   scoped_ptr<device::MediaTransferProtocolManager>
    131       media_transfer_protocol_manager_;
    132   scoped_ptr<MediaTransferProtocolDeviceObserverLinux>
    133       media_transfer_protocol_device_observer_;
    134 
    135   scoped_ptr<MtabWatcherLinux, MtabWatcherLinuxDeleter> mtab_watcher_;
    136 
    137   base::WeakPtrFactory<StorageMonitorLinux> weak_ptr_factory_;
    138 
    139   DISALLOW_COPY_AND_ASSIGN(StorageMonitorLinux);
    140 };
    141 
    142 #endif  // CHROME_BROWSER_STORAGE_MONITOR_STORAGE_MONITOR_LINUX_H_
    143