Skip to content

Commit

Permalink
ContentCapture: Reschedule task
Browse files Browse the repository at this point in the history
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/+/1875552
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Tao Bai <michaelbai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716444}
  • Loading branch information
Tao Bai authored and Commit Bot committed Nov 19, 2019
1 parent 502d7d8 commit 1f889f0
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,13 @@ bool ContentCaptureTask::RunInternal() {

void ContentCaptureTask::Run(TimerBase*) {
TRACE_EVENT0("content_capture", "RunTask");
is_scheduled_ = false;
if (!RunInternal()) {
ScheduleInternal(ScheduleReason::kRetryTask);
}
}

void ContentCaptureTask::ScheduleInternal(ScheduleReason reason) {
DCHECK(local_frame_root_);
if (is_scheduled_)
return;

base::TimeDelta delay;
switch (reason) {
Expand All @@ -220,15 +217,23 @@ 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);
delay_task_ = std::make_unique<TaskRunnerTimer<ContentCaptureTask>>(
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);
}
Expand All @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 1f889f0

Please sign in to comment.