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

#include <sys/time.h>

#include <algorithm>
#include <cmath>
#include <string>
#include <vector>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <dbus/message.h>

#include "power_manager/common/clock.h"
#include "power_manager/common/power_constants.h"
#include "power_manager/common/prefs.h"
#include "power_manager/powerd/policy/backlight_controller_observer.h"
#include "power_manager/powerd/system/dbus_wrapper.h"
#include "power_manager/powerd/system/display/display_power_setter.h"
#include "power_manager/proto_bindings/policy.pb.h"

namespace power_manager {
namespace policy {

namespace {

// Maximum valid value for percentages.
const double kMaxPercent = 100.0;

// When going into the idle-induced dim state, the backlight dims to this
// fraction (in the range [0.0, 1.0]) of its maximum brightness level.  This is
// a fraction rather than a percent so it won't change if
// kDefaultLevelToPercentExponent is modified.
const double kDimmedBrightnessFraction = 0.1;

// Value for |level_to_percent_exponent_|, assuming that at least
// |kMinLevelsForNonLinearScale| brightness levels are available -- if not, we
// just use 1.0 to give us a linear scale.
const double kDefaultLevelToPercentExponent = 0.5;

// Returns the animation duration for |transition|.
base::TimeDelta TransitionToTimeDelta(
    BacklightController::Transition transition) {
  switch (transition) {
    case BacklightController::Transition::INSTANT:
      return base::TimeDelta();
    case BacklightController::Transition::FAST:
      return base::TimeDelta::FromMilliseconds(kFastBacklightTransitionMs);
    case BacklightController::Transition::SLOW:
      return base::TimeDelta::FromMilliseconds(kSlowBacklightTransitionMs);
  }
}

// Clamps |percent| to fit between kMinVisiblePercent and 100.
double ClampPercentToVisibleRange(double percent) {
  return std::min(
      kMaxPercent,
      std::max(InternalBacklightController::kMinVisiblePercent, percent));
}

// Reads |pref_name| from |prefs| and returns the desired initial brightness
// percent corresponding to |backlight_nits|, the backlight's actual maximum
// luminance. Crashes on failure.
//
// The pref's value should consist of one or more lines, each containing either
// a single double brightness percentage or a space-separated "<double-percent>
// <int64_t-max-level>" pair. The percentage from the first line either using
// the single-value format or matching |backlight_nits| will be returned.
//
// For example,
//
// 60.0 300
// 50.0 400
// 40.0
//
// indicates that 60% should be used if the maximum luminance is 300, 50% should
// be used if it's 400, and 40% should be used otherwise.
//
// Note that this method will crash if no matching lines are found.
double GetInitialBrightnessPercent(PrefsInterface* prefs,
                                   const std::string& pref_name,
                                   int64_t backlight_nits) {
  DCHECK(prefs);
  std::string pref_value;
  CHECK(prefs->GetString(pref_name, &pref_value))
      << "Unable to read pref " << pref_name;

  std::vector<std::string> lines = base::SplitString(
      pref_value, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  for (size_t i = 0; i < lines.size(); ++i) {
    std::vector<std::string> parts =
        base::SplitString(lines[i], base::kWhitespaceASCII,
                          base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    CHECK(parts.size() == 1U || parts.size() == 2U)
        << "Unable to parse \"" << lines[i] << "\" from pref " << pref_name;

    double percent = 0.0;
    CHECK(base::StringToDouble(parts[0], &percent) && percent >= 0.0 &&
          percent <= 100.0)
        << "Unable to parse \"" << parts[0] << "\" from pref " << pref_name
        << " as double in [0.0, 100.0]";
    if (parts.size() == 1U)
      return percent;

    int64_t nits = -1;
    CHECK(base::StringToInt64(parts[1], &nits))
        << "Unable to parse \"" << parts[1] << "\" from pref " << pref_name;
    if (nits == backlight_nits)
      return percent;
  }

  LOG(FATAL) << "Unable to find initial brightness percentage in pref "
             << pref_name << " for " << backlight_nits << " nits";
  return kMaxPercent;
}

}  // namespace

const int64_t InternalBacklightController::kMaxBrightnessSteps = 16;
const double InternalBacklightController::kMinVisiblePercent =
    kMaxPercent / kMaxBrightnessSteps;
const double InternalBacklightController::kMinLevelsForNonLinearMapping = 100;
const double InternalBacklightController::kDefaultMinVisibleBrightnessFraction =
    0.0065;
const int InternalBacklightController::kAmbientLightSensorTimeoutSec = 10;

InternalBacklightController::InternalBacklightController()
    : clock_(new Clock),
      dimmed_brightness_percent_(kDimmedBrightnessFraction * 100.0),
      level_to_percent_exponent_(kDefaultLevelToPercentExponent),
      weak_ptr_factory_(this) {}

InternalBacklightController::~InternalBacklightController() = default;

void InternalBacklightController::Init(
    system::BacklightInterface* backlight,
    PrefsInterface* prefs,
    system::AmbientLightSensorInterface* sensor,
    system::DisplayPowerSetterInterface* display_power_setter,
    system::DBusWrapperInterface* dbus_wrapper,
    LidState initial_lid_state) {
  backlight_ = backlight;
  prefs_ = prefs;
  display_power_setter_ = display_power_setter;
  dbus_wrapper_ = dbus_wrapper;
  lid_state_ = initial_lid_state;

  max_level_ = backlight_->GetMaxBrightnessLevel();
  current_level_ = backlight_->GetCurrentBrightnessLevel();

  if (!prefs_->GetInt64(kMinVisibleBacklightLevelPref, &min_visible_level_)) {
    min_visible_level_ = static_cast<int64_t>(
        lround(kDefaultMinVisibleBrightnessFraction * max_level_));
  }
  min_visible_level_ = std::min(
      std::max(min_visible_level_, static_cast<int64_t>(1)), max_level_);

  const double initial_percent = LevelToPercent(current_level_);
  ambient_light_brightness_percent_ = initial_percent;

  int64_t max_nits = 0;
  prefs_->GetInt64(kInternalBacklightMaxNitsPref, &max_nits);
  ac_explicit_brightness_percent_ = GetInitialBrightnessPercent(
      prefs_, kInternalBacklightNoAlsAcBrightnessPref, max_nits);
  battery_explicit_brightness_percent_ = GetInitialBrightnessPercent(
      prefs_, kInternalBacklightNoAlsBatteryBrightnessPref, max_nits);

  prefs_->GetBool(kInstantTransitionsBelowMinLevelPref,
                  &instant_transitions_below_min_level_);

  if (sensor) {
    ambient_light_handler_.reset(new AmbientLightHandler(sensor, this));
    ambient_light_handler_->set_name("panel");
    std::string pref_value;
    CHECK(prefs_->GetString(kInternalBacklightAlsStepsPref, &pref_value))
        << "Failed to read pref " << kInternalBacklightAlsStepsPref;

    double als_smoothing_constant;
    CHECK(prefs_->GetDouble(kAlsSmoothingConstantPref, &als_smoothing_constant))
        << "Failed to read pref " << kAlsSmoothingConstantPref;
    ambient_light_handler_->Init(pref_value, initial_percent,
                                 als_smoothing_constant);
  } else {
    use_ambient_light_ = false;
  }

  int64_t turn_off_screen_timeout_ms = 0;
  prefs_->GetInt64(kTurnOffScreenTimeoutMsPref, &turn_off_screen_timeout_ms);
  turn_off_screen_timeout_ =
      base::TimeDelta::FromMilliseconds(turn_off_screen_timeout_ms);

  if (max_level_ == min_visible_level_ || kMaxBrightnessSteps == 1) {
    step_percent_ = kMaxPercent;
  } else {
    // 1 is subtracted from kMaxBrightnessSteps to account for the step between
    // |min_brightness_level_| and 0.
    step_percent_ =
        (kMaxPercent - kMinVisiblePercent) /
        std::min(kMaxBrightnessSteps - 1, max_level_ - min_visible_level_);
  }
  CHECK_GT(step_percent_, 0.0);

  system::BacklightInterface::BrightnessScale brightness_scale =
      backlight_->GetBrightnessScale();
  switch (brightness_scale) {
    case system::BacklightInterface::BrightnessScale::kLinear:
      level_to_percent_exponent_ = kDefaultLevelToPercentExponent;
      break;
    case system::BacklightInterface::BrightnessScale::kNonLinear:
      level_to_percent_exponent_ = 1.0;
      break;
    default:
      level_to_percent_exponent_ = max_level_ >= kMinLevelsForNonLinearMapping
                                       ? kDefaultLevelToPercentExponent
                                       : 1.0;
  }

  dimmed_brightness_percent_ = ClampPercentToVisibleRange(
      LevelToPercent(lround(kDimmedBrightnessFraction * max_level_)));

  RegisterIncreaseBrightnessHandler(
      dbus_wrapper_, kIncreaseScreenBrightnessMethod,
      base::Bind(&InternalBacklightController::HandleIncreaseBrightnessRequest,
                 weak_ptr_factory_.GetWeakPtr()));
  RegisterDecreaseBrightnessHandler(
      dbus_wrapper_, kDecreaseScreenBrightnessMethod,
      base::Bind(&InternalBacklightController::HandleDecreaseBrightnessRequest,
                 weak_ptr_factory_.GetWeakPtr()));
  RegisterSetBrightnessHandler(
      dbus_wrapper_, kSetScreenBrightnessMethod,
      base::Bind(&InternalBacklightController::HandleSetBrightnessRequest,
                 weak_ptr_factory_.GetWeakPtr()));
  RegisterGetBrightnessHandler(
      dbus_wrapper_, kGetScreenBrightnessPercentMethod,
      base::Bind(&InternalBacklightController::HandleGetBrightnessRequest,
                 weak_ptr_factory_.GetWeakPtr()));

  init_time_ = clock_->GetCurrentTime();
  LOG(INFO) << "Backlight has range [0, " << max_level_ << "] with "
            << step_percent_ << "% step and minimum-visible level of "
            << min_visible_level_ << "; current level is " << current_level_
            << " (" << LevelToPercent(current_level_) << "%)";
}

void InternalBacklightController::AddObserver(
    BacklightControllerObserver* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void InternalBacklightController::RemoveObserver(
    BacklightControllerObserver* observer) {
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

void InternalBacklightController::HandlePowerSourceChange(PowerSource source) {
  if (got_power_source_ && power_source_ == source)
    return;

  VLOG(1) << "Power source changed to " << PowerSourceToString(source);

  const bool on_ac = source == PowerSource::AC;

  // Ensure that the screen isn't dimmed in response to a transition to AC
  // or brightened in response to a transition to battery.
  if (got_power_source_) {
    const bool battery_exceeds_ac =
        battery_explicit_brightness_percent_ > ac_explicit_brightness_percent_;
    if (on_ac && battery_exceeds_ac)
      ac_explicit_brightness_percent_ = battery_explicit_brightness_percent_;
    else if (!on_ac && battery_exceeds_ac)
      battery_explicit_brightness_percent_ = ac_explicit_brightness_percent_;
  }

  power_source_ = source;
  got_power_source_ = true;
  UpdateState(
      on_ac ? BacklightBrightnessChange_Cause_EXTERNAL_POWER_CONNECTED
            : BacklightBrightnessChange_Cause_EXTERNAL_POWER_DISCONNECTED);
  if (ambient_light_handler_)
    ambient_light_handler_->HandlePowerSourceChange(source);
}

void InternalBacklightController::HandleDisplayModeChange(DisplayMode mode) {
  if (display_mode_ == mode)
    return;

  display_mode_ = mode;

  // If there's no external display now, make sure that the panel is on.
  if (display_mode_ == DisplayMode::NORMAL)
    EnsureUserBrightnessIsNonzero(BacklightBrightnessChange_Cause_OTHER);
}

void InternalBacklightController::HandleSessionStateChange(SessionState state) {
  EnsureUserBrightnessIsNonzero(BacklightBrightnessChange_Cause_OTHER);
  if (state == SessionState::STARTED) {
    als_adjustment_count_ = 0;
    user_adjustment_count_ = 0;
  }
}

void InternalBacklightController::HandlePowerButtonPress() {
  EnsureUserBrightnessIsNonzero(BacklightBrightnessChange_Cause_USER_ACTIVITY);
}

void InternalBacklightController::HandleLidStateChange(LidState state) {
  lid_state_ = state;
  UpdateState(BacklightBrightnessChange_Cause_OTHER);
}

void InternalBacklightController::HandleUserActivity(UserActivityType type) {
  // Don't increase the brightness automatically when the user hits a brightness
  // key: if they hit brightness-up, HandleIncreaseBrightnessRequest() will be
  // called soon anyway; if they hit brightness-down, the screen shouldn't get
  // turned back on. Also ignore volume keys.
  if (type != USER_ACTIVITY_BRIGHTNESS_UP_KEY_PRESS &&
      type != USER_ACTIVITY_BRIGHTNESS_DOWN_KEY_PRESS &&
      type != USER_ACTIVITY_VOLUME_UP_KEY_PRESS &&
      type != USER_ACTIVITY_VOLUME_DOWN_KEY_PRESS &&
      type != USER_ACTIVITY_VOLUME_MUTE_KEY_PRESS)
    EnsureUserBrightnessIsNonzero(
        BacklightBrightnessChange_Cause_USER_ACTIVITY);
}

void InternalBacklightController::HandleVideoActivity(bool is_fullscreen) {}

void InternalBacklightController::HandleWakeNotification() {
  // Increase the brightness of the display, even though the user might have set
  // it to zero, as this notification is waking up the device to get the user's
  // attention.
  EnsureUserBrightnessIsNonzero(
      BacklightBrightnessChange_Cause_WAKE_NOTIFICATION);
}

void InternalBacklightController::HandleHoverStateChange(bool hovering) {}

void InternalBacklightController::HandleTabletModeChange(TabletMode mode) {}

void InternalBacklightController::HandlePolicyChange(
    const PowerManagementPolicy& policy) {
  bool got_policy_brightness = false;

  double ac_brightness = ac_explicit_brightness_percent_;
  if (policy.has_ac_brightness_percent()) {
    LOG(INFO) << "Got policy-triggered request to set AC brightness to "
              << policy.ac_brightness_percent() << "%";
    ac_brightness = policy.ac_brightness_percent();
    got_policy_brightness = true;
  }
  double battery_brightness = battery_explicit_brightness_percent_;
  if (policy.has_battery_brightness_percent()) {
    LOG(INFO) << "Got policy-triggered request to set battery brightness to "
              << policy.battery_brightness_percent() << "%";
    battery_brightness = policy.battery_brightness_percent();
    got_policy_brightness = true;
  }

  using_policy_brightness_ = got_policy_brightness;
  if (got_policy_brightness) {
    SetExplicitBrightnessPercent(ac_brightness, battery_brightness,
                                 Transition::FAST,
                                 BacklightBrightnessChange_Cause_OTHER);
  }
  force_nonzero_brightness_for_user_activity_ =
      policy.has_force_nonzero_brightness_for_user_activity()
          ? policy.force_nonzero_brightness_for_user_activity()
          : true;
}

void InternalBacklightController::HandleDisplayServiceStart() {
  display_power_setter_->SetDisplayPower(display_power_state_,
                                         base::TimeDelta());
}

void InternalBacklightController::SetDimmedForInactivity(bool dimmed) {
  if (dimmed_for_inactivity_ == dimmed)
    return;

  VLOG(1) << (dimmed ? "Dimming" : "No longer dimming") << " for inactivity";
  dimmed_for_inactivity_ = dimmed;
  UpdateState(dimmed ? BacklightBrightnessChange_Cause_USER_INACTIVITY
                     : BacklightBrightnessChange_Cause_USER_ACTIVITY,
              dimmed ? Transition::FAST : Transition::INSTANT);
}

void InternalBacklightController::SetOffForInactivity(bool off) {
  if (off_for_inactivity_ == off)
    return;

  VLOG(1) << (off ? "Turning backlight off" : "No longer keeping backlight off")
          << " for inactivity";
  off_for_inactivity_ = off;
  UpdateState(off ? BacklightBrightnessChange_Cause_USER_INACTIVITY
                  : BacklightBrightnessChange_Cause_USER_ACTIVITY);
}

void InternalBacklightController::SetSuspended(bool suspended) {
  if (suspended_ == suspended)
    return;

  VLOG(1) << (suspended ? "Suspending" : "Unsuspending") << " backlight";
  suspended_ = suspended;
  UpdateState(BacklightBrightnessChange_Cause_OTHER);

  if (!suspended && use_ambient_light_)
    ambient_light_handler_->HandleResume();
}

void InternalBacklightController::SetShuttingDown(bool shutting_down) {
  if (shutting_down_ == shutting_down)
    return;

  if (shutting_down)
    VLOG(1) << "Preparing backlight for shutdown";
  else
    LOG(WARNING) << "Exiting shutting-down state";
  shutting_down_ = shutting_down;
  UpdateState(BacklightBrightnessChange_Cause_OTHER);
}

void InternalBacklightController::SetForcedOff(bool forced_off) {
  if (forced_off_ == forced_off)
    return;

  VLOG(1) << (forced_off ? "Forcing" : "Not forcing") << " backlight off";
  forced_off_ = forced_off;
  UpdateState(forced_off
                  ? BacklightBrightnessChange_Cause_FORCED_OFF
                  : BacklightBrightnessChange_Cause_NO_LONGER_FORCED_OFF);
}

bool InternalBacklightController::GetForcedOff() {
  return forced_off_;
}

bool InternalBacklightController::GetBrightnessPercent(double* percent) {
  DCHECK(percent);
  *percent = LevelToPercent(current_level_);
  return true;
}

int InternalBacklightController::GetNumAmbientLightSensorAdjustments() const {
  return als_adjustment_count_;
}

int InternalBacklightController::GetNumUserAdjustments() const {
  return user_adjustment_count_;
}

double InternalBacklightController::LevelToPercent(int64_t raw_level) const {
  // If the passed-in level is below the minimum visible level, just map it
  // linearly into [0, kMinVisiblePercent).
  if (raw_level < min_visible_level_)
    return kMinVisiblePercent * raw_level / min_visible_level_;

  // Since we're at or above the minimum level, we know that we're at 100% if
  // the min and max are equal.
  if (min_visible_level_ == max_level_)
    return 100.0;

  double linear_fraction = static_cast<double>(raw_level - min_visible_level_) /
                           (max_level_ - min_visible_level_);
  return kMinVisiblePercent +
         (kMaxPercent - kMinVisiblePercent) *
             pow(linear_fraction, level_to_percent_exponent_);
}

int64_t InternalBacklightController::PercentToLevel(double percent) const {
  if (percent < kMinVisiblePercent)
    return lround(min_visible_level_ * percent / kMinVisiblePercent);

  if (percent == kMaxPercent)
    return max_level_;

  double linear_fraction =
      (percent - kMinVisiblePercent) / (kMaxPercent - kMinVisiblePercent);
  return lround(min_visible_level_ +
                (max_level_ - min_visible_level_) *
                    pow(linear_fraction, 1.0 / level_to_percent_exponent_));
}

void InternalBacklightController::SetBrightnessPercentForAmbientLight(
    double brightness_percent,
    AmbientLightHandler::BrightnessChangeCause cause) {
  ambient_light_brightness_percent_ = brightness_percent;
  got_ambient_light_brightness_percent_ = true;

  if (!use_ambient_light_)
    return;

  // If powerd hasn't started controlling the backlight yet, don't blame ambient
  // light for any brightness change that UpdateState() may end up making.
  const BacklightBrightnessChange_Cause backlight_cause =
      already_set_initial_state_ ? AmbientLightHandler::ToProtobufCause(cause)
                                 : BacklightBrightnessChange_Cause_OTHER;

  // This method is also called for power source changes while
  // AmbientLightHandler is controlling the brightness. Perform a fast
  // transition in that case.
  const bool ambient_light_changed =
      backlight_cause == BacklightBrightnessChange_Cause_AMBIENT_LIGHT_CHANGED;
  const Transition transition =
      ambient_light_changed ? Transition::SLOW : Transition::FAST;

  const int64_t old_level = current_level_;
  UpdateState(backlight_cause, transition);
  if (ambient_light_changed && current_level_ != old_level)
    als_adjustment_count_++;
}

void InternalBacklightController::OnColorTemperatureChanged(
    int color_temperature) {
  dbus::Signal signal(kPowerManagerInterface,
                      kAmbientColorTemperatureChangedSignal);
  dbus::MessageWriter(&signal).AppendInt32(color_temperature);
  dbus_wrapper_->EmitSignal(&signal);
}

double InternalBacklightController::SnapBrightnessPercentToNearestStep(
    double percent) const {
  return round(percent / step_percent_) * step_percent_;
}

double InternalBacklightController::GetExplicitBrightnessPercent() const {
  return power_source_ == PowerSource::AC
             ? ac_explicit_brightness_percent_
             : battery_explicit_brightness_percent_;
}

double InternalBacklightController::GetUndimmedBrightnessPercent() const {
  if (use_ambient_light_)
    return ClampPercentToVisibleRange(ambient_light_brightness_percent_);

  const double percent = GetExplicitBrightnessPercent();
  return percent <= kEpsilon ? 0.0 : ClampPercentToVisibleRange(percent);
}

void InternalBacklightController::HandleIncreaseBrightnessRequest() {
  double old_percent = GetUndimmedBrightnessPercent();
  double new_percent =
      (old_percent < kMinVisiblePercent - kEpsilon)
          ? kMinVisiblePercent
          : ClampPercentToVisibleRange(SnapBrightnessPercentToNearestStep(
                old_percent + step_percent_));

  // If we don't actually change the brightness, emit a signal so the UI can
  // show the user that nothing changed.
  const double current_percent = LevelToPercent(current_level_);
  HandleSetBrightnessRequest(new_percent, Transition::FAST,
                             SetBacklightBrightnessRequest_Cause_USER_REQUEST);
  if (LevelToPercent(current_level_) == current_percent) {
    EmitBrightnessChangedSignal(dbus_wrapper_, kScreenBrightnessChangedSignal,
                                current_percent,
                                BacklightBrightnessChange_Cause_USER_REQUEST);
  }
}

void InternalBacklightController::HandleDecreaseBrightnessRequest(
    bool allow_off) {
  // Lower the backlight to the next step, turning it off if it was already at
  // the minimum visible level.
  double old_percent = GetUndimmedBrightnessPercent();
  double new_percent =
      old_percent <= kMinVisiblePercent + kEpsilon
          ? 0.0
          : ClampPercentToVisibleRange(SnapBrightnessPercentToNearestStep(
                old_percent - step_percent_));

  if (!allow_off && new_percent <= kEpsilon) {
    user_adjustment_count_++;
    return;
  }

  // If we don't actually change the brightness, emit a signal so the UI can
  // show the user that nothing changed.
  const double current_percent = LevelToPercent(current_level_);
  HandleSetBrightnessRequest(new_percent, Transition::FAST,
                             SetBacklightBrightnessRequest_Cause_USER_REQUEST);
  if (LevelToPercent(current_level_) == current_percent) {
    EmitBrightnessChangedSignal(dbus_wrapper_, kScreenBrightnessChangedSignal,
                                current_percent,
                                BacklightBrightnessChange_Cause_USER_REQUEST);
  }
}

void InternalBacklightController::HandleSetBrightnessRequest(
    double percent,
    Transition transition,
    SetBacklightBrightnessRequest_Cause cause) {
  BacklightBrightnessChange_Cause change_cause =
      BacklightBrightnessChange_Cause_OTHER;
  const char* cause_str = "unknown";
  switch (cause) {
    case SetBacklightBrightnessRequest_Cause_USER_REQUEST:
      cause_str = "user-triggered";
      change_cause = BacklightBrightnessChange_Cause_USER_REQUEST;
      break;
    case SetBacklightBrightnessRequest_Cause_MODEL:
      cause_str = "model-triggered";
      change_cause = BacklightBrightnessChange_Cause_MODEL;
      break;
  }

  LOG(INFO) << "Got " << cause_str << " request to set brightness to "
            << percent << "%";
  if (cause == SetBacklightBrightnessRequest_Cause_USER_REQUEST)
    user_adjustment_count_++;
  using_policy_brightness_ = false;

  // When the user explicitly requests a specific brightness level, use it for
  // both AC and battery power.
  SetExplicitBrightnessPercent(percent, percent, transition, change_cause);
}

void InternalBacklightController::HandleGetBrightnessRequest(
    double* percent_out, bool* success_out) {
  DCHECK(percent_out);
  DCHECK(success_out);
  *percent_out = LevelToPercent(current_level_);
  *success_out = true;
}

void InternalBacklightController::EnsureUserBrightnessIsNonzero(
    BacklightBrightnessChange_Cause cause) {
  // Avoid turning the backlight back on if an external display is
  // connected since doing so may result in the desktop being resized. Also
  // don't turn it on if a policy has forced the brightness to zero.
  if (force_nonzero_brightness_for_user_activity_ &&
      display_mode_ == DisplayMode::NORMAL &&
      GetExplicitBrightnessPercent() < kMinVisiblePercent &&
      !using_policy_brightness_ && !use_ambient_light_) {
    SetExplicitBrightnessPercent(kMinVisiblePercent, kMinVisiblePercent,
                                 Transition::FAST, cause);
  }
}

void InternalBacklightController::SetExplicitBrightnessPercent(
    double ac_percent,
    double battery_percent,
    Transition transition,
    BacklightBrightnessChange_Cause cause) {
  use_ambient_light_ = false;
  ac_explicit_brightness_percent_ =
      ac_percent <= kEpsilon ? 0.0 : ClampPercentToVisibleRange(ac_percent);
  battery_explicit_brightness_percent_ =
      battery_percent <= kEpsilon ? 0.0
                                  : ClampPercentToVisibleRange(battery_percent);
  UpdateState(cause, transition);
}

void InternalBacklightController::UpdateState(
    BacklightBrightnessChange_Cause cause, Transition adjust_transition) {
  // Give up on the ambient light sensor if it's not supplying readings.
  if (use_ambient_light_ && !got_ambient_light_brightness_percent_ &&
      clock_->GetCurrentTime() - init_time_ >=
          base::TimeDelta::FromSeconds(kAmbientLightSensorTimeoutSec)) {
    LOG(ERROR) << "Giving up on ambient light sensor after getting no reading "
               << "within " << kAmbientLightSensorTimeoutSec << " seconds";
    use_ambient_light_ = false;
  }

  // Hold off on changing the brightness at startup until all the required
  // state has been received.
  // TODO(chromeos-power): Don't bail out if we'll turn the display off, since
  // that's independent of all of this.
  if (!got_power_source_ ||
      (use_ambient_light_ && !got_ambient_light_brightness_percent_))
    return;

  // First, figure out the backlight brightness and display power state that we
  // should be using right now.
  double brightness_percent = 100.0;
  Transition brightness_transition = Transition::INSTANT;

  chromeos::DisplayPowerState display_power = chromeos::DISPLAY_POWER_ALL_ON;
  base::TimeDelta display_delay;
  bool set_display_power = true;

  if (shutting_down_ || forced_off_) {
    brightness_percent = 0.0;
    display_power = chromeos::DISPLAY_POWER_ALL_OFF;
  } else if (suspended_) {
    brightness_percent = 0.0;
    // Chrome puts displays into the correct power state before suspend.
    set_display_power = false;
  } else if (off_for_inactivity_) {
    brightness_percent = 0.0;
    brightness_transition = Transition::FAST;
    display_power = chromeos::DISPLAY_POWER_ALL_OFF;
    display_delay = TransitionToTimeDelta(brightness_transition);
  } else if (lid_state_ == LidState::CLOSED) {
    brightness_percent = 0.0;
    // Leave external displays on for docked mode.
    display_power = chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON;
  } else {
    brightness_percent =
        std::min(GetUndimmedBrightnessPercent(),
                 dimmed_for_inactivity_ ? dimmed_brightness_percent_ : 100.0);
    const bool turning_on =
        display_power_state_ != chromeos::DISPLAY_POWER_ALL_ON ||
        current_level_ == 0;
    brightness_transition =
        turning_on ? Transition::INSTANT
                   : (already_set_initial_state_ ? adjust_transition
                                                 : Transition::SLOW);

    if (brightness_percent <= kEpsilon) {
      // Keep external display(s) on if the brightness was explicitly set to 0.
      display_power = chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON;
      display_delay = TransitionToTimeDelta(brightness_transition) +
                      turn_off_screen_timeout_;
    }
  }

  // Now apply the state that we decided on.
  if (set_display_power && display_power != display_power_state_) {
    // For instant transitions, this call blocks until Chrome confirms that it
    // has made the change.
    display_power_setter_->SetDisplayPower(display_power, display_delay);
    display_power_state_ = display_power;
  }

  // Apply the brightness after toggling the display power. If we do it the
  // other way around, then the brightness set here has a potential to get
  // interleaved with the display power toggle operation in some drivers
  // resulting in this request being dropped and the brightness being set to its
  // previous value instead. See chrome-os-partner:31186 and :35662 for more
  // details.
  const int64_t new_level = PercentToLevel(brightness_percent);
  if (new_level != current_level_ || backlight_->TransitionInProgress()) {
    // Force an instant transition if we're moving into or out of the
    // below-min-visible (i.e. off-but-nonzero) range.
    bool starting_below_min_visible_level = current_level_ < min_visible_level_;
    bool ending_below_min_visible_level = new_level < min_visible_level_;
    if (instant_transitions_below_min_level_ &&
        starting_below_min_visible_level != ending_below_min_visible_level)
      brightness_transition = Transition::INSTANT;

    base::TimeDelta interval = TransitionToTimeDelta(brightness_transition);
    LOG(INFO) << "Setting brightness to " << new_level << " ("
              << brightness_percent << "%) over " << interval.InMilliseconds()
              << " ms";
    if (!backlight_->SetBrightnessLevel(new_level, interval)) {
      LOG(WARNING) << "Could not set brightness";
    } else {
      current_level_ = new_level;
      EmitBrightnessChangedSignal(dbus_wrapper_, kScreenBrightnessChangedSignal,
                                  brightness_percent, cause);
      for (BacklightControllerObserver& observer : observers_)
        observer.OnBrightnessChange(brightness_percent, cause, this);
    }
  }

  already_set_initial_state_ = true;
}

}  // namespace policy
}  // namespace power_manager
