forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathurl_data_manager.cc
143 lines (121 loc) · 4.56 KB
/
url_data_manager.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright (c) 2012 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 "content/browser/webui/url_data_manager.h"
#include <stddef.h>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/containers/contains.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/url_data_source.h"
namespace content {
namespace {
const char kURLDataManagerKeyName[] = "url_data_manager";
base::LazyInstance<base::Lock>::Leaky g_delete_lock = LAZY_INSTANCE_INITIALIZER;
URLDataManager* GetFromBrowserContext(BrowserContext* context) {
if (!context->GetUserData(kURLDataManagerKeyName)) {
context->SetUserData(kURLDataManagerKeyName,
std::make_unique<URLDataManager>(context));
}
return static_cast<URLDataManager*>(
context->GetUserData(kURLDataManagerKeyName));
}
} // namespace
// static
URLDataManager::URLDataSources* URLDataManager::data_sources_ PT_GUARDED_BY(
g_delete_lock.Get()) = nullptr;
URLDataManager::URLDataManager(BrowserContext* browser_context)
: browser_context_(browser_context) {
}
URLDataManager::~URLDataManager() {
}
void URLDataManager::AddDataSource(URLDataSourceImpl* source) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
URLDataManagerBackend::GetForBrowserContext(browser_context_)
->AddDataSource(source);
}
void URLDataManager::UpdateWebUIDataSource(
const std::string& source_name,
std::unique_ptr<base::DictionaryValue> update) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
URLDataManagerBackend::GetForBrowserContext(browser_context_)
->UpdateWebUIDataSource(source_name, *update);
}
// static
void URLDataManager::DeleteDataSources() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
URLDataSources sources;
{
base::AutoLock lock(g_delete_lock.Get());
if (!data_sources_)
return;
data_sources_->swap(sources);
}
for (size_t i = 0; i < sources.size(); ++i)
delete sources[i];
}
// static
void URLDataManager::DeleteDataSource(const URLDataSourceImpl* data_source) {
// Invoked when a DataSource is no longer referenced and needs to be deleted.
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
// We're on the UI thread, delete right away.
delete data_source;
return;
}
// We're not on the UI thread, add the DataSource to the list of DataSources
// to delete.
bool schedule_delete = false;
{
base::AutoLock lock(g_delete_lock.Get());
if (!data_sources_)
data_sources_ = new URLDataSources();
schedule_delete = data_sources_->empty();
data_sources_->push_back(data_source);
}
if (schedule_delete) {
// Schedule a task to delete the DataSource back on the UI thread.
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&URLDataManager::DeleteDataSources));
}
}
// static
void URLDataManager::AddDataSource(BrowserContext* browser_context,
std::unique_ptr<URLDataSource> source) {
std::string name = source->GetSource();
auto source_impl =
base::MakeRefCounted<URLDataSourceImpl>(name, std::move(source));
GetFromBrowserContext(browser_context)->AddDataSource(source_impl.get());
}
// static
void URLDataManager::AddWebUIDataSource(BrowserContext* browser_context,
WebUIDataSource* source) {
WebUIDataSourceImpl* impl = static_cast<WebUIDataSourceImpl*>(source);
GetFromBrowserContext(browser_context)->AddDataSource(impl);
}
void URLDataManager::UpdateWebUIDataSource(
BrowserContext* browser_context,
const std::string& source_name,
std::unique_ptr<base::DictionaryValue> update) {
GetFromBrowserContext(browser_context)
->UpdateWebUIDataSource(source_name, std::move(update));
}
// static
bool URLDataManager::IsScheduledForDeletion(
const URLDataSourceImpl* data_source) {
base::AutoLock lock(g_delete_lock.Get());
return data_sources_ && base::Contains(*data_sources_, data_source);
}
} // namespace content