diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/storage/storage_controller.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/modules/storage/storage_controller.cc | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc b/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc new file mode 100644 index 00000000000..855e3ba7254 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc @@ -0,0 +1,170 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/storage/storage_controller.h" + +#include "base/feature_list.h" +#include "base/sys_info.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/platform/interface_provider.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_storage_area.h" +#include "third_party/blink/public/platform/web_storage_namespace.h" +#include "third_party/blink/renderer/core/frame/content_settings_client.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/modules/storage/cached_storage_area.h" +#include "third_party/blink/renderer/modules/storage/storage_namespace.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" + +namespace blink { +namespace { + +#define STATIC_ASSERT_MATCHING_ENUM(enum_name1, enum_name2) \ + static_assert(static_cast<int>(enum_name1) == static_cast<int>(enum_name2), \ + "mismatching enums: " #enum_name1) +STATIC_ASSERT_MATCHING_ENUM(StorageArea::StorageType::kLocalStorage, + ContentSettingsClient::StorageType::kLocal); +STATIC_ASSERT_MATCHING_ENUM(StorageArea::StorageType::kSessionStorage, + ContentSettingsClient::StorageType::kSession); + +const size_t kStorageControllerTotalCacheLimitInBytesLowEnd = 1 * 1024 * 1024; +const size_t kStorageControllerTotalCacheLimitInBytes = 5 * 1024 * 1024; + +mojom::blink::StoragePartitionServicePtr GetAndCreateStorageInterface() { + mojom::blink::StoragePartitionServicePtr ptr; + Platform::Current()->GetInterfaceProvider()->GetInterface( + mojo::MakeRequest(&ptr)); + return ptr; +} +} // namespace + +// static +StorageController* StorageController::GetInstance() { + DEFINE_STATIC_LOCAL( + StorageController, gCachedStorageAreaController, + (Platform::Current()->MainThread()->Scheduler()->IPCTaskRunner(), + GetAndCreateStorageInterface(), + base::SysInfo::IsLowEndDevice() + ? kStorageControllerTotalCacheLimitInBytesLowEnd + : kStorageControllerTotalCacheLimitInBytes)); + return &gCachedStorageAreaController; +} + +// static +bool StorageController::CanAccessStorageArea(LocalFrame* frame, + StorageArea::StorageType type) { + DCHECK(frame->GetContentSettingsClient()); + return frame->GetContentSettingsClient()->AllowStorage( + static_cast<ContentSettingsClient::StorageType>(type)); +} + +StorageController::StorageController( + scoped_refptr<base::SingleThreadTaskRunner> ipc_runner, + mojom::blink::StoragePartitionServicePtr storage_partition_service, + size_t total_cache_limit) + : ipc_runner_(std::move(ipc_runner)), + namespaces_(new HeapHashMap<String, WeakMember<StorageNamespace>>()), + total_cache_limit_(total_cache_limit), + storage_partition_service_(std::move(storage_partition_service)) {} + +StorageNamespace* StorageController::CreateSessionStorageNamespace( + const String& namespace_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // There is an edge case where a user closes a tab that has other tabs in the + // same process, then restores that tab. The old namespace might still be + // around. + auto it = namespaces_->find(namespace_id); + if (it != namespaces_->end()) + return it->value; + StorageNamespace* ns = nullptr; + if (base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage)) { + ns = new StorageNamespace(this, namespace_id); + } else { + auto namespace_str = StringUTF8Adaptor(namespace_id); + auto web_namespace = Platform::Current()->CreateSessionStorageNamespace( + namespace_str.AsStringPiece()); + if (!web_namespace) + return nullptr; + ns = new StorageNamespace(std::move(web_namespace)); + } + namespaces_->insert(namespace_id, ns); + return ns; +} + +size_t StorageController::TotalCacheSize() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + size_t total = 0; + if (local_storage_namespace_) + total = local_storage_namespace_->TotalCacheSize(); + for (const auto& pair : *namespaces_) + total += pair.value->TotalCacheSize(); + return total; +} + +void StorageController::ClearAreasIfNeeded() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (TotalCacheSize() < total_cache_limit_) + return; + if (local_storage_namespace_) + local_storage_namespace_->CleanUpUnusedAreas(); + for (auto& pair : *namespaces_) + pair.value->CleanUpUnusedAreas(); +} + +scoped_refptr<CachedStorageArea> StorageController::GetLocalStorageArea( + const SecurityOrigin* origin) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage)); + EnsureLocalStorageNamespaceCreated(); + return local_storage_namespace_->GetCachedArea(origin); +} + +std::unique_ptr<WebStorageArea> StorageController::GetWebLocalStorageArea( + const SecurityOrigin* origin) { + DCHECK(IsMainThread()); + CHECK(!base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage)); + EnsureLocalStorageNamespaceCreated(); + return local_storage_namespace_->GetWebStorageArea(origin); +} + +void StorageController::AddLocalStorageInspectorStorageAgent( + InspectorDOMStorageAgent* agent) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureLocalStorageNamespaceCreated(); + local_storage_namespace_->AddInspectorStorageAgent(agent); +} + +void StorageController::RemoveLocalStorageInspectorStorageAgent( + InspectorDOMStorageAgent* agent) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureLocalStorageNamespaceCreated(); + local_storage_namespace_->RemoveInspectorStorageAgent(agent); +} + +void StorageController::DidDispatchLocalStorageEvent( + const SecurityOrigin* origin, + const String& key, + const String& old_value, + const String& new_value) { + if (local_storage_namespace_) { + local_storage_namespace_->DidDispatchStorageEvent(origin, key, old_value, + new_value); + } +} + +void StorageController::EnsureLocalStorageNamespaceCreated() { + if (local_storage_namespace_) + return; + if (base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage)) { + local_storage_namespace_ = new StorageNamespace(this); + } else { + local_storage_namespace_ = new StorageNamespace( + Platform::Current()->CreateLocalStorageNamespace()); + } +} + +} // namespace blink |