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