1 // Copyright 2013 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 "content/browser/dom_storage/dom_storage_host.h"
7 #include "content/browser/dom_storage/dom_storage_area.h"
8 #include "content/browser/dom_storage/dom_storage_context_impl.h"
9 #include "content/browser/dom_storage/dom_storage_namespace.h"
10 #include "content/common/dom_storage/dom_storage_types.h"
15 DOMStorageHost::DOMStorageHost(DOMStorageContextImpl
* context
,
16 int render_process_id
)
18 render_process_id_(render_process_id
) {
21 DOMStorageHost::~DOMStorageHost() {
22 AreaMap::const_iterator it
= connections_
.begin();
23 for (; it
!= connections_
.end(); ++it
)
24 it
->second
.namespace_
->CloseStorageArea(it
->second
.area_
.get());
25 connections_
.clear(); // Clear prior to releasing the context_
28 bool DOMStorageHost::OpenStorageArea(int connection_id
, int namespace_id
,
30 DCHECK(!GetOpenArea(connection_id
));
31 if (GetOpenArea(connection_id
))
32 return false; // Indicates the renderer gave us very bad data.
33 NamespaceAndArea references
;
34 references
.namespace_
= context_
->GetStorageNamespace(namespace_id
);
35 if (!references
.namespace_
.get())
37 references
.area_
= references
.namespace_
->OpenStorageArea(origin
);
38 DCHECK(references
.area_
.get());
39 connections_
[connection_id
] = references
;
43 void DOMStorageHost::CloseStorageArea(int connection_id
) {
44 AreaMap::iterator found
= connections_
.find(connection_id
);
45 if (found
== connections_
.end())
47 found
->second
.namespace_
->CloseStorageArea(found
->second
.area_
.get());
48 connections_
.erase(found
);
51 bool DOMStorageHost::ExtractAreaValues(
52 int connection_id
, DOMStorageValuesMap
* map
, bool* send_log_get_messages
) {
54 DOMStorageArea
* area
= GetOpenArea(connection_id
);
57 if (!area
->IsLoadedInMemory()) {
58 DOMStorageNamespace
* ns
= GetNamespace(connection_id
);
60 if (ns
->CountInMemoryAreas() > kMaxInMemoryStorageAreas
) {
61 ns
->PurgeMemory(DOMStorageNamespace::PURGE_UNOPENED
);
62 if (ns
->CountInMemoryAreas() > kMaxInMemoryStorageAreas
)
63 ns
->PurgeMemory(DOMStorageNamespace::PURGE_AGGRESSIVE
);
66 area
->ExtractValues(map
);
67 *send_log_get_messages
= false;
68 DOMStorageNamespace
* ns
= GetNamespace(connection_id
);
70 *send_log_get_messages
= ns
->IsLoggingRenderer(render_process_id_
);
74 unsigned DOMStorageHost::GetAreaLength(int connection_id
) {
75 DOMStorageArea
* area
= GetOpenArea(connection_id
);
78 return area
->Length();
81 base::NullableString16
DOMStorageHost::GetAreaKey(int connection_id
,
83 DOMStorageArea
* area
= GetOpenArea(connection_id
);
85 return base::NullableString16();
86 return area
->Key(index
);
89 base::NullableString16
DOMStorageHost::GetAreaItem(int connection_id
,
90 const base::string16
& key
) {
91 DOMStorageArea
* area
= GetOpenArea(connection_id
);
93 return base::NullableString16();
94 return area
->GetItem(key
);
97 bool DOMStorageHost::SetAreaItem(
98 int connection_id
, const base::string16
& key
,
99 const base::string16
& value
, const GURL
& page_url
,
100 base::NullableString16
* old_value
) {
101 DOMStorageArea
* area
= GetOpenArea(connection_id
);
104 if (!area
->SetItem(key
, value
, old_value
))
106 if (old_value
->is_null() || old_value
->string() != value
)
107 context_
->NotifyItemSet(area
, key
, value
, *old_value
, page_url
);
108 MaybeLogTransaction(connection_id
,
109 DOMStorageNamespace::TRANSACTION_WRITE
,
110 area
->origin(), page_url
, key
,
111 base::NullableString16(value
, false));
115 void DOMStorageHost::LogGetAreaItem(
116 int connection_id
, const base::string16
& key
,
117 const base::NullableString16
& value
) {
118 DOMStorageArea
* area
= GetOpenArea(connection_id
);
121 MaybeLogTransaction(connection_id
,
122 DOMStorageNamespace::TRANSACTION_READ
,
123 area
->origin(), GURL(), key
, value
);
126 bool DOMStorageHost::RemoveAreaItem(
127 int connection_id
, const base::string16
& key
, const GURL
& page_url
,
128 base::string16
* old_value
) {
129 DOMStorageArea
* area
= GetOpenArea(connection_id
);
132 if (!area
->RemoveItem(key
, old_value
))
134 context_
->NotifyItemRemoved(area
, key
, *old_value
, page_url
);
135 MaybeLogTransaction(connection_id
,
136 DOMStorageNamespace::TRANSACTION_REMOVE
,
137 area
->origin(), page_url
, key
, base::NullableString16());
141 bool DOMStorageHost::ClearArea(int connection_id
, const GURL
& page_url
) {
142 DOMStorageArea
* area
= GetOpenArea(connection_id
);
147 context_
->NotifyAreaCleared(area
, page_url
);
148 MaybeLogTransaction(connection_id
,
149 DOMStorageNamespace::TRANSACTION_CLEAR
,
150 area
->origin(), page_url
, base::string16(),
151 base::NullableString16());
155 bool DOMStorageHost::HasAreaOpen(
156 int64 namespace_id
, const GURL
& origin
, int64
* alias_namespace_id
) const {
157 AreaMap::const_iterator it
= connections_
.begin();
158 for (; it
!= connections_
.end(); ++it
) {
159 if (namespace_id
== it
->second
.area_
->namespace_id() &&
160 origin
== it
->second
.area_
->origin()) {
161 *alias_namespace_id
= it
->second
.namespace_
->namespace_id();
168 bool DOMStorageHost::ResetOpenAreasForNamespace(int64 namespace_id
) {
170 AreaMap::iterator it
= connections_
.begin();
171 for (; it
!= connections_
.end(); ++it
) {
172 if (namespace_id
== it
->second
.namespace_
->namespace_id()) {
173 GURL origin
= it
->second
.area_
->origin();
174 it
->second
.namespace_
->CloseStorageArea(it
->second
.area_
.get());
175 it
->second
.area_
= it
->second
.namespace_
->OpenStorageArea(origin
);
182 DOMStorageArea
* DOMStorageHost::GetOpenArea(int connection_id
) {
183 AreaMap::iterator found
= connections_
.find(connection_id
);
184 if (found
== connections_
.end())
186 return found
->second
.area_
.get();
189 DOMStorageNamespace
* DOMStorageHost::GetNamespace(int connection_id
) {
190 AreaMap::iterator found
= connections_
.find(connection_id
);
191 if (found
== connections_
.end())
193 return found
->second
.namespace_
.get();
196 void DOMStorageHost::MaybeLogTransaction(
198 DOMStorageNamespace::LogType transaction_type
,
200 const GURL
& page_url
,
201 const base::string16
& key
,
202 const base::NullableString16
& value
) {
203 DOMStorageNamespace
* ns
= GetNamespace(connection_id
);
205 if (!ns
->IsLoggingRenderer(render_process_id_
))
207 DOMStorageNamespace::TransactionRecord transaction
;
208 transaction
.transaction_type
= transaction_type
;
209 transaction
.origin
= origin
;
210 transaction
.page_url
= page_url
;
211 transaction
.key
= key
;
212 transaction
.value
= value
;
213 ns
->AddTransaction(render_process_id_
, transaction
);
218 DOMStorageHost::NamespaceAndArea::NamespaceAndArea() {}
219 DOMStorageHost::NamespaceAndArea::~NamespaceAndArea() {}
221 } // namespace content