chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>

#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_trace_processor.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_gesture.h"
#include "content/common/input/synthetic_gesture_controller.h"
#include "content/common/input/synthetic_gesture_params.h"
#include "content/common/input/synthetic_gesture_target.h"
#include "content/common/input/synthetic_smooth_scroll_gesture.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/shell/browser/shell.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
#include "third_party/blink/public/common/switches.h"
#include "ui/base/ui_base_features.h"
#include "ui/native_theme/native_theme_features.h"

#if BUILDFLAG(IS_MAC)
#include "ui/base/test/scoped_preferred_scroller_style_mac.h"
#endif

namespace {

const char kDataURL[] =;
}  // namespace

namespace content {

class ScrollLatencyBrowserTest : public ContentBrowserTest {};

// Do an upward touch scroll, and verify that no scroll metrics is recorded when
// the scroll event is ignored.
IN_PROC_BROWSER_TEST_F(ScrollLatencyBrowserTest,
                       ScrollLatencyNotRecordedIfGSUIgnored) {}

// A basic smoke test verifying that key scroll-related events are recorded
// during scrolling. This test performs a simple scroll and expects to see three
// EventLatency events with the correct types.
IN_PROC_BROWSER_TEST_F(ScrollLatencyBrowserTest, ScrollingEventLatencyTrace) {}

// Basic smoke test for predictor jank metrics.
#if BUILDFLAG(IS_ANDROID)
// TODO(b/345225978): the android-x86-rel bot occasionally flakes due to
// missing events after Swap.
#if !defined(ARCH_CPU_X86_FAMILY)
IN_PROC_BROWSER_TEST_F(ScrollLatencyBrowserTest, ScrollingPredictor) {
  LoadURL();
  base::test::TestTraceProcessor ttp;
  ttp.StartTrace("input.scrolling");

  const gfx::Vector2d scroll_1(0, -5);
  const gfx::Vector2d scroll_2(0, 1);   // Previous update and subsequent update
                                        // will produce jank where
                                        // min(prev, next)/curr > threshold.
  const gfx::Vector2d scroll_3(0, -5);  // Previous update and subsequent update
                                        // will not produce jank.
  const gfx::Vector2d scroll_4(0, -10);  // Previous update and subsequent
                                         // update will produce jank where
                                         // curr/max(prev, next) > threshold.
  const gfx::Vector2d scroll_5(0, 5);

  DoScroll(gfx::Vector2d(0, 25),
           {scroll_1, scroll_2, scroll_3, scroll_4, scroll_5},
           16 /*delay_ms - ensure there is enough time for vsync*/
  );

  // Allow enough time for the inputs to be processed and the trace events
  // to be recorded.
  GiveItSomeTime(100);

  absl::Status status = ttp.StopAndParseTrace();
  ASSERT_TRUE(status.ok()) << status.message();
  std::string query =
      R"(
      INCLUDE PERFETTO MODULE chrome.scroll_jank.predictor_error;

      SELECT
        prev_delta,
        delta_y,
        next_delta,
        predictor_jank,
        delta_threshold
      FROM chrome_predictor_error
        ORDER BY present_ts
      ;
      )";
  auto result = ttp.RunQuery(query);
  ASSERT_TRUE(result.has_value()) << result.error();
  EXPECT_THAT(
      result.value(),
      ::testing::ElementsAre(
          std::vector<std::string>{"prev_delta", "delta_y", "next_delta",
                                   "predictor_jank", "delta_threshold"},
          std::vector<std::string>{GetScaledDeltaTraceValue(scroll_1.y()),
                                   GetScaledDeltaTraceValue(scroll_2.y()),
                                   GetScaledDeltaTraceValue(scroll_3.y()),
                                   "3.8", "1.2"},
          std::vector<std::string>{GetScaledDeltaTraceValue(scroll_2.y()),
                                   GetScaledDeltaTraceValue(scroll_3.y()),
                                   GetScaledDeltaTraceValue(scroll_4.y()), "0",
                                   "1.2"},
          std::vector<std::string>{GetScaledDeltaTraceValue(scroll_3.y()),
                                   GetScaledDeltaTraceValue(scroll_4.y()),
                                   GetScaledDeltaTraceValue(scroll_5.y()),
                                   "0.8", "1.2"}));
}
#endif  // !defined(ARCH_CPU_X86_FAMILY)
#endif  // BUILDFLAG(IS_ANDROID)

}  // namespace content