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 #include "components/storage_monitor/storage_monitor.h"
7 #include "base/stl_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "components/storage_monitor/removable_storage_observer.h"
10 #include "components/storage_monitor/transient_device_ids.h"
12 namespace storage_monitor
{
16 StorageMonitor
* g_storage_monitor
= NULL
;
20 StorageMonitor::Receiver::~Receiver() {
23 class StorageMonitor::ReceiverImpl
: public StorageMonitor::Receiver
{
25 explicit ReceiverImpl(StorageMonitor
* notifications
)
26 : notifications_(notifications
) {}
28 virtual ~ReceiverImpl() {}
30 virtual void ProcessAttach(const StorageInfo
& info
) OVERRIDE
;
32 virtual void ProcessDetach(const std::string
& id
) OVERRIDE
;
34 virtual void MarkInitialized() OVERRIDE
;
37 StorageMonitor
* notifications_
;
40 void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo
& info
) {
41 notifications_
->ProcessAttach(info
);
44 void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string
& id
) {
45 notifications_
->ProcessDetach(id
);
48 void StorageMonitor::ReceiverImpl::MarkInitialized() {
49 notifications_
->MarkInitialized();
53 void StorageMonitor::Create() {
54 delete g_storage_monitor
;
55 g_storage_monitor
= CreateInternal();
59 void StorageMonitor::Destroy() {
60 delete g_storage_monitor
;
61 g_storage_monitor
= NULL
;
64 StorageMonitor
* StorageMonitor::GetInstance() {
65 return g_storage_monitor
;
68 void StorageMonitor::SetStorageMonitorForTesting(
69 scoped_ptr
<StorageMonitor
> storage_monitor
) {
70 delete g_storage_monitor
;
71 g_storage_monitor
= storage_monitor
.release();
74 std::vector
<StorageInfo
> StorageMonitor::GetAllAvailableStorages() const {
75 std::vector
<StorageInfo
> results
;
77 base::AutoLock
lock(storage_lock_
);
78 for (StorageMap::const_iterator it
= storage_map_
.begin();
79 it
!= storage_map_
.end();
81 results
.push_back(it
->second
);
86 void StorageMonitor::EnsureInitialized(base::Closure callback
) {
87 DCHECK(thread_checker_
.CalledOnValidThread());
89 if (!callback
.is_null())
94 if (!callback
.is_null()) {
95 on_initialize_callbacks_
.push_back(callback
);
101 initializing_
= true;
105 bool StorageMonitor::IsInitialized() const {
109 void StorageMonitor::AddObserver(RemovableStorageObserver
* obs
) {
110 observer_list_
->AddObserver(obs
);
113 void StorageMonitor::RemoveObserver(
114 RemovableStorageObserver
* obs
) {
115 observer_list_
->RemoveObserver(obs
);
118 std::string
StorageMonitor::GetTransientIdForDeviceId(
119 const std::string
& device_id
) {
120 return transient_device_ids_
->GetTransientIdForDeviceId(device_id
);
123 std::string
StorageMonitor::GetDeviceIdForTransientId(
124 const std::string
& transient_id
) const {
125 return transient_device_ids_
->DeviceIdFromTransientId(transient_id
);
128 void StorageMonitor::EjectDevice(
129 const std::string
& device_id
,
130 base::Callback
<void(EjectStatus
)> callback
) {
131 // Platform-specific implementations will override this method to
132 // perform actual device ejection.
133 callback
.Run(EJECT_FAILURE
);
136 StorageMonitor::StorageMonitor()
137 : observer_list_(new ObserverListThreadSafe
<RemovableStorageObserver
>()),
138 initializing_(false),
140 transient_device_ids_(new TransientDeviceIds
) {
141 receiver_
.reset(new ReceiverImpl(this));
144 StorageMonitor::~StorageMonitor() {
147 StorageMonitor::Receiver
* StorageMonitor::receiver() const {
148 return receiver_
.get();
151 void StorageMonitor::MarkInitialized() {
153 for (std::vector
<base::Closure
>::iterator iter
=
154 on_initialize_callbacks_
.begin();
155 iter
!= on_initialize_callbacks_
.end(); ++iter
) {
158 on_initialize_callbacks_
.clear();
161 void StorageMonitor::ProcessAttach(const StorageInfo
& info
) {
163 base::AutoLock
lock(storage_lock_
);
164 if (ContainsKey(storage_map_
, info
.device_id())) {
165 // This can happen if our unique id scheme fails. Ignore the incoming
166 // non-unique attachment.
169 storage_map_
.insert(std::make_pair(info
.device_id(), info
));
172 DVLOG(1) << "StorageAttached id " << info
.device_id();
173 if (StorageInfo::IsRemovableDevice(info
.device_id())) {
174 observer_list_
->Notify(
175 &RemovableStorageObserver::OnRemovableStorageAttached
, info
);
179 void StorageMonitor::ProcessDetach(const std::string
& id
) {
182 base::AutoLock
lock(storage_lock_
);
183 StorageMap::iterator it
= storage_map_
.find(id
);
184 if (it
== storage_map_
.end())
187 storage_map_
.erase(it
);
190 DVLOG(1) << "StorageDetached for id " << id
;
191 if (StorageInfo::IsRemovableDevice(info
.device_id())) {
192 observer_list_
->Notify(
193 &RemovableStorageObserver::OnRemovableStorageDetached
, info
);
197 } // namespace storage_monitor