Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / storage_monitor / storage_monitor.cc
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.
4
5 #include "chrome/browser/storage_monitor/storage_monitor.h"
6
7 #include "base/stl_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #if !defined(XWALK_STORAGE_MONITOR)
10 #include "chrome/browser/browser_process.h"
11 #endif
12 #include "chrome/browser/storage_monitor/removable_storage_observer.h"
13 #include "chrome/browser/storage_monitor/transient_device_ids.h"
14
15 StorageMonitor::Receiver::~Receiver() {
16 }
17
18 class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
19  public:
20   explicit ReceiverImpl(StorageMonitor* notifications)
21       : notifications_(notifications) {}
22
23   virtual ~ReceiverImpl() {}
24
25   virtual void ProcessAttach(const StorageInfo& info) OVERRIDE;
26
27   virtual void ProcessDetach(const std::string& id) OVERRIDE;
28
29   virtual void MarkInitialized() OVERRIDE;
30
31  private:
32   StorageMonitor* notifications_;
33 };
34
35 void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) {
36   notifications_->ProcessAttach(info);
37 }
38
39 void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) {
40   notifications_->ProcessDetach(id);
41 }
42
43 void StorageMonitor::ReceiverImpl::MarkInitialized() {
44   notifications_->MarkInitialized();
45 }
46
47 StorageMonitor* StorageMonitor::GetInstance() {
48 #if !defined(XWALK_STORAGE_MONITOR)
49   if (g_browser_process)
50     return g_browser_process->storage_monitor();
51
52   return NULL;
53 #else
54   static StorageMonitor* monitor(StorageMonitor::Create());
55
56   return monitor;
57 #endif
58 }
59
60 std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
61   std::vector<StorageInfo> results;
62
63   base::AutoLock lock(storage_lock_);
64   for (StorageMap::const_iterator it = storage_map_.begin();
65        it != storage_map_.end();
66        ++it) {
67     results.push_back(it->second);
68   }
69   return results;
70 }
71
72 void StorageMonitor::EnsureInitialized(base::Closure callback) {
73   DCHECK(thread_checker_.CalledOnValidThread());
74   if (initialized_) {
75     if (!callback.is_null())
76       callback.Run();
77     return;
78   }
79
80   if (!callback.is_null()) {
81     on_initialize_callbacks_.push_back(callback);
82   }
83
84   if (initializing_)
85     return;
86
87   initializing_ = true;
88   Init();
89 }
90
91 bool StorageMonitor::IsInitialized() const {
92   return initialized_;
93 }
94
95 void StorageMonitor::AddObserver(RemovableStorageObserver* obs) {
96   observer_list_->AddObserver(obs);
97 }
98
99 void StorageMonitor::RemoveObserver(
100     RemovableStorageObserver* obs) {
101   observer_list_->RemoveObserver(obs);
102 }
103
104 std::string StorageMonitor::GetTransientIdForDeviceId(
105     const std::string& device_id) {
106   return transient_device_ids_->GetTransientIdForDeviceId(device_id);
107 }
108
109 std::string StorageMonitor::GetDeviceIdForTransientId(
110     const std::string& transient_id) const {
111   return transient_device_ids_->DeviceIdFromTransientId(transient_id);
112 }
113
114 void StorageMonitor::EjectDevice(
115     const std::string& device_id,
116     base::Callback<void(EjectStatus)> callback) {
117   // Platform-specific implementations will override this method to
118   // perform actual device ejection.
119   callback.Run(EJECT_FAILURE);
120 }
121
122 StorageMonitor::StorageMonitor()
123     : observer_list_(new ObserverListThreadSafe<RemovableStorageObserver>()),
124       initializing_(false),
125       initialized_(false),
126       transient_device_ids_(new TransientDeviceIds) {
127   receiver_.reset(new ReceiverImpl(this));
128 }
129
130 StorageMonitor::~StorageMonitor() {
131 }
132
133 StorageMonitor::Receiver* StorageMonitor::receiver() const {
134   return receiver_.get();
135 }
136
137 void StorageMonitor::MarkInitialized() {
138   initialized_ = true;
139   for (std::vector<base::Closure>::iterator iter =
140            on_initialize_callbacks_.begin();
141        iter != on_initialize_callbacks_.end(); ++iter) {
142     iter->Run();
143   }
144   on_initialize_callbacks_.clear();
145 }
146
147 void StorageMonitor::ProcessAttach(const StorageInfo& info) {
148   {
149     base::AutoLock lock(storage_lock_);
150     if (ContainsKey(storage_map_, info.device_id())) {
151       // This can happen if our unique id scheme fails. Ignore the incoming
152       // non-unique attachment.
153       return;
154     }
155     storage_map_.insert(std::make_pair(info.device_id(), info));
156   }
157
158   DVLOG(1) << "StorageAttached with name " << base::UTF16ToUTF8(info.name())
159            << " and id " << info.device_id();
160   if (StorageInfo::IsRemovableDevice(info.device_id())) {
161     observer_list_->Notify(
162         &RemovableStorageObserver::OnRemovableStorageAttached, info);
163   }
164 }
165
166 void StorageMonitor::ProcessDetach(const std::string& id) {
167   StorageInfo info;
168   {
169     base::AutoLock lock(storage_lock_);
170     StorageMap::iterator it = storage_map_.find(id);
171     if (it == storage_map_.end())
172       return;
173     info = it->second;
174     storage_map_.erase(it);
175   }
176
177   DVLOG(1) << "StorageDetached for id " << id;
178   if (StorageInfo::IsRemovableDevice(info.device_id())) {
179     observer_list_->Notify(
180         &RemovableStorageObserver::OnRemovableStorageDetached, info);
181   }
182 }