Chromium Code Reviews| Index: components/net_log/net_log_file_writer.cc |
| diff --git a/components/net_log/net_log_file_writer.cc b/components/net_log/net_log_file_writer.cc |
| index db51ca7d2df294065553ee94c372e6bc0723a7e3..37eae5e5facecf606ac7e30ef248904c83cb16f7 100644 |
| --- a/components/net_log/net_log_file_writer.cc |
| +++ b/components/net_log/net_log_file_writer.cc |
| @@ -6,20 +6,27 @@ |
| #include <utility> |
| +#include "base/bind.h" |
| +#include "base/callback.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_file.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "base/task_runner_util.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "components/net_log/chrome_net_log.h" |
| -#include "net/log/write_to_file_net_log_observer.h" |
| +#include "net/log/file_net_log_observer.h" |
| +#include "net/log/net_log_util.h" |
| +#include "net/url_request/url_request_context_getter.h" |
| namespace net_log { |
| -// Path of logs if relative to default temporary directory of |
| +// Path of logs relative to default temporary directory given by |
| // base::GetTempDir(). Must be kept in sync with |
| -// chrome/android/java/res/xml/file_paths.xml. Only used if |
| -// not saving log file to a custom path. |
| +// chrome/android/java/res/xml/file_paths.xml. Only used if not saving log file |
| +// to a custom path. |
| base::FilePath::CharType kLogRelativePath[] = |
| FILE_PATH_LITERAL("net-export/chrome-net-export-log.json"); |
| @@ -28,219 +35,361 @@ base::FilePath::CharType kLogRelativePath[] = |
| base::FilePath::CharType kOldLogRelativePath[] = |
| FILE_PATH_LITERAL("chrome-net-export-log.json"); |
| +// Adds net info from net::GetNetInfo() to |polled_data|. Must run on the |
| +// |net_task_runner_| of NetLogFileWriter. |
| +std::unique_ptr<base::DictionaryValue> AddNetInfo( |
| + scoped_refptr<net::URLRequestContextGetter> context_getter, |
| + std::unique_ptr<base::DictionaryValue> polled_data) { |
| + DCHECK(context_getter); |
| + std::unique_ptr<base::DictionaryValue> net_info = net::GetNetInfo( |
| + context_getter->GetURLRequestContext(), net::NET_INFO_ALL_SOURCES); |
| + if (polled_data) |
| + net_info->MergeDictionary(polled_data.get()); |
| + return net_info; |
| +} |
| + |
| +// If running on a POSIX OS, this sets all the permission flags of the file at |
| +// |path| to 1. Returns false if file does not exist. |
| +bool SetPosixFilePermissionsAll(const base::FilePath& path) { |
| + if (!base::PathExists(path)) |
| + return false; |
| +#if defined(OS_POSIX) |
| + return base::SetPosixFilePermissions(path, base::FILE_PERMISSION_MASK); |
| +#else |
| + return true; |
| +#endif |
| +} |
| + |
| NetLogFileWriter::~NetLogFileWriter() { |
| if (write_to_file_observer_) |
| - write_to_file_observer_->StopObserving(nullptr); |
| + write_to_file_observer_->StopObserving(nullptr, base::Bind([] {})); |
| } |
| -void NetLogFileWriter::ProcessCommand(Command command) { |
| +NetLogFileWriter::NetLogFileWriter( |
| + ChromeNetLog* chrome_net_log, |
| + const base::CommandLine::StringType& command_line_string, |
| + const std::string& channel_string) |
| + : state_(STATE_UNINITIALIZED), |
| + log_exists_(false), |
| + log_capture_mode_known_(false), |
| + log_capture_mode_(net::NetLogCaptureMode::Default()), |
| + chrome_net_log_(chrome_net_log), |
| + command_line_string_(command_line_string), |
| + channel_string_(channel_string), |
| + default_log_base_directory_getter_(base::Bind(&base::GetTempDir)), |
| + weak_ptr_factory_(this) {} |
| + |
| +void NetLogFileWriter::StartNetLog(const base::FilePath& log_path, |
| + net::NetLogCaptureMode capture_mode, |
| + const StateCallback& state_callback) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (!EnsureInit()) |
| - return; |
| - switch (command) { |
| - case DO_START_LOG_BYTES: |
| - StartNetLog(LOG_TYPE_LOG_BYTES); |
| - break; |
| - case DO_START: |
| - StartNetLog(LOG_TYPE_NORMAL); |
| - break; |
| - case DO_START_STRIP_PRIVATE_DATA: |
| - StartNetLog(LOG_TYPE_STRIP_PRIVATE_DATA); |
| - break; |
| - case DO_STOP: |
| - StopNetLog(); |
| - break; |
| - default: |
| - NOTREACHED(); |
| - break; |
| + EnsureInitThenRun( |
| + base::Bind(&NetLogFileWriter::StartNetLogAfterInitialized, |
| + weak_ptr_factory_.GetWeakPtr(), log_path, capture_mode), |
| + state_callback, true); |
| +} |
| + |
| +void NetLogFileWriter::StartNetLogAfterInitialized( |
|
eroman
2017/01/21 02:17:40
style: in chrome code we try to match the definiti
wangyix1
2017/01/23 20:16:42
Done.
|
| + const base::FilePath& log_path, |
| + net::NetLogCaptureMode capture_mode) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING); |
| + DCHECK(file_task_runner_); |
| + |
| + if (state_ == STATE_NOT_LOGGING) { |
| + if (!log_path.empty()) |
| + log_path_ = log_path; |
| + |
| + state_ = STATE_LOGGING; |
| + log_exists_ = true; |
| + log_capture_mode_known_ = true; |
| + log_capture_mode_ = capture_mode; |
| + |
| + DCHECK(!log_path_.empty()); |
|
eroman
2017/01/21 02:17:40
[optional] I suggest moving this up to line 103.
wangyix1
2017/01/23 20:16:43
Done.
|
| + |
| + std::unique_ptr<base::Value> constants( |
| + ChromeNetLog::GetConstants(command_line_string_, channel_string_)); |
| + write_to_file_observer_.reset( |
|
eroman
2017/01/21 02:17:40
[optional]: write_to_file_observer_ = base::MakeU
wangyix1
2017/01/23 20:16:42
Done.
|
| + new net::FileNetLogObserver(file_task_runner_)); |
| + write_to_file_observer_->StartObservingUnbounded( |
| + chrome_net_log_, capture_mode, log_path_, std::move(constants), |
| + nullptr); |
| } |
| } |
| -bool NetLogFileWriter::GetFilePath(base::FilePath* path) { |
| +void NetLogFileWriter::StopNetLog( |
| + std::unique_ptr<base::DictionaryValue> polled_data, |
| + scoped_refptr<net::URLRequestContextGetter> context_getter, |
| + const StateCallback& state_callback) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (log_type_ == LOG_TYPE_NONE || state_ == STATE_LOGGING) |
| - return false; |
| + DCHECK(net_task_runner_); |
| + if (state_ == STATE_LOGGING) { |
| + // Stopping the log requires first grabbing the net info on the net thread. |
| + // Before posting that task to the net thread, change the state to |
| + // STATE_STOP_LOGGING so that if the NetLogFileWriter receives a command |
| + // while the net info is being retrieved on the net thread, the state can be |
| + // checked and the command can be ignored. It's the responsibility of the |
| + // commands (StartNetLog(), StopNetLog(), GetState()) to check the state |
| + // before performing their actions. |
| + state_ = STATE_STOPPING_LOG; |
| + |
| + // StopLogging() will always execute its state callback asynchronously, |
| + // which means |state_callback| will always be executed asynchronously |
| + // relative to the StopNetLog() call regardless of how StopLogging() is |
| + // called here. |
| + |
| + if (context_getter) { |
| + base::PostTaskAndReplyWithResult( |
| + net_task_runner_.get(), FROM_HERE, |
| + base::Bind(&AddNetInfo, context_getter, base::Passed(&polled_data)), |
| + base::Bind(&NetLogFileWriter::StopNetLogAfterAddNetInfo, |
| + weak_ptr_factory_.GetWeakPtr(), state_callback)); |
| + } else { |
| + StopNetLogAfterAddNetInfo(state_callback, std::move(polled_data)); |
| + } |
| + } else { |
| + // No-op; just run |state_callback| asynchronously. |
| + RunStateCallbackAsync(state_callback); |
| + } |
| +} |
| - if (!NetExportLogExists()) |
| - return false; |
| +void NetLogFileWriter::StopNetLogAfterAddNetInfo( |
| + const StateCallback& state_callback, |
| + std::unique_ptr<base::DictionaryValue> polled_data) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + DCHECK_EQ(state_, STATE_STOPPING_LOG); |
| - DCHECK(!log_path_.empty()); |
| -#if defined(OS_POSIX) |
| - // Users, group and others can read, write and traverse. |
| - int mode = base::FILE_PERMISSION_MASK; |
| - base::SetPosixFilePermissions(log_path_, mode); |
| -#endif // defined(OS_POSIX) |
| + write_to_file_observer_->StopObserving( |
| + std::move(polled_data), |
| + base::Bind(&NetLogFileWriter::ResetObserverThenSetStateNotLogging, |
| + weak_ptr_factory_.GetWeakPtr(), state_callback)); |
| +} |
| - *path = log_path_; |
| - return true; |
| +void NetLogFileWriter::ResetObserverThenSetStateNotLogging( |
| + const StateCallback& state_callback) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + write_to_file_observer_.reset(); |
| + state_ = STATE_NOT_LOGGING; |
| + |
| + RunStateCallback(state_callback); |
| } |
| -base::DictionaryValue* NetLogFileWriter::GetState() { |
| +void NetLogFileWriter::GetState(const StateCallback& state_callback) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - base::DictionaryValue* dict = new base::DictionaryValue; |
| + EnsureInitThenRun(base::Bind([] {}), state_callback, false); |
| +} |
| - EnsureInit(); |
| +std::unique_ptr<base::DictionaryValue> NetLogFileWriter::GetState() const { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); |
|
eroman
2017/01/21 02:17:40
[optional]: auto dict = base::MakeUnique<base::Dic
wangyix1
2017/01/23 20:16:43
Done.
|
| #ifndef NDEBUG |
|
eroman
2017/01/21 02:17:40
Do you know why this is only enabled in release mo
wangyix1
2017/01/23 20:16:43
I think this is only enabled in debug mode. Having
|
| dict->SetString("file", log_path_.LossyDisplayName()); |
| #endif // NDEBUG |
| switch (state_) { |
| + case STATE_UNINITIALIZED: |
| + dict->SetString("state", "UNINITIALIZED"); |
| + break; |
| + case STATE_INITIALIZING: |
| + dict->SetString("state", "INITIALIZING"); |
| + break; |
| case STATE_NOT_LOGGING: |
| dict->SetString("state", "NOT_LOGGING"); |
| break; |
| case STATE_LOGGING: |
| dict->SetString("state", "LOGGING"); |
| break; |
| - case STATE_UNINITIALIZED: |
| - dict->SetString("state", "UNINITIALIZED"); |
| + case STATE_STOPPING_LOG: |
| + dict->SetString("state", "STOPPING_LOG"); |
| break; |
| } |
| - switch (log_type_) { |
| - case LOG_TYPE_NONE: |
| - dict->SetString("logType", "NONE"); |
| - break; |
| - case LOG_TYPE_UNKNOWN: |
| - dict->SetString("logType", "UNKNOWN"); |
| - break; |
| - case LOG_TYPE_LOG_BYTES: |
| - dict->SetString("logType", "LOG_BYTES"); |
| - break; |
| - case LOG_TYPE_NORMAL: |
| - dict->SetString("logType", "NORMAL"); |
| - break; |
| - case LOG_TYPE_STRIP_PRIVATE_DATA: |
| - dict->SetString("logType", "STRIP_PRIVATE_DATA"); |
| - break; |
| - } |
| + dict->SetBoolean("logExists", log_exists_); |
| + dict->SetBoolean("logCaptureModeKnown", log_capture_mode_known_); |
| + dict->SetString("captureMode", CaptureModeToString(log_capture_mode_)); |
| return dict; |
| } |
| -NetLogFileWriter::NetLogFileWriter( |
| - ChromeNetLog* chrome_net_log, |
| - const base::CommandLine::StringType& command_line_string, |
| - const std::string& channel_string) |
| - : state_(STATE_UNINITIALIZED), |
| - log_type_(LOG_TYPE_NONE), |
| - chrome_net_log_(chrome_net_log), |
| - command_line_string_(command_line_string), |
| - channel_string_(channel_string) { |
| - // NetLogFileWriter can be created on one thread and used on another. |
| - thread_checker_.DetachFromThread(); |
| -} |
| - |
| -bool NetLogFileWriter::GetNetExportLogBaseDirectory( |
| - base::FilePath* path) const { |
| +void NetLogFileWriter::GetFilePathToCompletedLog( |
| + const FilePathCallback& path_callback) const { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - return base::GetTempDir(path); |
| -} |
| - |
| -net::NetLogCaptureMode NetLogFileWriter::GetCaptureModeForLogType( |
| - LogType log_type) { |
| - switch (log_type) { |
| - case LOG_TYPE_LOG_BYTES: |
| - return net::NetLogCaptureMode::IncludeSocketBytes(); |
| - case LOG_TYPE_NORMAL: |
| - return net::NetLogCaptureMode::IncludeCookiesAndCredentials(); |
| - case LOG_TYPE_STRIP_PRIVATE_DATA: |
| - return net::NetLogCaptureMode::Default(); |
| - case LOG_TYPE_NONE: |
| - case LOG_TYPE_UNKNOWN: |
| - NOTREACHED(); |
| + if (!log_exists_ || state_ == STATE_LOGGING) { |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(path_callback, base::FilePath())); |
| + return; |
| } |
| - return net::NetLogCaptureMode::Default(); |
| -} |
| -bool NetLogFileWriter::EnsureInit() { |
| - DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (state_ != STATE_UNINITIALIZED) |
| - return true; |
| + DCHECK(file_task_runner_); |
| + DCHECK(!log_path_.empty()); |
| - if (log_path_.empty() && !SetUpDefaultNetExportLogPath()) |
| - return false; |
| + base::PostTaskAndReplyWithResult( |
|
eroman
2017/01/21 02:17:40
[optional] Another way to express this would be:
wangyix1
2017/01/23 20:16:43
Done.
|
| + file_task_runner_.get(), FROM_HERE, |
| + base::Bind(&SetPosixFilePermissionsAll, log_path_), |
| + base::Bind(&NetLogFileWriter::RunFilePathCallback, path_callback, |
| + log_path_)); |
| +} |
| - state_ = STATE_NOT_LOGGING; |
| - if (NetExportLogExists()) |
| - log_type_ = LOG_TYPE_UNKNOWN; |
| +void NetLogFileWriter::RunFilePathCallback( |
| + const FilePathCallback& path_callback, |
| + const base::FilePath& path, |
| + bool set_file_permissions_success) { |
| + if (set_file_permissions_success) |
| + path_callback.Run(path); |
| else |
| - log_type_ = LOG_TYPE_NONE; |
| - |
| - return true; |
| + path_callback.Run(base::FilePath()); |
| } |
| -void NetLogFileWriter::StartNetLog(LogType log_type) { |
| +void NetLogFileWriter::SetTaskRunners( |
| + scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, |
| + scoped_refptr<base::SingleThreadTaskRunner> net_task_runner) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (state_ == STATE_LOGGING) |
| - return; |
| + if (file_task_runner_) |
| + DCHECK_EQ(file_task_runner, file_task_runner_); |
| + file_task_runner_ = file_task_runner; |
| - DCHECK_NE(STATE_UNINITIALIZED, state_); |
| - DCHECK(!log_path_.empty()); |
| + if (net_task_runner_) |
| + DCHECK_EQ(net_task_runner, net_task_runner_); |
| + net_task_runner_ = net_task_runner; |
| +} |
| - // Try to make sure we can create the file. |
| - // TODO(rtenneti): Find a better for doing the following. Surface some error |
| - // to the user if we couldn't create the file. |
| - base::ScopedFILE file(base::OpenFile(log_path_, "w")); |
| - if (!file) |
| - return; |
| +std::string NetLogFileWriter::CaptureModeToString( |
| + net::NetLogCaptureMode capture_mode) { |
| + if (capture_mode == net::NetLogCaptureMode::Default()) { |
| + return "STRIP_PRIVATE_DATA"; |
| + } else if (capture_mode == |
| + net::NetLogCaptureMode::IncludeCookiesAndCredentials()) { |
| + return "NORMAL"; |
| + } else if (capture_mode == net::NetLogCaptureMode::IncludeSocketBytes()) { |
| + return "LOG_BYTES"; |
| + } else { |
| + NOTREACHED(); |
| + return "STRIP_PRIVATE_DATA"; |
| + } |
| +} |
| - log_type_ = log_type; |
| - state_ = STATE_LOGGING; |
| +net::NetLogCaptureMode NetLogFileWriter::CaptureModeFromString( |
| + const std::string& capture_mode_string) { |
| + if (capture_mode_string == "STRIP_PRIVATE_DATA") { |
| + return net::NetLogCaptureMode::Default(); |
| + } else if (capture_mode_string == "NORMAL") { |
| + return net::NetLogCaptureMode::IncludeCookiesAndCredentials(); |
| + } else if (capture_mode_string == "LOG_BYTES") { |
| + return net::NetLogCaptureMode::IncludeSocketBytes(); |
| + } else { |
| + NOTREACHED(); |
| + return net::NetLogCaptureMode::Default(); |
| + } |
| +} |
| - std::unique_ptr<base::Value> constants( |
| - ChromeNetLog::GetConstants(command_line_string_, channel_string_)); |
| - write_to_file_observer_.reset(new net::WriteToFileNetLogObserver()); |
| - write_to_file_observer_->set_capture_mode(GetCaptureModeForLogType(log_type)); |
| - write_to_file_observer_->StartObserving(chrome_net_log_, std::move(file), |
| - constants.get(), nullptr); |
| +void NetLogFileWriter::SetDefaultLogBaseDirectoryGetterForTest( |
| + const DirectoryGetter& getter) { |
| + default_log_base_directory_getter_ = getter; |
| } |
| -void NetLogFileWriter::StopNetLog() { |
| +void NetLogFileWriter::EnsureInitThenRun( |
| + const base::Closure& after_successful_init_callback, |
| + const StateCallback& state_callback, |
| + bool state_callback_wait_if_already_initializing) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (state_ != STATE_LOGGING) |
| - return; |
| - write_to_file_observer_->StopObserving(nullptr); |
| - write_to_file_observer_.reset(); |
| - state_ = STATE_NOT_LOGGING; |
| + if (state_ == STATE_UNINITIALIZED) { |
| + state_ = STATE_INITIALIZING; |
| + // Run initialization tasks on the file thread, then the main thread. Once |
| + // finished, run |after_successful_init_callback| and |state_callback| on |
| + // the main thread. |
| + base::PostTaskAndReplyWithResult( |
| + file_task_runner_.get(), FROM_HERE, |
| + base::Bind(&NetLogFileWriter::SetUpDefaultLogPath, |
| + default_log_base_directory_getter_), |
| + base::Bind(&NetLogFileWriter::SetStateAfterSetUpDefaultLogPathThenRun, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + after_successful_init_callback, state_callback)); |
| + } else if (state_ == STATE_INITIALIZING) { |
| + // If NetLogFileWriter is already in the process of initializing due to a |
| + // previous call to EnsureInitThenRun(), commands received by |
| + // NetLogFileWriter should be ignored, so only |state_callback| will be |
| + // executed. |
| + if (state_callback_wait_if_already_initializing) { |
|
eroman
2017/01/21 02:17:40
I would say that all cases, including GetState(),
wangyix1
2017/01/23 20:16:42
It makes more sense to me from an API perspective:
wangyix1
2017/01/25 22:48:27
Done. Changed my mind
|
| + // Wait for the in-progress initialization to finish before calling |
| + // |state_callback|. To do this, post a dummy task to the file thread |
| + // (which is guaranteed to run after the tasks belonging to the |
| + // in-progress initialization have finished), and have that dummy task |
| + // post |state_callback| as a reply on the main thread. |
| + file_task_runner_->PostTaskAndReply( |
| + FROM_HERE, base::Bind([] {}), |
| + base::Bind(&NetLogFileWriter::RunStateCallback, |
| + weak_ptr_factory_.GetWeakPtr(), state_callback)); |
| + } else { |
| + RunStateCallbackAsync(state_callback); |
| + } |
| + } else { |
| + // NetLogFileWriter is already fully initialized. Run |
| + // |after_successful_init_callback| synchronously and |state_callback| |
| + // asynchronously. |
| + after_successful_init_callback.Run(); |
| + RunStateCallbackAsync(state_callback); |
| + } |
| } |
| -void NetLogFileWriter::SetUpNetExportLogPath( |
| - const base::FilePath& custom_path) { |
| - DCHECK(thread_checker_.CalledOnValidThread()); |
| +NetLogFileWriter::DefaultLogPathResults NetLogFileWriter::SetUpDefaultLogPath( |
| + const DirectoryGetter& default_log_base_directory_getter) { |
| + DefaultLogPathResults results; |
| + results.default_log_path_success = false; |
| + results.log_exists = false; |
| - // The directory should always exist because the custom path |
| - // is taken from a file selector dialog window. |
| - DCHECK(base::PathExists(custom_path.DirName())); |
| + base::FilePath default_base_dir; |
| + if (!default_log_base_directory_getter.Run(&default_base_dir)) |
| + return results; |
| - log_path_ = custom_path; |
| + // Delete log file at old location, if present. |
| + base::DeleteFile(default_base_dir.Append(kOldLogRelativePath), false); |
| + |
| + results.default_log_path = default_base_dir.Append(kLogRelativePath); |
| + if (!base::CreateDirectoryAndGetError(results.default_log_path.DirName(), |
| + nullptr)) |
| + return results; |
| + |
| + results.log_exists = base::PathExists(results.default_log_path); |
| + results.default_log_path_success = true; |
| + return results; |
| } |
| -bool NetLogFileWriter::SetUpDefaultNetExportLogPath() { |
| +void NetLogFileWriter::SetStateAfterSetUpDefaultLogPathThenRun( |
| + const base::Closure& after_successful_init_callback, |
| + const StateCallback& state_callback, |
| + const DefaultLogPathResults& set_up_default_log_path_results) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - base::FilePath temp_dir; |
| - if (!GetNetExportLogBaseDirectory(&temp_dir)) |
| - return false; |
| + DCHECK_EQ(state_, STATE_INITIALIZING); |
| - // Delete log file at old location, if present. |
| - DeleteFile(temp_dir.Append(kOldLogRelativePath), false); |
| - |
| - base::FilePath log_path = temp_dir.Append(kLogRelativePath); |
| + if (set_up_default_log_path_results.default_log_path_success) { |
| + state_ = STATE_NOT_LOGGING; |
| + log_path_ = set_up_default_log_path_results.default_log_path; |
| + log_exists_ = set_up_default_log_path_results.log_exists; |
| + DCHECK(!log_capture_mode_known_); |
| - if (!base::CreateDirectoryAndGetError(log_path.DirName(), nullptr)) { |
| - return false; |
| + after_successful_init_callback.Run(); |
| + } else { |
| + state_ = STATE_UNINITIALIZED; |
| } |
| - log_path_ = log_path; |
| - return true; |
| + RunStateCallback(state_callback); |
| } |
| -bool NetLogFileWriter::NetExportLogExists() const { |
| +void NetLogFileWriter::RunStateCallback( |
| + const StateCallback& state_callback) const { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(!log_path_.empty()); |
| - return base::PathExists(log_path_); |
| + state_callback.Run(GetState()); |
| +} |
| + |
| +void NetLogFileWriter::RunStateCallbackAsync( |
| + const StateCallback& state_callback) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(&NetLogFileWriter::RunStateCallback, |
| + weak_ptr_factory_.GetWeakPtr(), state_callback)); |
| } |
| } // namespace net_log |