Make pop-up menus more easily dismissable.
[chromium-blink-merge.git] / components / storage_monitor / storage_monitor.cc
blob85e604336bf1c45dbf8689b172354d84cf612a57
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 {
14 namespace {
16 StorageMonitor* g_storage_monitor = NULL;
18 } // namespace
20 StorageMonitor::Receiver::~Receiver() {
23 class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
24 public:
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;
36 private:
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();
52 // static
53 void StorageMonitor::Create() {
54 delete g_storage_monitor;
55 g_storage_monitor = CreateInternal();
58 // static
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();
80 ++it) {
81 results.push_back(it->second);
83 return results;
86 void StorageMonitor::EnsureInitialized(base::Closure callback) {
87 DCHECK(thread_checker_.CalledOnValidThread());
88 if (initialized_) {
89 if (!callback.is_null())
90 callback.Run();
91 return;
94 if (!callback.is_null()) {
95 on_initialize_callbacks_.push_back(callback);
98 if (initializing_)
99 return;
101 initializing_ = true;
102 Init();
105 bool StorageMonitor::IsInitialized() const {
106 return initialized_;
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),
139 initialized_(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() {
152 initialized_ = true;
153 for (std::vector<base::Closure>::iterator iter =
154 on_initialize_callbacks_.begin();
155 iter != on_initialize_callbacks_.end(); ++iter) {
156 iter->Run();
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.
167 return;
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) {
180 StorageInfo info;
182 base::AutoLock lock(storage_lock_);
183 StorageMap::iterator it = storage_map_.find(id);
184 if (it == storage_map_.end())
185 return;
186 info = it->second;
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