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.
5 #include "chrome/browser/storage_monitor/storage_monitor.h"
7 #include "base/stl_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/storage_monitor/removable_storage_observer.h"
11 #include "chrome/browser/storage_monitor/transient_device_ids.h"
13 StorageMonitor::Receiver::~Receiver() {
16 class StorageMonitor::ReceiverImpl
: public StorageMonitor::Receiver
{
18 explicit ReceiverImpl(StorageMonitor
* notifications
)
19 : notifications_(notifications
) {}
21 virtual ~ReceiverImpl() {}
23 virtual void ProcessAttach(const StorageInfo
& info
) OVERRIDE
;
25 virtual void ProcessDetach(const std::string
& id
) OVERRIDE
;
27 virtual void MarkInitialized() OVERRIDE
;
30 StorageMonitor
* notifications_
;
33 void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo
& info
) {
34 notifications_
->ProcessAttach(info
);
37 void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string
& id
) {
38 notifications_
->ProcessDetach(id
);
41 void StorageMonitor::ReceiverImpl::MarkInitialized() {
42 notifications_
->MarkInitialized();
45 StorageMonitor
* StorageMonitor::GetInstance() {
46 if (g_browser_process
)
47 return g_browser_process
->storage_monitor();
52 std::vector
<StorageInfo
> StorageMonitor::GetAllAvailableStorages() const {
53 std::vector
<StorageInfo
> results
;
55 base::AutoLock
lock(storage_lock_
);
56 for (StorageMap::const_iterator it
= storage_map_
.begin();
57 it
!= storage_map_
.end();
59 results
.push_back(it
->second
);
64 void StorageMonitor::EnsureInitialized(base::Closure callback
) {
65 DCHECK(thread_checker_
.CalledOnValidThread());
67 if (!callback
.is_null())
72 if (!callback
.is_null()) {
73 on_initialize_callbacks_
.push_back(callback
);
83 bool StorageMonitor::IsInitialized() const {
87 void StorageMonitor::AddObserver(RemovableStorageObserver
* obs
) {
88 observer_list_
->AddObserver(obs
);
91 void StorageMonitor::RemoveObserver(
92 RemovableStorageObserver
* obs
) {
93 observer_list_
->RemoveObserver(obs
);
96 std::string
StorageMonitor::GetTransientIdForDeviceId(
97 const std::string
& device_id
) {
98 return transient_device_ids_
->GetTransientIdForDeviceId(device_id
);
101 std::string
StorageMonitor::GetDeviceIdForTransientId(
102 const std::string
& transient_id
) const {
103 return transient_device_ids_
->DeviceIdFromTransientId(transient_id
);
106 void StorageMonitor::EjectDevice(
107 const std::string
& device_id
,
108 base::Callback
<void(EjectStatus
)> callback
) {
109 // Platform-specific implementations will override this method to
110 // perform actual device ejection.
111 callback
.Run(EJECT_FAILURE
);
114 StorageMonitor::StorageMonitor()
115 : observer_list_(new ObserverListThreadSafe
<RemovableStorageObserver
>()),
116 initializing_(false),
118 transient_device_ids_(new TransientDeviceIds
) {
119 receiver_
.reset(new ReceiverImpl(this));
122 StorageMonitor::~StorageMonitor() {
125 StorageMonitor::Receiver
* StorageMonitor::receiver() const {
126 return receiver_
.get();
129 void StorageMonitor::MarkInitialized() {
131 for (std::vector
<base::Closure
>::iterator iter
=
132 on_initialize_callbacks_
.begin();
133 iter
!= on_initialize_callbacks_
.end(); ++iter
) {
136 on_initialize_callbacks_
.clear();
139 void StorageMonitor::ProcessAttach(const StorageInfo
& info
) {
141 base::AutoLock
lock(storage_lock_
);
142 if (ContainsKey(storage_map_
, info
.device_id())) {
143 // This can happen if our unique id scheme fails. Ignore the incoming
144 // non-unique attachment.
147 storage_map_
.insert(std::make_pair(info
.device_id(), info
));
150 DVLOG(1) << "StorageAttached with name " << base::UTF16ToUTF8(info
.name())
151 << " and id " << info
.device_id();
152 if (StorageInfo::IsRemovableDevice(info
.device_id())) {
153 observer_list_
->Notify(
154 &RemovableStorageObserver::OnRemovableStorageAttached
, info
);
158 void StorageMonitor::ProcessDetach(const std::string
& id
) {
161 base::AutoLock
lock(storage_lock_
);
162 StorageMap::iterator it
= storage_map_
.find(id
);
163 if (it
== storage_map_
.end())
166 storage_map_
.erase(it
);
169 DVLOG(1) << "StorageDetached for id " << id
;
170 if (StorageInfo::IsRemovableDevice(info
.device_id())) {
171 observer_list_
->Notify(
172 &RemovableStorageObserver::OnRemovableStorageDetached
, info
);