// Copyright (c) 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 "chromeos/dbus/power_policy_controller.h"

#include <memory>

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/backlight.pb.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {

class PowerPolicyControllerTest : public testing::Test {
 public:
  PowerPolicyControllerTest() = default;
  ~PowerPolicyControllerTest() override = default;

  void SetUp() override {
    PowerManagerClient::Initialize();
    PowerPolicyController::Initialize(FakePowerManagerClient::Get());
    ASSERT_TRUE(PowerPolicyController::IsInitialized());
    policy_controller_ = PowerPolicyController::Get();
  }

  void TearDown() override {
    if (PowerPolicyController::IsInitialized())
      PowerPolicyController::Shutdown();
    PowerManagerClient::Shutdown();
  }

 protected:
  FakePowerManagerClient* power_manager() {
    return FakePowerManagerClient::Get();
  }

  PowerPolicyController* policy_controller_;
  base::MessageLoop message_loop_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PowerPolicyControllerTest);
};

TEST_F(PowerPolicyControllerTest, Prefs) {
  PowerPolicyController::PrefValues prefs;
  prefs.ac_screen_dim_delay_ms = 600000;
  prefs.ac_screen_off_delay_ms = 660000;
  prefs.ac_idle_delay_ms = 720000;
  prefs.battery_screen_dim_delay_ms = 300000;
  prefs.battery_screen_off_delay_ms = 360000;
  prefs.battery_idle_delay_ms = 420000;
  prefs.ac_idle_action = PowerPolicyController::ACTION_SUSPEND;
  prefs.battery_idle_action = PowerPolicyController::ACTION_STOP_SESSION;
  prefs.lid_closed_action = PowerPolicyController::ACTION_SHUT_DOWN;
  prefs.use_audio_activity = true;
  prefs.use_video_activity = true;
  prefs.ac_brightness_percent = 87.0;
  prefs.battery_brightness_percent = 43.0;
  prefs.enable_auto_screen_lock = false;
  prefs.presentation_screen_dim_delay_factor = 3.0;
  prefs.user_activity_screen_dim_delay_factor = 2.0;
  prefs.wait_for_initial_user_activity = true;
  prefs.force_nonzero_brightness_for_user_activity = false;
  policy_controller_->ApplyPrefs(prefs);

  power_manager::PowerManagementPolicy expected_policy;
  expected_policy.mutable_ac_delays()->set_screen_dim_ms(600000);
  expected_policy.mutable_ac_delays()->set_screen_off_ms(660000);
  expected_policy.mutable_ac_delays()->set_screen_lock_ms(-1);
  expected_policy.mutable_ac_delays()->set_idle_warning_ms(-1);
  expected_policy.mutable_ac_delays()->set_idle_ms(720000);
  expected_policy.mutable_battery_delays()->set_screen_dim_ms(300000);
  expected_policy.mutable_battery_delays()->set_screen_off_ms(360000);
  expected_policy.mutable_battery_delays()->set_screen_lock_ms(-1);
  expected_policy.mutable_battery_delays()->set_idle_warning_ms(-1);
  expected_policy.mutable_battery_delays()->set_idle_ms(420000);
  expected_policy.set_ac_idle_action(
      power_manager::PowerManagementPolicy_Action_SUSPEND);
  expected_policy.set_battery_idle_action(
      power_manager::PowerManagementPolicy_Action_STOP_SESSION);
  expected_policy.set_lid_closed_action(
      power_manager::PowerManagementPolicy_Action_SHUT_DOWN);
  expected_policy.set_use_audio_activity(true);
  expected_policy.set_use_video_activity(true);
  expected_policy.set_ac_brightness_percent(87.0);
  expected_policy.set_battery_brightness_percent(43.0);
  expected_policy.set_presentation_screen_dim_delay_factor(3.0);
  expected_policy.set_user_activity_screen_dim_delay_factor(2.0);
  expected_policy.set_wait_for_initial_user_activity(true);
  expected_policy.set_force_nonzero_brightness_for_user_activity(false);
  expected_policy.set_reason(PowerPolicyController::kPrefsReason);
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // Change some prefs and check that an updated policy is sent.
  prefs.ac_idle_warning_delay_ms = 700000;
  prefs.battery_idle_warning_delay_ms = 400000;
  prefs.lid_closed_action = PowerPolicyController::ACTION_SUSPEND;
  prefs.ac_brightness_percent = -1.0;
  prefs.force_nonzero_brightness_for_user_activity = true;
  policy_controller_->ApplyPrefs(prefs);
  expected_policy.mutable_ac_delays()->set_idle_warning_ms(700000);
  expected_policy.mutable_battery_delays()->set_idle_warning_ms(400000);
  expected_policy.set_lid_closed_action(
      power_manager::PowerManagementPolicy_Action_SUSPEND);
  expected_policy.clear_ac_brightness_percent();
  expected_policy.set_force_nonzero_brightness_for_user_activity(true);
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // The enable-auto-screen-lock pref should force the screen-lock delays to
  // match the screen-off delays plus a constant value.
  prefs.enable_auto_screen_lock = true;
  policy_controller_->ApplyPrefs(prefs);
  expected_policy.mutable_ac_delays()->set_screen_lock_ms(
      660000 + PowerPolicyController::kScreenLockAfterOffDelayMs);
  expected_policy.mutable_battery_delays()->set_screen_lock_ms(
      360000 + PowerPolicyController::kScreenLockAfterOffDelayMs);
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // If the screen-lock-delay prefs are set to lower values than the
  // screen-off delays plus the constant, the lock prefs should take
  // precedence.
  prefs.ac_screen_lock_delay_ms = 70000;
  prefs.battery_screen_lock_delay_ms = 60000;
  policy_controller_->ApplyPrefs(prefs);
  expected_policy.mutable_ac_delays()->set_screen_lock_ms(70000);
  expected_policy.mutable_battery_delays()->set_screen_lock_ms(60000);
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // If the artificial screen-lock delays would exceed the idle delay, they
  // shouldn't be set -- the power manager would ignore them since the
  // idle action should lock the screen in this case.
  prefs.ac_screen_off_delay_ms = prefs.ac_idle_delay_ms - 1;
  prefs.battery_screen_off_delay_ms = prefs.battery_idle_delay_ms - 1;
  prefs.ac_screen_lock_delay_ms = -1;
  prefs.battery_screen_lock_delay_ms = -1;
  policy_controller_->ApplyPrefs(prefs);
  expected_policy.mutable_ac_delays()->set_screen_off_ms(
      prefs.ac_screen_off_delay_ms);
  expected_policy.mutable_battery_delays()->set_screen_off_ms(
      prefs.battery_screen_off_delay_ms);
  expected_policy.mutable_ac_delays()->set_screen_lock_ms(-1);
  expected_policy.mutable_battery_delays()->set_screen_lock_ms(-1);
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // Set the "allow screen wake locks" pref to false and add a screen wake lock.
  // It should be downgraded to a system wake lock, and the pref-supplied delays
  // should be left untouched.
  prefs.allow_screen_wake_locks = false;
  policy_controller_->ApplyPrefs(prefs);
  policy_controller_->AddScreenWakeLock(PowerPolicyController::REASON_OTHER,
                                        "Screen");
  expected_policy.set_system_wake_lock(true);
  expected_policy.set_reason(std::string(PowerPolicyController::kPrefsReason) +
                             ", Screen");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // Set the "allow wake locks" pref to false and add a screen wake lock.
  // It should be ignored.
  prefs.allow_wake_locks = false;
  policy_controller_->ApplyPrefs(prefs);
  policy_controller_->AddScreenWakeLock(PowerPolicyController::REASON_OTHER,
                                        "Screen");
  expected_policy.clear_system_wake_lock();
  expected_policy.set_reason(std::string(PowerPolicyController::kPrefsReason));
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));
}

TEST_F(PowerPolicyControllerTest, SystemWakeLock) {
  policy_controller_->AddSystemWakeLock(PowerPolicyController::REASON_OTHER,
                                        "1");
  power_manager::PowerManagementPolicy expected_policy;
  expected_policy.set_system_wake_lock(true);
  expected_policy.set_reason("1");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));
}

TEST_F(PowerPolicyControllerTest, DimWakeLock) {
  policy_controller_->AddDimWakeLock(PowerPolicyController::REASON_OTHER, "1");
  power_manager::PowerManagementPolicy expected_policy;
  expected_policy.set_dim_wake_lock(true);
  expected_policy.set_reason("1");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));
}

TEST_F(PowerPolicyControllerTest, ScreenWakeLock) {
  policy_controller_->AddScreenWakeLock(PowerPolicyController::REASON_OTHER,
                                        "1");
  power_manager::PowerManagementPolicy expected_policy;
  expected_policy.set_screen_wake_lock(true);
  expected_policy.set_reason("1");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));
}

TEST_F(PowerPolicyControllerTest, IgnoreMediaWakeLocksWhenRequested) {
  PowerPolicyController::PrefValues prefs;
  policy_controller_->ApplyPrefs(prefs);
  const power_manager::PowerManagementPolicy kDefaultPolicy =
      power_manager()->policy();

  // Wake locks created for audio or video playback should be ignored when the
  // |use_audio_activity| or |use_video_activity| prefs are unset.
  prefs.use_audio_activity = false;
  prefs.use_video_activity = false;
  policy_controller_->ApplyPrefs(prefs);

  const int audio_id = policy_controller_->AddSystemWakeLock(
      PowerPolicyController::REASON_AUDIO_PLAYBACK, "audio");
  const int video_id = policy_controller_->AddScreenWakeLock(
      PowerPolicyController::REASON_VIDEO_PLAYBACK, "video");

  power_manager::PowerManagementPolicy expected_policy = kDefaultPolicy;
  expected_policy.set_use_audio_activity(false);
  expected_policy.set_use_video_activity(false);
  expected_policy.set_reason(PowerPolicyController::kPrefsReason);
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // Non-media screen wake locks should still be honored.
  const int other_id = policy_controller_->AddScreenWakeLock(
      PowerPolicyController::REASON_OTHER, "other");

  expected_policy.set_screen_wake_lock(true);
  expected_policy.set_reason(std::string(PowerPolicyController::kPrefsReason) +
                             ", other");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // Start honoring audio activity and check that the audio wake lock is used.
  policy_controller_->RemoveWakeLock(other_id);
  prefs.use_audio_activity = true;
  policy_controller_->ApplyPrefs(prefs);

  expected_policy = kDefaultPolicy;
  expected_policy.set_use_video_activity(false);
  expected_policy.set_system_wake_lock(true);
  expected_policy.set_reason(std::string(PowerPolicyController::kPrefsReason) +
                             ", audio");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  // Now honor video activity as well.
  prefs.use_video_activity = true;
  policy_controller_->ApplyPrefs(prefs);

  expected_policy = kDefaultPolicy;
  expected_policy.set_screen_wake_lock(true);
  expected_policy.set_system_wake_lock(true);
  expected_policy.set_reason(std::string(PowerPolicyController::kPrefsReason) +
                             ", audio, video");
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  policy_controller_->RemoveWakeLock(audio_id);
  policy_controller_->RemoveWakeLock(video_id);
}

TEST_F(PowerPolicyControllerTest, AvoidSendingEmptyPolicies) {
  // Check that empty policies aren't sent when PowerPolicyController is created
  // or destroyed.
  EXPECT_EQ(0, power_manager()->num_set_policy_calls());
  PowerPolicyController::Shutdown();
  EXPECT_EQ(0, power_manager()->num_set_policy_calls());
}

TEST_F(PowerPolicyControllerTest, DoNothingOnLidClosedWhileSigningOut) {
  PowerPolicyController::PrefValues prefs;
  policy_controller_->ApplyPrefs(prefs);
  const power_manager::PowerManagementPolicy kDefaultPolicy =
      power_manager()->policy();

  prefs.lid_closed_action = PowerPolicyController::ACTION_SHUT_DOWN;
  policy_controller_->ApplyPrefs(prefs);

  power_manager::PowerManagementPolicy expected_policy;
  expected_policy = kDefaultPolicy;
  expected_policy.set_lid_closed_action(
      power_manager::PowerManagementPolicy_Action_SHUT_DOWN);
  // Sanity check.
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  policy_controller_->NotifyChromeIsExiting();

  expected_policy.set_lid_closed_action(
      power_manager::PowerManagementPolicy_Action_DO_NOTHING);
  // Lid-closed action successfully changed to "do nothing".
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));
}

TEST_F(PowerPolicyControllerTest, SuspendOnLidClosedWhileSignedOut) {
  PowerPolicyController::PrefValues prefs;
  policy_controller_->ApplyPrefs(prefs);
  const power_manager::PowerManagementPolicy kDefaultPolicy =
      power_manager()->policy();

  prefs.lid_closed_action = PowerPolicyController::ACTION_SHUT_DOWN;
  policy_controller_->ApplyPrefs(prefs);

  power_manager::PowerManagementPolicy expected_policy;
  expected_policy = kDefaultPolicy;
  expected_policy.set_lid_closed_action(
      power_manager::PowerManagementPolicy_Action_SHUT_DOWN);
  // Sanity check
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));

  policy_controller_->SetEncryptionMigrationActive(true);
  expected_policy.set_lid_closed_action(
      power_manager::PowerManagementPolicy_Action_SUSPEND);
  expected_policy.set_reason("Prefs, encryption migration");
  // Lid-closed action successfully changed to "suspend".
  EXPECT_EQ(
      PowerPolicyController::GetPolicyDebugString(expected_policy),
      PowerPolicyController::GetPolicyDebugString(power_manager()->policy()));
}

TEST_F(PowerPolicyControllerTest, PerSessionScreenBrightnessOverride) {
  const double kAcBrightness = 99.0;
  const double kBatteryBrightness = 77.0;

  PowerPolicyController::PrefValues prefs;
  prefs.ac_brightness_percent = kAcBrightness;
  prefs.battery_brightness_percent = kBatteryBrightness;
  policy_controller_->ApplyPrefs(prefs);

  EXPECT_EQ(kAcBrightness, power_manager()->policy().ac_brightness_percent());
  EXPECT_EQ(kBatteryBrightness,
            power_manager()->policy().battery_brightness_percent());

  // Simulate model triggered brightness change - shouldn't override the policy.
  power_manager::SetBacklightBrightnessRequest request;
  request.set_percent(80.0);
  request.set_cause(power_manager::SetBacklightBrightnessRequest_Cause_MODEL);
  power_manager()->SetScreenBrightness(request);
  base::RunLoop().RunUntilIdle();
  policy_controller_->ApplyPrefs(prefs);

  EXPECT_EQ(kAcBrightness, power_manager()->policy().ac_brightness_percent());
  EXPECT_EQ(kBatteryBrightness,
            power_manager()->policy().battery_brightness_percent());

  // Simulate user triggered brightness change - should override the policy.
  request.set_percent(80.0);
  request.set_cause(
      power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST);
  power_manager()->SetScreenBrightness(request);
  base::RunLoop().RunUntilIdle();
  policy_controller_->ApplyPrefs(prefs);

  EXPECT_FALSE(power_manager()->policy().has_ac_brightness_percent());
  EXPECT_FALSE(power_manager()->policy().has_battery_brightness_percent());

  // Simulate policy values update that should be ignored.
  prefs.ac_brightness_percent = 98.0;
  prefs.battery_brightness_percent = 76.0;
  policy_controller_->ApplyPrefs(prefs);

  EXPECT_FALSE(power_manager()->policy().has_ac_brightness_percent());
  EXPECT_FALSE(power_manager()->policy().has_battery_brightness_percent());
}

TEST_F(PowerPolicyControllerTest, PolicyAutoScreenLockDelay) {
  PowerPolicyController::PrefValues prefs;
  policy_controller_->ApplyPrefs(prefs);

  // Autolock disabled.
  prefs.ac_screen_lock_delay_ms = 4000;
  prefs.battery_screen_lock_delay_ms = 1000;
  prefs.enable_auto_screen_lock = false;
  policy_controller_->ApplyPrefs(prefs);
  EXPECT_EQ(base::TimeDelta(),
            policy_controller_->Get()->GetMaxPolicyAutoScreenLockDelay());

  // Autolock enabled.

  // Longer AC delay.
  prefs.enable_auto_screen_lock = true;
  policy_controller_->ApplyPrefs(prefs);
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(prefs.ac_screen_lock_delay_ms),
            policy_controller_->Get()->GetMaxPolicyAutoScreenLockDelay());

  // Longer battery delay.
  prefs.ac_screen_lock_delay_ms = 1000;
  prefs.battery_screen_lock_delay_ms = 4000;
  policy_controller_->ApplyPrefs(prefs);
  EXPECT_EQ(
      base::TimeDelta::FromMilliseconds(prefs.battery_screen_lock_delay_ms),
      policy_controller_->Get()->GetMaxPolicyAutoScreenLockDelay());
}
}  // namespace chromeos
