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_STORAGE_MONITOR_H_
      6 #define COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/callback.h"
     13 #include "base/files/file_path.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/observer_list_threadsafe.h"
     16 #include "base/strings/string16.h"
     17 #include "base/synchronization/lock.h"
     18 #include "base/threading/thread_checker.h"
     19 #include "components/storage_monitor/storage_info.h"
     20 
     21 class MediaFileSystemRegistryTest;
     22 class MediaGalleriesPlatformAppBrowserTest;
     23 class SystemStorageApiTest;
     24 class SystemStorageEjectApiTest;
     25 
     26 namespace device {
     27 class MediaTransferProtocolManager;
     28 }
     29 
     30 namespace storage_monitor {
     31 
     32 class RemovableStorageObserver;
     33 class TransientDeviceIds;
     34 
     35 // Base class for platform-specific instances watching for removable storage
     36 // attachments/detachments.
     37 // Lifecycle contracts: This class is created in the browser process
     38 // before the profile is initialized, so listeners can be
     39 // created during profile construction. The platform-specific initialization,
     40 // which can lead to calling registered listeners with notifications of
     41 // attached volumes, are done lazily at first use through the async
     42 // |EnsureInitialized()| method. That must be done before any of the registered
     43 // listeners will receive updates or calls to other API methods return
     44 // meaningful results.
     45 // A post-initialization |GetAttachedStorage()| call coupled with a
     46 // registered listener will receive a complete set, albeit potentially with
     47 // duplicates. This is because there's no tracking between when listeners were
     48 // registered and the state of initialization, and the fact that platforms
     49 // behave differently in how these notifications are provided.
     50 class StorageMonitor {
     51  public:
     52   // This interface is provided to generators of storage notifications.
     53   class Receiver {
     54    public:
     55     virtual ~Receiver();
     56 
     57     virtual void ProcessAttach(const StorageInfo& info) = 0;
     58     virtual void ProcessDetach(const std::string& id) = 0;
     59     virtual void MarkInitialized() = 0;
     60   };
     61 
     62   // Status codes for the result of an EjectDevice() call.
     63   enum EjectStatus {
     64     EJECT_OK,
     65     EJECT_IN_USE,
     66     EJECT_NO_SUCH_DEVICE,
     67     EJECT_FAILURE
     68   };
     69 
     70   // Instantiates the StorageMonitor singleton. This function does not
     71   // guarantee the complete initialization of the object. For that, see
     72   // |EnsureInitialized|.
     73   static void Create();
     74 
     75   // Destroys the StorageMonitor singleton.
     76   static void Destroy();
     77 
     78   // Returns a pointer to an object owned by BrowserProcess, with lifetime
     79   // starting before main message loop start, and ending after main message loop
     80   // shutdown. Called outside it's lifetime (or with no browser process),
     81   // returns NULL.
     82   static StorageMonitor* GetInstance();
     83 
     84   static void SetStorageMonitorForTesting(
     85       scoped_ptr<StorageMonitor> storage_monitor);
     86 
     87   virtual ~StorageMonitor();
     88 
     89   // Ensures that the storage monitor is initialized. The provided callback, if
     90   // non-null, will be called when initialization is complete. If initialization
     91   // has already completed, this callback will be invoked within the calling
     92   // stack. Before the callback is run, calls to |GetAllAvailableStorages| and
     93   // |GetStorageInfoForPath| may not return the correct results. In addition,
     94   // registered observers will not be notified on device attachment/detachment.
     95   // Should be invoked on the UI thread; callbacks will be run on the UI thread.
     96   void EnsureInitialized(base::Closure callback);
     97 
     98   // Return true if the storage monitor has already been initialized.
     99   bool IsInitialized() const;
    100 
    101   // Finds the device that contains |path| and populates |device_info|.
    102   // Should be able to handle any path on the local system, not just removable
    103   // storage. Returns false if unable to find the device.
    104   virtual bool GetStorageInfoForPath(
    105       const base::FilePath& path,
    106       StorageInfo* device_info) const = 0;
    107 
    108 // TODO(gbillock): make this either unnecessary (implementation-specific) or
    109 // platform-independent.
    110 #if defined(OS_WIN)
    111   // Gets the MTP device storage information specified by |storage_device_id|.
    112   // On success, returns true and fills in |device_location| with device
    113   // interface details and |storage_object_id| with the string ID that
    114   // uniquely identifies the object on the device. This ID need not be
    115   // persistent across sessions.
    116   virtual bool GetMTPStorageInfoFromDeviceId(
    117       const std::string& storage_device_id,
    118       base::string16* device_location,
    119       base::string16* storage_object_id) const = 0;
    120 #endif
    121 
    122 #if defined(OS_LINUX)
    123   virtual device::MediaTransferProtocolManager*
    124       media_transfer_protocol_manager() = 0;
    125 #endif
    126 
    127   // Returns information for all known storages on the system,
    128   // including fixed and removable storages.
    129   std::vector<StorageInfo> GetAllAvailableStorages() const;
    130 
    131   void AddObserver(RemovableStorageObserver* obs);
    132   void RemoveObserver(RemovableStorageObserver* obs);
    133 
    134   std::string GetTransientIdForDeviceId(const std::string& device_id);
    135   std::string GetDeviceIdForTransientId(const std::string& transient_id) const;
    136 
    137   virtual void EjectDevice(
    138       const std::string& device_id,
    139       base::Callback<void(EjectStatus)> callback);
    140 
    141  protected:
    142   friend class ::MediaFileSystemRegistryTest;
    143   friend class ::MediaGalleriesPlatformAppBrowserTest;
    144   friend class ::SystemStorageApiTest;
    145   friend class ::SystemStorageEjectApiTest;
    146 
    147   StorageMonitor();
    148 
    149   virtual Receiver* receiver() const;
    150 
    151   // Called to initialize the storage monitor.
    152   virtual void Init() = 0;
    153 
    154   // Called by subclasses to mark the storage monitor as
    155   // fully initialized. Must be called on the UI thread.
    156   void MarkInitialized();
    157 
    158  private:
    159   // Internal method for creating platform specific StorageMonitor.
    160   static StorageMonitor* CreateInternal();
    161 
    162   class ReceiverImpl;
    163   friend class ReceiverImpl;
    164 
    165   // Key: device id.
    166   typedef std::map<std::string, StorageInfo> StorageMap;
    167 
    168   void ProcessAttach(const StorageInfo& storage);
    169   void ProcessDetach(const std::string& id);
    170 
    171   scoped_ptr<Receiver> receiver_;
    172 
    173   scoped_refptr<ObserverListThreadSafe<RemovableStorageObserver> >
    174       observer_list_;
    175 
    176   // Used to make sure we call initialize from the same thread as creation.
    177   base::ThreadChecker thread_checker_;
    178 
    179   bool initializing_;
    180   bool initialized_;
    181   std::vector<base::Closure> on_initialize_callbacks_;
    182 
    183   // For manipulating storage_map_ structure.
    184   mutable base::Lock storage_lock_;
    185 
    186   // Map of all known storage devices,including fixed and removable storages.
    187   StorageMap storage_map_;
    188 
    189   scoped_ptr<TransientDeviceIds> transient_device_ids_;
    190 };
    191 
    192 }  // namespace storage_monitor
    193 
    194 #endif  // COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_H_
    195