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

#include "ash/display/resolution_notification_controller.h"

#include "ash/display/display_change_dialog.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/screen_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/screen_layout_observer.h"
#include "ash/test/ash_test_base.h"
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/time_format.h"
#include "ui/display/manager/display_manager.h"
#include "ui/gfx/geometry/size.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/views/controls/label.h"

namespace ash {

class ResolutionNotificationControllerTest
    : public AshTestBase,
      public ::testing::WithParamInterface<bool> {
 public:
  ResolutionNotificationControllerTest() : accept_count_(0) {}

  ~ResolutionNotificationControllerTest() override = default;

  base::string16 ExpectedNotificationMessage(int64_t display_id,
                                             const gfx::Size& new_resolution) {
    if (features::IsDisplayChangeModalEnabled()) {
      return l10n_util::GetStringFUTF16(
          IDS_ASH_RESOLUTION_CHANGE_DIALOG_CHANGED,
          base::UTF8ToUTF16(display_manager()->GetDisplayNameForId(display_id)),
          base::UTF8ToUTF16(new_resolution.ToString()),
          ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
                                 ui::TimeFormat::LENGTH_LONG,
                                 base::TimeDelta::FromSeconds(10)));
    }
    return l10n_util::GetStringFUTF16(
        IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
        base::UTF8ToUTF16(display_manager()->GetDisplayNameForId(display_id)),
        base::UTF8ToUTF16(new_resolution.ToString()));
  }

  base::string16 ExpectedFallbackNotificationMessage(
      int64_t display_id,
      const gfx::Size& specified_resolution,
      const gfx::Size& fallback_resolution) {
    if (features::IsDisplayChangeModalEnabled()) {
      return l10n_util::GetStringFUTF16(
          IDS_ASH_RESOLUTION_CHANGE_DIALOG_FALLBACK,
          base::UTF8ToUTF16(display_manager()->GetDisplayNameForId(display_id)),
          base::UTF8ToUTF16(specified_resolution.ToString()),
          base::UTF8ToUTF16(fallback_resolution.ToString()),
          ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
                                 ui::TimeFormat::LENGTH_LONG,
                                 base::TimeDelta::FromSeconds(10)));
    }
    return l10n_util::GetStringFUTF16(
        IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED_TO_UNSUPPORTED,
        base::UTF8ToUTF16(display_manager()->GetDisplayNameForId(display_id)),
        base::UTF8ToUTF16(specified_resolution.ToString()),
        base::UTF8ToUTF16(fallback_resolution.ToString()));
  }

 protected:
  void SetUp() override {
    if (GetParam())
      scoped_feature_list_.InitAndEnableFeature(features::kDisplayChangeModal);
    else
      scoped_feature_list_.InitAndDisableFeature(features::kDisplayChangeModal);

    AshTestBase::SetUp();
    ResolutionNotificationController::SuppressTimerForTest();
  }

  void SetDisplayResolutionAndNotifyWithResolution(
      const display::Display& display,
      const gfx::Size& new_resolution,
      const gfx::Size& actual_new_resolution,
      mojom::DisplayConfigSource source = mojom::DisplayConfigSource::kUser) {
    const display::ManagedDisplayInfo& info =
        display_manager()->GetDisplayInfo(display.id());
    display::ManagedDisplayMode old_mode(
        info.size_in_pixel(), 60 /* refresh_rate */, false /* interlaced */,
        false /* native */);
    display::ManagedDisplayMode new_mode(
        new_resolution, old_mode.refresh_rate(), old_mode.is_interlaced(),
        old_mode.native(), old_mode.device_scale_factor());

    EXPECT_TRUE(controller()->PrepareNotificationAndSetDisplayMode(
        display.id(), old_mode, new_mode, source,
        base::BindOnce(&ResolutionNotificationControllerTest::OnAccepted,
                       base::Unretained(this))));

    // OnConfigurationChanged event won't be emitted in the test environment,
    // so invoke UpdateDisplay() to emit that event explicitly.
    std::vector<display::ManagedDisplayInfo> info_list;
    for (size_t i = 0; i < display_manager()->GetNumDisplays(); ++i) {
      int64_t id = display_manager()->GetDisplayAt(i).id();
      display::ManagedDisplayInfo info = display_manager()->GetDisplayInfo(id);
      if (display.id() == id) {
        gfx::Rect bounds = info.bounds_in_native();
        bounds.set_size(actual_new_resolution);
        info.SetBounds(bounds);
      }
      info_list.push_back(info);
    }
    display_manager()->OnNativeDisplaysChanged(info_list);
    base::RunLoop().RunUntilIdle();
  }

  void SetDisplayResolutionAndNotify(
      const display::Display& display,
      const gfx::Size& new_resolution,
      mojom::DisplayConfigSource source = mojom::DisplayConfigSource::kUser) {
    SetDisplayResolutionAndNotifyWithResolution(display, new_resolution,
                                                new_resolution, source);
  }

  static base::string16 GetNotificationMessage() {
    if (features::IsDisplayChangeModalEnabled())
      return controller()->dialog_for_testing()->label_->GetText();

    const message_center::NotificationList::Notifications& notifications =
        message_center::MessageCenter::Get()->GetVisibleNotifications();
    for (message_center::NotificationList::Notifications::const_iterator iter =
             notifications.begin();
         iter != notifications.end(); ++iter) {
      if ((*iter)->id() == ResolutionNotificationController::kNotificationId)
        return (*iter)->title();
    }

    return base::string16();
  }

  static void ClickOnNotification() {
    if (features::IsDisplayChangeModalEnabled()) {
      controller()->dialog_for_testing()->AcceptDialog();
      return;
    }
    message_center::MessageCenter::Get()->ClickOnNotification(
        ResolutionNotificationController::kNotificationId);
  }

  static void ClickOnNotificationButton(int index) {
    message_center::MessageCenter::Get()->ClickOnNotificationButton(
        ResolutionNotificationController::kNotificationId, index);
  }

  static void CloseNotification() {
    if (features::IsDisplayChangeModalEnabled()) {
      controller()->dialog_for_testing()->AcceptDialog();
      return;
    }
    message_center::MessageCenter::Get()->RemoveNotification(
        ResolutionNotificationController::kNotificationId, true /* by_user */);
  }

  static bool IsNotificationVisible() {
    if (features::IsDisplayChangeModalEnabled())
      return controller()->dialog_for_testing() != nullptr;

    return message_center::MessageCenter::Get()->FindVisibleNotificationById(
        ResolutionNotificationController::kNotificationId);
  }

  static bool IsScreenLayoutObserverNotificationVisible() {
    return !!message_center::MessageCenter::Get()->FindVisibleNotificationById(
        ScreenLayoutObserver::kNotificationId);
  }

  static void TickTimer() {
    if (features::IsDisplayChangeModalEnabled()) {
      controller()->dialog_for_testing()->OnTimerTick();
      return;
    }
    controller()->OnTimerTick();
  }

  static ResolutionNotificationController* controller() {
    return Shell::Get()->resolution_notification_controller();
  }

  static void CancelNotification() {
    if (features::IsDisplayChangeModalEnabled())
      controller()->dialog_for_testing()->CancelDialog();
    else
      ClickOnNotificationButton(0);
  }

  int accept_count() const { return accept_count_; }

 private:
  void OnAccepted() {
    EXPECT_FALSE(controller()->DoesNotificationTimeout());
    accept_count_++;
  }

  int accept_count_;

  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationControllerTest);
};

// Basic behaviors and verifies it doesn't cause crashes.
TEST_P(ResolutionNotificationControllerTest, Basic) {
  UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  EXPECT_EQ(ExpectedNotificationMessage(id2, gfx::Size(200, 200)),
            GetNotificationMessage());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0, mode.refresh_rate());

  // Click the revert button, which reverts to the best resolution.
  CancelNotification();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(0, accept_count());
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size().ToString());
  EXPECT_EQ(59.0, mode.refresh_rate());
}

// Check that notification is not shown when changes are forced by policy.
TEST_P(ResolutionNotificationControllerTest, ForcedByPolicy) {
  UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(200, 200),
                                mojom::DisplayConfigSource::kPolicy);
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0, mode.refresh_rate());
}

TEST_P(ResolutionNotificationControllerTest, ClickMeansAccept) {
  UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0, mode.refresh_rate());

  ClickOnNotification();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(1, accept_count());
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0, mode.refresh_rate());
}

TEST_P(ResolutionNotificationControllerTest, AcceptButton) {
  UpdateDisplay("300x300#300x300%59|200x200%60");
  const display::Display& display =
      display::Screen::GetScreen()->GetPrimaryDisplay();
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());

  if (features::IsDisplayChangeModalEnabled()) {
    controller()->dialog_for_testing()->AcceptDialog();
    base::RunLoop().RunUntilIdle();
  } else {
    // If there's a single display only, it will have timeout and the first
    // button becomes accept.
    EXPECT_TRUE(controller()->DoesNotificationTimeout());
    ClickOnNotificationButton(0);
  }
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(1, accept_count());

  display::ManagedDisplayMode mode;
  EXPECT_TRUE(
      display_manager()->GetSelectedModeForDisplayId(display.id(), &mode));

  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0f, mode.refresh_rate());

  // In that case the second button is revert.
  UpdateDisplay("300x300#300x300%59|200x200%60");
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());

  if (features::IsDisplayChangeModalEnabled()) {
    controller()->dialog_for_testing()->CancelDialog();
    base::RunLoop().RunUntilIdle();
  } else {
    EXPECT_TRUE(controller()->DoesNotificationTimeout());
    ClickOnNotificationButton(1);
  }
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(1, accept_count());
  EXPECT_TRUE(
      display_manager()->GetSelectedModeForDisplayId(display.id(), &mode));

  EXPECT_EQ("300x300", mode.size().ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate());
}

TEST_P(ResolutionNotificationControllerTest, Close) {
  UpdateDisplay("100x100,150x150#150x150%59|200x200%60");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0f, mode.refresh_rate());

  // Close the notification (imitates clicking [x] button). Also verifies if
  // this does not cause a crash.  See crbug.com/271784
  CloseNotification();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(1, accept_count());
}

TEST_P(ResolutionNotificationControllerTest, Timeout) {
  UpdateDisplay("300x300#300x300%59|200x200%60");
  const display::Display& display =
      display::Screen::GetScreen()->GetPrimaryDisplay();
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));

  const int timeout_in_seconds =
      features::IsDisplayChangeModalEnabled()
          ? DisplayChangeDialog::kDefaultTimeoutInSeconds
          : ResolutionNotificationController::kTimeoutInSec;
  for (int i = 0; i < timeout_in_seconds; ++i) {
    EXPECT_TRUE(IsNotificationVisible()) << "notification is closed after " << i
                                         << "-th timer tick";
    TickTimer();
    base::RunLoop().RunUntilIdle();
  }
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(0, accept_count());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(
      display_manager()->GetSelectedModeForDisplayId(display.id(), &mode));
  EXPECT_EQ("300x300", mode.size().ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate());
}

TEST_P(ResolutionNotificationControllerTest, DisplayDisconnected) {
  UpdateDisplay(
      "300x300#300x300%56|200x200%57,"
      "200x200#250x250%58|200x200%59|100x100%60");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(100, 100));
  ASSERT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());

  // Disconnects the secondary display and verifies it doesn't cause crashes.
  UpdateDisplay("300x300#300x300%56|200x200%57");
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(0, accept_count());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate());
}

// See http://crbug.com/869401 for details.
TEST_P(ResolutionNotificationControllerTest, MultipleResolutionChange) {
  UpdateDisplay(
      "300x300#300x300%56|200x200%57,"
      "250x250#250x250%58|200x200%59");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();

  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate());

  // Invokes SetDisplayResolutionAndNotify during the previous notification is
  // visible.
  SetDisplayResolutionAndNotify(display_manager()->GetSecondaryDisplay(),
                                gfx::Size(250, 250));
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size().ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate());

  // Then, click the revert button. Although |old_resolution| for the second
  // SetDisplayResolutionAndNotify is 200x200, it should revert to the original
  // size 250x250.
  CancelNotification();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(0, accept_count());
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size().ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate());
}

TEST_P(ResolutionNotificationControllerTest, Fallback) {
  UpdateDisplay(
      "300x300#300x300%56|200x200%57,"
      "250x250#250x250%58|220x220%59|200x200%60");
  int64_t id2 = display_manager()->GetSecondaryDisplay().id();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotifyWithResolution(
      display_manager()->GetSecondaryDisplay(), gfx::Size(220, 220),
      gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  EXPECT_EQ(ExpectedFallbackNotificationMessage(id2, gfx::Size(220, 220),
                                                gfx::Size(200, 200)),
            GetNotificationMessage());
  display::ManagedDisplayMode mode;
  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size().ToString());
  EXPECT_EQ(60.0f, mode.refresh_rate());

  // Click the revert button, which reverts to the best resolution.
  CancelNotification();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_FALSE(IsScreenLayoutObserverNotificationVisible());
  EXPECT_EQ(0, accept_count());

  EXPECT_TRUE(display_manager()->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size().ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate());
}

TEST_P(ResolutionNotificationControllerTest, NoTimeoutInKioskMode) {
  // Login in as kiosk app.
  UserSession session;
  session.session_id = 1u;
  session.user_info.type = user_manager::USER_TYPE_KIOSK_APP;
  session.user_info.account_id = AccountId::FromUserEmail("user1@test.com");
  session.user_info.display_name = "User 1";
  session.user_info.display_email = "user1@test.com";
  Shell::Get()->session_controller()->UpdateUserSession(std::move(session));
  EXPECT_EQ(LoginStatus::KIOSK_APP,
            Shell::Get()->session_controller()->login_status());

  UpdateDisplay("300x300#300x300%59|200x200%60");
  const display::Display& display =
      display::Screen::GetScreen()->GetPrimaryDisplay();
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
}

// Parametrizes all tests to run with features::kDisplayChangeModal enabled and
// disabled.
INSTANTIATE_TEST_SUITE_P(All,
                         ResolutionNotificationControllerTest,
                         ::testing::Bool());

}  // namespace ash
