blob: c9c1d37a646ddd773bfd8514c2dfddb6a3924d57 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/metrics/perf/perf_output.h"
#include <memory>
#include "base/bind.h"
#include "base/location.h"
#include "base/task_runner_util.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon_client.h"
namespace {
// Create a dbus::FileDescriptor from a base::File.
dbus::ScopedFileDescriptor CreateFileDescriptor(base::File pipe_write_end) {
dbus::ScopedFileDescriptor file_descriptor(new dbus::FileDescriptor);
file_descriptor->PutValue(pipe_write_end.TakePlatformFile());
file_descriptor->CheckValidity();
return file_descriptor;
}
} // namespace
PerfOutputCall::PerfOutputCall(
scoped_refptr<base::TaskRunner> blocking_task_runner,
base::TimeDelta duration,
const std::vector<std::string>& perf_args,
const DoneCallback& callback)
: blocking_task_runner_(blocking_task_runner),
duration_(duration),
perf_args_(perf_args),
done_callback_(callback),
weak_factory_(this) {
DCHECK(thread_checker_.CalledOnValidThread());
perf_data_pipe_reader_.reset(new chromeos::PipeReaderForString(
blocking_task_runner_,
base::Bind(&PerfOutputCall::OnIOComplete, weak_factory_.GetWeakPtr())));
base::File pipe_write_end = perf_data_pipe_reader_->StartIO();
base::PostTaskAndReplyWithResult(
blocking_task_runner_.get(), FROM_HERE,
base::Bind(&CreateFileDescriptor, base::Passed(&pipe_write_end)),
base::Bind(&PerfOutputCall::OnFileDescriptorCreated,
weak_factory_.GetWeakPtr()));
}
PerfOutputCall::~PerfOutputCall() {}
void PerfOutputCall::OnFileDescriptorCreated(
dbus::ScopedFileDescriptor file_descriptor) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(file_descriptor);
chromeos::DebugDaemonClient* client =
chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
client->GetPerfOutput(duration_, perf_args_, std::move(file_descriptor),
base::Bind(&PerfOutputCall::OnGetPerfOutputError,
weak_factory_.GetWeakPtr()));
}
void PerfOutputCall::OnIOComplete() {
DCHECK(thread_checker_.CalledOnValidThread());
std::string stdout_data;
perf_data_pipe_reader_->GetData(&stdout_data);
done_callback_.Run(stdout_data);
// The callback may delete us, so it's hammertime: Can't touch |this|.
}
void PerfOutputCall::OnGetPerfOutputError(const std::string& error_name,
const std::string& error_message) {
DCHECK(thread_checker_.CalledOnValidThread());
// Signal pipe reader to shut down. This will cause
// OnIOComplete to be called, probably with an empty string.
perf_data_pipe_reader_->OnDataReady(-1);
}