Commit 0a13ec57 authored by Jacob Dufault's avatar Jacob Dufault Committed by Commit Bot

cros: Fix lock screen not unlocking after bedtime

SaveScreenTimeProgressBeforeExit gets called after the lock screen was shown,
which cancelled all running timers, including those that updated the lock screen
state. If some other event fired, ie, timezone change, then the timers would get
rescheduled.

As a fix, don't cancel the timers which update lock screen state; only cancel
in-session timers for the notification and recording actively used screen time.

Bug: 872689
Change-Id: Ibbead3c2e455866fc09ced036c5c78a81e05357b
Reviewed-on: https://chromium-review.googlesource.com/1171811Reviewed-by: default avatarXiaoyin Hu <xiaoyinh@chromium.org>
Reviewed-by: default avatarRahul Chaturvedi <rkc@chromium.org>
Commit-Queue: Jacob Dufault <jdufault@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582627}
parent f278b1ab
...@@ -91,9 +91,12 @@ base::TimeDelta ScreenTimeController::GetScreenTimeDuration() const { ...@@ -91,9 +91,12 @@ base::TimeDelta ScreenTimeController::GetScreenTimeDuration() const {
return current_screen_duration + previous_duration; return current_screen_duration + previous_duration;
} }
void ScreenTimeController::CheckTimeLimit() { void ScreenTimeController::CheckTimeLimit(const std::string& source) {
// Stop any currently running timer. VLOG(1) << "Checking time limits (source=" << source << ")";
ResetTimers();
// Stop all timers. They will be rescheduled below.
ResetStateTimers();
ResetInSessionTimers();
base::Time now = base::Time::Now(); base::Time now = base::Time::Now();
const icu::TimeZone& time_zone = const icu::TimeZone& time_zone =
...@@ -162,10 +165,12 @@ void ScreenTimeController::CheckTimeLimit() { ...@@ -162,10 +165,12 @@ void ScreenTimeController::CheckTimeLimit() {
} }
if (!state.next_state_change_time.is_null()) { if (!state.next_state_change_time.is_null()) {
VLOG(1) << "Scheduling state change timer in "
<< state.next_state_change_time - now;
next_state_timer_.Start( next_state_timer_.Start(
FROM_HERE, state.next_state_change_time - base::Time::Now(), FROM_HERE, state.next_state_change_time - now,
base::BindRepeating(&ScreenTimeController::CheckTimeLimit, base::BindRepeating(&ScreenTimeController::CheckTimeLimit,
base::Unretained(this))); base::Unretained(this), "next_state_timer_"));
} }
// Schedule timer to refresh the screen time usage. // Schedule timer to refresh the screen time usage.
...@@ -174,6 +179,7 @@ void ScreenTimeController::CheckTimeLimit() { ...@@ -174,6 +179,7 @@ void ScreenTimeController::CheckTimeLimit() {
if (reset_time <= now) { if (reset_time <= now) {
RefreshScreenLimit(); RefreshScreenLimit();
} else { } else {
VLOG(1) << "Scheduling screen reset timer in " << reset_time - now;
reset_screen_time_timer_.Start( reset_screen_time_timer_.Start(
FROM_HERE, reset_time - now, FROM_HERE, reset_time - now,
base::BindRepeating(&ScreenTimeController::RefreshScreenLimit, base::BindRepeating(&ScreenTimeController::RefreshScreenLimit,
...@@ -246,24 +252,30 @@ void ScreenTimeController::RefreshScreenLimit() { ...@@ -246,24 +252,30 @@ void ScreenTimeController::RefreshScreenLimit() {
} }
void ScreenTimeController::OnPolicyChanged() { void ScreenTimeController::OnPolicyChanged() {
CheckTimeLimit(); CheckTimeLimit("OnPolicyChanged");
} }
void ScreenTimeController::ResetTimers() { void ScreenTimeController::ResetStateTimers() {
VLOG(1) << "Stopping state timers";
next_state_timer_.Stop(); next_state_timer_.Stop();
reset_screen_time_timer_.Stop();
}
void ScreenTimeController::ResetInSessionTimers() {
VLOG(1) << "Stopping in-session timers";
warning_notification_timer_.Stop(); warning_notification_timer_.Stop();
exit_notification_timer_.Stop(); exit_notification_timer_.Stop();
save_screen_time_timer_.Stop(); save_screen_time_timer_.Stop();
reset_screen_time_timer_.Stop();
} }
void ScreenTimeController::SaveScreenTimeProgressBeforeExit() { void ScreenTimeController::SaveScreenTimeProgressBeforeExit() {
VLOG(1) << "Saving screen time progress before exiting";
pref_service_->SetInteger(prefs::kScreenTimeMinutesUsed, pref_service_->SetInteger(prefs::kScreenTimeMinutesUsed,
GetScreenTimeDuration().InMinutes()); GetScreenTimeDuration().InMinutes());
pref_service_->ClearPref(prefs::kCurrentScreenStartTime); pref_service_->ClearPref(prefs::kCurrentScreenStartTime);
pref_service_->CommitPendingWrite(); pref_service_->CommitPendingWrite();
current_screen_start_time_ = base::Time(); current_screen_start_time_ = base::Time();
ResetTimers(); ResetInSessionTimers();
} }
void ScreenTimeController::SaveScreenTimeProgressPeriodically() { void ScreenTimeController::SaveScreenTimeProgressPeriodically() {
...@@ -428,7 +440,7 @@ void ScreenTimeController::OnSessionStateChanged() { ...@@ -428,7 +440,7 @@ void ScreenTimeController::OnSessionStateChanged() {
pref_service_->SetTime(prefs::kCurrentScreenStartTime, pref_service_->SetTime(prefs::kCurrentScreenStartTime,
current_screen_start_time_); current_screen_start_time_);
pref_service_->CommitPendingWrite(); pref_service_->CommitPendingWrite();
CheckTimeLimit(); CheckTimeLimit("OnSessionStateChanged");
save_screen_time_timer_.Start( save_screen_time_timer_.Start(
FROM_HERE, kScreenTimeUsageUpdateFrequency, FROM_HERE, kScreenTimeUsageUpdateFrequency,
...@@ -439,7 +451,7 @@ void ScreenTimeController::OnSessionStateChanged() { ...@@ -439,7 +451,7 @@ void ScreenTimeController::OnSessionStateChanged() {
} }
void ScreenTimeController::TimezoneChanged(const icu::TimeZone& timezone) { void ScreenTimeController::TimezoneChanged(const icu::TimeZone& timezone) {
CheckTimeLimit(); CheckTimeLimit("TimezoneChanged");
} }
} // namespace chromeos } // namespace chromeos
...@@ -39,15 +39,15 @@ class ScreenTimeController : public KeyedService, ...@@ -39,15 +39,15 @@ class ScreenTimeController : public KeyedService,
// kScreenTimeMinutesUsed plus time passed since |current_screen_start_time_|. // kScreenTimeMinutesUsed plus time passed since |current_screen_start_time_|.
base::TimeDelta GetScreenTimeDuration() const; base::TimeDelta GetScreenTimeDuration() const;
// Call time limit processor for new state.
void CheckTimeLimit();
private: private:
// The types of time limit notifications. |SCREEN_TIME| is used when the // The types of time limit notifications. |SCREEN_TIME| is used when the
// the screen time limit is about to be used up, and |BED_TIME| is used when // the screen time limit is about to be used up, and |BED_TIME| is used when
// the bed time is approaching. // the bed time is approaching.
enum TimeLimitNotificationType { kScreenTime, kBedTime }; enum TimeLimitNotificationType { kScreenTime, kBedTime };
// Call time limit processor for new state.
void CheckTimeLimit(const std::string& source);
// Request to lock the screen and show the time limits message when the screen // Request to lock the screen and show the time limits message when the screen
// is locked. // is locked.
void ForceScreenLockByPolicy(base::Time next_unlock_time); void ForceScreenLockByPolicy(base::Time next_unlock_time);
...@@ -73,7 +73,8 @@ class ScreenTimeController : public KeyedService, ...@@ -73,7 +73,8 @@ class ScreenTimeController : public KeyedService,
void OnPolicyChanged(); void OnPolicyChanged();
// Reset any currently running timers. // Reset any currently running timers.
void ResetTimers(); void ResetStateTimers();
void ResetInSessionTimers();
// Save the screen time progress when screen is locked, or user sign out or // Save the screen time progress when screen is locked, or user sign out or
// power down the device. // power down the device.
...@@ -98,10 +99,17 @@ class ScreenTimeController : public KeyedService, ...@@ -98,10 +99,17 @@ class ScreenTimeController : public KeyedService,
content::BrowserContext* context_; content::BrowserContext* context_;
PrefService* pref_service_; PrefService* pref_service_;
// Called to show warning and exit notifications.
base::OneShotTimer warning_notification_timer_; base::OneShotTimer warning_notification_timer_;
base::OneShotTimer exit_notification_timer_; base::OneShotTimer exit_notification_timer_;
base::OneShotTimer next_state_timer_;
// Called to record the current amount of time spent in-session.
base::RepeatingTimer save_screen_time_timer_; base::RepeatingTimer save_screen_time_timer_;
// Timers that are called when lock screen state change event happens, ie,
// bedtime is over or the usage limit ends.
base::OneShotTimer next_state_timer_;
base::OneShotTimer reset_screen_time_timer_; base::OneShotTimer reset_screen_time_timer_;
// Timestamp to keep track of the screen start time for the current active // Timestamp to keep track of the screen start time for the current active
......
...@@ -112,8 +112,8 @@ class Override { ...@@ -112,8 +112,8 @@ class Override {
enum class ActivePolicies { enum class ActivePolicies {
kNoActivePolicy, kNoActivePolicy,
kOverride, kOverride,
kFixedLimit, kFixedLimit, // Past bed time (ie, 9pm)
kUsageLimit kUsageLimit // Too much time on screen (ie, 30 minutes per day)
}; };
struct State { struct State {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment