Commit 1f889f0b authored by Tao Bai's avatar Tao Bai Committed by Commit Bot

ContentCapture: Reschedule task

Reschedule the current task if it waits longer than needed to run.

Bug: 1017431
Change-Id: I69f7199c9999bbe39514b1d1e5b563ffdf56d80d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1875552Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Tao Bai <michaelbai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716444}
parent 502d7d88
......@@ -197,7 +197,6 @@ bool ContentCaptureTask::RunInternal() {
void ContentCaptureTask::Run(TimerBase*) {
TRACE_EVENT0("content_capture", "RunTask");
is_scheduled_ = false;
if (!RunInternal()) {
ScheduleInternal(ScheduleReason::kRetryTask);
}
......@@ -205,8 +204,6 @@ void ContentCaptureTask::Run(TimerBase*) {
void ContentCaptureTask::ScheduleInternal(ScheduleReason reason) {
DCHECK(local_frame_root_);
if (is_scheduled_)
return;
base::TimeDelta delay;
switch (reason) {
......@@ -220,6 +217,12 @@ void ContentCaptureTask::ScheduleInternal(ScheduleReason reason) {
break;
}
// Return if the current task is about to run soon.
if (delay_task_ && delay_task_->IsActive() &&
delay_task_->NextFireInterval() < delay) {
return;
}
if (!delay_task_) {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
local_frame_root_->GetTaskRunner(TaskType::kInternalContentCapture);
......@@ -227,8 +230,10 @@ void ContentCaptureTask::ScheduleInternal(ScheduleReason reason) {
task_runner, this, &ContentCaptureTask::Run);
}
if (delay_task_->IsActive())
delay_task_->Stop();
delay_task_->StartOneShot(delay, FROM_HERE);
is_scheduled_ = true;
TRACE_EVENT_INSTANT1("content_capture", "ScheduleTask",
TRACE_EVENT_SCOPE_THREAD, "reason", reason);
}
......@@ -252,4 +257,15 @@ void ContentCaptureTask::ClearDocumentSessionsForTesting() {
task_session_->ClearDocumentSessionsForTesting();
}
base::TimeDelta ContentCaptureTask::GetTaskNextFireIntervalForTesting() const {
return delay_task_ && delay_task_->IsActive()
? delay_task_->NextFireInterval()
: base::TimeDelta();
}
void ContentCaptureTask::CancelTaskForTesting() {
if (delay_task_ && delay_task_->IsActive())
delay_task_->Stop();
}
} // namespace blink
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/time/time.h"
#include "cc/paint/node_id.h"
#include "third_party/blink/renderer/core/content_capture/content_capture_task_histogram_reporter.h"
#include "third_party/blink/renderer/core/content_capture/task_session.h"
......@@ -65,6 +66,9 @@ class CORE_EXPORT ContentCaptureTask : public RefCounted<ContentCaptureTask> {
void ClearDocumentSessionsForTesting();
base::TimeDelta GetTaskNextFireIntervalForTesting() const;
void CancelTaskForTesting();
protected:
// All protected data and methods are for testing purpose.
// Return true if the task should pause.
......@@ -96,8 +100,6 @@ class CORE_EXPORT ContentCaptureTask : public RefCounted<ContentCaptureTask> {
void ScheduleInternal(ScheduleReason reason);
bool CaptureContent(Vector<cc::NodeId>& data);
bool is_scheduled_ = false;
// Indicates if there is content change since last run.
bool has_content_change_ = false;
......
......@@ -520,6 +520,38 @@ TEST_F(ContentCaptureTest, TaskHistogramReporter) {
ContentCaptureTaskHistogramReporter::kSentContentCount, 9u, 1u);
}
TEST_F(ContentCaptureTest, RescheduleTask) {
// This test assumes test runs much faster than task's long delay which is 5s.
scoped_refptr<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
task->CancelTaskForTesting();
EXPECT_TRUE(task->GetTaskNextFireIntervalForTesting().is_zero());
task->Schedule(ContentCaptureTask::ScheduleReason::kContentChange);
auto begin = base::TimeTicks::Now();
base::TimeDelta interval1 = task->GetTaskNextFireIntervalForTesting();
task->Schedule(ContentCaptureTask::ScheduleReason::kScrolling);
base::TimeDelta interval2 = task->GetTaskNextFireIntervalForTesting();
auto test_running_time = base::TimeTicks::Now() - begin;
// The interval1 will be greater than interval2 even the task wasn't
// rescheduled, removing the test_running_time from interval1 make sure
// task rescheduled.
EXPECT_GT(interval1 - test_running_time, interval2);
}
TEST_F(ContentCaptureTest, NotRescheduleTask) {
// This test assumes test runs much faster than task's long delay which is 5s.
scoped_refptr<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
task->CancelTaskForTesting();
EXPECT_TRUE(task->GetTaskNextFireIntervalForTesting().is_zero());
task->Schedule(ContentCaptureTask::ScheduleReason::kContentChange);
auto begin = base::TimeTicks::Now();
base::TimeDelta interval1 = task->GetTaskNextFireIntervalForTesting();
task->Schedule(ContentCaptureTask::ScheduleReason::kContentChange);
base::TimeDelta interval2 = task->GetTaskNextFireIntervalForTesting();
auto test_running_time = base::TimeTicks::Now() - begin;
EXPECT_GE(interval1, interval2);
EXPECT_LE(interval1 - test_running_time, interval2);
}
// TODO(michaelbai): use RenderingTest instead of PageTestBase for multiple
// frame test.
class ContentCaptureSimTest : public SimTest {
......
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