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.
5 #ifndef COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_H_
6 #define COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_H_
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"
21 class MediaFileSystemRegistryTest
;
22 class MediaGalleriesPlatformAppBrowserTest
;
23 class SystemStorageApiTest
;
24 class SystemStorageEjectApiTest
;
27 class MediaTransferProtocolManager
;
30 namespace storage_monitor
{
32 class RemovableStorageObserver
;
33 class TransientDeviceIds
;
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
{
52 // This interface is provided to generators of storage notifications.
57 virtual void ProcessAttach(const StorageInfo
& info
) = 0;
58 virtual void ProcessDetach(const std::string
& id
) = 0;
59 virtual void MarkInitialized() = 0;
62 // Status codes for the result of an EjectDevice() call.
70 // Instantiates the StorageMonitor singleton. This function does not
71 // guarantee the complete initialization of the object. For that, see
72 // |EnsureInitialized|.
75 // Destroys the StorageMonitor singleton.
76 static void Destroy();
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),
82 static StorageMonitor
* GetInstance();
84 static void SetStorageMonitorForTesting(
85 scoped_ptr
<StorageMonitor
> storage_monitor
);
87 virtual ~StorageMonitor();
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
);
98 // Return true if the storage monitor has already been initialized.
99 bool IsInitialized() const;
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;
108 // TODO(gbillock): make this either unnecessary (implementation-specific) or
109 // platform-independent.
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;
122 #if defined(OS_LINUX)
123 virtual device::MediaTransferProtocolManager
*
124 media_transfer_protocol_manager() = 0;
127 // Returns information for all known storages on the system,
128 // including fixed and removable storages.
129 std::vector
<StorageInfo
> GetAllAvailableStorages() const;
131 void AddObserver(RemovableStorageObserver
* obs
);
132 void RemoveObserver(RemovableStorageObserver
* obs
);
134 std::string
GetTransientIdForDeviceId(const std::string
& device_id
);
135 std::string
GetDeviceIdForTransientId(const std::string
& transient_id
) const;
137 virtual void EjectDevice(
138 const std::string
& device_id
,
139 base::Callback
<void(EjectStatus
)> callback
);
142 friend class ::MediaFileSystemRegistryTest
;
143 friend class ::MediaGalleriesPlatformAppBrowserTest
;
144 friend class ::SystemStorageApiTest
;
145 friend class ::SystemStorageEjectApiTest
;
149 virtual Receiver
* receiver() const;
151 // Called to initialize the storage monitor.
152 virtual void Init() = 0;
154 // Called by subclasses to mark the storage monitor as
155 // fully initialized. Must be called on the UI thread.
156 void MarkInitialized();
159 // Internal method for creating platform specific StorageMonitor.
160 static StorageMonitor
* CreateInternal();
163 friend class ReceiverImpl
;
166 typedef std::map
<std::string
, StorageInfo
> StorageMap
;
168 void ProcessAttach(const StorageInfo
& storage
);
169 void ProcessDetach(const std::string
& id
);
171 scoped_ptr
<Receiver
> receiver_
;
173 scoped_refptr
<base::ObserverListThreadSafe
<RemovableStorageObserver
>>
176 // Used to make sure we call initialize from the same thread as creation.
177 base::ThreadChecker thread_checker_
;
181 std::vector
<base::Closure
> on_initialize_callbacks_
;
183 // For manipulating storage_map_ structure.
184 mutable base::Lock storage_lock_
;
186 // Map of all known storage devices,including fixed and removable storages.
187 StorageMap storage_map_
;
189 scoped_ptr
<TransientDeviceIds
> transient_device_ids_
;
192 } // namespace storage_monitor
194 #endif // COMPONENTS_STORAGE_MONITOR_STORAGE_MONITOR_H_