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.
5 #include "content/browser/webui/url_data_manager.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/strings/string_util.h"
14 #include "base/synchronization/lock.h"
15 #include "content/browser/resource_context_impl.h"
16 #include "content/browser/webui/url_data_manager_backend.h"
17 #include "content/browser/webui/url_data_source_impl.h"
18 #include "content/browser/webui/web_ui_data_source_impl.h"
19 #include "content/public/browser/browser_context.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/url_data_source.h"
26 const char kURLDataManagerKeyName
[] = "url_data_manager";
28 base::LazyInstance
<base::Lock
>::Leaky g_delete_lock
= LAZY_INSTANCE_INITIALIZER
;
30 URLDataManager
* GetFromBrowserContext(BrowserContext
* context
) {
31 if (!context
->GetUserData(kURLDataManagerKeyName
)) {
32 context
->SetUserData(kURLDataManagerKeyName
, new URLDataManager(context
));
34 return static_cast<URLDataManager
*>(
35 context
->GetUserData(kURLDataManagerKeyName
));
38 // Invoked on the IO thread to do the actual adding of the DataSource.
39 static void AddDataSourceOnIOThread(
40 ResourceContext
* resource_context
,
41 scoped_refptr
<URLDataSourceImpl
> data_source
) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
43 GetURLDataManagerForResourceContext(resource_context
)->AddDataSource(
50 URLDataManager::URLDataSources
* URLDataManager::data_sources_
= NULL
;
52 URLDataManager::URLDataManager(BrowserContext
* browser_context
)
53 : browser_context_(browser_context
) {
56 URLDataManager::~URLDataManager() {
59 void URLDataManager::AddDataSource(URLDataSourceImpl
* source
) {
60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
61 BrowserThread::PostTask(
62 BrowserThread::IO
, FROM_HERE
,
63 base::Bind(&AddDataSourceOnIOThread
,
64 browser_context_
->GetResourceContext(),
65 make_scoped_refptr(source
)));
69 void URLDataManager::DeleteDataSources() {
70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
71 URLDataSources sources
;
73 base::AutoLock
lock(g_delete_lock
.Get());
76 data_sources_
->swap(sources
);
78 for (size_t i
= 0; i
< sources
.size(); ++i
)
83 void URLDataManager::DeleteDataSource(const URLDataSourceImpl
* data_source
) {
84 // Invoked when a DataSource is no longer referenced and needs to be deleted.
85 if (BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
86 // We're on the UI thread, delete right away.
91 // We're not on the UI thread, add the DataSource to the list of DataSources
93 bool schedule_delete
= false;
95 base::AutoLock
lock(g_delete_lock
.Get());
97 data_sources_
= new URLDataSources();
98 schedule_delete
= data_sources_
->empty();
99 data_sources_
->push_back(data_source
);
101 if (schedule_delete
) {
102 // Schedule a task to delete the DataSource back on the UI thread.
103 BrowserThread::PostTask(
104 BrowserThread::UI
, FROM_HERE
,
105 base::Bind(&URLDataManager::DeleteDataSources
));
110 void URLDataManager::AddDataSource(BrowserContext
* browser_context
,
111 URLDataSource
* source
) {
112 GetFromBrowserContext(browser_context
)->
113 AddDataSource(new URLDataSourceImpl(source
->GetSource(), source
));
117 void URLDataManager::AddWebUIDataSource(BrowserContext
* browser_context
,
118 WebUIDataSource
* source
) {
119 WebUIDataSourceImpl
* impl
= static_cast<WebUIDataSourceImpl
*>(source
);
120 GetFromBrowserContext(browser_context
)->AddDataSource(impl
);
124 bool URLDataManager::IsScheduledForDeletion(
125 const URLDataSourceImpl
* data_source
) {
126 base::AutoLock
lock(g_delete_lock
.Get());
129 return std::find(data_sources_
->begin(), data_sources_
->end(), data_source
) !=
130 data_sources_
->end();
133 } // namespace content