chromium/ash/system/privacy_screen/privacy_screen_feature_pod_controller_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/system/privacy_screen/privacy_screen_feature_pod_controller.h"

#include <memory>

#include "ash/shell.h"
#include "ash/system/unified/feature_tile.h"
#include "ash/test/ash_test_base.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/manager/display_change_observer.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/test/action_logger.h"
#include "ui/display/manager/test/fake_display_snapshot.h"
#include "ui/display/manager/test/test_native_display_delegate.h"
#include "ui/display/types/display_constants.h"

namespace ash {
namespace {

constexpr gfx::Size kDisplaySize{1024, 768};

}  // namespace

class PrivacyScreenFeaturePodControllerTest : public AshTestBase {
 public:
  PrivacyScreenFeaturePodControllerTest() = default;

  // AshTestBase:
  void SetUp() override {
    AshTestBase::SetUp();

    // Setup helpers for overriding the display configuration.
    logger_ = std::make_unique<display::test::ActionLogger>();
    native_display_delegate_ =
        new display::test::TestNativeDisplayDelegate(logger_.get());
    display_manager()->configurator()->SetDelegateForTesting(
        base::WrapUnique(native_display_delegate_.get()));
    display_change_observer_ =
        std::make_unique<display::DisplayChangeObserver>(display_manager());
    test_api_ = std::make_unique<display::DisplayConfigurator::TestApi>(
        display_manager()->configurator());
  }

  void TearDown() override {
    display_change_observer_.reset();
    tile_.reset();
    controller_.reset();
    AshTestBase::TearDown();
  }

  void CreateButton() {
    controller_ = std::make_unique<PrivacyScreenFeaturePodController>();
    tile_ = controller_->CreateTile();
  }

  // Sets up the internal display to support privacy screen.
  void CreateDisplayWithPrivacyScreen() {
    std::vector<std::unique_ptr<display::DisplaySnapshot>> outputs;
    outputs.push_back(display::FakeDisplaySnapshot::Builder()
                          .SetId(123u)
                          .SetNativeMode(kDisplaySize)
                          .SetCurrentMode(kDisplaySize)
                          .SetType(display::DISPLAY_CONNECTION_TYPE_INTERNAL)
                          .SetPrivacyScreen(display::kDisabled)
                          .Build());

    native_display_delegate_->SetOutputs(std::move(outputs));
    display_manager()->configurator()->OnConfigurationChanged();
    display_manager()->configurator()->ForceInitialConfigure();
    EXPECT_TRUE(test_api_->TriggerConfigureTimeout());
    display_change_observer_->OnDisplayConfigurationChanged(
        native_display_delegate_->GetOutputs());
  }

  bool IsButtonVisible() { return tile_->GetVisible(); }

  bool IsButtonToggled() { return tile_->IsToggled(); }

  void PressIcon() { controller_->OnIconPressed(); }

 private:

  std::unique_ptr<display::test::ActionLogger> logger_;
  raw_ptr<display::test::TestNativeDisplayDelegate, DanglingUntriaged>
      native_display_delegate_ = nullptr;
  std::unique_ptr<display::DisplayChangeObserver> display_change_observer_;
  std::unique_ptr<display::DisplayConfigurator::TestApi> test_api_;

  std::unique_ptr<PrivacyScreenFeaturePodController> controller_;
  std::unique_ptr<FeatureTile> tile_;
};

TEST_F(PrivacyScreenFeaturePodControllerTest, NormalDisplay) {
  ASSERT_FALSE(Shell::Get()->privacy_screen_controller()->IsSupported());

  // With a display that does not support privacy screen, the button is hidden.
  CreateButton();
  EXPECT_FALSE(IsButtonVisible());
}

TEST_F(PrivacyScreenFeaturePodControllerTest, PrivacyScreenDisplay) {
  CreateDisplayWithPrivacyScreen();
  auto* privacy_screen_controller = Shell::Get()->privacy_screen_controller();
  ASSERT_TRUE(privacy_screen_controller->IsSupported());

  // With a display that supports privacy screen, the button is visible.
  CreateButton();
  EXPECT_TRUE(IsButtonVisible());

  // Pressing the button enables the privacy screen.
  PressIcon();
  EXPECT_TRUE(privacy_screen_controller->GetEnabled());
  EXPECT_TRUE(IsButtonToggled());

  // Pressing the button again disables the privacy screen.
  PressIcon();
  EXPECT_FALSE(privacy_screen_controller->GetEnabled());
  EXPECT_FALSE(IsButtonToggled());
}

}  // namespace ash