// Copyright (c) 2012 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/system/power/power_button_controller.h"

#include <limits>
#include <string>
#include <utility>

#include "ash/accelerators/accelerator_controller.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/shutdown_reason.h"
#include "ash/system/power/power_button_display_controller.h"
#include "ash/system/power/power_button_menu_item_view.h"
#include "ash/system/power/power_button_menu_metrics_type.h"
#include "ash/system/power/power_button_menu_screen_view.h"
#include "ash/system/power/power_button_menu_view.h"
#include "ash/system/power/power_button_screenshot_controller.h"
#include "ash/wm/lock_state_controller.h"
#include "ash/wm/session_state_animator.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_util.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/time/default_tick_clock.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager/backlight.pb.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"

namespace ash {
namespace {

// Amount of time power button must be held to start the power menu animation
// for convertible/slate/detachable devices. This differs depending on whether
// the screen is on or off when the power button is initially pressed.
constexpr base::TimeDelta kShowMenuWhenScreenOnTimeout =
    base::TimeDelta::FromMilliseconds(500);
constexpr base::TimeDelta kShowMenuWhenScreenOffTimeout =
    base::TimeDelta::FromMilliseconds(2000);

// Time that power button should be pressed after power menu is shown before
// starting the cancellable pre-shutdown animation.
constexpr base::TimeDelta kStartShutdownAnimationTimeout =
    base::TimeDelta::FromMilliseconds(650);

enum PowerButtonUpState {
  UP_NONE = 0,
  UP_MENU_TIMER_WAS_RUNNING = 1 << 0,
  UP_PRE_SHUTDOWN_TIMER_WAS_RUNNING = 1 << 1,
  UP_SHOWING_ANIMATION_CANCELLED = 1 << 2,
  UP_CAN_CANCEL_SHUTDOWN_ANIMATION = 1 << 3,
  UP_MENU_WAS_OPENED = 1 << 4,
};

// Creates a fullscreen widget responsible for showing the power button menu.
std::unique_ptr<views::Widget> CreateMenuWidget() {
  auto menu_widget = std::make_unique<views::Widget>();
  views::Widget::InitParams params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.keep_on_top = true;
  params.accept_events = true;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.name = "PowerButtonMenuWindow";
  params.layer_type = ui::LAYER_SOLID_COLOR;
  params.parent = Shell::GetPrimaryRootWindow()->GetChildById(
      kShellWindowId_PowerMenuContainer);
  menu_widget->Init(params);

  gfx::Rect widget_bounds =
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  menu_widget->SetBounds(widget_bounds);

  // Enable arrow key in FocusManager. Arrow right/left and down/up triggers
  // the same focus movement as tab/shift+tab.
  menu_widget->GetFocusManager()->set_arrow_key_traversal_enabled_for_widget(
      true);
  return menu_widget;
}

}  // namespace

constexpr base::TimeDelta PowerButtonController::kScreenStateChangeDelay;

constexpr base::TimeDelta PowerButtonController::kIgnoreRepeatedButtonUpDelay;

constexpr base::TimeDelta
    PowerButtonController::kIgnorePowerButtonAfterResumeDelay;

constexpr const char* PowerButtonController::kEdgeField;
constexpr const char* PowerButtonController::kLeftEdge;
constexpr const char* PowerButtonController::kRightEdge;
constexpr const char* PowerButtonController::kTopEdge;
constexpr const char* PowerButtonController::kBottomEdge;

// Maintain active state of the given |widget|. Sets |widget| to always render
// as active if it's not already initially configured that way. Resets the
// setting if |widget| still exists when this class is destroyed.
class PowerButtonController::ActiveWindowWidgetController
    : public views::WidgetObserver {
 public:
  static std::unique_ptr<ActiveWindowWidgetController> Create(
      views::Widget* widget) {
    if (!widget || widget->IsAlwaysRenderAsActive())
      return nullptr;

    widget->SetAlwaysRenderAsActive(true);
    return std::unique_ptr<ActiveWindowWidgetController>(
        base::WrapUnique(new ActiveWindowWidgetController(widget)));
  }

  ~ActiveWindowWidgetController() override {
    if (!widget_)
      return;
    widget_->SetAlwaysRenderAsActive(false);
    widget_->RemoveObserver(this);
  }

  // views::WidgetObserver:
  void OnWidgetClosing(views::Widget* widget) override {
    DCHECK_EQ(widget_, widget);
    widget_ = nullptr;
    widget->RemoveObserver(this);
  }

  // views::WidgetObserver:
  void OnWidgetDestroying(views::Widget* widget) override {
    OnWidgetClosing(widget);
  }

 private:
  explicit ActiveWindowWidgetController(views::Widget* widget)
      : widget_(widget) {
    if (widget)
      widget->AddObserver(this);
  }

  views::Widget* widget_ = nullptr;  // Not owned.

  DISALLOW_COPY_AND_ASSIGN(ActiveWindowWidgetController);
};

PowerButtonController::PowerButtonController(
    BacklightsForcedOffSetter* backlights_forced_off_setter)
    : backlights_forced_off_setter_(backlights_forced_off_setter),
      lock_state_controller_(Shell::Get()->lock_state_controller()),
      tick_clock_(base::DefaultTickClock::GetInstance()),
      backlights_forced_off_observer_(this),
      weak_factory_(this) {
  ProcessCommandLine();
  display_controller_ = std::make_unique<PowerButtonDisplayController>(
      backlights_forced_off_setter_, tick_clock_);
  chromeos::PowerManagerClient* power_manager_client =
      chromeos::PowerManagerClient::Get();
  power_manager_client->AddObserver(this);
  power_manager_client->GetSwitchStates(base::BindOnce(
      &PowerButtonController::OnGetSwitchStates, weak_factory_.GetWeakPtr()));
  AccelerometerReader::GetInstance()->AddObserver(this);
  Shell::Get()->display_configurator()->AddObserver(this);
  backlights_forced_off_observer_.Add(backlights_forced_off_setter);
  Shell::Get()->tablet_mode_controller()->AddObserver(this);
  Shell::Get()->lock_state_controller()->AddObserver(this);
}

PowerButtonController::~PowerButtonController() {
  Shell::Get()->lock_state_controller()->RemoveObserver(this);
  if (Shell::Get()->tablet_mode_controller())
    Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
  Shell::Get()->display_configurator()->RemoveObserver(this);
  AccelerometerReader::GetInstance()->RemoveObserver(this);
  chromeos::PowerManagerClient::Get()->RemoveObserver(this);
}

void PowerButtonController::OnPreShutdownTimeout() {
  lock_state_controller_->StartShutdownAnimation(ShutdownReason::POWER_BUTTON);
  DCHECK(menu_widget_);
  static_cast<PowerButtonMenuScreenView*>(menu_widget_->GetContentsView())
      ->power_button_menu_view()
      ->FocusPowerOffButton();
}

void PowerButtonController::OnLegacyPowerButtonEvent(bool down) {
  // Avoid starting the lock/shutdown sequence if the power button is pressed
  // while the screen is off (http://crbug.com/128451), unless an external
  // display is still on (http://crosbug.com/p/24912).
  if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
    return;

  if (!down)
    return;

  // Ignore the power button down event if the menu is partially opened.
  if (IsMenuOpened() && !show_menu_animation_done_)
    return;

  // If power button releases won't get reported correctly because we're not
  // running on official hardware, show menu animation on the first power
  // button press. On a further press while the menu is open, simply shut down
  // (http://crbug.com/945005).
  if (!show_menu_animation_done_)
    StartPowerMenuAnimation();
  else
    lock_state_controller_->RequestShutdown(ShutdownReason::POWER_BUTTON);
}

void PowerButtonController::OnPowerButtonEvent(
    bool down,
    const base::TimeTicks& timestamp) {
  if (down) {
    force_off_on_button_up_ = false;
    if (UseTabletBehavior()) {
      force_off_on_button_up_ = true;

      // When the system resumes in response to the power button being pressed,
      // Chrome receives powerd's SuspendDone signal and notification that the
      // backlight has been turned back on before seeing the power button events
      // that woke the system. Avoid forcing off display just after resuming to
      // ensure that we don't turn the display off in response to the events.
      if (timestamp - last_resume_time_ <= kIgnorePowerButtonAfterResumeDelay)
        force_off_on_button_up_ = false;

      // The actual display may remain off for a short period after powerd asks
      // Chrome to turn it on. If the user presses the power button again during
      // this time, they probably intend to turn the display on. Avoid forcing
      // off in this case.
      if (timestamp - display_controller_->screen_state_last_changed() <=
          kScreenStateChangeDelay) {
        force_off_on_button_up_ = false;
      }
    }

    screen_off_when_power_button_down_ = !display_controller_->IsScreenOn();
    menu_shown_when_power_button_down_ = show_menu_animation_done_;
    display_controller_->SetBacklightsForcedOff(false);

    if (menu_shown_when_power_button_down_) {
      pre_shutdown_timer_.Start(FROM_HERE, kStartShutdownAnimationTimeout, this,
                                &PowerButtonController::OnPreShutdownTimeout);
      return;
    }

    if (!UseTabletBehavior()) {
      StartPowerMenuAnimation();
    } else {
      base::TimeDelta timeout = screen_off_when_power_button_down_
                                    ? kShowMenuWhenScreenOffTimeout
                                    : kShowMenuWhenScreenOnTimeout;

      power_button_menu_timer_.Start(
          FROM_HERE, timeout, this,
          &PowerButtonController::StartPowerMenuAnimation);
    }
  } else {
    uint32_t up_state = UP_NONE;
    if (lock_state_controller_->CanCancelShutdownAnimation()) {
      up_state |= UP_CAN_CANCEL_SHUTDOWN_ANIMATION;
      lock_state_controller_->CancelShutdownAnimation();
    }
    const base::TimeTicks previous_up_time = last_button_up_time_;
    last_button_up_time_ = timestamp;

    const bool menu_timer_was_running = power_button_menu_timer_.IsRunning();
    const bool pre_shutdown_timer_was_running = pre_shutdown_timer_.IsRunning();
    power_button_menu_timer_.Stop();
    pre_shutdown_timer_.Stop();

    const bool menu_was_partially_opened =
        IsMenuOpened() && !show_menu_animation_done_;
    // Cancel the menu animation if it's still ongoing when the button is
    // released.
    if (menu_was_partially_opened) {
      static_cast<PowerButtonMenuScreenView*>(menu_widget_->GetContentsView())
          ->ScheduleShowHideAnimation(false);
      up_state |= UP_SHOWING_ANIMATION_CANCELLED;
    }

    // If the button is tapped (i.e. not held long enough to start the
    // cancellable shutdown animation) while the menu is open, dismiss the menu.
    if (menu_shown_when_power_button_down_ && pre_shutdown_timer_was_running)
      DismissMenu();

    // Ignore the event if it comes too soon after the last one.
    if (timestamp - previous_up_time <= kIgnoreRepeatedButtonUpDelay)
      return;

    if (!screen_off_when_power_button_down_) {
      if (menu_timer_was_running)
        up_state |= UP_MENU_TIMER_WAS_RUNNING;
      if (pre_shutdown_timer_was_running)
        up_state |= UP_PRE_SHUTDOWN_TIMER_WAS_RUNNING;
      if (show_menu_animation_done_)
        up_state |= UP_MENU_WAS_OPENED;
      UpdatePowerButtonEventUMAHistogram(up_state);
    }

    if (screen_off_when_power_button_down_ || !force_off_on_button_up_)
      return;

    if (menu_timer_was_running || menu_was_partially_opened ||
        (menu_shown_when_power_button_down_ &&
         pre_shutdown_timer_was_running)) {
      display_controller_->SetBacklightsForcedOff(true);
      LockScreenIfRequired();
    }
  }
}

void PowerButtonController::OnLockButtonEvent(
    bool down,
    const base::TimeTicks& timestamp) {
  lock_button_down_ = down;

  // Ignore the lock button behavior if power button is being pressed.
  if (power_button_down_)
    return;

  const SessionController* const session_controller =
      Shell::Get()->session_controller();
  if (!session_controller->CanLockScreen() ||
      session_controller->IsScreenLocked() ||
      lock_state_controller_->LockRequested() ||
      lock_state_controller_->ShutdownRequested()) {
    return;
  }

  if (down)
    lock_state_controller_->StartLockAnimation();
  else
    lock_state_controller_->CancelLockAnimation();
}

void PowerButtonController::CancelPowerButtonEvent() {
  force_off_on_button_up_ = false;
  StopTimersAndDismissMenu();
}

bool PowerButtonController::IsMenuOpened() const {
  return menu_widget_ && menu_widget_->GetLayer()->GetTargetVisibility();
}

void PowerButtonController::DismissMenu() {
  if (IsMenuOpened())
    menu_widget_->Hide();

  show_menu_animation_done_ = false;
  active_window_widget_controller_.reset();
}

void PowerButtonController::StopForcingBacklightsOff() {
  display_controller_->SetBacklightsForcedOff(false);
}

void PowerButtonController::OnDisplayModeChanged(
    const display::DisplayConfigurator::DisplayStateList& display_states) {
  bool internal_display_off = false;
  bool external_display_on = false;
  for (const display::DisplaySnapshot* display : display_states) {
    if (display->type() == display::DISPLAY_CONNECTION_TYPE_INTERNAL) {
      if (!display->current_mode())
        internal_display_off = true;
    } else if (display->current_mode()) {
      external_display_on = true;
    }
  }
  internal_display_off_and_external_display_on_ =
      internal_display_off && external_display_on;
}

void PowerButtonController::ScreenBrightnessChanged(
    const power_manager::BacklightBrightnessChange& change) {
  brightness_is_zero_ =
      change.percent() <= std::numeric_limits<double>::epsilon();
}

void PowerButtonController::PowerButtonEventReceived(
    bool down,
    const base::TimeTicks& timestamp) {
  if (lock_state_controller_->ShutdownRequested())
    return;

  // Handle tablet mode power button screenshot accelerator.
  if (screenshot_controller_ &&
      screenshot_controller_->OnPowerButtonEvent(down, timestamp)) {
    return;
  }

  power_button_down_ = down;
  // Ignore power button if lock button is being pressed.
  if (lock_button_down_)
    return;

  button_type_ == ButtonType::LEGACY ? OnLegacyPowerButtonEvent(down)
                                     : OnPowerButtonEvent(down, timestamp);
}

void PowerButtonController::SuspendImminent(
    power_manager::SuspendImminent::Reason reason) {
  DismissMenu();
}

void PowerButtonController::SuspendDone(const base::TimeDelta& sleep_duration) {
  last_resume_time_ = tick_clock_->NowTicks();
}

void PowerButtonController::OnGetSwitchStates(
    base::Optional<chromeos::PowerManagerClient::SwitchStates> result) {
  if (!result.has_value())
    return;

  if (result->tablet_mode !=
      chromeos::PowerManagerClient::TabletMode::UNSUPPORTED) {
    has_tablet_mode_switch_ = true;
    InitTabletPowerButtonMembers();
  }
}

void PowerButtonController::OnAccelerometerUpdated(
    scoped_refptr<const AccelerometerUpdate> update) {
  if (!has_tablet_mode_switch_ && observe_accelerometer_events_)
    InitTabletPowerButtonMembers();
}

void PowerButtonController::OnBacklightsForcedOffChanged(bool forced_off) {
  DismissMenu();
}

void PowerButtonController::OnScreenStateChanged(
    BacklightsForcedOffSetter::ScreenState screen_state) {
  if (screen_state != BacklightsForcedOffSetter::ScreenState::ON)
    DismissMenu();
}

void PowerButtonController::OnTabletModeStarted() {
  in_tablet_mode_ = true;
  StopTimersAndDismissMenu();
}

void PowerButtonController::OnTabletModeEnded() {
  in_tablet_mode_ = false;
  StopTimersAndDismissMenu();
}

void PowerButtonController::OnLockStateEvent(
    LockStateObserver::EventType event) {
  // Reset |lock_button_down_| when lock animation finished. LOCK_RELEASED is
  // not allowed when screen is locked, which means OnLockButtonEvent will not
  // be called in lock screen. This will lead |lock_button_down_| to stay in a
  // dirty state if press lock button after login but release in lock screen.
  if (event == EVENT_LOCK_ANIMATION_FINISHED)
    lock_button_down_ = false;
}

bool PowerButtonController::UseTabletBehavior() const {
  return in_tablet_mode_ || force_tablet_power_button_;
}

void PowerButtonController::StopTimersAndDismissMenu() {
  pre_shutdown_timer_.Stop();
  power_button_menu_timer_.Stop();
  DismissMenu();
}

void PowerButtonController::StartPowerMenuAnimation() {
  // Avoid a distracting deactivation animation on the formerly-active
  // window when the menu is activated.
  views::Widget* active_toplevel_widget =
      views::Widget::GetTopLevelWidgetForNativeView(wm::GetActiveWindow());
  active_window_widget_controller_ =
      ActiveWindowWidgetController::Create(active_toplevel_widget);

  if (!menu_widget_)
    menu_widget_ = CreateMenuWidget();
  menu_widget_->SetContentsView(new PowerButtonMenuScreenView(
      power_button_position_, power_button_offset_percentage_,
      base::BindRepeating(&PowerButtonController::SetShowMenuAnimationDone,
                          base::Unretained(this))));
  menu_widget_->Show();

  // Hide cursor, but let it reappear if the mouse moves.
  Shell* shell = Shell::Get();
  if (shell->cursor_manager())
    shell->cursor_manager()->HideCursor();

  static_cast<PowerButtonMenuScreenView*>(menu_widget_->GetContentsView())
      ->ScheduleShowHideAnimation(true);
}

void PowerButtonController::ProcessCommandLine() {
  const base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  button_type_ = cl->HasSwitch(switches::kAuraLegacyPowerButton)
                     ? ButtonType::LEGACY
                     : ButtonType::NORMAL;
  observe_accelerometer_events_ = cl->HasSwitch(switches::kAshEnableTabletMode);
  force_tablet_power_button_ = cl->HasSwitch(switches::kForceTabletPowerButton);

  ParsePowerButtonPositionSwitch();
}

void PowerButtonController::InitTabletPowerButtonMembers() {
  if (!screenshot_controller_) {
    screenshot_controller_ =
        std::make_unique<PowerButtonScreenshotController>(tick_clock_);
  }
}

void PowerButtonController::LockScreenIfRequired() {
  const SessionController* session_controller =
      Shell::Get()->session_controller();
  if (session_controller->ShouldLockScreenAutomatically() &&
      session_controller->CanLockScreen() &&
      !session_controller->IsUserSessionBlocked() &&
      !lock_state_controller_->LockRequested()) {
    lock_state_controller_->LockWithoutAnimation();
  }
}

void PowerButtonController::SetShowMenuAnimationDone() {
  show_menu_animation_done_ = true;
  if (button_type_ != ButtonType::LEGACY) {
    pre_shutdown_timer_.Start(FROM_HERE, kStartShutdownAnimationTimeout, this,
                              &PowerButtonController::OnPreShutdownTimeout);
  }
}

void PowerButtonController::ParsePowerButtonPositionSwitch() {
  const base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  if (!cl->HasSwitch(switches::kAshPowerButtonPosition))
    return;

  std::unique_ptr<base::DictionaryValue> position_info =
      base::DictionaryValue::From(base::JSONReader::ReadDeprecated(
          cl->GetSwitchValueASCII(switches::kAshPowerButtonPosition)));
  if (!position_info) {
    LOG(ERROR) << switches::kAshPowerButtonPosition << " flag has no value";
    return;
  }

  std::string edge, position;
  if (!position_info->GetString(kEdgeField, &edge) ||
      !position_info->GetDouble(kPositionField,
                                &power_button_offset_percentage_)) {
    LOG(ERROR) << "Both " << kEdgeField << " field and " << kPositionField
               << " are always needed if " << switches::kAshPowerButtonPosition
               << " is set";
    return;
  }

  if (edge == kLeftEdge) {
    power_button_position_ = PowerButtonPosition::LEFT;
  } else if (edge == kRightEdge) {
    power_button_position_ = PowerButtonPosition::RIGHT;
  } else if (edge == kTopEdge) {
    power_button_position_ = PowerButtonPosition::TOP;
  } else if (edge == kBottomEdge) {
    power_button_position_ = PowerButtonPosition::BOTTOM;
  } else {
    LOG(ERROR) << "Invalid " << kEdgeField << " field in "
               << switches::kAshPowerButtonPosition;
    return;
  }

  if (power_button_offset_percentage_ < 0 ||
      power_button_offset_percentage_ > 1.0f) {
    LOG(ERROR) << "Invalid " << kPositionField << " field in "
               << switches::kAshPowerButtonPosition;
    power_button_position_ = PowerButtonPosition::NONE;
  }
}

void PowerButtonController::UpdatePowerButtonEventUMAHistogram(
    uint32_t up_state) {
  if (up_state & UP_SHOWING_ANIMATION_CANCELLED)
    RecordPressInLaptopModeHistogram(PowerButtonPressType::kTapWithoutMenu);

  if (up_state & UP_MENU_TIMER_WAS_RUNNING)
    RecordPressInTabletModeHistogram(PowerButtonPressType::kTapWithoutMenu);

  if (menu_shown_when_power_button_down_) {
    if (up_state & UP_PRE_SHUTDOWN_TIMER_WAS_RUNNING) {
      force_off_on_button_up_
          ? RecordPressInTabletModeHistogram(PowerButtonPressType::kTapWithMenu)
          : RecordPressInLaptopModeHistogram(
                PowerButtonPressType::kTapWithMenu);
    } else if (!(up_state & UP_CAN_CANCEL_SHUTDOWN_ANIMATION)) {
      force_off_on_button_up_
          ? RecordPressInTabletModeHistogram(
                PowerButtonPressType::kLongPressWithMenuToShutdown)
          : RecordPressInLaptopModeHistogram(
                PowerButtonPressType::kLongPressWithMenuToShutdown);
    }
  } else if (up_state & UP_MENU_WAS_OPENED) {
    if (up_state & UP_PRE_SHUTDOWN_TIMER_WAS_RUNNING ||
        up_state & UP_CAN_CANCEL_SHUTDOWN_ANIMATION) {
      force_off_on_button_up_ ? RecordPressInTabletModeHistogram(
                                    PowerButtonPressType::kLongPressToShowMenu)
                              : RecordPressInLaptopModeHistogram(
                                    PowerButtonPressType::kLongPressToShowMenu);
    } else if (!(up_state & UP_SHOWING_ANIMATION_CANCELLED)) {
      force_off_on_button_up_
          ? RecordPressInTabletModeHistogram(
                PowerButtonPressType::kLongPressWithoutMenuToShutdown)
          : RecordPressInLaptopModeHistogram(
                PowerButtonPressType::kLongPressWithoutMenuToShutdown);
    }
  }
}

}  // namespace ash
