Commit 98ab6f55 authored by Eric Seckler's avatar Eric Seckler Committed by Commit Bot

headless: Use virtual time stamps in CompositorController.

This aligns animations with virtual time progression when
the CompositorController is used to issue BeginFrames.

Also updates VirtualTimeController to use TimeDeltas instead
of millisecond ints and initializes BeginFrameArgs frame_time
to its minimum value by default to support emulated negative
base::TimeTicks values in continuity DCHECKS throughout the
compositor code.

Bug: 646774
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: Ia28ab131dd1a327907f8570a1f26ce794208d3d4
Reviewed-on: https://chromium-review.googlesource.com/790910
Commit-Queue: Eric Seckler <eseckler@chromium.org>
Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519725}
parent 4793571a
......@@ -27,8 +27,8 @@ constexpr uint64_t BeginFrameArgs::kInvalidFrameNumber;
constexpr uint64_t BeginFrameArgs::kStartingFrameNumber;
BeginFrameArgs::BeginFrameArgs()
: frame_time(base::TimeTicks()),
deadline(base::TimeTicks()),
: frame_time(base::TimeTicks::Min()),
deadline(base::TimeTicks::Min()),
interval(base::TimeDelta::FromMicroseconds(-1)),
source_id(0),
sequence_number(kInvalidFrameNumber),
......
......@@ -45,7 +45,7 @@ const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) {
DCHECK(args.IsValid());
DCHECK(args.frame_time >= last_begin_frame_args_.frame_time);
DCHECK_GE(args.frame_time, last_begin_frame_args_.frame_time);
DCHECK(args.sequence_number > last_begin_frame_args_.sequence_number ||
args.source_id != last_begin_frame_args_.source_id)
<< "current " << args.AsValue()->ToString() << ", last "
......
......@@ -863,7 +863,7 @@ void HeadlessDevToolsManagerDelegate::BeginFrame(
base::TimeDelta interval;
if (const base::Value* frame_time_value = params->FindKey("frameTime")) {
frame_time = base::Time::FromDoubleT(frame_time_value->GetDouble());
frame_time = base::Time::FromJsTime(frame_time_value->GetDouble());
base::TimeDelta delta = frame_time - base::Time::UnixEpoch();
frame_timeticks = base::TimeTicks::UnixEpoch() + delta;
} else {
......
......@@ -26,7 +26,7 @@ class CompositorController::AnimationBeginFrameTask
weak_ptr_factory_(this) {}
// VirtualTimeController::RepeatingTask implementation:
void IntervalElapsed(const base::TimeDelta& virtual_time,
void IntervalElapsed(base::TimeDelta virtual_time_offset,
const base::Closure& continue_callback) override {
continue_callback_ = continue_callback;
......@@ -42,8 +42,8 @@ class CompositorController::AnimationBeginFrameTask
FROM_HERE, begin_frame_task_.callback());
}
void BudgetRequested(const base::TimeDelta& virtual_time,
int requested_budget_ms,
void BudgetRequested(base::TimeDelta virtual_time_offset,
base::TimeDelta requested_budget,
const base::Closure& continue_callback) override {
// Run a BeginFrame if we cancelled it because the budged expired previously
// and no other BeginFrame was sent while virtual time was paused.
......@@ -55,7 +55,7 @@ class CompositorController::AnimationBeginFrameTask
continue_callback.Run();
}
void BudgetExpired(const base::TimeDelta& virtual_time) override {
void BudgetExpired(base::TimeDelta virtual_time_offset) override {
// Wait until a new budget was requested before sending another animation
// BeginFrame, as it's likely that we will send a screenshotting BeginFrame.
if (!begin_frame_task_.IsCancelled()) {
......@@ -111,13 +111,13 @@ CompositorController::CompositorController(
scoped_refptr<base::SequencedTaskRunner> task_runner,
HeadlessDevToolsClient* devtools_client,
VirtualTimeController* virtual_time_controller,
int animation_begin_frame_interval_ms,
base::TimeDelta animation_begin_frame_interval,
base::TimeDelta wait_for_compositor_ready_begin_frame_delay)
: task_runner_(std::move(task_runner)),
devtools_client_(devtools_client),
virtual_time_controller_(virtual_time_controller),
animation_task_(base::MakeUnique<AnimationBeginFrameTask>(this)),
animation_begin_frame_interval_ms_(animation_begin_frame_interval_ms),
animation_begin_frame_interval_(animation_begin_frame_interval),
wait_for_compositor_ready_begin_frame_delay_(
wait_for_compositor_ready_begin_frame_delay),
weak_ptr_factory_(this) {
......@@ -129,7 +129,7 @@ CompositorController::CompositorController(
devtools_client_->GetHeadlessExperimental()->GetExperimental()->Enable(
headless_experimental::EnableParams::Builder().Build());
virtual_time_controller_->ScheduleRepeatingTask(
animation_task_.get(), animation_begin_frame_interval_ms_);
animation_task_.get(), animation_begin_frame_interval_);
}
CompositorController::~CompositorController() {
......@@ -162,6 +162,24 @@ void CompositorController::BeginFrame(
begin_frame_complete_callback_ = begin_frame_complete_callback;
if (needs_begin_frames_ || screenshot) {
auto params_builder = headless_experimental::BeginFrameParams::Builder();
// Use virtual time for frame time, so that rendering of animations etc. is
// aligned with virtual time progression.
base::Time frame_time = virtual_time_controller_->GetCurrentVirtualTime();
if (frame_time <= last_begin_frame_time_) {
// Frame time cannot go backwards or stop, so we issue another BeginFrame
// with a small time offset from the last BeginFrame's time instead.
frame_time =
last_begin_frame_time_ + base::TimeDelta::FromMicroseconds(1);
}
params_builder.SetFrameTime(frame_time.ToJsTime());
DCHECK_GT(frame_time, last_begin_frame_time_);
DCHECK_GT(frame_time.ToJsTime(), last_begin_frame_time_.ToJsTime());
last_begin_frame_time_ = frame_time;
params_builder.SetInterval(
animation_begin_frame_interval_.InMillisecondsF());
// TODO(eseckler): Set time fields. This requires obtaining the absolute
// virtual time stamp.
if (screenshot)
......
......@@ -31,7 +31,7 @@ class HEADLESS_EXPORT CompositorController
using ScreenshotParams = headless_experimental::ScreenshotParams;
using ScreenshotParamsFormat = headless_experimental::ScreenshotParamsFormat;
// |animation_begin_frame_interval_ms| specifies the virtual time between
// |animation_begin_frame_interval| specifies the virtual time between
// individual BeginFrames while virtual time advances.
// |wait_for_compositor_ready_begin_frame_delay| is the real time delay
// between BeginFrames that are sent while waiting for the main frame
......@@ -40,7 +40,7 @@ class HEADLESS_EXPORT CompositorController
scoped_refptr<base::SequencedTaskRunner> task_runner,
HeadlessDevToolsClient* devtools_client,
VirtualTimeController* virtual_time_controller,
int animation_begin_frame_interval_ms,
base::TimeDelta animation_begin_frame_interval,
base::TimeDelta wait_for_compositor_ready_begin_frame_delay);
~CompositorController() override;
......@@ -125,12 +125,11 @@ class HEADLESS_EXPORT CompositorController
base::Callback<void(std::unique_ptr<BeginFrameResult>)>
begin_frame_complete_callback_;
base::CancelableClosure wait_for_compositor_ready_begin_frame_task_;
// TODO(eseckler): Port DevTools VirtualTime commands to accept a higher
// resolution than milliseconds for this.
int animation_begin_frame_interval_ms_;
base::TimeDelta animation_begin_frame_interval_;
base::TimeDelta wait_for_compositor_ready_begin_frame_delay_;
bool needs_begin_frames_ = false;
bool main_frame_ready_ = false;
base::Time last_begin_frame_time_ = base::Time::UnixEpoch();
base::WeakPtrFactory<CompositorController> weak_ptr_factory_;
};
......
......@@ -8,6 +8,7 @@
#include "base/command_line.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "headless/public/devtools/domains/runtime.h"
#include "headless/public/headless_browser.h"
......@@ -22,7 +23,8 @@ namespace headless {
#if !defined(OS_MACOSX)
namespace {
static constexpr int kAnimationFrameIntervalMs = 16;
static constexpr base::TimeDelta kAnimationFrameInterval =
base::TimeDelta::FromMilliseconds(16);
static constexpr base::TimeDelta kWaitForCompositorReadyFrameDelay =
base::TimeDelta::FromMilliseconds(20);
} // namespace
......@@ -33,6 +35,7 @@ class CompositorControllerBrowserTest
void SetUpCommandLine(base::CommandLine* command_line) override {
HeadlessAsyncDevTooledBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw);
command_line->AppendSwitch(switches::kDisableNewContentRenderingTimeout);
}
bool GetEnableBeginFrameControl() override { return true; }
......@@ -42,7 +45,7 @@ class CompositorControllerBrowserTest
base::MakeUnique<VirtualTimeController>(devtools_client_.get());
compositor_controller_ = base::MakeUnique<CompositorController>(
browser()->BrowserMainThread(), devtools_client_.get(),
virtual_time_controller_.get(), kAnimationFrameIntervalMs,
virtual_time_controller_.get(), kAnimationFrameInterval,
kWaitForCompositorReadyFrameDelay);
compositor_controller_->WaitForCompositorReady(
......@@ -69,12 +72,12 @@ class CompositorControllerBrowserTest
virtual_time_controller_->GrantVirtualTimeBudget(
emulation::VirtualTimePolicy::ADVANCE,
kNumFrames * kAnimationFrameIntervalMs, base::Bind([]() {}),
base::Bind(&CompositorControllerBrowserTest::OnVirtualTimeBudgetEpired,
kNumFrames * kAnimationFrameInterval, base::Bind([]() {}),
base::Bind(&CompositorControllerBrowserTest::OnVirtualTimeBudgetExpired,
base::Unretained(this)));
}
void OnVirtualTimeBudgetEpired() {
void OnVirtualTimeBudgetExpired() {
// Get animation frame count.
devtools_client_->GetRuntime()->Evaluate(
"window.rafCount",
......
......@@ -26,7 +26,7 @@ VirtualTimeController::~VirtualTimeController() {
void VirtualTimeController::GrantVirtualTimeBudget(
emulation::VirtualTimePolicy policy,
int budget_ms,
base::TimeDelta budget,
const base::Callback<void()>& set_up_complete_callback,
const base::Callback<void()>& budget_expired_callback) {
DCHECK(!set_up_complete_callback_);
......@@ -34,8 +34,8 @@ void VirtualTimeController::GrantVirtualTimeBudget(
set_up_complete_callback_ = set_up_complete_callback;
budget_expired_callback_ = budget_expired_callback;
requested_budget_ = TimeDelta::FromMilliseconds(budget_ms);
accumulated_time_ = TimeDelta();
requested_budget_ = budget;
accumulated_budget_portion_ = TimeDelta();
virtual_time_policy_ = policy;
// Notify tasks of new budget request.
......@@ -44,7 +44,7 @@ void VirtualTimeController::GrantVirtualTimeBudget(
iterating_over_tasks_ = true;
for (TaskEntry& entry : tasks_)
NotifyTaskBudgetRequested(&entry, budget_ms);
NotifyTaskBudgetRequested(&entry, requested_budget_);
iterating_over_tasks_ = false;
DeleteTasksIfRequested();
......@@ -65,21 +65,21 @@ void VirtualTimeController::NotifyTasksAndAdvance() {
// Give at most as much virtual time as available until the next callback.
bool ready_to_advance = true;
iterating_over_tasks_ = true;
TimeDelta next_budget = requested_budget_ - accumulated_time_;
TimeDelta next_budget = requested_budget_ - accumulated_budget_portion_;
// TODO(alexclarke): This is a little ugly, find a nicer way.
for (TaskEntry& entry : tasks_) {
if (entry.next_execution_time <= total_elapsed_time_)
if (entry.next_execution_time <= total_elapsed_time_offset_)
entry.ready_to_advance = false;
}
for (TaskEntry& entry : tasks_) {
if (entry.next_execution_time <= total_elapsed_time_)
if (entry.next_execution_time <= total_elapsed_time_offset_)
NotifyTaskIntervalElapsed(&entry);
if (tasks_to_delete_.find(entry.task) == tasks_to_delete_.end()) {
ready_to_advance &= entry.ready_to_advance;
next_budget = std::min(next_budget,
entry.next_execution_time - total_elapsed_time_);
next_budget = std::min(
next_budget, entry.next_execution_time - total_elapsed_time_offset_);
}
}
iterating_over_tasks_ = false;
......@@ -88,13 +88,13 @@ void VirtualTimeController::NotifyTasksAndAdvance() {
if (!ready_to_advance)
return;
if (accumulated_time_ >= requested_budget_) {
if (accumulated_budget_portion_ >= requested_budget_) {
for (TaskEntry& entry : tasks_)
entry.ready_to_advance = false;
iterating_over_tasks_ = true;
for (const TaskEntry& entry : tasks_)
entry.task->BudgetExpired(total_elapsed_time_);
entry.task->BudgetExpired(total_elapsed_time_offset_);
iterating_over_tasks_ = false;
DeleteTasksIfRequested();
......@@ -119,19 +119,19 @@ void VirtualTimeController::DeleteTasksIfRequested() {
void VirtualTimeController::NotifyTaskIntervalElapsed(TaskEntry* entry) {
DCHECK(!entry->ready_to_advance);
entry->next_execution_time = total_elapsed_time_ + entry->interval;
entry->next_execution_time = total_elapsed_time_offset_ + entry->interval;
entry->task->IntervalElapsed(
total_elapsed_time_,
total_elapsed_time_offset_,
base::Bind(&VirtualTimeController::TaskReadyToAdvance,
base::Unretained(this), base::Unretained(entry)));
}
void VirtualTimeController::NotifyTaskBudgetRequested(TaskEntry* entry,
int budget_ms) {
base::TimeDelta budget) {
DCHECK(!entry->ready_to_advance);
entry->task->BudgetRequested(
total_elapsed_time_, budget_ms,
total_elapsed_time_offset_, budget,
base::Bind(&VirtualTimeController::TaskReadyToAdvance,
base::Unretained(this), base::Unretained(entry)));
}
......@@ -141,13 +141,13 @@ void VirtualTimeController::TaskReadyToAdvance(TaskEntry* entry) {
NotifyTasksAndAdvance();
}
void VirtualTimeController::SetVirtualTimePolicy(const TimeDelta& next_budget) {
void VirtualTimeController::SetVirtualTimePolicy(base::TimeDelta next_budget) {
last_used_budget_ = next_budget;
virtual_time_active_ = true;
devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy(
emulation::SetVirtualTimePolicyParams::Builder()
.SetPolicy(virtual_time_policy_)
.SetBudget(next_budget.InMilliseconds())
.SetBudget(next_budget.InMillisecondsF())
.SetMaxVirtualTimeTaskStarvationCount(max_task_starvation_count_)
.Build(),
base::Bind(&VirtualTimeController::SetVirtualTimePolicyDone,
......@@ -155,7 +155,12 @@ void VirtualTimeController::SetVirtualTimePolicy(const TimeDelta& next_budget) {
}
void VirtualTimeController::SetVirtualTimePolicyDone(
std::unique_ptr<emulation::SetVirtualTimePolicyResult>) {
std::unique_ptr<emulation::SetVirtualTimePolicyResult> result) {
if (result) {
virtual_time_base_ = base::Time::FromJsTime(result->GetVirtualTimeBase());
} else {
LOG(WARNING) << "SetVirtualTimePolicy did not succeed";
}
if (set_up_complete_callback_) {
set_up_complete_callback_.Run();
set_up_complete_callback_.Reset();
......@@ -169,14 +174,14 @@ void VirtualTimeController::OnVirtualTimeBudgetExpired(
if (!budget_expired_callback_)
return;
accumulated_time_ += last_used_budget_;
total_elapsed_time_ += last_used_budget_;
accumulated_budget_portion_ += last_used_budget_;
total_elapsed_time_offset_ += last_used_budget_;
virtual_time_active_ = false;
NotifyTasksAndAdvance();
}
void VirtualTimeController::ScheduleRepeatingTask(RepeatingTask* task,
int interval_ms) {
base::TimeDelta interval) {
if (virtual_time_active_) {
// We cannot accurately modify any previously granted virtual time budget.
LOG(WARNING) << "VirtualTimeController tasks should be added while "
......@@ -185,8 +190,8 @@ void VirtualTimeController::ScheduleRepeatingTask(RepeatingTask* task,
TaskEntry entry;
entry.task = task;
entry.interval = TimeDelta::FromMilliseconds(interval_ms);
entry.next_execution_time = total_elapsed_time_ + entry.interval;
entry.interval = interval;
entry.next_execution_time = total_elapsed_time_offset_ + entry.interval;
tasks_.push_back(entry);
}
......@@ -199,4 +204,12 @@ void VirtualTimeController::CancelRepeatingTask(RepeatingTask* task) {
[task](const TaskEntry& entry) { return entry.task == task; });
}
base::Time VirtualTimeController::GetVirtualTimeBase() const {
return virtual_time_base_;
}
base::TimeDelta VirtualTimeController::GetCurrentVirtualTimeOffset() const {
return total_elapsed_time_offset_;
}
} // namespace headless
......@@ -23,8 +23,7 @@ class HEADLESS_EXPORT VirtualTimeController
int max_task_starvation_count = 0);
~VirtualTimeController() override;
// Grants |budget_ms| milliseconds of virtual time by applying the provided
// |policy|.
// Grants a |budget| of virtual time by applying the provided |policy|.
//
// |set_up_complete_callback|, if set, is run after the (initial) policy was
// applied via DevTools. |budget_expired_callback| will be called when the
......@@ -34,7 +33,7 @@ class HEADLESS_EXPORT VirtualTimeController
// budget_expired_callback was executed.
virtual void GrantVirtualTimeBudget(
emulation::VirtualTimePolicy policy,
int budget_ms,
base::TimeDelta budget,
const base::Callback<void()>& set_up_complete_callback,
const base::Callback<void()>& budget_expired_callback);
......@@ -43,36 +42,49 @@ class HEADLESS_EXPORT VirtualTimeController
virtual ~RepeatingTask() {}
// Called when the tasks's requested virtual time interval has elapsed.
// |virtual_time| is the virtual time duration that has advanced since the
// page started loading (millisecond granularity). The task should call
// |continue_callback| when it is ready for virtual time to continue
// |virtual_time_offset| is the virtual time duration that has advanced
// since the page started loading (millisecond granularity). The task should
// call |continue_callback| when it is ready for virtual time to continue
// advancing.
virtual void IntervalElapsed(
const base::TimeDelta& virtual_time,
base::TimeDelta virtual_time_offset,
const base::Callback<void()>& continue_callback) = 0;
// Called when a new virtual time budget grant was requested. The task
// should call |continue_callback| when it is ready for virtual time to
// continue advancing.
virtual void BudgetRequested(
const base::TimeDelta& virtual_time,
int requested_budget_ms,
base::TimeDelta virtual_time_offset,
base::TimeDelta requested_budget,
const base::Callback<void()>& continue_callback) = 0;
// Called when the latest virtual time budget has been used up.
virtual void BudgetExpired(const base::TimeDelta& virtual_time) = 0;
virtual void BudgetExpired(base::TimeDelta virtual_time_offset) = 0;
};
// Interleaves execution of the provided |task| with advancing of virtual
// time. The task will be notified whenever another |interval_ms| milliseconds
// of virtual time have elapsed, as well as when the last granted budget has
// been used up.
// Interleaves execution of the provided |task| with progression of virtual
// time. The task will be notified whenever another |interval| of virtual time
// have elapsed, as well as when the last granted budget has been used up.
//
// To ensure that the task is notified of elapsed intervals accurately, it
// should be added while virtual time is paused.
virtual void ScheduleRepeatingTask(RepeatingTask* task, int interval_ms);
virtual void ScheduleRepeatingTask(RepeatingTask* task,
base::TimeDelta interval);
virtual void CancelRepeatingTask(RepeatingTask* task);
// Returns the time that virtual time offsets are relative to.
virtual base::Time GetVirtualTimeBase() const;
// Returns the current virtual time offset. Only accurate while virtual time
// is paused.
virtual base::TimeDelta GetCurrentVirtualTimeOffset() const;
// Returns the current virtual time stamp. Only accurate while virtual time
// is paused.
base::Time GetCurrentVirtualTime() const {
return GetVirtualTimeBase() + GetCurrentVirtualTimeOffset();
}
private:
struct TaskEntry {
RepeatingTask* task;
......@@ -87,12 +99,12 @@ class HEADLESS_EXPORT VirtualTimeController
void NotifyTasksAndAdvance();
void NotifyTaskIntervalElapsed(TaskEntry* entry);
void NotifyTaskBudgetRequested(TaskEntry* entry, int budget_ms);
void NotifyTaskBudgetRequested(TaskEntry* entry, base::TimeDelta budget);
void TaskReadyToAdvance(TaskEntry* entry);
void DeleteTasksIfRequested();
void SetVirtualTimePolicy(const base::TimeDelta& next_budget);
void SetVirtualTimePolicy(base::TimeDelta next_budget);
void SetVirtualTimePolicyDone(
std::unique_ptr<emulation::SetVirtualTimePolicyResult>);
......@@ -105,10 +117,12 @@ class HEADLESS_EXPORT VirtualTimeController
base::Callback<void()> budget_expired_callback_;
bool virtual_time_active_ = false;
base::TimeDelta total_elapsed_time_;
base::TimeDelta total_elapsed_time_offset_;
base::TimeDelta requested_budget_;
base::TimeDelta last_used_budget_;
base::TimeDelta accumulated_time_;
base::TimeDelta accumulated_budget_portion_;
// Initial virtual time that virtual time offsets are relative to.
base::Time virtual_time_base_;
std::list<TaskEntry> tasks_;
std::set<RepeatingTask*> tasks_to_delete_;
......
......@@ -41,7 +41,8 @@ class VirtualTimeControllerTest : public ::testing::Test {
ASSERT_FALSE(budget_expired_);
controller_->GrantVirtualTimeBudget(
emulation::VirtualTimePolicy::ADVANCE, budget_ms,
emulation::VirtualTimePolicy::ADVANCE,
base::TimeDelta::FromMilliseconds(budget_ms),
base::Bind(
[](bool* set_up_complete) {
EXPECT_FALSE(*set_up_complete);
......@@ -118,13 +119,13 @@ namespace {
class MockTask : public VirtualTimeController::RepeatingTask {
public:
MOCK_METHOD2(IntervalElapsed,
void(const base::TimeDelta& virtual_time,
void(base::TimeDelta virtual_time_offset,
const base::Callback<void()>& continue_callback));
MOCK_METHOD3(BudgetRequested,
void(const base::TimeDelta& virtual_time,
int requested_budget_ms,
void(base::TimeDelta virtual_time_offset,
base::TimeDelta requested_budget,
const base::Callback<void()>& continue_callback));
MOCK_METHOD1(BudgetExpired, void(const base::TimeDelta& virtual_time));
MOCK_METHOD1(BudgetExpired, void(base::TimeDelta virtual_time_offset));
};
ACTION_TEMPLATE(RunClosure,
......@@ -140,10 +141,11 @@ ACTION_P(RunClosure, closure) {
TEST_F(VirtualTimeControllerTest, InterleavesTasksWithVirtualTime) {
MockTask task;
controller_->ScheduleRepeatingTask(&task, 1000);
controller_->ScheduleRepeatingTask(&task,
base::TimeDelta::FromMilliseconds(1000));
EXPECT_CALL(task,
BudgetRequested(base::TimeDelta::FromMilliseconds(0), 3000, _))
EXPECT_CALL(task, BudgetRequested(base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(3000), _))
.WillOnce(RunClosure<2>());
EXPECT_CALL(*mock_host_,
DispatchProtocolMessage(
......@@ -209,10 +211,11 @@ TEST_F(VirtualTimeControllerTest, InterleavesTasksWithVirtualTime) {
TEST_F(VirtualTimeControllerTest, CanceledTask) {
MockTask task;
controller_->ScheduleRepeatingTask(&task, 1000);
controller_->ScheduleRepeatingTask(&task,
base::TimeDelta::FromMilliseconds(1000));
EXPECT_CALL(task,
BudgetRequested(base::TimeDelta::FromMilliseconds(0), 5000, _))
EXPECT_CALL(task, BudgetRequested(base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(5000), _))
.WillOnce(RunClosure<2>());
EXPECT_CALL(*mock_host_,
DispatchProtocolMessage(
......@@ -292,14 +295,18 @@ TEST_F(VirtualTimeControllerTest, CanceledTask) {
TEST_F(VirtualTimeControllerTest, MultipleTasks) {
MockTask task1;
MockTask task2;
controller_->ScheduleRepeatingTask(&task1, 1000);
controller_->ScheduleRepeatingTask(&task2, 1000);
controller_->ScheduleRepeatingTask(&task1,
base::TimeDelta::FromMilliseconds(1000));
controller_->ScheduleRepeatingTask(&task2,
base::TimeDelta::FromMilliseconds(1000));
EXPECT_CALL(task1,
BudgetRequested(base::TimeDelta::FromMilliseconds(0), 2000, _))
BudgetRequested(base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(2000), _))
.WillOnce(RunClosure<2>());
EXPECT_CALL(task2,
BudgetRequested(base::TimeDelta::FromMilliseconds(0), 2000, _))
BudgetRequested(base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(2000), _))
.WillOnce(RunClosure<2>());
// We should only get one call to Emulation.setVirtualTimePolicy despite
// having two tasks.
......@@ -326,7 +333,7 @@ TEST_F(VirtualTimeControllerTest, MultipleTasks) {
class VirtualTimeTask : public VirtualTimeController::RepeatingTask {
public:
using Task = base::Callback<void(const base::TimeDelta& virtual_time)>;
using Task = base::Callback<void(base::TimeDelta virtual_time)>;
VirtualTimeTask(VirtualTimeController* controller,
Task budget_requested_task,
......@@ -338,21 +345,21 @@ class VirtualTimeTask : public VirtualTimeController::RepeatingTask {
budget_expired_task_(budget_expired_task) {}
void IntervalElapsed(
const base::TimeDelta& virtual_time,
base::TimeDelta virtual_time,
const base::Callback<void()>& continue_callback) override {
interval_elapsed_task_.Run(virtual_time);
continue_callback.Run();
}
void BudgetRequested(
const base::TimeDelta& virtual_time,
int requested_budget_ms,
base::TimeDelta virtual_time,
base::TimeDelta requested_budget_ms,
const base::Callback<void()>& continue_callback) override {
budget_requested_task_.Run(virtual_time);
continue_callback.Run();
}
void BudgetExpired(const base::TimeDelta& virtual_time) override {
void BudgetExpired(base::TimeDelta virtual_time) override {
budget_expired_task_.Run(virtual_time);
};
......@@ -368,8 +375,7 @@ TEST_F(VirtualTimeControllerTest, ReentrantTask) {
VirtualTimeTask task_b(
controller_.get(),
base::Bind(
[](std::vector<std::string>* log,
const base::TimeDelta& virtual_time) {
[](std::vector<std::string>* log, base::TimeDelta virtual_time) {
log->push_back(base::StringPrintf(
"B: budget requested @ %d",
static_cast<int>(virtual_time.InMilliseconds())));
......@@ -377,7 +383,7 @@ TEST_F(VirtualTimeControllerTest, ReentrantTask) {
&log),
base::Bind(
[](std::vector<std::string>* log, VirtualTimeController* controller,
VirtualTimeTask* task_b, const base::TimeDelta& virtual_time) {
VirtualTimeTask* task_b, base::TimeDelta virtual_time) {
log->push_back(base::StringPrintf(
"B: interval elapsed @ %d",
static_cast<int>(virtual_time.InMilliseconds())));
......@@ -385,8 +391,7 @@ TEST_F(VirtualTimeControllerTest, ReentrantTask) {
},
&log, controller_.get(), &task_b),
base::Bind(
[](std::vector<std::string>* log,
const base::TimeDelta& virtual_time) {
[](std::vector<std::string>* log, base::TimeDelta virtual_time) {
log->push_back(base::StringPrintf(
"B: budget expired @ %d",
static_cast<int>(virtual_time.InMilliseconds())));
......@@ -396,8 +401,7 @@ TEST_F(VirtualTimeControllerTest, ReentrantTask) {
VirtualTimeTask task_a(
controller_.get(),
base::Bind(
[](std::vector<std::string>* log,
const base::TimeDelta& virtual_time) {
[](std::vector<std::string>* log, base::TimeDelta virtual_time) {
log->push_back(base::StringPrintf(
"A: budget requested @ %d",
static_cast<int>(virtual_time.InMilliseconds())));
......@@ -406,24 +410,25 @@ TEST_F(VirtualTimeControllerTest, ReentrantTask) {
base::Bind(
[](std::vector<std::string>* log, VirtualTimeController* controller,
VirtualTimeTask* task_a, VirtualTimeTask* task_b,
const base::TimeDelta& virtual_time) {
base::TimeDelta virtual_time) {
log->push_back(base::StringPrintf(
"A: interval elapsed @ %d",
static_cast<int>(virtual_time.InMilliseconds())));
controller->CancelRepeatingTask(task_a);
controller->ScheduleRepeatingTask(task_b, 1500);
controller->ScheduleRepeatingTask(
task_b, base::TimeDelta::FromMilliseconds(1500));
},
&log, controller_.get(), &task_a, &task_b),
base::Bind(
[](std::vector<std::string>* log,
const base::TimeDelta& virtual_time) {
[](std::vector<std::string>* log, base::TimeDelta virtual_time) {
log->push_back(base::StringPrintf(
"A: budget expired @ %d",
static_cast<int>(virtual_time.InMilliseconds())));
},
&log));
controller_->ScheduleRepeatingTask(&task_a, 1000);
controller_->ScheduleRepeatingTask(&task_a,
base::TimeDelta::FromMilliseconds(1000));
EXPECT_CALL(*mock_host_,
DispatchProtocolMessage(
......
......@@ -114,8 +114,8 @@ void HeadlessRenderTest::OnFrameStartedLoading(
if (state_ == STARTING) {
state_ = LOADING;
virtual_time_controller_->GrantVirtualTimeBudget(
emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING, 5000,
base::Closure(),
emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING,
base::TimeDelta::FromMilliseconds(5000), base::Closure(),
base::Bind(&HeadlessRenderTest::HandleVirtualTimeExhausted,
weak_ptr_factory_.GetWeakPtr()));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment