- add sources.
[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 #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"
12
13 StorageMonitor::Receiver::~Receiver() {
14 }
15
16 class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
17  public:
18   explicit ReceiverImpl(StorageMonitor* notifications)
19       : notifications_(notifications) {}
20
21   virtual ~ReceiverImpl() {}
22
23   virtual void ProcessAttach(const StorageInfo& info) OVERRIDE;
24
25   virtual void ProcessDetach(const std::string& id) OVERRIDE;
26
27   virtual void MarkInitialized() OVERRIDE;
28
29  private:
30   StorageMonitor* notifications_;
31 };
32
33 void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) {
34   notifications_->ProcessAttach(info);
35 }
36
37 void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) {
38   notifications_->ProcessDetach(id);
39 }
40
41 void StorageMonitor::ReceiverImpl::MarkInitialized() {
42   notifications_->MarkInitialized();
43 }
44
45 StorageMonitor* StorageMonitor::GetInstance() {
46   if (g_browser_process)
47     return g_browser_process->storage_monitor();
48
49   return NULL;
50 }
51
52 std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
53   std::vector<StorageInfo> results;
54
55   base::AutoLock lock(storage_lock_);
56   for (StorageMap::const_iterator it = storage_map_.begin();
57        it != storage_map_.end();
58        ++it) {
59     results.push_back(it->second);
60   }
61   return results;
62 }
63
64 void StorageMonitor::EnsureInitialized(base::Closure callback) {
65   DCHECK(thread_checker_.CalledOnValidThread());
66   if (initialized_) {
67     if (!callback.is_null())
68       callback.Run();
69     return;
70   }
71
72   if (!callback.is_null()) {
73     on_initialize_callbacks_.push_back(callback);
74   }
75
76   if (initializing_)
77     return;
78
79   initializing_ = true;
80   Init();
81 }
82
83 bool StorageMonitor::IsInitialized() const {
84   return initialized_;
85 }
86
87 void StorageMonitor::AddObserver(RemovableStorageObserver* obs) {
88   observer_list_->AddObserver(obs);
89 }
90
91 void StorageMonitor::RemoveObserver(
92     RemovableStorageObserver* obs) {
93   observer_list_->RemoveObserver(obs);
94 }
95
96 std::string StorageMonitor::GetTransientIdForDeviceId(
97     const std::string& device_id) {
98   return transient_device_ids_->GetTransientIdForDeviceId(device_id);
99 }
100
101 std::string StorageMonitor::GetDeviceIdForTransientId(
102     const std::string& transient_id) const {
103   return transient_device_ids_->DeviceIdFromTransientId(transient_id);
104 }
105
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);
112 }
113
114 StorageMonitor::StorageMonitor()
115     : observer_list_(new ObserverListThreadSafe<RemovableStorageObserver>()),
116       initializing_(false),
117       initialized_(false),
118       transient_device_ids_(new TransientDeviceIds) {
119   receiver_.reset(new ReceiverImpl(this));
120 }
121
122 StorageMonitor::~StorageMonitor() {
123 }
124
125 StorageMonitor::Receiver* StorageMonitor::receiver() const {
126   return receiver_.get();
127 }
128
129 void StorageMonitor::MarkInitialized() {
130   initialized_ = true;
131   for (std::vector<base::Closure>::iterator iter =
132            on_initialize_callbacks_.begin();
133        iter != on_initialize_callbacks_.end(); ++iter) {
134     iter->Run();
135   }
136   on_initialize_callbacks_.clear();
137 }
138
139 void StorageMonitor::ProcessAttach(const StorageInfo& info) {
140   {
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.
145       return;
146     }
147     storage_map_.insert(std::make_pair(info.device_id(), info));
148   }
149
150   DVLOG(1) << "StorageAttached with name " << UTF16ToUTF8(info.name())
151            << " and id " << info.device_id();
152   if (StorageInfo::IsRemovableDevice(info.device_id())) {
153     observer_list_->Notify(
154         &RemovableStorageObserver::OnRemovableStorageAttached, info);
155   }
156 }
157
158 void StorageMonitor::ProcessDetach(const std::string& id) {
159   StorageInfo info;
160   {
161     base::AutoLock lock(storage_lock_);
162     StorageMap::iterator it = storage_map_.find(id);
163     if (it == storage_map_.end())
164       return;
165     info = it->second;
166     storage_map_.erase(it);
167   }
168
169   DVLOG(1) << "StorageDetached for id " << id;
170   if (StorageInfo::IsRemovableDevice(info.device_id())) {
171     observer_list_->Notify(
172         &RemovableStorageObserver::OnRemovableStorageDetached, info);
173   }
174 }