• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/webui/url_data_manager.h"
6 
7 #include <vector>
8 
9 #include "base/bind.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"
22 
23 namespace content {
24 namespace {
25 
26 const char kURLDataManagerKeyName[] = "url_data_manager";
27 
28 base::LazyInstance<base::Lock>::Leaky g_delete_lock = LAZY_INSTANCE_INITIALIZER;
29 
GetFromBrowserContext(BrowserContext * context)30 URLDataManager* GetFromBrowserContext(BrowserContext* context) {
31   if (!context->GetUserData(kURLDataManagerKeyName)) {
32     context->SetUserData(kURLDataManagerKeyName, new URLDataManager(context));
33   }
34   return static_cast<URLDataManager*>(
35       context->GetUserData(kURLDataManagerKeyName));
36 }
37 
38 // Invoked on the IO thread to do the actual adding of the DataSource.
AddDataSourceOnIOThread(ResourceContext * resource_context,scoped_refptr<URLDataSourceImpl> data_source)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(
44       data_source.get());
45 }
46 
47 }  // namespace
48 
49 // static
50 URLDataManager::URLDataSources* URLDataManager::data_sources_ = NULL;
51 
URLDataManager(BrowserContext * browser_context)52 URLDataManager::URLDataManager(BrowserContext* browser_context)
53     : browser_context_(browser_context) {
54 }
55 
~URLDataManager()56 URLDataManager::~URLDataManager() {
57 }
58 
AddDataSource(URLDataSourceImpl * source)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)));
66 }
67 
68 // static
DeleteDataSources()69 void URLDataManager::DeleteDataSources() {
70   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
71   URLDataSources sources;
72   {
73     base::AutoLock lock(g_delete_lock.Get());
74     if (!data_sources_)
75       return;
76     data_sources_->swap(sources);
77   }
78   for (size_t i = 0; i < sources.size(); ++i)
79     delete sources[i];
80 }
81 
82 // static
DeleteDataSource(const URLDataSourceImpl * data_source)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.
87     delete data_source;
88     return;
89   }
90 
91   // We're not on the UI thread, add the DataSource to the list of DataSources
92   // to delete.
93   bool schedule_delete = false;
94   {
95     base::AutoLock lock(g_delete_lock.Get());
96     if (!data_sources_)
97       data_sources_ = new URLDataSources();
98     schedule_delete = data_sources_->empty();
99     data_sources_->push_back(data_source);
100   }
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));
106   }
107 }
108 
109 // static
AddDataSource(BrowserContext * browser_context,URLDataSource * source)110 void URLDataManager::AddDataSource(BrowserContext* browser_context,
111                                    URLDataSource* source) {
112   GetFromBrowserContext(browser_context)->
113       AddDataSource(new URLDataSourceImpl(source->GetSource(), source));
114 }
115 
116 // static
AddWebUIDataSource(BrowserContext * browser_context,WebUIDataSource * source)117 void URLDataManager::AddWebUIDataSource(BrowserContext* browser_context,
118                                         WebUIDataSource* source) {
119   WebUIDataSourceImpl* impl = static_cast<WebUIDataSourceImpl*>(source);
120   GetFromBrowserContext(browser_context)->AddDataSource(impl);
121 }
122 
123 // static
IsScheduledForDeletion(const URLDataSourceImpl * data_source)124 bool URLDataManager::IsScheduledForDeletion(
125     const URLDataSourceImpl* data_source) {
126   base::AutoLock lock(g_delete_lock.Get());
127   if (!data_sources_)
128     return false;
129   return std::find(data_sources_->begin(), data_sources_->end(), data_source) !=
130       data_sources_->end();
131 }
132 
133 }  // namespace content
134