1 // Copyright 2014 The Chromium Authors
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"
10 #include "base/containers/contains.h"
11 #include "base/logging.h"
12 #include "base/memory/raw_ptr.h"
13 #include "components/storage_monitor/removable_storage_observer.h"
14 #include "components/storage_monitor/transient_device_ids.h"
16 namespace storage_monitor {
20 StorageMonitor* g_storage_monitor = nullptr;
24 StorageMonitor::Receiver::~Receiver() = default;
26 class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
28 explicit ReceiverImpl(StorageMonitor* notifications)
29 : notifications_(notifications) {}
31 ~ReceiverImpl() override = default;
33 void ProcessAttach(const StorageInfo& info) override;
35 void ProcessDetach(const std::string& id) override;
37 void MarkInitialized() override;
40 raw_ptr<StorageMonitor> notifications_;
43 void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) {
44 notifications_->ProcessAttach(info);
47 void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) {
48 notifications_->ProcessDetach(id);
51 void StorageMonitor::ReceiverImpl::MarkInitialized() {
52 notifications_->MarkInitialized();
56 void StorageMonitor::Create() {
57 delete g_storage_monitor;
58 g_storage_monitor = CreateInternal();
62 void StorageMonitor::Destroy() {
63 delete g_storage_monitor;
64 g_storage_monitor = nullptr;
67 StorageMonitor* StorageMonitor::GetInstance() {
68 return g_storage_monitor;
71 void StorageMonitor::SetStorageMonitorForTesting(
72 std::unique_ptr<StorageMonitor> storage_monitor) {
73 delete g_storage_monitor;
74 g_storage_monitor = storage_monitor.release();
77 std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
78 std::vector<StorageInfo> results;
80 base::AutoLock lock(storage_lock_);
81 for (const auto& item : storage_map_) {
82 results.push_back(item.second);
87 void StorageMonitor::EnsureInitialized(base::OnceClosure callback) {
88 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
90 if (!callback.is_null())
91 std::move(callback).Run();
95 if (!callback.is_null()) {
96 on_initialize_callbacks_.push_back(std::move(callback));
102 initializing_ = true;
106 bool StorageMonitor::IsInitialized() const {
110 void StorageMonitor::AddObserver(RemovableStorageObserver* obs) {
111 observer_list_->AddObserver(obs);
114 void StorageMonitor::RemoveObserver(
115 RemovableStorageObserver* obs) {
116 observer_list_->RemoveObserver(obs);
119 std::string StorageMonitor::GetTransientIdForDeviceId(
120 const std::string& device_id) {
121 return transient_device_ids_->GetTransientIdForDeviceId(device_id);
124 std::string StorageMonitor::GetDeviceIdForTransientId(
125 const std::string& transient_id) const {
126 return transient_device_ids_->DeviceIdFromTransientId(transient_id);
129 void StorageMonitor::EjectDevice(
130 const std::string& device_id,
131 base::OnceCallback<void(EjectStatus)> callback) {
132 // Platform-specific implementations will override this method to
133 // perform actual device ejection.
134 std::move(callback).Run(EJECT_FAILURE);
137 StorageMonitor::StorageMonitor()
139 new base::ObserverListThreadSafe<RemovableStorageObserver>()),
140 initializing_(false),
142 transient_device_ids_(new TransientDeviceIds) {
143 receiver_ = std::make_unique<ReceiverImpl>(this);
146 StorageMonitor::~StorageMonitor() = default;
148 StorageMonitor::Receiver* StorageMonitor::receiver() const {
149 return receiver_.get();
152 void StorageMonitor::MarkInitialized() {
154 for (auto& callback : on_initialize_callbacks_)
155 std::move(callback).Run();
156 on_initialize_callbacks_.clear();
159 void StorageMonitor::ProcessAttach(const StorageInfo& info) {
161 base::AutoLock lock(storage_lock_);
162 if (base::Contains(storage_map_, info.device_id())) {
163 // This can happen if our unique id scheme fails. Ignore the incoming
164 // non-unique attachment.
167 storage_map_.insert(std::make_pair(info.device_id(), info));
170 DVLOG(1) << "StorageAttached id " << info.device_id();
171 if (StorageInfo::IsRemovableDevice(info.device_id())) {
172 observer_list_->Notify(
173 FROM_HERE, &RemovableStorageObserver::OnRemovableStorageAttached, info);
177 void StorageMonitor::ProcessDetach(const std::string& id) {
180 base::AutoLock lock(storage_lock_);
181 auto it = storage_map_.find(id);
182 if (it == storage_map_.end())
185 storage_map_.erase(it);
188 DVLOG(1) << "StorageDetached for id " << id;
189 if (StorageInfo::IsRemovableDevice(info.device_id())) {
190 observer_list_->Notify(
191 FROM_HERE, &RemovableStorageObserver::OnRemovableStorageDetached, info);
195 } // namespace storage_monitor