| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/media/webrtc_logging_handler_host.h" | 5 #include "chrome/browser/media/webrtc_logging_handler_host.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | |
| 11 #include "base/cpu.h" | 10 #include "base/cpu.h" |
| 12 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 13 #include "base/logging.h" | 12 #include "base/logging.h" |
| 14 #include "base/prefs/pref_service.h" | |
| 15 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/sys_info.h" | 14 #include "base/sys_info.h" |
| 17 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 18 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/chromeos/settings/cros_settings.h" | |
| 20 #include "chrome/browser/media/webrtc_log_list.h" | 17 #include "chrome/browser/media/webrtc_log_list.h" |
| 21 #include "chrome/browser/media/webrtc_log_uploader.h" | 18 #include "chrome/browser/media/webrtc_log_uploader.h" |
| 22 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/common/chrome_switches.h" | |
| 24 #include "chrome/common/media/webrtc_logging_messages.h" | 20 #include "chrome/common/media/webrtc_logging_messages.h" |
| 25 #include "chrome/common/partial_circular_buffer.h" | 21 #include "chrome/common/partial_circular_buffer.h" |
| 26 #include "chrome/common/pref_names.h" | |
| 27 #include "chromeos/settings/cros_settings_names.h" | |
| 28 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/content_browser_client.h" | 23 #include "content/public/browser/content_browser_client.h" |
| 30 #include "content/public/browser/gpu_data_manager.h" | 24 #include "content/public/browser/gpu_data_manager.h" |
| 31 #include "content/public/browser/render_process_host.h" | 25 #include "content/public/browser/render_process_host.h" |
| 32 #include "gpu/config/gpu_info.h" | 26 #include "gpu/config/gpu_info.h" |
| 33 #include "net/base/address_family.h" | 27 #include "net/base/address_family.h" |
| 34 #include "net/url_request/url_request_context_getter.h" | 28 #include "net/url_request/url_request_context_getter.h" |
| 35 | 29 |
| 36 #if defined(OS_LINUX) | 30 #if defined(OS_LINUX) |
| 37 #include "base/linux_util.h" | 31 #include "base/linux_util.h" |
| 38 #endif | 32 #endif |
| 39 | 33 |
| 40 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
| 41 #include "base/mac/mac_util.h" | 35 #include "base/mac/mac_util.h" |
| 42 #endif | 36 #endif |
| 43 | 37 |
| 44 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
| 39 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 40 #include "chromeos/settings/cros_settings_names.h" |
| 45 #include "chromeos/system/statistics_provider.h" | 41 #include "chromeos/system/statistics_provider.h" |
| 46 #endif | 42 #endif |
| 47 | 43 |
| 48 using base::IntToString; | 44 using base::IntToString; |
| 49 using content::BrowserThread; | 45 using content::BrowserThread; |
| 50 | 46 |
| 51 | 47 |
| 52 #if defined(OS_ANDROID) | 48 #if defined(OS_ANDROID) |
| 53 const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB | 49 const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB |
| 54 #else | 50 #else |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 meta_data_ = meta_data; | 127 meta_data_ = meta_data; |
| 132 } else if (logging_state_ == STARTED) { | 128 } else if (logging_state_ == STARTED) { |
| 133 meta_data_ = meta_data; | 129 meta_data_ = meta_data; |
| 134 std::string meta_data_message; | 130 std::string meta_data_message; |
| 135 FormatMetaDataAsLogMessage(meta_data_, &meta_data_message); | 131 FormatMetaDataAsLogMessage(meta_data_, &meta_data_message); |
| 136 LogToCircularBuffer(meta_data_message); | 132 LogToCircularBuffer(meta_data_message); |
| 137 } else { | 133 } else { |
| 138 error_message = "Meta data must be set before stop or upload."; | 134 error_message = "Meta data must be set before stop or upload."; |
| 139 } | 135 } |
| 140 bool success = error_message.empty(); | 136 bool success = error_message.empty(); |
| 141 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 137 BrowserThread::PostTask(BrowserThread::UI, |
| 142 base::Bind(callback, success, | 138 FROM_HERE, |
| 143 error_message)); | 139 base::Bind(callback, success, error_message)); |
| 144 } | 140 } |
| 145 | 141 |
| 146 void WebRtcLoggingHandlerHost::StartLogging( | 142 void WebRtcLoggingHandlerHost::StartLogging( |
| 147 const GenericDoneCallback& callback) { | 143 const GenericDoneCallback& callback) { |
| 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 149 DCHECK(!callback.is_null()); | 145 DCHECK(!callback.is_null()); |
| 150 | 146 |
| 151 start_callback_ = callback; | 147 start_callback_ = callback; |
| 152 if (logging_state_ != CLOSED) { | 148 if (logging_state_ != CLOSED) { |
| 153 FireGenericDoneCallback(&start_callback_, false, "A log is already open"); | 149 FireGenericDoneCallback(&start_callback_, false, "A log is already open"); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 171 logging_state_ = STOPPING; | 167 logging_state_ = STOPPING; |
| 172 Send(new WebRtcLoggingMsg_StopLogging()); | 168 Send(new WebRtcLoggingMsg_StopLogging()); |
| 173 } | 169 } |
| 174 | 170 |
| 175 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) { | 171 void WebRtcLoggingHandlerHost::UploadLog(const UploadDoneCallback& callback) { |
| 176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 177 DCHECK(!callback.is_null()); | 173 DCHECK(!callback.is_null()); |
| 178 | 174 |
| 179 if (logging_state_ != STOPPED) { | 175 if (logging_state_ != STOPPED) { |
| 180 if (!callback.is_null()) { | 176 if (!callback.is_null()) { |
| 181 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 177 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 182 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen)); | 178 base::Bind(callback, false, "", kLogNotStoppedOrNoLogOpen)); |
| 183 } | 179 } |
| 184 return; | 180 return; |
| 185 } | 181 } |
| 186 upload_callback_ = callback; | 182 upload_callback_ = callback; |
| 187 logging_state_ = UPLOADING; | 183 logging_state_ = UPLOADING; |
| 188 content::BrowserThread::PostTaskAndReplyWithResult( | 184 base::PostTaskAndReplyWithResult( |
| 189 content::BrowserThread::FILE, | 185 BrowserThread::GetBlockingPool(), |
| 190 FROM_HERE, | 186 FROM_HERE, |
| 191 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | 187 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, |
| 192 this), | 188 this), |
| 193 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); | 189 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); |
| 194 } | 190 } |
| 195 | 191 |
| 196 void WebRtcLoggingHandlerHost::UploadLogDone() { | 192 void WebRtcLoggingHandlerHost::UploadLogDone() { |
| 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 198 logging_state_ = CLOSED; | 194 logging_state_ = CLOSED; |
| 199 } | 195 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 const GenericDoneCallback& callback) { | 234 const GenericDoneCallback& callback) { |
| 239 NOTIMPLEMENTED(); | 235 NOTIMPLEMENTED(); |
| 240 } | 236 } |
| 241 | 237 |
| 242 void WebRtcLoggingHandlerHost::OnChannelClosing() { | 238 void WebRtcLoggingHandlerHost::OnChannelClosing() { |
| 243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 244 if (logging_state_ == STARTED || logging_state_ == STOPPED) { | 240 if (logging_state_ == STARTED || logging_state_ == STOPPED) { |
| 245 if (upload_log_on_render_close_) { | 241 if (upload_log_on_render_close_) { |
| 246 logging_state_ = UPLOADING; | 242 logging_state_ = UPLOADING; |
| 247 logging_started_time_ = base::Time(); | 243 logging_started_time_ = base::Time(); |
| 248 content::BrowserThread::PostTaskAndReplyWithResult( | 244 base::PostTaskAndReplyWithResult( |
| 249 content::BrowserThread::FILE, | 245 BrowserThread::GetBlockingPool(), |
| 250 FROM_HERE, | 246 FROM_HERE, |
| 251 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, | 247 base::Bind(&WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists, |
| 252 this), | 248 this), |
| 253 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); | 249 base::Bind(&WebRtcLoggingHandlerHost::TriggerUploadLog, this)); |
| 254 } else { | 250 } else { |
| 255 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload(); | 251 g_browser_process->webrtc_log_uploader()->LoggingStoppedDontUpload(); |
| 256 } | 252 } |
| 257 } | 253 } |
| 258 content::BrowserMessageFilter::OnChannelClosing(); | 254 BrowserMessageFilter::OnChannelClosing(); |
| 259 } | 255 } |
| 260 | 256 |
| 261 void WebRtcLoggingHandlerHost::OnDestruct() const { | 257 void WebRtcLoggingHandlerHost::OnDestruct() const { |
| 262 BrowserThread::DeleteOnIOThread::Destruct(this); | 258 BrowserThread::DeleteOnIOThread::Destruct(this); |
| 263 } | 259 } |
| 264 | 260 |
| 265 bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message) { | 261 bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message) { |
| 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 267 bool handled = true; | 263 bool handled = true; |
| 268 IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingHandlerHost, message) | 264 IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingHandlerHost, message) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 void WebRtcLoggingHandlerHost::DoStartLogging() { | 319 void WebRtcLoggingHandlerHost::DoStartLogging() { |
| 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 325 | 321 |
| 326 log_buffer_.reset(new unsigned char[kWebRtcLogSize]); | 322 log_buffer_.reset(new unsigned char[kWebRtcLogSize]); |
| 327 circular_buffer_.reset( | 323 circular_buffer_.reset( |
| 328 new PartialCircularBuffer(log_buffer_.get(), | 324 new PartialCircularBuffer(log_buffer_.get(), |
| 329 kWebRtcLogSize, | 325 kWebRtcLogSize, |
| 330 kWebRtcLogSize / 2, | 326 kWebRtcLogSize / 2, |
| 331 false)); | 327 false)); |
| 332 | 328 |
| 333 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( | 329 BrowserThread::PostBlockingPoolTask( |
| 334 &WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread, this)); | 330 FROM_HERE, |
| 331 base::Bind(&WebRtcLoggingHandlerHost::LogInitialInfoOnBlockingPool, |
| 332 this)); |
| 335 } | 333 } |
| 336 | 334 |
| 337 void WebRtcLoggingHandlerHost::LogInitialInfoOnFileThread() { | 335 void WebRtcLoggingHandlerHost::LogInitialInfoOnBlockingPool() { |
| 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 336 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 339 | 337 |
| 340 net::NetworkInterfaceList network_list; | 338 net::NetworkInterfaceList network_list; |
| 341 net::GetNetworkList(&network_list, | 339 net::GetNetworkList(&network_list, |
| 342 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); | 340 net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES); |
| 343 | 341 |
| 344 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 342 std::string linux_distro; |
| 345 &WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, this, network_list)); | 343 #if defined(OS_LINUX) |
| 344 linux_distro = base::GetLinuxDistro(); |
| 345 #endif |
| 346 |
| 347 BrowserThread::PostTask( |
| 348 BrowserThread::IO, |
| 349 FROM_HERE, |
| 350 base::Bind(&WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread, |
| 351 this, |
| 352 network_list, |
| 353 linux_distro)); |
| 346 } | 354 } |
| 347 | 355 |
| 348 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread( | 356 void WebRtcLoggingHandlerHost::LogInitialInfoOnIOThread( |
| 349 const net::NetworkInterfaceList& network_list) { | 357 const net::NetworkInterfaceList& network_list, |
| 358 const std::string& linux_distro) { |
| 350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 351 | 360 |
| 352 // Log start time (current time). We don't use base/i18n/time_formatting.h | 361 // Log start time (current time). We don't use base/i18n/time_formatting.h |
| 353 // here because we don't want the format of the current locale. | 362 // here because we don't want the format of the current locale. |
| 354 base::Time::Exploded now = {0}; | 363 base::Time::Exploded now = {0}; |
| 355 base::Time::Now().LocalExplode(&now); | 364 base::Time::Now().LocalExplode(&now); |
| 356 LogToCircularBuffer(base::StringPrintf( | 365 LogToCircularBuffer(base::StringPrintf( |
| 357 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month, | 366 "Start %d-%02d-%02d %02d:%02d:%02d", now.year, now.month, |
| 358 now.day_of_month, now.hour, now.minute, now.second)); | 367 now.day_of_month, now.hour, now.minute, now.second)); |
| 359 | 368 |
| 360 // Write metadata if received before logging started. | 369 // Write metadata if received before logging started. |
| 361 if (!meta_data_.empty()) { | 370 if (!meta_data_.empty()) { |
| 362 std::string info; | 371 std::string info; |
| 363 FormatMetaDataAsLogMessage(meta_data_, &info); | 372 FormatMetaDataAsLogMessage(meta_data_, &info); |
| 364 LogToCircularBuffer(info); | 373 LogToCircularBuffer(info); |
| 365 } | 374 } |
| 366 | 375 |
| 367 // OS | 376 // OS |
| 368 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " + | 377 LogToCircularBuffer(base::SysInfo::OperatingSystemName() + " " + |
| 369 base::SysInfo::OperatingSystemVersion() + " " + | 378 base::SysInfo::OperatingSystemVersion() + " " + |
| 370 base::SysInfo::OperatingSystemArchitecture()); | 379 base::SysInfo::OperatingSystemArchitecture()); |
| 371 #if defined(OS_LINUX) | 380 #if defined(OS_LINUX) |
| 372 LogToCircularBuffer("Linux distribution: " + base::GetLinuxDistro()); | 381 LogToCircularBuffer("Linux distribution: " + linux_distro); |
| 373 #endif | 382 #endif |
| 374 | 383 |
| 375 // CPU | 384 // CPU |
| 376 base::CPU cpu; | 385 base::CPU cpu; |
| 377 LogToCircularBuffer( | 386 LogToCircularBuffer( |
| 378 "Cpu: " + IntToString(cpu.family()) + "." + IntToString(cpu.model()) + | 387 "Cpu: " + IntToString(cpu.family()) + "." + IntToString(cpu.model()) + |
| 379 "." + IntToString(cpu.stepping()) + ", x" + | 388 "." + IntToString(cpu.stepping()) + ", x" + |
| 380 IntToString(base::SysInfo::NumberOfProcessors()) + ", " + | 389 IntToString(base::SysInfo::NumberOfProcessors()) + ", " + |
| 381 IntToString(base::SysInfo::AmountOfPhysicalMemoryMB()) + "MB"); | 390 IntToString(base::SysInfo::AmountOfPhysicalMemoryMB()) + "MB"); |
| 382 std::string cpu_brand = cpu.cpu_brand(); | 391 std::string cpu_brand = cpu.cpu_brand(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 | 442 |
| 434 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) { | 443 void WebRtcLoggingHandlerHost::LogToCircularBuffer(const std::string& message) { |
| 435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 436 DCHECK(circular_buffer_.get()); | 445 DCHECK(circular_buffer_.get()); |
| 437 circular_buffer_->Write(message.c_str(), message.length()); | 446 circular_buffer_->Write(message.c_str(), message.length()); |
| 438 const char eol = '\n'; | 447 const char eol = '\n'; |
| 439 circular_buffer_->Write(&eol, 1); | 448 circular_buffer_->Write(&eol, 1); |
| 440 } | 449 } |
| 441 | 450 |
| 442 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() { | 451 base::FilePath WebRtcLoggingHandlerHost::GetLogDirectoryAndEnsureExists() { |
| 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 452 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 444 base::FilePath log_dir_path = | 453 base::FilePath log_dir_path = |
| 445 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath()); | 454 WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile_->GetPath()); |
| 446 base::File::Error error; | 455 base::File::Error error; |
| 447 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) { | 456 if (!base::CreateDirectoryAndGetError(log_dir_path, &error)) { |
| 448 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error; | 457 DLOG(ERROR) << "Could not create WebRTC log directory, error: " << error; |
| 449 return base::FilePath(); | 458 return base::FilePath(); |
| 450 } | 459 } |
| 451 return log_dir_path; | 460 return log_dir_path; |
| 452 } | 461 } |
| 453 | 462 |
| 454 void WebRtcLoggingHandlerHost::TriggerUploadLog( | 463 void WebRtcLoggingHandlerHost::TriggerUploadLog( |
| 455 const base::FilePath& log_directory) { | 464 const base::FilePath& log_directory) { |
| 456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 457 DCHECK_EQ(logging_state_, UPLOADING); | 466 DCHECK_EQ(logging_state_, UPLOADING); |
| 458 | 467 |
| 459 WebRtcLogUploadDoneData upload_done_data; | 468 WebRtcLogUploadDoneData upload_done_data; |
| 460 upload_done_data.log_path = log_directory; | 469 upload_done_data.log_path = log_directory; |
| 461 upload_done_data.callback = upload_callback_; | 470 upload_done_data.callback = upload_callback_; |
| 462 upload_done_data.host = this; | 471 upload_done_data.host = this; |
| 463 upload_callback_.Reset(); | 472 upload_callback_.Reset(); |
| 464 | 473 |
| 465 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( | 474 BrowserThread::PostBlockingPoolTask( |
| 466 &WebRtcLogUploader::LoggingStoppedDoUpload, | 475 FROM_HERE, |
| 467 base::Unretained(g_browser_process->webrtc_log_uploader()), | 476 base::Bind(&WebRtcLogUploader::LoggingStoppedDoUpload, |
| 468 Passed(&log_buffer_), | 477 base::Unretained(g_browser_process->webrtc_log_uploader()), |
| 469 kWebRtcLogSize, | 478 Passed(&log_buffer_), |
| 470 meta_data_, | 479 kWebRtcLogSize, |
| 471 upload_done_data)); | 480 meta_data_, |
| 481 upload_done_data)); |
| 472 | 482 |
| 473 meta_data_.clear(); | 483 meta_data_.clear(); |
| 474 circular_buffer_.reset(); | 484 circular_buffer_.reset(); |
| 475 } | 485 } |
| 476 | 486 |
| 477 void WebRtcLoggingHandlerHost::FireGenericDoneCallback( | 487 void WebRtcLoggingHandlerHost::FireGenericDoneCallback( |
| 478 GenericDoneCallback* callback, bool success, | 488 GenericDoneCallback* callback, bool success, |
| 479 const std::string& error_message) { | 489 const std::string& error_message) { |
| 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 481 DCHECK(!(*callback).is_null()); | 491 DCHECK(!callback->is_null()); |
| 482 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 492 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 483 base::Bind(*callback, success, | 493 base::Bind(*callback, success, error_message)); |
| 484 error_message)); | 494 callback->Reset(); |
| 485 (*callback).Reset(); | |
| 486 } | 495 } |
| OLD | NEW |