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