| Index: ash/system/night_light/night_light_controller.h | 
| diff --git a/ash/system/night_light/night_light_controller.h b/ash/system/night_light/night_light_controller.h | 
| index bdef68d407bf91d9935b6562a33318449b371332..b9eef8f6528f8dacfeef1446f965fc7a897d0e98 100644 | 
| --- a/ash/system/night_light/night_light_controller.h | 
| +++ b/ash/system/night_light/night_light_controller.h | 
| @@ -9,7 +9,10 @@ | 
|  | 
| #include "ash/ash_export.h" | 
| #include "ash/session/session_observer.h" | 
| +#include "ash/system/night_light/time_of_day.h" | 
| #include "base/observer_list.h" | 
| +#include "base/time/time.h" | 
| +#include "base/timer/timer.h" | 
| #include "components/prefs/pref_change_registrar.h" | 
|  | 
| class PrefRegistrySimple; | 
| @@ -23,6 +26,46 @@ class SessionController; | 
| // screen. | 
| class ASH_EXPORT NightLightController : public SessionObserver { | 
| public: | 
| +  enum class ScheduleType : int { | 
| +    // Automatic toggling of NightLight is turned off. | 
| +    kNone = 0, | 
| + | 
| +    // Turned automatically on at the user's local sunset time, and off at the | 
| +    // user's local sunrise time. | 
| +    kSunsetToSunrise = 1, | 
| + | 
| +    // Toggled automatically based on the custom set start and end times | 
| +    // selected by the user from the system settings. | 
| +    kCustom = 2, | 
| +  }; | 
| + | 
| +  enum class AnimationDuration { | 
| +    // Short animation (2 seconds) used for manual changes of NightLight status | 
| +    // and temperature by the user. | 
| +    kShort, | 
| + | 
| +    // Long animation (20 seconds) used for applying the color temperature | 
| +    // gradually as a result of getting into or out of the automatically | 
| +    // scheduled NightLight mode. This gives the user a smooth transition. | 
| +    kLong, | 
| +  }; | 
| + | 
| +  // This class enables us to inject fake values for "Now" as well as the sunset | 
| +  // and sunrise times, so that we can reliably test the behavior in various | 
| +  // schedule types and times. | 
| +  class Delegate { | 
| +   public: | 
| +    // NightLightController owns the delegate. | 
| +    virtual ~Delegate() {} | 
| + | 
| +    // Gets the current time. | 
| +    virtual base::Time GetNow() const = 0; | 
| + | 
| +    // Gets the sunset and sunrise times. | 
| +    virtual base::Time GetSunsetTime() const = 0; | 
| +    virtual base::Time GetSunriseTime() const = 0; | 
| +  }; | 
| + | 
| class Observer { | 
| public: | 
| // Emitted when the NightLight status is changed. | 
| @@ -40,24 +83,40 @@ class ASH_EXPORT NightLightController : public SessionObserver { | 
|  | 
| static void RegisterPrefs(PrefRegistrySimple* registry); | 
|  | 
| +  AnimationDuration animation_duration() const { return animation_duration_; } | 
| +  AnimationDuration last_animation_duration() const { | 
| +    return last_animation_duration_; | 
| +  } | 
| +  const base::OneShotTimer& timer() const { return timer_; } | 
| + | 
| void AddObserver(Observer* observer); | 
| void RemoveObserver(Observer* observer); | 
|  | 
| // Get the NightLight settings stored in the current active user prefs. | 
| bool GetEnabled() const; | 
| float GetColorTemperature() const; | 
| +  ScheduleType GetScheduleType() const; | 
| +  TimeOfDay GetCustomStartTime() const; | 
| +  TimeOfDay GetCustomEndTime() const; | 
|  | 
| // Set the desired NightLight settings in the current active user prefs. | 
| -  void SetEnabled(bool enabled); | 
| +  void SetEnabled(bool enabled, AnimationDuration animation_type); | 
| void SetColorTemperature(float temperature); | 
| +  void SetScheduleType(ScheduleType type); | 
| +  void SetCustomStartTime(TimeOfDay start_time); | 
| +  void SetCustomEndTime(TimeOfDay end_time); | 
|  | 
| +  // This is always called as a result of a user action and will always use the | 
| +  // AnimationDurationType::kShort. | 
| void Toggle(); | 
|  | 
| // ash::SessionObserver: | 
| void OnActiveUserSessionChanged(const AccountId& account_id) override; | 
|  | 
| +  void SetDelegateForTesting(std::unique_ptr<Delegate> delegate); | 
| + | 
| private: | 
| -  void Refresh(); | 
| +  void RefreshLayersTemperature(); | 
|  | 
| void StartWatchingPrefsChanges(); | 
|  | 
| @@ -71,14 +130,50 @@ class ASH_EXPORT NightLightController : public SessionObserver { | 
| // Called when the user pref for the color temperature is changed. | 
| void OnColorTemperaturePrefChanged(); | 
|  | 
| +  // Called when any of the schedule related prefs (schedule type, custom start | 
| +  // and end times) are changed. | 
| +  void OnScheduleParamsPrefsChanged(); | 
| + | 
| +  // Refreshes the state of NightLight according to the currently set | 
| +  // parameters. |did_schedule_change| is true when Refresh() is called as a | 
| +  // result of a change in one of the schedule related prefs, and false | 
| +  // otherwise. | 
| +  void Refresh(bool did_schedule_change); | 
| + | 
| +  // Given the desired start and end times that determine the time interval | 
| +  // during which NightLight will be ON, depending on the time of "now", it | 
| +  // refreshes the |timer_| to either schedule the future start or end of | 
| +  // NightLight mode, as well as update the current status if needed. | 
| +  // For |did_schedule_change|, see Refresh() above. | 
| +  // This function should never be called if the schedule type is |kNone|. | 
| +  void RefreshScheduleTimer(base::Time start_time, | 
| +                            base::Time end_time, | 
| +                            bool did_schedule_change); | 
| + | 
| +  // Schedule the upcoming next toggle of NightLight mode. This is used for the | 
| +  // automatic status changes of NightLight which always use an | 
| +  // AnimationDurationType::kLong. | 
| +  void ScheduleNextToggle(base::TimeDelta delay); | 
| + | 
| // The observed session controller instance from which we know when to | 
| // initialize the NightLight settings from the user preferences. | 
| SessionController* const session_controller_; | 
|  | 
| +  std::unique_ptr<Delegate> delegate_; | 
| + | 
| // The pref service of the currently active user. Can be null in | 
| // ash_unittests. | 
| PrefService* active_user_pref_service_ = nullptr; | 
|  | 
| +  // The animation duration of any upcoming future change. | 
| +  AnimationDuration animation_duration_ = AnimationDuration::kShort; | 
| +  // The animation duration of the change that was just performed. | 
| +  AnimationDuration last_animation_duration_ = AnimationDuration::kShort; | 
| + | 
| +  // The timer that schedules the start and end of NightLight when the schedule | 
| +  // type is either kSunsetToSunrise or kCustom. | 
| +  base::OneShotTimer timer_; | 
| + | 
| // The registrar used to watch NightLight prefs changes in the above | 
| // |active_user_pref_service_| from outside ash. | 
| // NOTE: Prefs are how Chrome communicates changes to the NightLight settings | 
|  |