Commit a586c9e3 authored by yilkal's avatar yilkal Committed by Commit Bot

Ensure time limit is reset at the specified time in PATL policy.

This Cl ensures that time limit is reset at the specified time in
PATL policy. When the computer wakes up it decides to reset time
limit based on the last reset time. If reset time boundary
has been crossed because either time has moved forward or backward,
chromeos resets the time and saves the current time as the last
reset time which will result in wrong reset times in the future.

The following is an example scenario where the reset time is 6 am.
1. User opens computer at 1 pm on day 1. There was no reset time before
so the computer saves 1 pm day 1 as the last reset time.
2. Computer schedules the next reset time to be on 6 am on day 2.
3. After a few hours of activity, the computer is closed before reaching
the correctly scheduled limit.
4. User opens computer at 9 am on day 2.
   User observes ERROR:
   	-> EXPECTED: time limits are reset because the reset time
		     has been crossed.
	-> ACTUAL: time limits are not reset until after 1 pm on day 2.

This cl corrects the issue seen in step 4.

Bug: 1069932
Change-Id: I9cd4ad4c887e2067292612cf1d32c9dd43bafa6a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2149289
Commit-Queue: Yilkal Abe <yilkal@chromium.org>
Reviewed-by: default avatarAga Wronska <agawronska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759427}
parent e25d77f7
...@@ -518,12 +518,26 @@ void AppTimeController::RestoreLastResetTime() { ...@@ -518,12 +518,26 @@ void AppTimeController::RestoreLastResetTime() {
} }
void AppTimeController::SetLastResetTime(base::Time timestamp) { void AppTimeController::SetLastResetTime(base::Time timestamp) {
last_limits_reset_time_ = timestamp; // |timestamp| needs to be adjusted to ensure that it is happening at the time
// specified by policy.
const base::Time nearest_midnight = timestamp.LocalMidnight();
base::Time prev_midnight;
if (timestamp > nearest_midnight)
prev_midnight = nearest_midnight;
else
prev_midnight = nearest_midnight - base::TimeDelta::FromHours(24);
base::Time reset_time = prev_midnight + limits_reset_time_;
if (reset_time <= timestamp)
last_limits_reset_time_ = reset_time;
else
last_limits_reset_time_ = reset_time - base::TimeDelta::FromHours(24);
PrefService* service = profile_->GetPrefs(); PrefService* service = profile_->GetPrefs();
DCHECK(service); DCHECK(service);
service->SetInt64(prefs::kPerAppTimeLimitsLastResetTime, service->SetInt64(
timestamp.ToDeltaSinceWindowsEpoch().InMicroseconds()); prefs::kPerAppTimeLimitsLastResetTime,
last_limits_reset_time_.ToDeltaSinceWindowsEpoch().InMicroseconds());
service->CommitPendingWrite(); service->CommitPendingWrite();
} }
......
...@@ -47,6 +47,23 @@ constexpr char kApp2Name[] = "App2"; ...@@ -47,6 +47,23 @@ constexpr char kApp2Name[] = "App2";
const AppId kApp1(apps::mojom::AppType::kArc, "1"); const AppId kApp1(apps::mojom::AppType::kArc, "1");
const AppId kApp2(apps::mojom::AppType::kArc, "2"); const AppId kApp2(apps::mojom::AppType::kArc, "2");
// Calculate the previous reset time.
base::Time GetLastResetTime(base::Time timestamp) {
base::Time nearest_midnight = timestamp.LocalMidnight();
base::Time prev_midnight;
if (timestamp > nearest_midnight)
prev_midnight = nearest_midnight;
else
prev_midnight = nearest_midnight - base::TimeDelta::FromHours(24);
// Reset time is at 6 am for the tests.
base::Time reset_time = prev_midnight + base::TimeDelta::FromHours(6);
if (reset_time <= timestamp)
return reset_time;
else
return reset_time - base::TimeDelta::FromHours(24);
}
} // namespace } // namespace
class AppTimeControllerTest : public testing::Test { class AppTimeControllerTest : public testing::Test {
...@@ -407,8 +424,9 @@ TEST_F(AppTimeControllerTest, RestoreLastResetTime) { ...@@ -407,8 +424,9 @@ TEST_F(AppTimeControllerTest, RestoreLastResetTime) {
} }
// If there was no valid last reset time stored in user pref, // If there was no valid last reset time stored in user pref,
// AppTimeController sets it to base::Time::Now(). // AppTimeController sets it to the expected last reset time based on
base::Time last_reset_time = base::Time::Now(); // base::Time::Now().
base::Time last_reset_time = GetLastResetTime(base::Time::Now());
EXPECT_EQ(test_api()->GetLastResetTime(), last_reset_time); EXPECT_EQ(test_api()->GetLastResetTime(), last_reset_time);
controller()->app_registry()->OnAppActive(kApp1, nullptr, last_reset_time); controller()->app_registry()->OnAppActive(kApp1, nullptr, last_reset_time);
...@@ -454,7 +472,8 @@ TEST_F(AppTimeControllerTest, RestoreLastResetTime) { ...@@ -454,7 +472,8 @@ TEST_F(AppTimeControllerTest, RestoreLastResetTime) {
// AppTimeController will realize that the reset boundary has been crossed. // AppTimeController will realize that the reset boundary has been crossed.
// Therefore, it will trigger reset and update the last reset time to now. // Therefore, it will trigger reset and update the last reset time to now.
EXPECT_EQ(test_api()->GetLastResetTime(), base::Time::Now()); EXPECT_EQ(test_api()->GetLastResetTime(),
GetLastResetTime(base::Time::Now()));
EXPECT_EQ(controller()->app_registry()->GetAppState(kApp1), EXPECT_EQ(controller()->app_registry()->GetAppState(kApp1),
AppState::kAvailable); AppState::kAvailable);
...@@ -518,5 +537,32 @@ TEST_F(AppTimeControllerTest, MetricsTest) { ...@@ -518,5 +537,32 @@ TEST_F(AppTimeControllerTest, MetricsTest) {
histogram_tester.ExpectBucketCount(kPolicyUpdateCountMetric, 0, 1); histogram_tester.ExpectBucketCount(kPolicyUpdateCountMetric, 0, 1);
} }
TEST_F(AppTimeControllerTest, SetLastResetTimeTest) {
base::Time now = base::Time::Now();
base::Time nearest_midnight = now.LocalMidnight();
base::Time prev_midnight;
if (now > nearest_midnight)
prev_midnight = nearest_midnight;
else
prev_midnight = nearest_midnight - kDay;
base::Time reset_time = prev_midnight + kSixHours;
test_api()->SetLastResetTime(prev_midnight);
EXPECT_EQ(test_api()->GetLastResetTime(), reset_time - kDay);
test_api()->SetLastResetTime(prev_midnight + 3 * kOneHour);
EXPECT_EQ(test_api()->GetLastResetTime(), reset_time - kDay);
test_api()->SetLastResetTime(prev_midnight + kSixHours);
EXPECT_EQ(test_api()->GetLastResetTime(), reset_time);
test_api()->SetLastResetTime(prev_midnight + 2 * kSixHours);
EXPECT_EQ(test_api()->GetLastResetTime(), reset_time);
test_api()->SetLastResetTime(prev_midnight + kDay);
EXPECT_EQ(test_api()->GetLastResetTime(), reset_time);
}
} // namespace app_time } // namespace app_time
} // namespace chromeos } // namespace chromeos
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