// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "ash/public/cpp/login_screen_test_api.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/ash/child_accounts/screen_time_controller.h"
#include "chrome/browser/ash/child_accounts/screen_time_controller_factory.h"
#include "chrome/browser/ash/child_accounts/time_limit_override.h"
#include "chrome/browser/ash/child_accounts/time_limit_test_utils.h"
#include "chrome/browser/ash/login/lock/screen_locker.h"
#include "chrome/browser/ash/login/lock/screen_locker_tester.h"
#include "chrome/browser/ash/login/test/logged_in_user_mixin.h"
#include "chrome/browser/ash/policy/core/user_policy_test_helper.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/mixin_based_in_process_browser_test.h"
#include "components/prefs/pref_service.h"
#include "components/session_manager/core/session_manager.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash {
namespace {
// Time delta representing the usage time limit warning time.
constexpr base::TimeDelta kUsageTimeLimitWarningTime = base::Minutes(15);
class TestScreenTimeControllerObserver : public ScreenTimeController::Observer {
public:
TestScreenTimeControllerObserver() = default;
TestScreenTimeControllerObserver(const TestScreenTimeControllerObserver&) =
delete;
TestScreenTimeControllerObserver& operator=(
const TestScreenTimeControllerObserver&) = delete;
~TestScreenTimeControllerObserver() override = default;
int usage_time_limit_warnings() const { return usage_time_limit_warnings_; }
private:
void UsageTimeLimitWarning() override { usage_time_limit_warnings_++; }
int usage_time_limit_warnings_ = 0;
};
} // namespace
namespace utils = time_limit_test_utils;
class ScreenTimeControllerTest : public MixinBasedInProcessBrowserTest {
public:
ScreenTimeControllerTest() = default;
ScreenTimeControllerTest(const ScreenTimeControllerTest&) = delete;
ScreenTimeControllerTest& operator=(const ScreenTimeControllerTest&) = delete;
~ScreenTimeControllerTest() override = default;
// MixinBasedInProcessBrowserTest:
void SetUpInProcessBrowserTestFixture() override {
MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
// A basic starting policy.
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
logged_in_user_mixin_.GetUserPolicyMixin()
->RequestPolicyUpdate()
->policy_payload()
->mutable_usagetimelimit()
->set_value(utils::PolicyToString(policy_content));
}
protected:
void LogInChildAndSetupClockWithTime(const char* time) {
SetupTaskRunnerWithTime(utils::TimeFromString(time));
logged_in_user_mixin_.LogInUser();
MockClockForActiveUser();
}
void SetupTaskRunnerWithTime(base::Time start_time) {
task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
start_time, base::TimeTicks::UnixEpoch());
}
void MockClockForActiveUser() {
const user_manager::UserManager* const user_manager =
user_manager::UserManager::Get();
EXPECT_EQ(user_manager->GetActiveUser()->GetType(),
user_manager::UserType::kChild);
child_profile_ =
ProfileHelper::Get()->GetProfileByUser(user_manager->GetActiveUser());
// Mock time for ScreenTimeController.
ScreenTimeControllerFactory::GetForBrowserContext(child_profile_)
->SetClocksForTesting(task_runner_->GetMockClock(),
task_runner_->GetMockTickClock(), task_runner_);
}
bool IsAuthEnabled() {
return !ScreenLocker::default_screen_locker()
->IsAuthTemporarilyDisabledForUser(
logged_in_user_mixin_.GetAccountId());
}
const AccountId& GetAccountId() {
return logged_in_user_mixin_.GetAccountId();
}
void MockChildScreenTime(base::TimeDelta used_time) {
child_profile_->GetPrefs()->SetInteger(prefs::kChildScreenTimeMilliseconds,
used_time.InMilliseconds());
}
bool IsLocked() {
base::RunLoop().RunUntilIdle();
return session_manager::SessionManager::Get()->IsScreenLocked();
}
void SetUsageTimeLimitPolicy(const base::Value::Dict& policy_content) {
logged_in_user_mixin_.GetUserPolicyMixin()
->RequestPolicyUpdate()
->policy_payload()
->mutable_usagetimelimit()
->set_value(utils::PolicyToString(policy_content));
logged_in_user_mixin_.GetUserPolicyTestHelper()->RefreshPolicyAndWait(
child_profile_);
}
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
raw_ptr<Profile, DanglingUntriaged> child_profile_ = nullptr;
private:
LoggedInUserMixin logged_in_user_mixin_{
&mixin_host_, /*test_base=*/this, embedded_test_server(),
LoggedInUserMixin::LogInType::kChild, /*include_initial_user=*/false};
};
// Tests a simple lock override.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, LockOverride) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 GMT");
ScreenLockerTester().Lock();
// Verify user is able to log in.
EXPECT_TRUE(IsAuthEnabled());
// Wait one hour.
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsAuthEnabled());
// Set new policy.
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddOverride(&policy_content,
usage_time_limit::TimeLimitOverride::Action::kLock,
task_runner_->Now());
SetUsageTimeLimitPolicy(policy_content);
EXPECT_FALSE(IsAuthEnabled());
}
// Tests an unlock override on a bedtime.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, UnlockBedtime) {
LogInChildAndSetupClockWithTime("5 Jan 2018 22:00:00 BRT");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"BRT");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 BRT");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kFriday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kSaturday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Check that auth is disabled, since the bedtime has already started.
EXPECT_FALSE(IsAuthEnabled());
// Create unlock override and update the policy.
utils::AddOverride(&policy_content,
usage_time_limit::TimeLimitOverride::Action::kUnlock,
task_runner_->Now());
SetUsageTimeLimitPolicy(policy_content);
// Check that the unlock worked and auth is enabled.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 6 AM and check that auth is still enabled.
task_runner_->FastForwardBy(base::Hours(8));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 9 PM and check that auth is disabled because bedtime started.
task_runner_->FastForwardBy(base::Hours(15));
EXPECT_FALSE(IsAuthEnabled());
}
// Tests an override with duration on a bedtime before it's locked.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, OverrideBedtimeWithDuration) {
LogInChildAndSetupClockWithTime("5 Jan 2018 20:45:00 PST");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"PST");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 PST");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kFriday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kSaturday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Check that auth is enable, since the bedtime hasn't started.
EXPECT_TRUE(IsAuthEnabled());
// Create unlock override with a duration of 2 hours and update the policy.
utils::AddOverrideWithDuration(
&policy_content, usage_time_limit::TimeLimitOverride::Action::kUnlock,
task_runner_->Now(), base::Hours(2));
SetUsageTimeLimitPolicy(policy_content);
// Check that the unlock worked and auth is enabled.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 10:15 PM and check that auth is still enabled.
task_runner_->FastForwardBy(base::Minutes(90));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 10:45 PM and check that auth is disabled because the duration is
// over.
task_runner_->FastForwardBy(base::Minutes(30));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 11 PM and check that auth is still disabled.
task_runner_->FastForwardBy(base::Minutes(15));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 6 AM and check that auth is still disabled.
task_runner_->FastForwardBy(base::Hours(7));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 7 AM and check that auth is enable because bedtime is finished.
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 9 PM and check that auth is disabled because bedtime started.
task_runner_->FastForwardBy(base::Hours(14));
EXPECT_FALSE(IsAuthEnabled());
}
// Tests an override with duration on a daily limit before it's locked.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest,
OverrideDailyLimitWithDuration) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 BRT");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"BRT");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 BRT");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeUsageLimit(&policy_content, utils::kMonday, base::Hours(2),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Check that auth is enabled at 10 AM with 0 usage time.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 12 PM with 1:50 hours of usage time.
MockChildScreenTime(base::Minutes(110));
task_runner_->FastForwardBy(base::Hours(2));
EXPECT_TRUE(IsAuthEnabled());
// Create unlock override with a duration of 1 hour and update the policy.
utils::AddOverrideWithDuration(
&policy_content, usage_time_limit::TimeLimitOverride::Action::kUnlock,
task_runner_->Now(), base::Hours(1));
SetUsageTimeLimitPolicy(policy_content);
// Check that the unlock worked and auth is enabled.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 12:30 PM with 2:20 hours of usage time and check that auth is
// still enabled.
MockChildScreenTime(base::Minutes(140));
task_runner_->FastForwardBy(base::Minutes(30));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 1 PM and check that auth is disabled because the duration is
// over.
task_runner_->FastForwardBy(base::Minutes(30));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 5 AM and check that auth is still disabled.
task_runner_->FastForwardBy(base::Hours(16));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 6 AM and check that auth is enabled.
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsAuthEnabled());
}
// Tests an unlock override with duration on a bedtime.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, UnlockBedtimeWithDuration) {
LogInChildAndSetupClockWithTime("5 Jan 2018 22:00:00 GMT");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 GMT");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kFriday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kSaturday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Check that auth is disabled, since the bedtime has already started.
EXPECT_FALSE(IsAuthEnabled());
// Create unlock override with a duration of 2 hours and update the policy.
utils::AddOverrideWithDuration(
&policy_content, usage_time_limit::TimeLimitOverride::Action::kUnlock,
task_runner_->Now(), base::Hours(2));
SetUsageTimeLimitPolicy(policy_content);
// Check that the unlock worked and auth is enabled.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 11:30 PM and check that auth is still enabled.
task_runner_->FastForwardBy(base::Minutes(90));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 12 AM and check that auth is disabled because the duration is
// over.
task_runner_->FastForwardBy(base::Minutes(30));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 6 AM and check that auth is still disabled because bedtime ends
// at 7 AM.
task_runner_->FastForwardBy(base::Hours(6));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 7 AM and check that auth is enable because bedtime is finished.
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 9 PM and check that auth is disabled because bedtime started.
task_runner_->FastForwardBy(base::Hours(14));
EXPECT_FALSE(IsAuthEnabled());
}
// Tests an unlock override with duration on a daily limit.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, UnlockDailyLimitWithDuration) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 PST");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"PST");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 PST");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeUsageLimit(&policy_content, utils::kMonday, base::Hours(2),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Check that auth is enabled at 10 AM with 0 usage time.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 12 PM with 2 hours of usage time and check if auth is disabled.
MockChildScreenTime(base::Hours(2));
task_runner_->FastForwardBy(base::Hours(2));
EXPECT_FALSE(IsAuthEnabled());
// Create unlock override with a duration of 1 hour and update the policy.
utils::AddOverrideWithDuration(
&policy_content, usage_time_limit::TimeLimitOverride::Action::kUnlock,
task_runner_->Now(), base::Hours(1));
SetUsageTimeLimitPolicy(policy_content);
// Check that the unlock worked and auth is enabled.
EXPECT_TRUE(IsAuthEnabled());
// Forward to 12:30 PM with 2:30 hours of usage time and check that auth is
// still enabled.
MockChildScreenTime(base::Minutes(150));
task_runner_->FastForwardBy(base::Minutes(30));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 1 PM and check that auth is disabled because the duration is
// over.
task_runner_->FastForwardBy(base::Minutes(30));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 5 AM and check that auth is still disabled.
task_runner_->FastForwardBy(base::Hours(16));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 6 AM and check that auth is enabled.
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsAuthEnabled());
}
// Tests the default time window limit.
// TODO(crbug.com/1358216): Flaky on Linux
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_DefaultBedtime DISABLED_DefaultBedtime
#else
#define MAYBE_DefaultBedtime DefaultBedtime
#endif
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, MAYBE_DefaultBedtime) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 GMT");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 GMT");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kMonday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kTuesday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kWednesday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kThursday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kFriday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kSaturday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
utils::AddTimeWindowLimit(&policy_content, utils::kSunday,
utils::CreateTime(21, 0), utils::CreateTime(7, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Iterate over a week checking that the device is locked properly everyday.
for (int i = 0; i < 7; i++) {
// Verify that auth is enabled at 10 AM.
EXPECT_TRUE(IsAuthEnabled());
// Verify that auth is enabled at 8 PM.
task_runner_->FastForwardBy(base::Hours(10));
EXPECT_TRUE(IsAuthEnabled());
// Verify that the auth was disabled at 9 PM (start of bedtime).
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 7 AM and check that auth was re-enabled (end of bedtime).
task_runner_->FastForwardBy(base::Hours(10));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 10 AM.
task_runner_->FastForwardBy(base::Hours(3));
}
}
// Tests the default time window limit.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, DefaultDailyLimit) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 GMT");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 GMT");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeUsageLimit(&policy_content, utils::kMonday, base::Hours(3),
last_updated);
utils::AddTimeUsageLimit(&policy_content, utils::kTuesday, base::Hours(3),
last_updated);
utils::AddTimeUsageLimit(&policy_content, utils::kWednesday, base::Hours(3),
last_updated);
utils::AddTimeUsageLimit(&policy_content, utils::kThursday, base::Hours(3),
last_updated);
utils::AddTimeUsageLimit(&policy_content, utils::kFriday, base::Hours(3),
last_updated);
utils::AddTimeUsageLimit(&policy_content, utils::kSaturday, base::Hours(3),
last_updated);
utils::AddTimeUsageLimit(&policy_content, utils::kSunday, base::Hours(3),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Iterate over a week checking that the device is locked properly
// every day.
for (int i = 0; i < 7; i++) {
// Check that auth is enabled at 10 AM with 0 usage time.
EXPECT_TRUE(IsAuthEnabled());
// Check that auth is enabled after forwarding to 1 PM and using the device
// for 2 hours.
MockChildScreenTime(base::Hours(2));
task_runner_->FastForwardBy(base::Hours(3));
EXPECT_TRUE(IsAuthEnabled());
// Check that auth is enabled after forwarding to 2 PM with no extra usage.
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsAuthEnabled());
// Check that auth is disabled after forwarding to 3 PM and using the device
// for 3 hours.
MockChildScreenTime(base::Hours(3));
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_FALSE(IsAuthEnabled());
// Forward to 6 AM, reset the usage time and check that auth was re-enabled.
MockChildScreenTime(base::Hours(0));
task_runner_->FastForwardBy(base::Hours(15));
EXPECT_TRUE(IsAuthEnabled());
// Forward to 10 AM.
task_runner_->FastForwardBy(base::Hours(4));
}
}
// Tests that the bedtime locks an active session when it is reached.
// TODO(crbug.com/334319436): Flaky test.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest,
DISABLED_ActiveSessionBedtime) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 PST");
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"PST");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 PST");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kMonday,
utils::CreateTime(23, 0), utils::CreateTime(8, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Verify that device is unlocked at 10 AM.
EXPECT_FALSE(IsLocked());
// Verify that device is still unlocked at 10 PM.
task_runner_->FastForwardBy(base::Hours(12));
EXPECT_FALSE(IsLocked());
// Verify that device is locked at 11 PM (start of bedtime).
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsLocked());
// Forward to 8 AM and check that auth was re-enabled (end of bedtime).
task_runner_->FastForwardBy(base::Hours(9));
EXPECT_TRUE(IsAuthEnabled());
}
// Tests that the daily limit locks the device when it is reached.
// TODO(crbug.com/334304756): Flaky on CrOS.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest,
DISABLED_ActiveSessionDailyLimit) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 PST");
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"PST");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 PST");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeUsageLimit(&policy_content, utils::kMonday, base::Hours(1),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Verify that device is unlocked at 10 AM.
EXPECT_FALSE(IsLocked());
// Forward 1 hour to 11 AM and add 1 hour of usage and verify that device is
// locked (start of daily limit).
MockChildScreenTime(base::Hours(1));
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_TRUE(IsLocked());
// Forward to 6 AM, reset the usage time and check that auth was re-enabled.
MockChildScreenTime(base::Hours(0));
task_runner_->FastForwardBy(base::Hours(19));
EXPECT_TRUE(IsAuthEnabled());
}
// Tests bedtime during timezone changes.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, BedtimeOnTimezoneChange) {
LogInChildAndSetupClockWithTime("3 Jan 2018 10:00:00 GMT-0600");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT-0600");
// Set new policy.
base::Time last_updated = utils::TimeFromString("3 Jan 2018 0:00 GMT-0600");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kWednesday,
utils::CreateTime(19, 0), utils::CreateTime(7, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Verify that auth is enabled at 10 AM.
EXPECT_TRUE(IsAuthEnabled());
// Verify that auth is enabled at 6 PM.
task_runner_->FastForwardBy(base::Hours(8));
EXPECT_TRUE(IsAuthEnabled());
// Verify that the auth is disabled at 7 PM (start of bedtime).
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_FALSE(IsAuthEnabled());
// Change timezone, so that local time goes back to 6 PM and check that auth
// is enabled since bedtime has not started yet.
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT-0700");
EXPECT_TRUE(IsAuthEnabled());
// Verify that auth is disabled at 7 PM (start of bedtime).
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_FALSE(IsAuthEnabled());
// Change timezone, so that local time goes forward to 7 AM and check that
// auth is enabled since bedtime has ended in the new local time.
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT+0500");
EXPECT_TRUE(IsAuthEnabled());
}
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, BedtimeLockScreen24HourClock) {
LogInChildAndSetupClockWithTime("1 Jan 2018 22:00:00 GMT");
// Set preference of using 24 hour clock to be true.
child_profile_->GetPrefs()->SetBoolean(prefs::kUse24HourClock, true);
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT");
// Set new policy.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 GMT");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kMonday,
utils::CreateTime(21, 0), utils::CreateTime(17, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Check that auth is disabled, since the bedtime has already started.
EXPECT_FALSE(IsAuthEnabled());
EXPECT_EQ(u"Come back at 17:00.",
LoginScreenTestApi::GetDisabledAuthMessage(GetAccountId()));
}
// Tests bedtime during timezone changes that make the clock go back in time.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest,
BedtimeOnEastToWestTimezoneChanges) {
LogInChildAndSetupClockWithTime("3 Jan 2018 8:00:00 GMT+1300");
ScreenLockerTester().Lock();
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT+1300");
// Set new policy.
base::Time last_updated = utils::TimeFromString("3 Jan 2018 0:00 GMT+1300");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeWindowLimit(&policy_content, utils::kTuesday,
utils::CreateTime(20, 0), utils::CreateTime(7, 0),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
// Verify that auth is disabled at 8 AM.
EXPECT_TRUE(IsAuthEnabled());
// Change timezone so that local time goes back to 6 AM and check that auth is
// disable, since the tuesday's bedtime is not over yet.
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT+1100");
EXPECT_FALSE(IsAuthEnabled());
// Change timezone so that local time goes back to 7 PM on Tuesday and check
// that auth is enabled, because the bedtime has not started yet in the
// new local time.
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"GMT");
EXPECT_TRUE(IsAuthEnabled());
// Verify that auth is disabled at 8 PM (start of bedtime).
task_runner_->FastForwardBy(base::Hours(1));
EXPECT_FALSE(IsAuthEnabled());
}
// Tests if call the observers for usage time limit warning.
// TODO(crbug.com/334160972): Flaky on CrOS.
IN_PROC_BROWSER_TEST_F(ScreenTimeControllerTest, DISABLED_CallObservers) {
LogInChildAndSetupClockWithTime("1 Jan 2018 10:00:00 PST");
system::TimezoneSettings::GetInstance()->SetTimezoneFromID(u"PST");
// Set new policy with 3 hours of time usage limit.
base::Time last_updated = utils::TimeFromString("1 Jan 2018 0:00 PST");
base::Value::Dict policy_content =
utils::CreateTimeLimitPolicy(utils::CreateTime(6, 0));
utils::AddTimeUsageLimit(&policy_content, utils::kMonday, base::Hours(3),
last_updated);
SetUsageTimeLimitPolicy(policy_content);
TestScreenTimeControllerObserver observer;
ScreenTimeControllerFactory::GetForBrowserContext(child_profile_)
->AddObserver(&observer);
base::TimeDelta current_screen_time;
base::TimeDelta last_screen_time;
// Check that observer was not called at 10 AM.
EXPECT_EQ(0, observer.usage_time_limit_warnings());
// Check that observer was not called after child used device for 2 hours and
// forward to 12 AM.
last_screen_time = base::TimeDelta();
current_screen_time = base::Hours(2);
MockChildScreenTime(current_screen_time);
task_runner_->FastForwardBy(current_screen_time - last_screen_time);
EXPECT_EQ(0, observer.usage_time_limit_warnings());
// Check that observer was not called after using the device for
// 3 hours - |kUsageTimeLimitWarningTime| - 1 second. Forward to
// 1 PM - |kUsageTimeLimitWarningTime| - 1 second.
last_screen_time = current_screen_time;
current_screen_time =
base::Hours(3) - kUsageTimeLimitWarningTime - base::Seconds(1);
MockChildScreenTime(current_screen_time);
task_runner_->FastForwardBy(current_screen_time - last_screen_time);
EXPECT_EQ(0, observer.usage_time_limit_warnings());
// Check that observer was called after using the device for
// 3 hours - |kUsageTimeLimitWarningTime| + 1 second. Forward to
// 1 PM - |kUsageTimeLimitWarningTime| + 1 second.
last_screen_time = current_screen_time;
current_screen_time =
base::Hours(3) - kUsageTimeLimitWarningTime + base::Seconds(1);
MockChildScreenTime(current_screen_time);
task_runner_->FastForwardBy(current_screen_time - last_screen_time);
EXPECT_EQ(1, observer.usage_time_limit_warnings());
// Check that observer was not called after using the device for 3 hours.
// Forward to 1 PM.
last_screen_time = current_screen_time;
current_screen_time = base::Hours(3);
MockChildScreenTime(current_screen_time);
task_runner_->FastForwardBy(current_screen_time - last_screen_time);
EXPECT_EQ(1, observer.usage_time_limit_warnings());
// Forward to 6 AM, reset the usage time.
MockChildScreenTime(base::Hours(0));
task_runner_->FastForwardBy(base::Hours(17));
// Forward to 10 AM.
task_runner_->FastForwardBy(base::Hours(4));
EXPECT_EQ(1, observer.usage_time_limit_warnings());
ScreenTimeControllerFactory::GetForBrowserContext(child_profile_)
->RemoveObserver(&observer);
}
} // namespace ash