Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 1 | // Copyright 2013 The Chromium Authors. All rights reserved. |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 5 | #include "content/browser/dom_storage/dom_storage_host.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 6 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 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" |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 11 | #include "url/gurl.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 12 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 13 | namespace content { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 14 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 15 | DOMStorageHost::DOMStorageHost(DOMStorageContextImpl* context) |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 16 | : context_(context) { |
| 17 | } |
| 18 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 19 | DOMStorageHost::~DOMStorageHost() { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 20 | AreaMap::const_iterator it = connections_.begin(); |
| 21 | for (; it != connections_.end(); ++it) |
| 22 | it->second.namespace_->CloseStorageArea(it->second.area_.get()); |
| 23 | connections_.clear(); // Clear prior to releasing the context_ |
| 24 | } |
| 25 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 26 | bool DOMStorageHost::OpenStorageArea(int connection_id, int namespace_id, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 27 | const GURL& origin) { |
| 28 | DCHECK(!GetOpenArea(connection_id)); |
| 29 | if (GetOpenArea(connection_id)) |
| 30 | return false; // Indicates the renderer gave us very bad data. |
| 31 | NamespaceAndArea references; |
| 32 | references.namespace_ = context_->GetStorageNamespace(namespace_id); |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 33 | if (!references.namespace_.get()) { |
| 34 | // TODO(michaeln): Fix crbug/134003 and return false here. |
| 35 | // Until then return true to avoid crashing the renderer for |
| 36 | // sending a bad message. |
| 37 | return true; |
| 38 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 39 | references.area_ = references.namespace_->OpenStorageArea(origin); |
| 40 | DCHECK(references.area_.get()); |
| 41 | connections_[connection_id] = references; |
| 42 | return true; |
| 43 | } |
| 44 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 45 | void DOMStorageHost::CloseStorageArea(int connection_id) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 46 | AreaMap::iterator found = connections_.find(connection_id); |
| 47 | if (found == connections_.end()) |
| 48 | return; |
| 49 | found->second.namespace_->CloseStorageArea(found->second.area_.get()); |
| 50 | connections_.erase(found); |
| 51 | } |
| 52 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 53 | bool DOMStorageHost::ExtractAreaValues( |
| 54 | int connection_id, DOMStorageValuesMap* map) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 55 | map->clear(); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 56 | DOMStorageArea* area = GetOpenArea(connection_id); |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 57 | if (!area) { |
| 58 | // TODO(michaeln): Fix crbug/134003 and return false here. |
| 59 | // Until then return true to avoid crashing the renderer |
| 60 | // for sending a bad message. |
| 61 | return true; |
| 62 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 63 | if (!area->IsLoadedInMemory()) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 64 | DOMStorageNamespace* ns = GetNamespace(connection_id); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 65 | DCHECK(ns); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 66 | if (ns->CountInMemoryAreas() > kMaxInMemoryStorageAreas) { |
| 67 | ns->PurgeMemory(DOMStorageNamespace::PURGE_UNOPENED); |
| 68 | if (ns->CountInMemoryAreas() > kMaxInMemoryStorageAreas) |
| 69 | ns->PurgeMemory(DOMStorageNamespace::PURGE_AGGRESSIVE); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 70 | } |
| 71 | } |
| 72 | area->ExtractValues(map); |
| 73 | return true; |
| 74 | } |
| 75 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 76 | unsigned DOMStorageHost::GetAreaLength(int connection_id) { |
| 77 | DOMStorageArea* area = GetOpenArea(connection_id); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 78 | if (!area) |
| 79 | return 0; |
| 80 | return area->Length(); |
| 81 | } |
| 82 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 83 | base::NullableString16 DOMStorageHost::GetAreaKey(int connection_id, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 84 | unsigned index) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 85 | DOMStorageArea* area = GetOpenArea(connection_id); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 86 | if (!area) |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 87 | return base::NullableString16(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 88 | return area->Key(index); |
| 89 | } |
| 90 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 91 | base::NullableString16 DOMStorageHost::GetAreaItem(int connection_id, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 92 | const base::string16& key) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 93 | DOMStorageArea* area = GetOpenArea(connection_id); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 94 | if (!area) |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 95 | return base::NullableString16(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 96 | return area->GetItem(key); |
| 97 | } |
| 98 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 99 | bool DOMStorageHost::SetAreaItem( |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 100 | int connection_id, const base::string16& key, |
| 101 | const base::string16& value, const GURL& page_url, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 102 | base::NullableString16* old_value) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 103 | DOMStorageArea* area = GetOpenArea(connection_id); |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 104 | if (!area) { |
| 105 | // TODO(michaeln): Fix crbug/134003 and return false here. |
| 106 | // Until then return true to allow the renderer to operate |
| 107 | // to a limited degree out of its cache. |
| 108 | return true; |
| 109 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 110 | if (!area->SetItem(key, value, old_value)) |
| 111 | return false; |
| 112 | if (old_value->is_null() || old_value->string() != value) |
| 113 | context_->NotifyItemSet(area, key, value, *old_value, page_url); |
| 114 | return true; |
| 115 | } |
| 116 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 117 | bool DOMStorageHost::RemoveAreaItem( |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 118 | int connection_id, const base::string16& key, const GURL& page_url, |
| 119 | base::string16* old_value) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 120 | DOMStorageArea* area = GetOpenArea(connection_id); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 121 | if (!area) |
| 122 | return false; |
| 123 | if (!area->RemoveItem(key, old_value)) |
| 124 | return false; |
| 125 | context_->NotifyItemRemoved(area, key, *old_value, page_url); |
| 126 | return true; |
| 127 | } |
| 128 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 129 | bool DOMStorageHost::ClearArea(int connection_id, const GURL& page_url) { |
| 130 | DOMStorageArea* area = GetOpenArea(connection_id); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 131 | if (!area) |
| 132 | return false; |
| 133 | if (!area->Clear()) |
| 134 | return false; |
| 135 | context_->NotifyAreaCleared(area, page_url); |
| 136 | return true; |
| 137 | } |
| 138 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 139 | bool DOMStorageHost::HasAreaOpen( |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 140 | int namespace_id, const GURL& origin) const { |
| 141 | AreaMap::const_iterator it = connections_.begin(); |
| 142 | for (; it != connections_.end(); ++it) { |
| 143 | if (namespace_id == it->second.namespace_->namespace_id() && |
| 144 | origin == it->second.area_->origin()) { |
| 145 | return true; |
| 146 | } |
| 147 | } |
| 148 | return false; |
| 149 | } |
| 150 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 151 | DOMStorageArea* DOMStorageHost::GetOpenArea(int connection_id) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 152 | AreaMap::iterator found = connections_.find(connection_id); |
| 153 | if (found == connections_.end()) |
| 154 | return NULL; |
| 155 | return found->second.area_.get(); |
| 156 | } |
| 157 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 158 | DOMStorageNamespace* DOMStorageHost::GetNamespace(int connection_id) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 159 | AreaMap::iterator found = connections_.find(connection_id); |
| 160 | if (found == connections_.end()) |
| 161 | return NULL; |
| 162 | return found->second.namespace_.get(); |
| 163 | } |
| 164 | |
| 165 | // NamespaceAndArea |
| 166 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 167 | DOMStorageHost::NamespaceAndArea::NamespaceAndArea() {} |
| 168 | DOMStorageHost::NamespaceAndArea::~NamespaceAndArea() {} |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 169 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 170 | } // namespace content |