| Index: ash/system/night_light/night_light_controller.cc | 
| diff --git a/ash/system/night_light/night_light_controller.cc b/ash/system/night_light/night_light_controller.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..bf1cae453389a00c818fa2f3b9af12303634b1fd | 
| --- /dev/null | 
| +++ b/ash/system/night_light/night_light_controller.cc | 
| @@ -0,0 +1,142 @@ | 
| +// Copyright 2017 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/night_light/night_light_controller.h" | 
| + | 
| +#include "ash/session/session_controller.h" | 
| +#include "ash/shell.h" | 
| +#include "base/time/time.h" | 
| +#include "base/values.h" | 
| +#include "components/prefs/pref_registry_simple.h" | 
| +#include "components/prefs/scoped_user_pref_update.h" | 
| +#include "ui/compositor/layer.h" | 
| +#include "ui/compositor/scoped_layer_animation_settings.h" | 
| + | 
| +namespace ash { | 
| + | 
| +namespace { | 
| + | 
| +// The key of the dictionary value in the user's pref service that contains all | 
| +// the NightLight settings. | 
| +constexpr char kNightLightPrefsKey[] = "prefs.night_light_prefs"; | 
| + | 
| +// Keys to the various NightLight settings inside its dictionary value. | 
| +constexpr char kStatusKey[] = "night_light_status"; | 
| +constexpr char kColorTemperatureKey[] = "night_light_color_temperature"; | 
| + | 
| +// The duration of the temperature change animation when the change is a result | 
| +// of a manual user setting. | 
| +// TODO(afakhry): Add automatic schedule animation duration when you implement | 
| +// that part. It should be large enough (20 seconds as agreed) to give the user | 
| +// a nice smooth transition. | 
| +constexpr int kManualToggleAnimationDurationSec = 2; | 
| + | 
| +}  // namespace | 
| + | 
| +NightLightController::NightLightController( | 
| +    SessionController* session_controller) | 
| +    : session_controller_(session_controller) { | 
| +  session_controller_->AddObserver(this); | 
| +} | 
| + | 
| +NightLightController::~NightLightController() { | 
| +  session_controller_->RemoveObserver(this); | 
| +} | 
| + | 
| +// static | 
| +void NightLightController::RegisterPrefs(PrefRegistrySimple* registry) { | 
| +  registry->RegisterDictionaryPref(kNightLightPrefsKey); | 
| +} | 
| + | 
| +void NightLightController::AddObserver(Observer* observer) { | 
| +  observers_.AddObserver(observer); | 
| +} | 
| + | 
| +void NightLightController::RemoveObserver(Observer* observer) { | 
| +  observers_.RemoveObserver(observer); | 
| +} | 
| + | 
| +void NightLightController::Toggle() { | 
| +  SetEnabled(!enabled_); | 
| +} | 
| + | 
| +void NightLightController::SetEnabled(bool enabled) { | 
| +  if (enabled_ == enabled) | 
| +    return; | 
| + | 
| +  enabled_ = enabled; | 
| +  Refresh(); | 
| +  NotifyStatusChanged(); | 
| +  PersistUserPrefs(); | 
| +} | 
| + | 
| +void NightLightController::SetColorTemperature(float temperature) { | 
| +  // TODO(afakhry): Spport changing the temperature when you implement the | 
| +  // settings part of this feature. Right now we'll keep it fixed at the value | 
| +  // |color_temperature_| whenever NightLight is turned on. | 
| + | 
| +  for (aura::Window* root_window : Shell::GetAllRootWindows()) { | 
| +    ui::Layer* layer = root_window->layer(); | 
| + | 
| +    ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); | 
| +    settings.SetTransitionDuration( | 
| +        base::TimeDelta::FromSeconds(kManualToggleAnimationDurationSec)); | 
| +    settings.SetPreemptionStrategy( | 
| +        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 
| + | 
| +    layer->SetLayerTemperature(temperature); | 
| +  } | 
| +} | 
| + | 
| +void NightLightController::OnActiveUserSessionChanged( | 
| +    const AccountId& account_id) { | 
| +  // Initial login and user switching in multi profiles. | 
| +  InitFromUserPrefs(); | 
| +} | 
| + | 
| +void NightLightController::Refresh() { | 
| +  SetColorTemperature(enabled_ ? color_temperature_ : 0.0f); | 
| +} | 
| + | 
| +void NightLightController::InitFromUserPrefs() { | 
| +  auto* pref_service = Shell::Get()->GetActiveUserPrefService(); | 
| +  if (!pref_service) { | 
| +    // The pref_service can be NULL in ash_unittests. | 
| +    return; | 
| +  } | 
| + | 
| +  const base::DictionaryValue* night_light_prefs = | 
| +      pref_service->GetDictionary(kNightLightPrefsKey); | 
| +  bool enabled = false; | 
| +  night_light_prefs->GetBoolean(kStatusKey, &enabled); | 
| +  enabled_ = enabled; | 
| + | 
| +  double color_temperature = 0.5; | 
| +  night_light_prefs->GetDouble(kColorTemperatureKey, &color_temperature); | 
| +  color_temperature_ = static_cast<float>(color_temperature); | 
| + | 
| +  Refresh(); | 
| +  NotifyStatusChanged(); | 
| +} | 
| + | 
| +void NightLightController::PersistUserPrefs() { | 
| +  auto* pref_service = ash::Shell::Get()->GetActiveUserPrefService(); | 
| +  if (!pref_service) { | 
| +    // The pref_service can be NULL in ash_unittests. | 
| +    return; | 
| +  } | 
| +  DictionaryPrefUpdate pref_updater(pref_service, kNightLightPrefsKey); | 
| + | 
| +  base::DictionaryValue* dictionary = pref_updater.Get(); | 
| +  dictionary->SetBoolean(kStatusKey, enabled_); | 
| +  dictionary->SetDouble(kColorTemperatureKey, | 
| +                        static_cast<double>(color_temperature_)); | 
| +} | 
| + | 
| +void NightLightController::NotifyStatusChanged() { | 
| +  for (auto& observer : observers_) | 
| +    observer.OnNightLightEnabledChanged(enabled_); | 
| +} | 
| + | 
| +}  // namespace ash | 
|  |