// Copyright 2014 The Chromium OS 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 "power_manager/powerd/policy/input_device_controller.h"

#include <cstdarg>

#include <gtest/gtest.h>

#include "power_manager/common/fake_prefs.h"
#include "power_manager/common/power_constants.h"
#include "power_manager/powerd/policy/backlight_controller_stub.h"
#include "power_manager/powerd/system/acpi_wakeup_helper_stub.h"
#include "power_manager/powerd/system/cros_ec_helper_stub.h"
#include "power_manager/powerd/system/udev_stub.h"
#include "power_manager/proto_bindings/backlight.pb.h"

namespace power_manager {
namespace policy {

namespace {
// An artificial syspath for tests.
const char kSyspath0[] = "/sys/devices/test/0";

// Create aliases for lengthy constant names.
const char* const kTagInhibit = InputDeviceController::kTagInhibit;
const char* const kTagUsableWhenDocked =
    InputDeviceController::kTagUsableWhenDocked;
const char* const kTagUsableWhenDisplayOff =
    InputDeviceController::kTagUsableWhenDisplayOff;
const char* const kTagUsableWhenLaptop =
    InputDeviceController::kTagUsableWhenLaptop;
const char* const kTagUsableWhenTablet =
    InputDeviceController::kTagUsableWhenTablet;
const char* const kTagWakeup = InputDeviceController::kTagWakeup;
const char* const kTagWakeupWhenLaptop =
    InputDeviceController::kTagWakeupWhenLaptop;
const char* const kTagWakeupOnlyWhenUsable =
    InputDeviceController::kTagWakeupOnlyWhenUsable;
const char* const kTagWakeupDisabled =
    InputDeviceController::kTagWakeupDisabled;
const char* const kEnabled = InputDeviceController::kWakeupEnabled;
const char* const kDisabled = InputDeviceController::kWakeupDisabled;
const char* const kInhibited = InputDeviceController::kInhibited;
const char* const kTPAD = InputDeviceController::kTPAD;
const char* const kTSCR = InputDeviceController::kTSCR;

}  // namespace

class InputDeviceControllerTest : public ::testing::Test {
 public:
  InputDeviceControllerTest() = default;
  InputDeviceControllerTest(const InputDeviceControllerTest&) = delete;
  InputDeviceControllerTest& operator=(const InputDeviceControllerTest&) =
      delete;

  ~InputDeviceControllerTest() override = default;

 protected:
  std::string GetSysattr(const std::string& syspath,
                         const std::string& sysattr) {
    std::string value;
    if (!udev_.GetSysattr(syspath, sysattr, &value))
      return "(error)";
    return value;
  }

  bool GetAcpiWakeup(const std::string& acpi_name) {
    bool value = false;
    if (!acpi_wakeup_helper_.GetWakeupEnabled(acpi_name, &value)) {
      ADD_FAILURE() << "Expected ACPI wakeup for " << acpi_name
                    << " to be defined";
    }
    return value;
  }

  // Adds a device at |syspath| with one or more udev tags. The tag list must be
  // null-terminated.
  void AddDeviceWithTags(const std::string& syspath, const char* tag, ...) {
    udev_.SetSysattr(syspath, kPowerWakeup, kDisabled);

    std::string tags;
    va_list arg_list;
    va_start(arg_list, tag);
    while (tag) {
      if (!tags.empty())
        tags += " ";
      tags += tag;
      tag = va_arg(arg_list, const char*);
    }
    va_end(arg_list);

    udev_.TaggedDeviceChanged(syspath, base::FilePath(syspath), tags);
  }

  void InitInputDeviceController() {
    input_device_controller_.Init(&backlight_controller_, &udev_,
                                  &acpi_wakeup_helper_, &ec_helper_,
                                  initial_lid_state_, initial_tablet_mode_,
                                  initial_display_mode_, &prefs_);
  }

  policy::BacklightControllerStub backlight_controller_;
  system::UdevStub udev_;
  system::AcpiWakeupHelperStub acpi_wakeup_helper_;
  system::CrosEcHelperStub ec_helper_;
  FakePrefs prefs_;

  LidState initial_lid_state_ = LidState::OPEN;
  TabletMode initial_tablet_mode_ = TabletMode::OFF;
  DisplayMode initial_display_mode_ = DisplayMode::NORMAL;

  InputDeviceController input_device_controller_;
};

TEST_F(InputDeviceControllerTest, ConfigureWakeupOnInit) {
  AddDeviceWithTags(kSyspath0, kTagWakeup, nullptr);

  EXPECT_EQ(kDisabled, GetSysattr(kSyspath0, kPowerWakeup));
  InitInputDeviceController();
  EXPECT_EQ(kEnabled, GetSysattr(kSyspath0, kPowerWakeup));
  EXPECT_TRUE(GetAcpiWakeup(kTPAD));
  EXPECT_FALSE(GetAcpiWakeup(kTSCR));
}

TEST_F(InputDeviceControllerTest, ConfigureWakeupOnAdd) {
  InitInputDeviceController();

  // The device starts out with wakeup disabled, but should get configured by
  // InputDeviceController right away.
  AddDeviceWithTags(kSyspath0, kTagWakeup, nullptr);
  EXPECT_EQ(kEnabled, GetSysattr(kSyspath0, kPowerWakeup));
}

TEST_F(InputDeviceControllerTest, DisableWakeupWhenClosed) {
  AddDeviceWithTags(kSyspath0, kTagWakeup, kTagWakeupOnlyWhenUsable,
                    kTagUsableWhenLaptop, nullptr);
  InitInputDeviceController();

  // In laptop mode, wakeup should be enabled.
  EXPECT_EQ(kEnabled, GetSysattr(kSyspath0, kPowerWakeup));
  EXPECT_TRUE(GetAcpiWakeup("TPAD"));

  // When the lid is closed, wakeup should be disabled.
  input_device_controller_.SetLidState(LidState::CLOSED);
  EXPECT_EQ(kDisabled, GetSysattr(kSyspath0, kPowerWakeup));
  EXPECT_FALSE(GetAcpiWakeup(kTPAD));
}

TEST_F(InputDeviceControllerTest, PermanentlyDisableWakeup) {
  AddDeviceWithTags(kSyspath0, kTagWakeup, kTagWakeupDisabled, nullptr);

  // Simulate a device that has wakeup enabled initially.
  udev_.SetSysattr(kSyspath0, kPowerWakeup, kEnabled);
  InitInputDeviceController();
  EXPECT_EQ(kDisabled, GetSysattr(kSyspath0, kPowerWakeup));
}

TEST_F(InputDeviceControllerTest, ConfigureInhibit) {
  AddDeviceWithTags(kSyspath0, kTagInhibit, kTagUsableWhenLaptop, nullptr);
  InitInputDeviceController();

  // In laptop mode, inhibit should be off.
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));

  // When the lid is closed, inhibit should be on.
  input_device_controller_.SetLidState(LidState::CLOSED);
  EXPECT_EQ("1", GetSysattr(kSyspath0, kInhibited));

  // When the lid is open, inhibit should be off again.
  input_device_controller_.SetLidState(LidState::OPEN);
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));
}

TEST_F(InputDeviceControllerTest, InhibitDocking) {
  AddDeviceWithTags(kSyspath0, kTagInhibit, kTagUsableWhenLaptop,
                    kTagUsableWhenDocked, nullptr);
  initial_display_mode_ = DisplayMode::PRESENTATION;
  InitInputDeviceController();

  // In laptop mode, inhibit should be off.
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));

  // When the lid is closed, inhibit should remain off.
  input_device_controller_.SetLidState(LidState::CLOSED);
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));

  // When the lid is open, inhibit should still be off.
  input_device_controller_.SetLidState(LidState::OPEN);
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));
}

TEST_F(InputDeviceControllerTest, SetDisplayModeExternalInput) {
  AddDeviceWithTags(kSyspath0, kTagInhibit, kTagUsableWhenLaptop,
                    kTagUsableWhenDocked, nullptr);
  initial_lid_state_ = LidState::CLOSED;
  InitInputDeviceController();

  // When the lid is closed with no external display, external input devices
  // should be inhibited.
  EXPECT_EQ("1", GetSysattr(kSyspath0, kInhibited));

  // When an external display is attached, device should be un-inhibited.
  input_device_controller_.SetDisplayMode(DisplayMode::PRESENTATION);
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));

  // When external display goes away, input should be inhibited again.
  input_device_controller_.SetDisplayMode(DisplayMode::NORMAL);
  EXPECT_EQ("1", GetSysattr(kSyspath0, kInhibited));
}

TEST_F(InputDeviceControllerTest, SetDisplayModeInternalInput) {
  AddDeviceWithTags(kSyspath0, kTagInhibit, kTagUsableWhenLaptop, nullptr);
  InitInputDeviceController();

  // Devices that are only usable when in laptop mode should not be inhibited
  // while the lid is open.
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));

  // When an external display is attached, device should remain uninhibited.
  input_device_controller_.SetDisplayMode(DisplayMode::PRESENTATION);
  EXPECT_EQ("0", GetSysattr(kSyspath0, kInhibited));

  // When the lid is closed, internal input should be inhibited regardless
  // of display mode.
  input_device_controller_.SetLidState(LidState::CLOSED);
  EXPECT_EQ("1", GetSysattr(kSyspath0, kInhibited));

  input_device_controller_.SetDisplayMode(DisplayMode::NORMAL);
  EXPECT_EQ("1", GetSysattr(kSyspath0, kInhibited));
}

TEST_F(InputDeviceControllerTest, AllowEcWakeupAsTabletWhenDisplayOff) {
  InitInputDeviceController();

  // Start in presentation mode at full brightness.
  input_device_controller_.SetDisplayMode(DisplayMode::PRESENTATION);
  backlight_controller_.NotifyObservers(
      100.0, BacklightBrightnessChange_Cause_USER_REQUEST);

  // EC wakeups should be inhibited in tablet mode while backlight is on.
  EXPECT_FALSE(ec_helper_.IsWakeupAsTabletAllowed());

  // Automated display off should not trigger a mode change.
  backlight_controller_.NotifyObservers(
      0.0, BacklightBrightnessChange_Cause_USER_INACTIVITY);
  EXPECT_FALSE(ec_helper_.IsWakeupAsTabletAllowed());

  // ...but manual should.
  backlight_controller_.NotifyObservers(
      0.0, BacklightBrightnessChange_Cause_USER_REQUEST);
  EXPECT_TRUE(ec_helper_.IsWakeupAsTabletAllowed());

  // Leaving presentation mode should disallow it.
  input_device_controller_.SetDisplayMode(DisplayMode::NORMAL);
  EXPECT_FALSE(ec_helper_.IsWakeupAsTabletAllowed());
  input_device_controller_.SetDisplayMode(DisplayMode::PRESENTATION);
  EXPECT_TRUE(ec_helper_.IsWakeupAsTabletAllowed());

  // As should raising the brightness, even if automatic.
  backlight_controller_.NotifyObservers(10.0,
                                        BacklightBrightnessChange_Cause_OTHER);
  EXPECT_FALSE(ec_helper_.IsWakeupAsTabletAllowed());
}

TEST_F(InputDeviceControllerTest, HandleTabletMode) {
  const char kKeyboardSyspath[] = "/sys/devices/keyboard/0";
  const char kTouchscreenSyspath[] = "/sys/devices/touchscreen/0";
  AddDeviceWithTags(kKeyboardSyspath, kTagInhibit, kTagWakeup,
                    kTagWakeupOnlyWhenUsable, kTagUsableWhenLaptop,
                    kTagUsableWhenDisplayOff, nullptr);
  AddDeviceWithTags(kTouchscreenSyspath, kTagInhibit, kTagWakeup,
                    kTagWakeupOnlyWhenUsable, kTagUsableWhenLaptop,
                    kTagUsableWhenTablet, nullptr);
  initial_tablet_mode_ = TabletMode::ON;

  // While in tablet mode, the keyboard should be inhibited with wakeup
  // disabled.
  InitInputDeviceController();
  EXPECT_EQ("1", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kDisabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));
  EXPECT_EQ("0", GetSysattr(kTouchscreenSyspath, kInhibited));
  EXPECT_EQ(kEnabled, GetSysattr(kTouchscreenSyspath, kPowerWakeup));

  // Switching to laptop mode should uninhibit the keyboard and permit wakeups.
  input_device_controller_.SetTabletMode(TabletMode::OFF);
  EXPECT_EQ("0", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kEnabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));
  EXPECT_EQ("0", GetSysattr(kTouchscreenSyspath, kInhibited));
  EXPECT_EQ(kEnabled, GetSysattr(kTouchscreenSyspath, kPowerWakeup));

  // Lid-closed mode should take precedence over tablet mode. (See b/119287727)
  input_device_controller_.SetTabletMode(TabletMode::ON);
  input_device_controller_.SetLidState(LidState::CLOSED);
  EXPECT_EQ("1", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kDisabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));
  EXPECT_EQ("1", GetSysattr(kTouchscreenSyspath, kInhibited));
  EXPECT_EQ(kDisabled, GetSysattr(kTouchscreenSyspath, kPowerWakeup));

  // Display-off mode should take precedence over tablet mode.
  input_device_controller_.SetDisplayMode(DisplayMode::PRESENTATION);
  input_device_controller_.SetLidState(LidState::OPEN);
  input_device_controller_.SetTabletMode(TabletMode::ON);
  input_device_controller_.OnBrightnessChange(
      0.0, BacklightBrightnessChange_Cause_USER_REQUEST,
      &backlight_controller_);
  EXPECT_EQ("0", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kEnabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));
  EXPECT_EQ("1", GetSysattr(kTouchscreenSyspath, kInhibited));
  EXPECT_EQ(kDisabled, GetSysattr(kTouchscreenSyspath, kPowerWakeup));
}

TEST_F(InputDeviceControllerTest, UsableWithoutWakeup) {
  // Add a keyboard device that should remain usable while in tablet mode (say,
  // because it also produces power button events: http://crbug.com/703691) but
  // that should only wake the device while in laptop mode.
  const char kKeyboardSyspath[] = "/sys/devices/keyboard/0";
  AddDeviceWithTags(kKeyboardSyspath, kTagInhibit, kTagUsableWhenLaptop,
                    kTagUsableWhenTablet, kTagWakeup, kTagWakeupWhenLaptop,
                    nullptr);

  initial_tablet_mode_ = TabletMode::OFF;
  InitInputDeviceController();
  EXPECT_EQ("0", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kEnabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));

  input_device_controller_.SetTabletMode(TabletMode::ON);
  EXPECT_EQ("0", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kDisabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));

  input_device_controller_.SetTabletMode(TabletMode::OFF);
  EXPECT_EQ("0", GetSysattr(kKeyboardSyspath, kInhibited));
  EXPECT_EQ(kEnabled, GetSysattr(kKeyboardSyspath, kPowerWakeup));
}

TEST_F(InputDeviceControllerTest, InitWithoutBacklightController) {
  // Init with null backlight controller shouldn't crash.
  input_device_controller_.Init(
      nullptr, &udev_, &acpi_wakeup_helper_, &ec_helper_, initial_lid_state_,
      initial_tablet_mode_, initial_display_mode_, &prefs_);
}

}  // namespace policy
}  // namespace power_manager
