Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(364)

Side by Side Diff: chrome/browser/dom_ui/net_internals_ui.cc

Issue 1088007: Add an initial implementation of net-internals inspector in javascript.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: more build file Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/dom_ui/net_internals_ui.h" 5 #include "chrome/browser/dom_ui/net_internals_ui.h"
6 6
7 #include "app/resource_bundle.h" 7 #include "app/resource_bundle.h"
8 #include "base/file_util.h"
9 #include "base/path_service.h"
8 #include "base/singleton.h" 10 #include "base/singleton.h"
9 #include "base/string_piece.h" 11 #include "base/string_piece.h"
12 #include "base/string_util.h"
10 #include "base/values.h" 13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/dom_ui/chrome_url_data_manager.h" 15 #include "chrome/browser/dom_ui/chrome_url_data_manager.h"
12 #include "chrome/browser/chrome_thread.h" 16 #include "chrome/browser/chrome_thread.h"
17 #include "chrome/browser/io_thread.h"
18 #include "chrome/browser/net/chrome_net_log.h"
19 #include "chrome/common/chrome_paths.h"
13 #include "chrome/common/url_constants.h" 20 #include "chrome/common/url_constants.h"
14 21
15 #include "grit/browser_resources.h" 22 namespace {
16 23
17 namespace { 24 // TODO(eroman): Bootstrap the net-internals page using the passively logged
25 // data.
18 26
19 class NetInternalsHTMLSource : public ChromeURLDataManager::DataSource { 27 class NetInternalsHTMLSource : public ChromeURLDataManager::DataSource {
20 public: 28 public:
21 NetInternalsHTMLSource(); 29 NetInternalsHTMLSource();
22 30
23 // Called when the network layer has requested a resource underneath 31 // Called when the network layer has requested a resource underneath
24 // the path we registered. 32 // the path we registered.
25 virtual void StartDataRequest(const std::string& path, 33 virtual void StartDataRequest(const std::string& path,
26 bool is_off_the_record, 34 bool is_off_the_record,
27 int request_id); 35 int request_id);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 73
66 DISALLOW_COPY_AND_ASSIGN(NetInternalsMessageHandler); 74 DISALLOW_COPY_AND_ASSIGN(NetInternalsMessageHandler);
67 }; 75 };
68 76
69 // This class is the "real" message handler. With the exception of being 77 // This class is the "real" message handler. With the exception of being
70 // allocated and destroyed on the UI thread, its methods are expected to be 78 // allocated and destroyed on the UI thread, its methods are expected to be
71 // called from the IO thread. 79 // called from the IO thread.
72 class NetInternalsMessageHandler::IOThreadImpl 80 class NetInternalsMessageHandler::IOThreadImpl
73 : public base::RefCountedThreadSafe< 81 : public base::RefCountedThreadSafe<
74 NetInternalsMessageHandler::IOThreadImpl, 82 NetInternalsMessageHandler::IOThreadImpl,
75 ChromeThread::DeleteOnUIThread> { 83 ChromeThread::DeleteOnUIThread>,
84 public ChromeNetLog::Observer {
76 public: 85 public:
77 // Type for methods that can be used as MessageHandler callbacks. 86 // Type for methods that can be used as MessageHandler callbacks.
78 typedef void (IOThreadImpl::*MessageHandler)(const Value*); 87 typedef void (IOThreadImpl::*MessageHandler)(const Value*);
79 88
80 // Creates a proxy for |handler| that will live on the IO thread. 89 // Creates a proxy for |handler| that will live on the IO thread.
81 // |handler| is a weak pointer, since it is possible for the DOMMessageHandler 90 // |handler| is a weak pointer, since it is possible for the DOMMessageHandler
82 // to be deleted on the UI thread while we were executing on the IO thread. 91 // to be deleted on the UI thread while we were executing on the IO thread.
83 explicit IOThreadImpl( 92 // |io_thread| is the global IOThread (it is passed in as an argument since
84 const base::WeakPtr<NetInternalsMessageHandler>& handler); 93 // we need to grab it from the UI thread).
94 IOThreadImpl(
95 const base::WeakPtr<NetInternalsMessageHandler>& handler,
96 IOThread* io_thread);
85 97
86 ~IOThreadImpl(); 98 ~IOThreadImpl();
87 99
88 // Creates a callback that will run |method| on the IO thread. 100 // Creates a callback that will run |method| on the IO thread.
89 // 101 //
90 // This can be used with DOMUI::RegisterMessageCallback() to bind to a method 102 // This can be used with DOMUI::RegisterMessageCallback() to bind to a method
91 // on the IO thread. 103 // on the IO thread.
92 DOMUI::MessageCallback* CreateCallback(MessageHandler method); 104 DOMUI::MessageCallback* CreateCallback(MessageHandler method);
93 105
94 // Called once the DOMUI has attached to the renderer, on the IO thread.
95 void Attach();
96
97 // Called once the DOMUI has been deleted (i.e. renderer went away), on the 106 // Called once the DOMUI has been deleted (i.e. renderer went away), on the
98 // IO thread. 107 // IO thread.
99 void Detach(); 108 void Detach();
100 109
101 //-------------------------------- 110 //--------------------------------
102 // Javascript message handlers: 111 // Javascript message handlers:
103 //-------------------------------- 112 //--------------------------------
104 113
105 // TODO(eroman): This is temporary! 114 // This message is called after the webpage's onloaded handler has fired.
106 void OnTestMessage(const Value* value); 115 // it indicates that the renderer is ready to start receiving captured data.
116 void OnRendererReady(const Value* value);
117
118 // ChromeNetLog::Observer implementation:
119 virtual void OnAddEntry(const net::NetLog::Entry& entry);
107 120
108 private: 121 private:
109 class CallbackHelper; 122 class CallbackHelper;
110 123
111 // Helper that runs |method| with |arg|, and deletes |arg| on completion. 124 // Helper that runs |method| with |arg|, and deletes |arg| on completion.
112 void DispatchToMessageHandler(Value* arg, MessageHandler method); 125 void DispatchToMessageHandler(Value* arg, MessageHandler method);
113 126
114 // Helper that executes |function_name| in the attached renderer. 127 // Helper that executes |function_name| in the attached renderer.
115 // The function takes ownership of |arg|. 128 // The function takes ownership of |arg|.
116 void CallJavascriptFunction(const std::wstring& function_name, 129 void CallJavascriptFunction(const std::wstring& function_name,
117 Value* arg); 130 Value* arg);
118 131
119 private: 132 private:
120 // Pointer to the UI-thread message handler. Only access this from 133 // Pointer to the UI-thread message handler. Only access this from
121 // the UI thread. 134 // the UI thread.
122 base::WeakPtr<NetInternalsMessageHandler> handler_; 135 base::WeakPtr<NetInternalsMessageHandler> handler_;
136
137 // The global IOThread, which contains the global NetLog to observer.
138 IOThread* io_thread_;
139
140 // True if we have attached an observer to the NetLog already.
141 bool is_observing_log_;
123 friend class base::RefCountedThreadSafe<IOThreadImpl>; 142 friend class base::RefCountedThreadSafe<IOThreadImpl>;
124 }; 143 };
125 144
126 // Helper class for a DOMUI::MessageCallback which when excuted calls 145 // Helper class for a DOMUI::MessageCallback which when excuted calls
127 // instance->*method(value) on the IO thread. 146 // instance->*method(value) on the IO thread.
128 class NetInternalsMessageHandler::IOThreadImpl::CallbackHelper 147 class NetInternalsMessageHandler::IOThreadImpl::CallbackHelper
129 : public DOMUI::MessageCallback { 148 : public DOMUI::MessageCallback {
130 public: 149 public:
131 CallbackHelper(IOThreadImpl* instance, IOThreadImpl::MessageHandler method) 150 CallbackHelper(IOThreadImpl* instance, IOThreadImpl::MessageHandler method)
132 : instance_(instance), 151 : instance_(instance),
(...skipping 29 matching lines...) Expand all
162 // 181 //
163 //////////////////////////////////////////////////////////////////////////////// 182 ////////////////////////////////////////////////////////////////////////////////
164 183
165 NetInternalsHTMLSource::NetInternalsHTMLSource() 184 NetInternalsHTMLSource::NetInternalsHTMLSource()
166 : DataSource(chrome::kChromeUINetInternalsHost, MessageLoop::current()) { 185 : DataSource(chrome::kChromeUINetInternalsHost, MessageLoop::current()) {
167 } 186 }
168 187
169 void NetInternalsHTMLSource::StartDataRequest(const std::string& path, 188 void NetInternalsHTMLSource::StartDataRequest(const std::string& path,
170 bool is_off_the_record, 189 bool is_off_the_record,
171 int request_id) { 190 int request_id) {
172 // Serve up the HTML contained in the resource bundle. 191 // The provided |path| identifies a file in resources/net_internals/.
173 base::StringPiece html( 192 std::string data_string;
174 ResourceBundle::GetSharedInstance().GetRawDataResource( 193 FilePath file_path;
175 IDR_NET_INTERNALS_HTML)); 194 PathService::Get(chrome::DIR_NET_INTERNALS, &file_path);
195 std::string filename = path.empty() ? "index.html" : path;
196 file_path = file_path.AppendASCII(filename);
176 197
177 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); 198 if (!file_util::ReadFileToString(file_path, &data_string)) {
178 html_bytes->data.resize(html.size()); 199 LOG(WARNING) << "Could not read resource: " << file_path.value();
179 std::copy(html.begin(), html.end(), html_bytes->data.begin()); 200 data_string = StringPrintf(
201 "Failed to read file RESOURCES/net_internals/%s",
202 filename.c_str());
203 }
180 204
181 SendResponse(request_id, html_bytes); 205 scoped_refptr<RefCountedBytes> bytes(new RefCountedBytes);
206 bytes->data.resize(data_string.size());
207 std::copy(data_string.begin(), data_string.end(), bytes->data.begin());
208
209 SendResponse(request_id, bytes);
182 } 210 }
183 211
184 std::string NetInternalsHTMLSource::GetMimeType(const std::string&) const { 212 std::string NetInternalsHTMLSource::GetMimeType(const std::string&) const {
213 // TODO(eroman): This is incorrect -- some of the subresources may be
214 // css/javascript.
185 return "text/html"; 215 return "text/html";
186 } 216 }
187 217
188 //////////////////////////////////////////////////////////////////////////////// 218 ////////////////////////////////////////////////////////////////////////////////
189 // 219 //
190 // NetInternalsMessageHandler 220 // NetInternalsMessageHandler
191 // 221 //
192 //////////////////////////////////////////////////////////////////////////////// 222 ////////////////////////////////////////////////////////////////////////////////
193 223
194 NetInternalsMessageHandler::NetInternalsMessageHandler() {} 224 NetInternalsMessageHandler::NetInternalsMessageHandler() {}
195 225
196 NetInternalsMessageHandler::~NetInternalsMessageHandler() { 226 NetInternalsMessageHandler::~NetInternalsMessageHandler() {
197 if (proxy_) { 227 if (proxy_) {
198 // Notify the handler on the IO thread that the renderer is gone. 228 // Notify the handler on the IO thread that the renderer is gone.
199 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, 229 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE,
200 NewRunnableMethod(proxy_.get(), &IOThreadImpl::Detach)); 230 NewRunnableMethod(proxy_.get(), &IOThreadImpl::Detach));
201 } 231 }
202 } 232 }
203 233
204 DOMMessageHandler* NetInternalsMessageHandler::Attach(DOMUI* dom_ui) { 234 DOMMessageHandler* NetInternalsMessageHandler::Attach(DOMUI* dom_ui) {
205 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 235 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
206 proxy_ = new IOThreadImpl(this->AsWeakPtr()); 236 proxy_ = new IOThreadImpl(this->AsWeakPtr(), g_browser_process->io_thread());
207
208 DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui); 237 DOMMessageHandler* result = DOMMessageHandler::Attach(dom_ui);
209
210 // Notify the handler on the IO thread that a renderer is attached.
211 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE,
212 NewRunnableMethod(proxy_.get(), &IOThreadImpl::Attach));
213
214 return result; 238 return result;
215 } 239 }
216 240
217 void NetInternalsMessageHandler::RegisterMessages() { 241 void NetInternalsMessageHandler::RegisterMessages() {
218 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 242 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
219 243
220 // TODO(eroman): Register message handlers here. 244 dom_ui_->RegisterMessageCallback("notifyReady",
221 dom_ui_->RegisterMessageCallback("testMessage", 245 proxy_->CreateCallback(&IOThreadImpl::OnRendererReady));
222 proxy_->CreateCallback(&IOThreadImpl::OnTestMessage));
223 } 246 }
224 247
225 void NetInternalsMessageHandler::CallJavascriptFunction( 248 void NetInternalsMessageHandler::CallJavascriptFunction(
226 const std::wstring& function_name, 249 const std::wstring& function_name,
227 const Value& value) { 250 const Value& value) {
228 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 251 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
229 dom_ui_->CallJavascriptFunction(function_name, value); 252 dom_ui_->CallJavascriptFunction(function_name, value);
230 } 253 }
231 254
232 //////////////////////////////////////////////////////////////////////////////// 255 ////////////////////////////////////////////////////////////////////////////////
233 // 256 //
234 // NetInternalsMessageHandler::IOThreadImpl 257 // NetInternalsMessageHandler::IOThreadImpl
235 // 258 //
236 //////////////////////////////////////////////////////////////////////////////// 259 ////////////////////////////////////////////////////////////////////////////////
237 260
238 NetInternalsMessageHandler::IOThreadImpl::IOThreadImpl( 261 NetInternalsMessageHandler::IOThreadImpl::IOThreadImpl(
239 const base::WeakPtr<NetInternalsMessageHandler>& handler) 262 const base::WeakPtr<NetInternalsMessageHandler>& handler,
240 : handler_(handler) { 263 IOThread* io_thread)
264 : handler_(handler),
265 io_thread_(io_thread),
266 is_observing_log_(false) {
241 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 267 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
242 } 268 }
243 269
244 NetInternalsMessageHandler::IOThreadImpl::~IOThreadImpl() { 270 NetInternalsMessageHandler::IOThreadImpl::~IOThreadImpl() {
245 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 271 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
246 } 272 }
247 273
248 DOMUI::MessageCallback* 274 DOMUI::MessageCallback*
249 NetInternalsMessageHandler::IOThreadImpl::CreateCallback( 275 NetInternalsMessageHandler::IOThreadImpl::CreateCallback(
250 MessageHandler method) { 276 MessageHandler method) {
251 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 277 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
252 return new CallbackHelper(this, method); 278 return new CallbackHelper(this, method);
253 } 279 }
254 280
255 void NetInternalsMessageHandler::IOThreadImpl::Attach() {
256 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
257 // TODO(eroman): Register with network stack to observe events.
258 }
259
260 void NetInternalsMessageHandler::IOThreadImpl::Detach() { 281 void NetInternalsMessageHandler::IOThreadImpl::Detach() {
261 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 282 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
262 // TODO(eroman): Unregister with network stack to observe events. 283 // Unregister with network stack to observe events.
284 if (is_observing_log_)
285 io_thread_->globals()->net_log->RemoveObserver(this);
263 } 286 }
264 287
265 void NetInternalsMessageHandler::IOThreadImpl::OnTestMessage( 288 void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady(
266 const Value* value) { 289 const Value* value) {
267 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 290 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
291 DCHECK(!is_observing_log_) << "notifyReady called twice";
268 292
269 // TODO(eroman): This is just a temporary method, to see something in 293 // Register with network stack to observe events.
270 // action. We expect to have been called with an array 294 is_observing_log_ = true;
271 // containing 1 string, and print it to the screen. 295 io_thread_->globals()->net_log->AddObserver(this);
272 std::string str; 296
273 if (value && value->GetType() == Value::TYPE_LIST) { 297 // Tell the javascript about the relationship between event type enums and
274 const ListValue* list_value = static_cast<const ListValue*>(value); 298 // their symbolic name.
275 Value* list_member; 299 {
276 if (list_value->Get(0, &list_member) && 300 std::vector<net::NetLog::EventType> event_types =
277 list_member->GetType() == Value::TYPE_STRING) { 301 net::NetLog::GetAllEventTypes();
278 const StringValue* string_value = 302
279 static_cast<const StringValue*>(list_member); 303 DictionaryValue* dict = new DictionaryValue();
280 string_value->GetAsString(&str); 304
305 for (size_t i = 0; i < event_types.size(); ++i) {
306 const char* name = net::NetLog::EventTypeToString(event_types[i]);
307 dict->SetInteger(ASCIIToWide(name),
308 static_cast<int>(event_types[i]));
281 } 309 }
310
311 CallJavascriptFunction(L"setLogEventTypeConstants", dict);
282 } 312 }
283 313
284 CallJavascriptFunction( 314 // Tell the javascript about the relationship between event phase enums and
285 L"log", 315 // their symbolic name.
286 Value::CreateStringValue("Browser received testMessage: " + str)); 316 {
317 DictionaryValue* dict = new DictionaryValue();
318
319 dict->SetInteger(L"PHASE_BEGIN", net::NetLog::PHASE_BEGIN);
320 dict->SetInteger(L"PHASE_END", net::NetLog::PHASE_END);
321 dict->SetInteger(L"PHASE_NONE", net::NetLog::PHASE_NONE);
322
323 CallJavascriptFunction(L"setLogEventPhaseConstants", dict);
324 }
325
326 // Tell the javascript about the relationship between source type enums and
327 // their symbolic name.
328 // TODO(eroman): Don't duplicate the values, it will never stay up to date!
329 {
330 DictionaryValue* dict = new DictionaryValue();
331
332 dict->SetInteger(L"NONE", net::NetLog::SOURCE_NONE);
333 dict->SetInteger(L"URL_REQUEST", net::NetLog::SOURCE_URL_REQUEST);
334 dict->SetInteger(L"SOCKET_STREAM", net::NetLog::SOURCE_SOCKET_STREAM);
335 dict->SetInteger(L"INIT_PROXY_RESOLVER",
336 net::NetLog::SOURCE_INIT_PROXY_RESOLVER);
337 dict->SetInteger(L"CONNECT_JOB", net::NetLog::SOURCE_CONNECT_JOB);
338
339 CallJavascriptFunction(L"setLogSourceTypeConstants", dict);
340 }
341
342 // Tell the javascript about the relationship between entry type enums and
343 // their symbolic name.
344 {
345 DictionaryValue* dict = new DictionaryValue();
346
347 dict->SetInteger(L"TYPE_EVENT", net::NetLog::Entry::TYPE_EVENT);
348 dict->SetInteger(L"TYPE_STRING", net::NetLog::Entry::TYPE_STRING);
349 dict->SetInteger(L"TYPE_ERROR_CODE", net::NetLog::Entry::TYPE_ERROR_CODE);
350
351 CallJavascriptFunction(L"setLogEntryTypeConstants", dict);
352 }
353 }
354
355 void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry(
356 const net::NetLog::Entry& entry) {
357 DCHECK(is_observing_log_);
358
359 // JSONify the NetLog::Entry.
360 // TODO(eroman): Need a better format for this.
361 DictionaryValue* entry_dict = new DictionaryValue();
362
363 // Set the entry type.
364 {
365 net::NetLog::Entry::Type entry_type = entry.type;
366 if (entry_type == net::NetLog::Entry::TYPE_STRING_LITERAL)
367 entry_type = net::NetLog::Entry::TYPE_STRING;
368 entry_dict->SetInteger(L"type", static_cast<int>(entry_type));
369 }
370
371 // Set the entry time.
372 entry_dict->SetInteger(
373 L"time",
374 static_cast<int>((entry.time - base::TimeTicks()).InMilliseconds()));
375
376 // Set the entry source.
377 DictionaryValue* source_dict = new DictionaryValue();
378 source_dict->SetInteger(L"id", entry.source.id);
379 source_dict->SetInteger(L"type", static_cast<int>(entry.source.type));
380 entry_dict->Set(L"source", source_dict);
381
382 // Set the event info (if it is an event entry).
383 if (entry.type == net::NetLog::Entry::TYPE_EVENT) {
384 DictionaryValue* event_dict = new DictionaryValue();
385 event_dict->SetInteger(L"type", static_cast<int>(entry.event.type));
386 event_dict->SetInteger(L"phase", static_cast<int>(entry.event.phase));
387 entry_dict->Set(L"event", event_dict);
388 }
389
390 // Add the string information (events my have a string too, due to current
391 // hacks).
392 if (entry.type == net::NetLog::Entry::TYPE_STRING || !entry.string.empty()) {
393 entry_dict->SetString(L"string", entry.string);
394 }
395
396 // Treat string literals the same as strings.
397 if (entry.type == net::NetLog::Entry::TYPE_STRING_LITERAL) {
398 entry_dict->SetString(L"string", entry.literal);
399 }
400
401 if (entry.type == net::NetLog::Entry::TYPE_ERROR_CODE) {
402 entry_dict->SetInteger(L"error_code", entry.error_code);
403 }
404
405 CallJavascriptFunction(L"onLogEntryAdded", entry_dict);
287 } 406 }
288 407
289 void NetInternalsMessageHandler::IOThreadImpl::DispatchToMessageHandler( 408 void NetInternalsMessageHandler::IOThreadImpl::DispatchToMessageHandler(
290 Value* arg, MessageHandler method) { 409 Value* arg, MessageHandler method) {
291 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 410 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
292 (this->*method)(arg); 411 (this->*method)(arg);
293 delete arg; 412 delete arg;
294 } 413 }
295 414
296 void NetInternalsMessageHandler::IOThreadImpl::CallJavascriptFunction( 415 void NetInternalsMessageHandler::IOThreadImpl::CallJavascriptFunction(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource(); 457 NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource();
339 458
340 // Set up the chrome://net-internals/ source. 459 // Set up the chrome://net-internals/ source.
341 ChromeThread::PostTask( 460 ChromeThread::PostTask(
342 ChromeThread::IO, FROM_HERE, 461 ChromeThread::IO, FROM_HERE,
343 NewRunnableMethod( 462 NewRunnableMethod(
344 Singleton<ChromeURLDataManager>::get(), 463 Singleton<ChromeURLDataManager>::get(),
345 &ChromeURLDataManager::AddDataSource, 464 &ChromeURLDataManager::AddDataSource,
346 make_scoped_refptr(html_source))); 465 make_scoped_refptr(html_source)));
347 } 466 }
OLDNEW
« no previous file with comments | « chrome/browser/browser_resources.grd ('k') | chrome/browser/resources/net_internals/detailsview.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698