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 #ifndef COMPONENTS_STORAGE_MONITOR_VOLUME_MOUNT_WATCHER_WIN_H_
      6 #define COMPONENTS_STORAGE_MONITOR_VOLUME_MOUNT_WATCHER_WIN_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/callback.h"
     15 #include "base/files/file_path.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/sequenced_task_runner.h"
     18 #include "base/strings/string16.h"
     19 #include "base/threading/sequenced_worker_pool.h"
     20 #include "components/storage_monitor/storage_info.h"
     21 #include "components/storage_monitor/storage_monitor.h"
     22 
     23 namespace storage_monitor {
     24 
     25 class TestVolumeMountWatcherWin;
     26 
     27 // This class watches the volume mount points and sends notifications to
     28 // StorageMonitor about the device attach/detach events.
     29 // This is a singleton class instantiated by StorageMonitorWin.
     30 class VolumeMountWatcherWin {
     31  public:
     32   VolumeMountWatcherWin();
     33   virtual ~VolumeMountWatcherWin();
     34 
     35   // Returns the volume file path of the drive specified by the |drive_number|.
     36   // |drive_number| inputs of 0 - 25 are valid. Returns an empty file path if
     37   // the |drive_number| is invalid.
     38   static base::FilePath DriveNumberToFilePath(int drive_number);
     39 
     40   void Init();
     41 
     42   // Gets the information about the device mounted at |device_path|. On success,
     43   // returns true and fills in |info|.
     44   // Can block during startup while device info is still loading.
     45   bool GetDeviceInfo(const base::FilePath& device_path,
     46                      StorageInfo* info) const;
     47 
     48   // Processes DEV_BROADCAST_VOLUME messages and triggers a
     49   // notification if appropriate.
     50   void OnWindowMessage(UINT event_type, LPARAM data);
     51 
     52   // Processes SHCNE_MEDIAINSERTED (and REMOVED).
     53   void OnMediaChange(WPARAM wparam, LPARAM lparam);
     54 
     55   // Set the volume notifications object to be used when new
     56   // removable volumes are found.
     57   void SetNotifications(StorageMonitor::Receiver* notifications);
     58 
     59   void EjectDevice(const std::string& device_id,
     60                    base::Callback<void(StorageMonitor::EjectStatus)> callback);
     61 
     62  protected:
     63   typedef base::Callback<bool(const base::FilePath&,
     64                               StorageInfo*)> GetDeviceDetailsCallbackType;
     65 
     66   typedef base::Callback<std::vector<base::FilePath>(void)>
     67       GetAttachedDevicesCallbackType;
     68 
     69   // Handles mass storage device attach event on UI thread.
     70   void HandleDeviceAttachEventOnUIThread(
     71       const base::FilePath& device_path,
     72       const StorageInfo& info);
     73 
     74   // Handles mass storage device detach event on UI thread.
     75   void HandleDeviceDetachEventOnUIThread(const base::string16& device_location);
     76 
     77   // UI thread delegate to set up adding storage devices.
     78   void AddDevicesOnUIThread(std::vector<base::FilePath> removable_devices);
     79 
     80   // Runs |get_device_details_callback| for |device_path| on a worker thread.
     81   // |volume_watcher| points back to the VolumeMountWatcherWin that called it.
     82   static void RetrieveInfoForDeviceAndAdd(
     83       const base::FilePath& device_path,
     84       const GetDeviceDetailsCallbackType& get_device_details_callback,
     85       base::WeakPtr<VolumeMountWatcherWin> volume_watcher);
     86 
     87   // Mark that a device we started a metadata check for has completed.
     88   virtual void DeviceCheckComplete(const base::FilePath& device_path);
     89 
     90   virtual GetAttachedDevicesCallbackType GetAttachedDevicesCallback() const;
     91   virtual GetDeviceDetailsCallbackType GetDeviceDetailsCallback() const;
     92 
     93   // Worker pool used to collect device information. Used because some
     94   // devices freeze workers trying to get device info, resulting in
     95   // shutdown hangs.
     96   scoped_refptr<base::SequencedWorkerPool> device_info_worker_pool_;
     97   scoped_refptr<base::SequencedTaskRunner> task_runner_;
     98 
     99  private:
    100   friend class TestVolumeMountWatcherWin;
    101 
    102   // Key: Mass storage device mount point.
    103   // Value: Mass storage device metadata.
    104   typedef std::map<base::FilePath, StorageInfo> MountPointDeviceMetadataMap;
    105 
    106   // Maintain a set of device attribute check calls in-flight. Only accessed
    107   // on the UI thread. This is to try and prevent the same device from
    108   // occupying our worker pool in case of windows API call hangs.
    109   std::set<base::FilePath> pending_device_checks_;
    110 
    111   // A map from device mount point to device metadata. Only accessed on the UI
    112   // thread.
    113   MountPointDeviceMetadataMap device_metadata_;
    114 
    115   base::WeakPtrFactory<VolumeMountWatcherWin> weak_factory_;
    116 
    117   // The notifications object to use to signal newly attached volumes. Only
    118   // removable devices will be notified.
    119   StorageMonitor::Receiver* notifications_;
    120 
    121   DISALLOW_COPY_AND_ASSIGN(VolumeMountWatcherWin);
    122 };
    123 
    124 }  // namespace storage_monitor
    125 
    126 #endif  // COMPONENTS_STORAGE_MONITOR_VOLUME_MOUNT_WATCHER_WIN_H_
    127