scheduled_feature.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_SYSTEM_SCHEDULED_FEATURE_SCHEDULED_FEATURE_H_
  5. #define ASH_SYSTEM_SCHEDULED_FEATURE_SCHEDULED_FEATURE_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "ash/public/cpp/schedule_enums.h"
  9. #include "ash/public/cpp/session/session_observer.h"
  10. #include "ash/system/geolocation/geolocation_controller.h"
  11. #include "ash/system/time/time_of_day.h"
  12. #include "base/containers/flat_map.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "base/time/clock.h"
  15. #include "base/time/time.h"
  16. #include "base/timer/timer.h"
  17. #include "chromeos/dbus/power/power_manager_client.h"
  18. #include "components/prefs/pref_change_registrar.h"
  19. #include "ui/aura/env_observer.h"
  20. class PrefService;
  21. namespace ash {
  22. // ScheduledFeature represents a feature that can be automatically scheduled to
  23. // be on and off at a specific time. By default, it supports no scheduler and
  24. // auto scheduler (enable during sunset to sunrise). Optionally it may support
  25. // a custom scheduler with a custom start and end time.
  26. class ASH_EXPORT ScheduledFeature
  27. : public GeolocationController::Observer,
  28. public aura::EnvObserver,
  29. public SessionObserver,
  30. public chromeos::PowerManagerClient::Observer {
  31. public:
  32. // `prefs_path_custom_start_time` and `prefs_path_custom_end_time` can be
  33. // empty strings. Supplying only one of the custom time prefs is invalid,
  34. // while supplying both of them enables the custom scheduling support.
  35. ScheduledFeature(const std::string prefs_path_enabled,
  36. const std::string prefs_path_schedule_type,
  37. const std::string prefs_path_custom_start_time,
  38. const std::string prefs_path_custom_end_time);
  39. ScheduledFeature(const ScheduledFeature&) = delete;
  40. ScheduledFeature& operator=(const ScheduledFeature&) = delete;
  41. ~ScheduledFeature() override;
  42. PrefService* active_user_pref_service() const {
  43. return active_user_pref_service_;
  44. }
  45. base::OneShotTimer* timer() { return &timer_; }
  46. bool GetEnabled() const;
  47. ScheduleType GetScheduleType() const;
  48. TimeOfDay GetCustomStartTime() const;
  49. TimeOfDay GetCustomEndTime() const;
  50. // Get whether the current time is after sunset and before sunrise.
  51. bool IsNowWithinSunsetSunrise() const;
  52. // Set the desired ScheduledFeature settings in the current active user
  53. // prefs.
  54. void SetEnabled(bool enabled);
  55. void SetScheduleType(ScheduleType type);
  56. void SetCustomStartTime(TimeOfDay start_time);
  57. void SetCustomEndTime(TimeOfDay end_time);
  58. // SessionObserver:
  59. void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
  60. // GeolocationController::Observer:
  61. void OnGeopositionChanged(bool possible_change_in_timezone) override;
  62. // chromeos::PowerManagerClient::Observer:
  63. void SuspendDone(base::TimeDelta sleep_duration) override;
  64. void SetClockForTesting(base::Clock* clock);
  65. protected:
  66. // Called by `Refresh()` and `RefreshScheduleTimer()` to refresh the feature
  67. // state such as display temperature in Night Light.
  68. virtual void RefreshFeatureState() {}
  69. private:
  70. virtual const char* GetFeatureName() const = 0;
  71. // Gets now time from the `clock_`, used for testing, or `base::Time::Now()`
  72. // if `clock_` does not exist.
  73. base::Time GetNow() const;
  74. // Attempts restoring a previously stored schedule for the current user if
  75. // possible and returns true if so, false otherwise.
  76. bool MaybeRestoreSchedule();
  77. void StartWatchingPrefsChanges();
  78. void InitFromUserPrefs();
  79. // Called when the user pref for the enabled status of ScheduledFeature is
  80. // changed.
  81. void OnEnabledPrefChanged();
  82. // Called when the user pref for the schedule type is changed or initialized.
  83. // During initialization, `keep_manual_toggles_during_schedules` is set to
  84. // true, so the load user pref override any user current toggled setting. For
  85. // more detail about `keep_manual_toggles_during_schedules`, see `Refresh()`.
  86. void OnScheduleTypePrefChanged(bool keep_manual_toggles_during_schedules);
  87. // Called when either of the custom schedule prefs (custom start or end times)
  88. // are changed.
  89. void OnCustomSchedulePrefsChanged();
  90. // Refreshes the state of ScheduledFeature according to the currently set
  91. // parameters. `did_schedule_change` is true when Refresh() is called as a
  92. // result of a change in one of the schedule related prefs, and false
  93. // otherwise.
  94. // If `keep_manual_toggles_during_schedules` is true, refreshing the schedule
  95. // will not override a previous user's decision to toggle the
  96. // ScheduledFeature status while the schedule is being used.
  97. void Refresh(bool did_schedule_change,
  98. bool keep_manual_toggles_during_schedules);
  99. // Given the desired start and end times that determine the time interval
  100. // during which the feature will be ON, depending on the time of "now", it
  101. // refreshes the `timer_` to either schedule the future start or end of
  102. // the feature, as well as update the current status if needed.
  103. // For `did_schedule_change` and `keep_manual_toggles_during_schedules`, see
  104. // Refresh() above.
  105. // This function should never be called if the schedule type is `kNone`.
  106. void RefreshScheduleTimer(base::Time start_time,
  107. base::Time end_time,
  108. bool did_schedule_change,
  109. bool keep_manual_toggles_during_schedules);
  110. // Schedule the upcoming next toggle of the feature status.
  111. void ScheduleNextToggle(base::TimeDelta delay);
  112. // The pref service of the currently active user. Can be null in
  113. // ash_unittests.
  114. PrefService* active_user_pref_service_ = nullptr;
  115. // Tracks the upcoming feature state changes per each user due to automatic
  116. // schedules. This can be used to restore a manually toggled status while the
  117. // schedule is being used. See MaybeRestoreSchedule().
  118. struct ScheduleTargetState {
  119. // The time at which the feature will switch to `target_status` defined
  120. // below.
  121. base::Time target_time;
  122. bool target_status;
  123. };
  124. base::flat_map<PrefService*, ScheduleTargetState>
  125. per_user_schedule_target_state_;
  126. // The timer that schedules the start and end of this feature when the
  127. // schedule type is either kSunsetToSunrise or kCustom.
  128. base::OneShotTimer timer_;
  129. // True only until this feature is initialized from the very first user
  130. // session. After that, it is set to false.
  131. bool is_first_user_init_ = true;
  132. // The registrar used to watch prefs changes in the above
  133. // `active_user_pref_service_` from outside ash.
  134. // NOTE: Prefs are how Chrome communicates changes to the ScheduledFeature
  135. // settings controlled by this class from the WebUI settings.
  136. std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
  137. const std::string prefs_path_enabled_;
  138. const std::string prefs_path_schedule_type_;
  139. const std::string prefs_path_custom_start_time_;
  140. const std::string prefs_path_custom_end_time_;
  141. const std::string prefs_path_latitude_;
  142. const std::string prefs_path_longitude_;
  143. GeolocationController* geolocation_controller_;
  144. // Track if this is `GeolocationController::Observer` to make sure it is not
  145. // added twice if it is already an observer.
  146. bool is_observing_geolocation_ = false;
  147. // Optional Used in tests to override the time of "Now".
  148. base::Clock* clock_ = nullptr; // Not owned.
  149. };
  150. } // namespace ash
  151. #endif // ASH_SYSTEM_SCHEDULED_FEATURE_SCHEDULED_FEATURE_H_