chromium/ash/ambient/metrics/ambient_session_metrics_recorder_unittest.cc

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

#include "ash/ambient/metrics/ambient_session_metrics_recorder.h"

#include <string>
#include <string_view>
#include <utility>

#include "ash/ambient/ambient_ui_settings.h"
#include "ash/ambient/metrics/ambient_consumer_session_metrics_delegate.h"
#include "ash/constants/ambient_video.h"
#include "ash/public/cpp/ambient/ambient_ui_model.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/strings/strcat.h"

#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "cc/test/skia_common.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/size.h"
#include "ui/lottie/animation.h"

namespace ash {
namespace {
using ::testing::Eq;
}  // namespace

class AmbientSessionMetricsRecorderTest
    : public AshTestBase,
      public ::testing::WithParamInterface<AmbientUiSettings> {
 protected:
  AmbientSessionMetricsRecorderTest()
      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}

  void SetUp() override {
    AshTestBase::SetUp();
    // Simulate the screensaver being launched in all tests.
    AmbientUiModel::Get()->SetUiVisibility(AmbientUiVisibility::kShouldShow);
  }

  std::string GetMetricNameForTheme(std::string_view prefix) {
    return base::StrCat({prefix, GetParam().ToString()});
  }

  std::unique_ptr<AmbientSessionMetricsRecorder::Delegate> CreateDelegate() {
    return std::make_unique<AmbientConsumerSessionMetricsDelegate>(GetParam());
  }
};

INSTANTIATE_TEST_SUITE_P(
    AllUiSettings,
    AmbientSessionMetricsRecorderTest,
    // Just one sample for each category of ui settings
    // is needed.
    testing::Values(
        AmbientUiSettings(personalization_app::mojom::AmbientTheme::kSlideshow),
        AmbientUiSettings(
            personalization_app::mojom::AmbientTheme::kFeelTheBreeze),
        AmbientUiSettings(personalization_app::mojom::AmbientTheme::kVideo,
                          AmbientVideo::kNewMexico)));

TEST_P(AmbientSessionMetricsRecorderTest, MetricsEngagementTime) {
  constexpr base::TimeDelta kExpectedEngagementTime = base::Minutes(5);
  base::HistogramTester histogram_tester;
  Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
  {
    AmbientSessionMetricsRecorder recorder(CreateDelegate());
    recorder.SetInitStatus(true);
    recorder.RegisterScreen();
    task_environment()->FastForwardBy(kExpectedEngagementTime);
  }

  histogram_tester.ExpectTimeBucketCount(
      "Ash.AmbientMode.EngagementTime.ClamshellMode", kExpectedEngagementTime,
      1);
  histogram_tester.ExpectTimeBucketCount(
      base::StrCat({"Ash.AmbientMode.EngagementTime.", GetParam().ToString()}),
      kExpectedEngagementTime, 1);

  // Now do the same sequence in tablet mode.
  Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  {
    AmbientSessionMetricsRecorder recorder(CreateDelegate());
    recorder.SetInitStatus(true);
    recorder.RegisterScreen();
    task_environment()->FastForwardBy(kExpectedEngagementTime);
  }

  histogram_tester.ExpectTimeBucketCount(
      "Ash.AmbientMode.EngagementTime.TabletMode", kExpectedEngagementTime, 1);
  histogram_tester.ExpectTimeBucketCount(
      base::StrCat({"Ash.AmbientMode.EngagementTime.", GetParam().ToString()}),
      kExpectedEngagementTime, 2);
}

TEST_P(AmbientSessionMetricsRecorderTest, MetricsStartupTime) {
  constexpr base::TimeDelta kExpectedStartupTime = base::Seconds(5);

  base::HistogramTester histogram_tester;
  AmbientSessionMetricsRecorder recorder(CreateDelegate());
  task_environment()->FastForwardBy(kExpectedStartupTime);
  recorder.SetInitStatus(true);
  recorder.RegisterScreen();
  // Should be ignored. The time that the first screen starts rendering should
  // be when the startup time is recorded.
  task_environment()->FastForwardBy(base::Minutes(1));
  recorder.RegisterScreen();
  histogram_tester.ExpectTimeBucketCount(
      base::StrCat({"Ash.AmbientMode.StartupTime.", GetParam().ToString()}),
      kExpectedStartupTime, 1);
}

TEST_P(AmbientSessionMetricsRecorderTest, MetricsStartupTimeFailedToStart) {
  constexpr base::TimeDelta kFailedStartupTime = base::Minutes(1);
  base::HistogramTester histogram_tester;
  {
    AmbientSessionMetricsRecorder recorder(CreateDelegate());
    task_environment()->FastForwardBy(kFailedStartupTime);
  }
  histogram_tester.ExpectUniqueTimeSample(
      base::StrCat({"Ash.AmbientMode.StartupTime.", GetParam().ToString()}),
      kFailedStartupTime, 1);
  histogram_tester.ExpectUniqueSample(
      base::StrCat({"Ash.AmbientMode.Init.", GetParam().ToString()}),
      /*sample=*/0, /*expected_count=*/1);
}

TEST_P(AmbientSessionMetricsRecorderTest, InitStatusSuccess) {
  base::HistogramTester histogram_tester;
  AmbientSessionMetricsRecorder recorder(CreateDelegate());
  recorder.SetInitStatus(true);
  recorder.RegisterScreen();
  recorder.RegisterScreen();
  histogram_tester.ExpectUniqueSample(
      base::StrCat({"Ash.AmbientMode.Init.", GetParam().ToString()}),
      /*sample=*/1, /*expected_count=*/1);
}

TEST_P(AmbientSessionMetricsRecorderTest, InitStatusFailed) {
  base::HistogramTester histogram_tester;
  AmbientSessionMetricsRecorder recorder(CreateDelegate());
  recorder.SetInitStatus(false);
  histogram_tester.ExpectUniqueSample(
      base::StrCat({"Ash.AmbientMode.Init.", GetParam().ToString()}),
      /*sample=*/0, /*expected_count=*/1);
}

TEST_P(AmbientSessionMetricsRecorderTest, RecordsScreenCount) {
  base::HistogramTester histogram_tester;
  {
    AmbientSessionMetricsRecorder recorder(CreateDelegate());
    recorder.SetInitStatus(true);
    recorder.RegisterScreen();
  }
  histogram_tester.ExpectUniqueSample(
      GetMetricNameForTheme("Ash.AmbientMode.ScreenCount."), /*sample=*/1,
      /*expected_bucket_count=*/1);
  {
    AmbientSessionMetricsRecorder recorder(CreateDelegate());
    recorder.SetInitStatus(true);
    recorder.RegisterScreen();
    recorder.RegisterScreen();
  }
  histogram_tester.ExpectBucketCount(
      GetMetricNameForTheme("Ash.AmbientMode.ScreenCount."), /*sample=*/2,
      /*expected_count=*/1);
}

}  // namespace ash