chromium/ash/components/arc/metrics/arc_wm_metrics_unittest.cc

// Copyright 2023 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/components/arc/metrics/arc_wm_metrics.h"

#include <memory>

#include "ash/test/ash_test_base.h"
#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
#include "base/test/metrics/histogram_tester.h"
#include "chromeos/ui/base/app_types.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/views/widget/widget.h"

namespace arc {

class ArcWmMetricsTest : public ash::AshTestBase {
 public:
  ArcWmMetricsTest() = default;
  ArcWmMetricsTest(const ArcWmMetricsTest&) = delete;
  ArcWmMetricsTest& operator=(const ArcWmMetricsTest&) = delete;
  ~ArcWmMetricsTest() override = default;

  void SetUp() override {
    ash::AshTestBase::SetUp();
    arc_wm_metrics_ = std::make_unique<ArcWmMetrics>();
  }

  void TearDown() override {
    arc_wm_metrics_.reset();
    ash::AshTestBase::TearDown();
  }

  void OnWindowCloseRequested(aura::Window* window) {
    arc_wm_metrics_->OnWindowCloseRequested(window);
  }

  void OnDisplayRotated() {
    arc_wm_metrics_->OnScreenCopiedBeforeRotation();
    display::Display display =
        display::Screen::GetScreen()->GetPrimaryDisplay();
    ash::Shell::Get()->display_manager()->SetDisplayRotation(
        display.id(), display::Display::ROTATE_90,
        display::Display::RotationSource::USER);
  }

 private:
  std::unique_ptr<ArcWmMetrics> arc_wm_metrics_;
};

TEST_F(ArcWmMetricsTest, TestWindowMaximizeDelayMetrics) {
  chromeos::AppType app_type = chromeos::AppType::ARC_APP;
  auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100), app_type);
  window->SetProperty(aura::client::kResizeBehaviorKey,
                      aura::client::kResizeBehaviorCanMaximize);
  window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name =
      ArcWmMetrics::GetWindowMaximizedTimeHistogramName(app_type);
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  auto* widget = views::Widget::GetWidgetForNativeWindow(window.get());
  widget->Maximize();
  histogram_tester.ExpectTotalCount(histogram_name, 1);

  // If the old window state type is not `kNormal`, the data should not be
  // recorded in histogram.
  widget->Minimize();
  widget->Maximize();
  histogram_tester.ExpectTotalCount(histogram_name, 1);

  // The histogram should not record data when maximizing in tablet mode.
  ash::TabletModeControllerTestApi().EnterTabletMode();
  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  widget->Maximize();
  histogram_tester.ExpectTotalCount(histogram_name, 1);
}

TEST_F(ArcWmMetricsTest, TestWindowMinimizeDelayMetrics) {
  chromeos::AppType app_type = chromeos::AppType::ARC_APP;
  auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100), app_type);
  window->SetProperty(aura::client::kResizeBehaviorKey,
                      aura::client::kResizeBehaviorCanMinimize);
  window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name =
      ArcWmMetrics::GetWindowMinimizedTimeHistogramName(app_type);
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  auto* widget = views::Widget::GetWidgetForNativeWindow(window.get());
  widget->Minimize();
  histogram_tester.ExpectTotalCount(histogram_name, 1);

  // The histogram should not record data when minimizing in tablet mode.
  ash::TabletModeControllerTestApi().EnterTabletMode();
  widget->Maximize();
  widget->Minimize();
  histogram_tester.ExpectTotalCount(histogram_name, 1);
}

TEST_F(ArcWmMetricsTest, TestWindowCloseDelayMetrics) {
  auto window =
      CreateAppWindow(gfx::Rect(0, 0, 100, 100), chromeos::AppType::ARC_APP);
  window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name =
      ArcWmMetrics::GetArcWindowClosedTimeHistogramName();
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  OnWindowCloseRequested(window.get());
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  window.reset();
  histogram_tester.ExpectTotalCount(histogram_name, 1);
}

TEST_F(ArcWmMetricsTest, TestWindowEnterTabletModeDelayMetrics) {
  chromeos::AppType app_type = chromeos::AppType::ARC_APP;
  auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100), app_type);
  window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name =
      ArcWmMetrics::GetWindowEnterTabletModeTimeHistogramName(app_type);
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  ash::TabletModeControllerTestApi().EnterTabletMode();
  histogram_tester.ExpectTotalCount(histogram_name, 1);

  // Window maximizing histogram should not record data.
  histogram_tester.ExpectTotalCount(
      ArcWmMetrics::GetWindowMaximizedTimeHistogramName(app_type), 0);
}

TEST_F(ArcWmMetricsTest, TestMultipleWindowsEnterTabletModeDelayMetrics) {
  auto lower_window =
      CreateAppWindow(gfx::Rect(0, 0, 100, 100), chromeos::AppType::BROWSER);
  lower_window->Show();
  auto upper_window =
      CreateAppWindow(gfx::Rect(0, 0, 100, 100), chromeos::AppType::ARC_APP);
  upper_window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name_lower_window =
      ArcWmMetrics::GetWindowEnterTabletModeTimeHistogramName(
          chromeos::AppType::BROWSER);
  const auto histogram_name_upper_window =
      ArcWmMetrics::GetWindowEnterTabletModeTimeHistogramName(
          chromeos::AppType::ARC_APP);

  histogram_tester.ExpectTotalCount(histogram_name_lower_window, 0);
  histogram_tester.ExpectTotalCount(histogram_name_upper_window, 0);

  // Only the data of upper window should be recorded.
  ash::TabletModeControllerTestApi().EnterTabletMode();
  histogram_tester.ExpectTotalCount(histogram_name_lower_window, 0);
  histogram_tester.ExpectTotalCount(histogram_name_upper_window, 1);
}

TEST_F(ArcWmMetricsTest, TestWindowLeaveTabletModeDelayMetrics) {
  chromeos::AppType app_type = chromeos::AppType::ARC_APP;
  auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100), app_type);
  window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name =
      ArcWmMetrics::GetWindowExitTabletModeTimeHistogramName(app_type);
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  ash::TabletModeControllerTestApi().EnterTabletMode();
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  ash::TabletModeControllerTestApi().LeaveTabletMode();
  histogram_tester.ExpectTotalCount(histogram_name, 1);

  // If the window state of a window is maximized before entering into tablet
  // mode, its window state should remains maximized after exiting tablet mode.
  // In this case, histogram should not records data.
  views::Widget::GetWidgetForNativeWindow(window.get())->Maximize();
  ash::TabletModeControllerTestApi().EnterTabletMode();
  histogram_tester.ExpectTotalCount(histogram_name, 1);
  ash::TabletModeControllerTestApi().LeaveTabletMode();
  histogram_tester.ExpectTotalCount(histogram_name, 1);
}

TEST_F(ArcWmMetricsTest, TestWindowRotateDelayOnDisplayRotationMetrics) {
  chromeos::AppType app_type = chromeos::AppType::ARC_APP;
  auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100), app_type);
  window->Show();

  base::HistogramTester histogram_tester;
  const auto histogram_name =
      ArcWmMetrics::GetWindowRotateTimeHistogramName(app_type);
  histogram_tester.ExpectTotalCount(histogram_name, 0);

  // UMA only records data when display rotates in tablet mode.
  ash::TabletModeControllerTestApi().EnterTabletMode();
  OnDisplayRotated();
  histogram_tester.ExpectTotalCount(histogram_name, 1);
}

}  // namespace arc