Commit 2f699614 authored by Henrique Grandinetti's avatar Henrique Grandinetti Committed by Commit Bot

Save child screen time in a pref and expose data to screen time controller

By doing data we can guarantee consistency between the data that locks the
device and the data reported.

Bug: 881445
Change-Id: I4451a082f14afb38c4e01fff05aa83df813b96bd
Reviewed-on: https://chromium-review.googlesource.com/1249741
Commit-Queue: Henrique Grandinetti <hgrandinetti@google.com>
Reviewed-by: default avatarRahul Chaturvedi <rkc@chromium.org>
Reviewed-by: default avatarAga Wronska <agawronska@chromium.org>
Reviewed-by: default avatarXiaoyin Hu <xiaoyinh@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595114}
parent 749f9301
...@@ -94,6 +94,12 @@ void ConsumerStatusReportingService::RequestImmediateStatusReport() { ...@@ -94,6 +94,12 @@ void ConsumerStatusReportingService::RequestImmediateStatusReport() {
status_uploader_->ScheduleNextStatusUploadImmediately(); status_uploader_->ScheduleNextStatusUploadImmediately();
} }
base::TimeDelta ConsumerStatusReportingService::GetChildScreenTime() const {
return const_cast<policy::DeviceStatusCollector*>(
status_uploader_->device_status_collector())
->GetActiveChildScreenTime();
}
void ConsumerStatusReportingService::OnTimeLimitsPolicyChanged() { void ConsumerStatusReportingService::OnTimeLimitsPolicyChanged() {
CreateStatusUploaderIfNeeded(user_cloud_policy_manager_->core()->client()); CreateStatusUploaderIfNeeded(user_cloud_policy_manager_->core()->client());
} }
......
...@@ -36,6 +36,9 @@ class ConsumerStatusReportingService : public KeyedService { ...@@ -36,6 +36,9 @@ class ConsumerStatusReportingService : public KeyedService {
~ConsumerStatusReportingService() override; ~ConsumerStatusReportingService() override;
void RequestImmediateStatusReport(); void RequestImmediateStatusReport();
// Get the child's usage time so far today.
base::TimeDelta GetChildScreenTime() const;
private: private:
// Creates new status uploader if parameters changed. // Creates new status uploader if parameters changed.
void CreateStatusUploaderIfNeeded(policy::CloudPolicyClient* client); void CreateStatusUploaderIfNeeded(policy::CloudPolicyClient* client);
......
...@@ -32,8 +32,6 @@ constexpr base::TimeDelta kWarningNotificationTimeout = ...@@ -32,8 +32,6 @@ constexpr base::TimeDelta kWarningNotificationTimeout =
base::TimeDelta::FromMinutes(5); base::TimeDelta::FromMinutes(5);
constexpr base::TimeDelta kExitNotificationTimeout = constexpr base::TimeDelta kExitNotificationTimeout =
base::TimeDelta::FromMinutes(1); base::TimeDelta::FromMinutes(1);
constexpr base::TimeDelta kScreenTimeUsageUpdateFrequency =
base::TimeDelta::FromMinutes(1);
// The notification id. All the time limit notifications share the same id so // The notification id. All the time limit notifications share the same id so
// that a subsequent notification can replace the previous one. // that a subsequent notification can replace the previous one.
...@@ -57,9 +55,6 @@ constexpr char kScreenStateLastStateChanged[] = "last_state_changed"; ...@@ -57,9 +55,6 @@ constexpr char kScreenStateLastStateChanged[] = "last_state_changed";
// static // static
void ScreenTimeController::RegisterProfilePrefs(PrefRegistrySimple* registry) { void ScreenTimeController::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterTimePref(prefs::kCurrentScreenStartTime, base::Time());
registry->RegisterTimePref(prefs::kFirstScreenStartTime, base::Time());
registry->RegisterIntegerPref(prefs::kScreenTimeMinutesUsed, 0);
registry->RegisterDictionaryPref(prefs::kUsageTimeLimit); registry->RegisterDictionaryPref(prefs::kUsageTimeLimit);
registry->RegisterDictionaryPref(prefs::kScreenTimeLastState); registry->RegisterDictionaryPref(prefs::kScreenTimeLastState);
} }
...@@ -79,18 +74,11 @@ ScreenTimeController::ScreenTimeController(content::BrowserContext* context) ...@@ -79,18 +74,11 @@ ScreenTimeController::ScreenTimeController(content::BrowserContext* context)
ScreenTimeController::~ScreenTimeController() { ScreenTimeController::~ScreenTimeController() {
session_manager::SessionManager::Get()->RemoveObserver(this); session_manager::SessionManager::Get()->RemoveObserver(this);
system::TimezoneSettings::GetInstance()->RemoveObserver(this); system::TimezoneSettings::GetInstance()->RemoveObserver(this);
SaveScreenTimeProgressBeforeExit();
} }
base::TimeDelta ScreenTimeController::GetScreenTimeDuration() const { base::TimeDelta ScreenTimeController::GetScreenTimeDuration() {
base::TimeDelta previous_duration = base::TimeDelta::FromMinutes( return ConsumerStatusReportingServiceFactory::GetForBrowserContext(context_)
pref_service_->GetInteger(prefs::kScreenTimeMinutesUsed)); ->GetChildScreenTime();
if (current_screen_start_time_.is_null())
return previous_duration;
base::TimeDelta current_screen_duration =
base::Time::Now() - current_screen_start_time_;
return current_screen_duration + previous_duration;
} }
void ScreenTimeController::CheckTimeLimit(const std::string& source) { void ScreenTimeController::CheckTimeLimit(const std::string& source) {
...@@ -107,27 +95,8 @@ void ScreenTimeController::CheckTimeLimit(const std::string& source) { ...@@ -107,27 +95,8 @@ void ScreenTimeController::CheckTimeLimit(const std::string& source) {
const base::DictionaryValue* time_limit = const base::DictionaryValue* time_limit =
pref_service_->GetDictionary(prefs::kUsageTimeLimit); pref_service_->GetDictionary(prefs::kUsageTimeLimit);
// Refresh the screen time usage when needed.
// |first_screen_start_time_| is retrieved from prefs::kFirstScreenStartTime
// which stores the timestamp of last screen time reset.
base::TimeDelta used_time = GetScreenTimeDuration();
base::Time reset_time = usage_time_limit::GetExpectedResetTime(
time_limit->CreateDeepCopy(), now, &time_zone);
if (reset_time - first_screen_start_time_ >= base::TimeDelta::FromDays(1)) {
VLOG(1) << "Reset screen time now.";
RefreshScreenLimit();
used_time = base::TimeDelta::FromMinutes(0);
} else {
VLOG(1) << "Scheduling screen reset timer in " << reset_time - now;
reset_screen_time_timer_.Start(
FROM_HERE, reset_time - now,
base::BindRepeating(&ScreenTimeController::CheckTimeLimit,
base::Unretained(this),
"reset_screen_time_timer_"));
}
usage_time_limit::State state = usage_time_limit::GetState( usage_time_limit::State state = usage_time_limit::GetState(
time_limit->CreateDeepCopy(), used_time, first_screen_start_time_, now, time_limit->CreateDeepCopy(), GetScreenTimeDuration(), now, now,
&time_zone, last_state); &time_zone, last_state);
SaveCurrentStateToPref(state); SaveCurrentStateToPref(state);
...@@ -180,11 +149,15 @@ void ScreenTimeController::CheckTimeLimit(const std::string& source) { ...@@ -180,11 +149,15 @@ void ScreenTimeController::CheckTimeLimit(const std::string& source) {
} }
} }
if (!state.next_state_change_time.is_null()) { base::Time next_get_state_time =
std::min(state.next_state_change_time,
usage_time_limit::GetExpectedResetTime(
time_limit->CreateDeepCopy(), now, &time_zone));
if (!next_get_state_time.is_null()) {
VLOG(1) << "Scheduling state change timer in " VLOG(1) << "Scheduling state change timer in "
<< state.next_state_change_time - now; << state.next_state_change_time - now;
next_state_timer_.Start( next_state_timer_.Start(
FROM_HERE, state.next_state_change_time - now, FROM_HERE, next_get_state_time - now,
base::BindRepeating(&ScreenTimeController::CheckTimeLimit, base::BindRepeating(&ScreenTimeController::CheckTimeLimit,
base::Unretained(this), "next_state_timer_")); base::Unretained(this), "next_state_timer_"));
} }
...@@ -243,17 +216,6 @@ void ScreenTimeController::ShowNotification( ...@@ -243,17 +216,6 @@ void ScreenTimeController::ShowNotification(
->Display(NotificationHandler::Type::TRANSIENT, *notification); ->Display(NotificationHandler::Type::TRANSIENT, *notification);
} }
void ScreenTimeController::RefreshScreenLimit() {
base::Time now = base::Time::Now();
pref_service_->SetTime(prefs::kFirstScreenStartTime, now);
pref_service_->SetTime(prefs::kCurrentScreenStartTime, now);
pref_service_->SetInteger(prefs::kScreenTimeMinutesUsed, 0);
pref_service_->CommitPendingWrite();
first_screen_start_time_ = now;
current_screen_start_time_ = now;
}
void ScreenTimeController::OnPolicyChanged() { void ScreenTimeController::OnPolicyChanged() {
CheckTimeLimit("OnPolicyChanged"); CheckTimeLimit("OnPolicyChanged");
} }
...@@ -261,33 +223,12 @@ void ScreenTimeController::OnPolicyChanged() { ...@@ -261,33 +223,12 @@ void ScreenTimeController::OnPolicyChanged() {
void ScreenTimeController::ResetStateTimers() { void ScreenTimeController::ResetStateTimers() {
VLOG(1) << "Stopping state timers"; VLOG(1) << "Stopping state timers";
next_state_timer_.Stop(); next_state_timer_.Stop();
reset_screen_time_timer_.Stop();
} }
void ScreenTimeController::ResetInSessionTimers() { void ScreenTimeController::ResetInSessionTimers() {
VLOG(1) << "Stopping in-session timers"; 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();
}
void ScreenTimeController::SaveScreenTimeProgressBeforeExit() {
VLOG(1) << "Saving screen time progress before exiting";
pref_service_->SetInteger(prefs::kScreenTimeMinutesUsed,
GetScreenTimeDuration().InMinutes());
pref_service_->ClearPref(prefs::kCurrentScreenStartTime);
pref_service_->CommitPendingWrite();
current_screen_start_time_ = base::Time();
ResetInSessionTimers();
}
void ScreenTimeController::SaveScreenTimeProgressPeriodically() {
pref_service_->SetInteger(prefs::kScreenTimeMinutesUsed,
GetScreenTimeDuration().InMinutes());
current_screen_start_time_ = base::Time::Now();
pref_service_->SetTime(prefs::kCurrentScreenStartTime,
current_screen_start_time_);
pref_service_->CommitPendingWrite();
} }
void ScreenTimeController::SaveCurrentStateToPref( void ScreenTimeController::SaveCurrentStateToPref(
...@@ -416,40 +357,9 @@ void ScreenTimeController::OnSessionStateChanged() { ...@@ -416,40 +357,9 @@ void ScreenTimeController::OnSessionStateChanged() {
UpdateTimeLimitsMessage(true /*visible*/, next_unlock_time_.value()); UpdateTimeLimitsMessage(true /*visible*/, next_unlock_time_.value());
next_unlock_time_.reset(); next_unlock_time_.reset();
} }
SaveScreenTimeProgressBeforeExit(); ResetInSessionTimers();
} else if (session_state == session_manager::SessionState::ACTIVE) { } else if (session_state == session_manager::SessionState::ACTIVE) {
base::Time now = base::Time::Now();
const base::Time first_screen_start_time =
pref_service_->GetTime(prefs::kFirstScreenStartTime);
if (first_screen_start_time.is_null()) {
pref_service_->SetTime(prefs::kFirstScreenStartTime, now);
first_screen_start_time_ = now;
} else {
first_screen_start_time_ = first_screen_start_time;
}
const base::Time current_screen_start_time =
pref_service_->GetTime(prefs::kCurrentScreenStartTime);
if (!current_screen_start_time.is_null() &&
current_screen_start_time < now &&
(now - current_screen_start_time) <
2 * kScreenTimeUsageUpdateFrequency) {
current_screen_start_time_ = current_screen_start_time;
} else {
// If kCurrentScreenStartTime is not set or it's been too long since the
// last update, set the time to now.
current_screen_start_time_ = now;
}
pref_service_->SetTime(prefs::kCurrentScreenStartTime,
current_screen_start_time_);
pref_service_->CommitPendingWrite();
CheckTimeLimit("OnSessionStateChanged"); CheckTimeLimit("OnSessionStateChanged");
save_screen_time_timer_.Start(
FROM_HERE, kScreenTimeUsageUpdateFrequency,
base::BindRepeating(
&ScreenTimeController::SaveScreenTimeProgressPeriodically,
base::Unretained(this)));
} }
} }
......
...@@ -35,9 +35,9 @@ class ScreenTimeController : public KeyedService, ...@@ -35,9 +35,9 @@ class ScreenTimeController : public KeyedService,
explicit ScreenTimeController(content::BrowserContext* context); explicit ScreenTimeController(content::BrowserContext* context);
~ScreenTimeController() override; ~ScreenTimeController() override;
// Returns the screen time duration. This includes time in // Returns the child's screen time duration. This is how long the child has
// kScreenTimeMinutesUsed plus time passed since |current_screen_start_time_|. // used the device today (since the last reset).
base::TimeDelta GetScreenTimeDuration() const; base::TimeDelta GetScreenTimeDuration();
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
...@@ -66,9 +66,6 @@ class ScreenTimeController : public KeyedService, ...@@ -66,9 +66,6 @@ class ScreenTimeController : public KeyedService,
void ShowNotification(ScreenTimeController::TimeLimitNotificationType type, void ShowNotification(ScreenTimeController::TimeLimitNotificationType type,
const base::TimeDelta& time_remaining); const base::TimeDelta& time_remaining);
// Reset time tracking relevant prefs and local timestamps.
void RefreshScreenLimit();
// Called when the policy of time limits changes. // Called when the policy of time limits changes.
void OnPolicyChanged(); void OnPolicyChanged();
...@@ -76,14 +73,6 @@ class ScreenTimeController : public KeyedService, ...@@ -76,14 +73,6 @@ class ScreenTimeController : public KeyedService,
void ResetStateTimers(); void ResetStateTimers();
void ResetInSessionTimers(); void ResetInSessionTimers();
// Save the screen time progress when screen is locked, or user sign out or
// power down the device.
void SaveScreenTimeProgressBeforeExit();
// Save the screen time progress periodically in case of a crash or power
// outage.
void SaveScreenTimeProgressPeriodically();
// Save the |state| to |prefs::kScreenTimeLastState|. // Save the |state| to |prefs::kScreenTimeLastState|.
void SaveCurrentStateToPref(const usage_time_limit::State& state); void SaveCurrentStateToPref(const usage_time_limit::State& state);
...@@ -104,26 +93,11 @@ class ScreenTimeController : public KeyedService, ...@@ -104,26 +93,11 @@ class ScreenTimeController : public KeyedService,
base::OneShotTimer warning_notification_timer_; base::OneShotTimer warning_notification_timer_;
base::OneShotTimer exit_notification_timer_; base::OneShotTimer exit_notification_timer_;
// Called to record the current amount of time spent in-session.
base::RepeatingTimer save_screen_time_timer_;
// Timers that are called when lock screen state change event happens, ie, // Timers that are called when lock screen state change event happens, ie,
// bedtime is over or the usage limit ends. // bedtime is over or the usage limit ends.
base::OneShotTimer next_state_timer_; 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
// screen. This timestamp is periodically updated by
// SaveScreenTimeProgressPeriodically(), and is cleared when user exits the
// active screen(lock, sign out, shutdown).
base::Time current_screen_start_time_;
// Timestamp to keep track of the screen start time when user starts using
// the device for the first time of the day.
// Used to calculate the screen time limit and this will be refreshed by
// RefreshScreenLimit();
base::Time first_screen_start_time_;
PrefChangeRegistrar pref_change_registrar_; PrefChangeRegistrar pref_change_registrar_;
// Used to update the time limits message, if any, when screen is locked. // Used to update the time limits message, if any, when screen is locked.
......
...@@ -459,7 +459,8 @@ class DeviceStatusCollector::ActivityStorage { ...@@ -459,7 +459,8 @@ class DeviceStatusCollector::ActivityStorage {
// represents the distance from midnight. // represents the distance from midnight.
ActivityStorage(PrefService* pref_service, ActivityStorage(PrefService* pref_service,
const std::string& pref_name, const std::string& pref_name,
TimeDelta activity_day_start); TimeDelta activity_day_start,
bool is_enterprise_reporting);
~ActivityStorage(); ~ActivityStorage();
// Adds an activity period. Accepts empty |active_user_email| if it should not // Adds an activity period. Accepts empty |active_user_email| if it should not
...@@ -501,6 +502,7 @@ class DeviceStatusCollector::ActivityStorage { ...@@ -501,6 +502,7 @@ class DeviceStatusCollector::ActivityStorage {
void ProcessActivityPeriods(const base::DictionaryValue& activity_times, void ProcessActivityPeriods(const base::DictionaryValue& activity_times,
const std::vector<std::string>& reporting_users, const std::vector<std::string>& reporting_users,
base::DictionaryValue* const filtered_times); base::DictionaryValue* const filtered_times);
void StoreChildScreenTime(Time activity_day_start, TimeDelta activity);
// Determine the day key (milliseconds since epoch for corresponding // Determine the day key (milliseconds since epoch for corresponding
// |day_start_| in UTC) for a given |timestamp|. // |day_start_| in UTC) for a given |timestamp|.
...@@ -513,16 +515,21 @@ class DeviceStatusCollector::ActivityStorage { ...@@ -513,16 +515,21 @@ class DeviceStatusCollector::ActivityStorage {
// from midnight. // from midnight.
const TimeDelta day_start_; const TimeDelta day_start_;
// Whether reporting is for enterprise or consumer.
bool is_enterprise_reporting_ = false;
DISALLOW_COPY_AND_ASSIGN(ActivityStorage); DISALLOW_COPY_AND_ASSIGN(ActivityStorage);
}; };
DeviceStatusCollector::ActivityStorage::ActivityStorage( DeviceStatusCollector::ActivityStorage::ActivityStorage(
PrefService* pref_service, PrefService* pref_service,
const std::string& pref_name, const std::string& pref_name,
TimeDelta activity_day_start) TimeDelta activity_day_start,
bool is_enterprise_reporting)
: pref_service_(pref_service), : pref_service_(pref_service),
pref_name_(pref_name), pref_name_(pref_name),
day_start_(activity_day_start) { day_start_(activity_day_start),
is_enterprise_reporting_(is_enterprise_reporting) {
DCHECK(pref_service_); DCHECK(pref_service_);
const PrefService::PrefInitializationStatus pref_service_status = const PrefService::PrefInitializationStatus pref_service_status =
pref_service_->GetInitializationStatus(); pref_service_->GetInitializationStatus();
...@@ -554,6 +561,15 @@ void DeviceStatusCollector::ActivityStorage::AddActivityPeriod( ...@@ -554,6 +561,15 @@ void DeviceStatusCollector::ActivityStorage::AddActivityPeriod(
int previous_activity = 0; int previous_activity = 0;
activity_times->GetInteger(key, &previous_activity); activity_times->GetInteger(key, &previous_activity);
activity_times->SetInteger(key, previous_activity + activity); activity_times->SetInteger(key, previous_activity + activity);
// If the user is a child, the child screen time pref may need to be
// updated.
if (user_manager::UserManager::Get()->IsLoggedInAsChildUser() &&
!is_enterprise_reporting_) {
StoreChildScreenTime(day_start - TimeDelta::FromDays(1),
TimeDelta::FromMilliseconds(activity));
}
start = day_start; start = day_start;
} }
} }
...@@ -705,6 +721,35 @@ int64_t DeviceStatusCollector::ActivityStorage::TimestampToDayKey( ...@@ -705,6 +721,35 @@ int64_t DeviceStatusCollector::ActivityStorage::TimestampToDayKey(
return out_time.ToJavaTime(); return out_time.ToJavaTime();
} }
void DeviceStatusCollector::ActivityStorage::StoreChildScreenTime(
Time activity_day_start,
TimeDelta activity) {
DCHECK(user_manager::UserManager::Get()->IsLoggedInAsChildUser() &&
!is_enterprise_reporting_);
// Today's start time.
Time today_start = Time::Now().LocalMidnight() + day_start_;
TimeDelta previous_activity = TimeDelta::FromMilliseconds(
pref_service_->GetInteger(prefs::kChildScreenTimeMilliseconds));
// Reset screen time if it has not been reset today.
if (today_start > pref_service_->GetTime(prefs::kLastChildScreenTimeReset)) {
pref_service_->SetTime(prefs::kLastChildScreenTimeReset, Time::Now());
pref_service_->SetInteger(prefs::kChildScreenTimeMilliseconds, 0);
previous_activity = TimeDelta::FromSeconds(0);
}
// If this activity window belongs to the current day, the screen time pref
// should be updated.
if (activity_day_start >= today_start) {
pref_service_->SetInteger(prefs::kChildScreenTimeMilliseconds,
(previous_activity + activity).InMilliseconds());
pref_service_->SetTime(prefs::kLastChildScreenTimeSaved, Time::Now());
}
pref_service_->CommitPendingWrite();
}
DeviceStatusCollector::DeviceStatusCollector( DeviceStatusCollector::DeviceStatusCollector(
PrefService* pref_service, PrefService* pref_service,
chromeos::system::StatisticsProvider* provider, chromeos::system::StatisticsProvider* provider,
...@@ -822,7 +867,7 @@ DeviceStatusCollector::DeviceStatusCollector( ...@@ -822,7 +867,7 @@ DeviceStatusCollector::DeviceStatusCollector(
pref_service_, pref_service_,
(is_enterprise_reporting_ ? prefs::kDeviceActivityTimes (is_enterprise_reporting_ ? prefs::kDeviceActivityTimes
: prefs::kUserActivityTimes), : prefs::kUserActivityTimes),
activity_day_start); activity_day_start, is_enterprise_reporting_);
} }
DeviceStatusCollector::~DeviceStatusCollector() { DeviceStatusCollector::~DeviceStatusCollector() {
...@@ -841,6 +886,18 @@ void DeviceStatusCollector::RegisterProfilePrefs(PrefRegistrySimple* registry) { ...@@ -841,6 +886,18 @@ void DeviceStatusCollector::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(prefs::kReportArcStatusEnabled, false); registry->RegisterBooleanPref(prefs::kReportArcStatusEnabled, false);
registry->RegisterDictionaryPref(prefs::kUserActivityTimes, registry->RegisterDictionaryPref(prefs::kUserActivityTimes,
std::make_unique<base::DictionaryValue>()); std::make_unique<base::DictionaryValue>());
registry->RegisterTimePref(prefs::kLastChildScreenTimeReset, Time());
registry->RegisterTimePref(prefs::kLastChildScreenTimeSaved, Time());
registry->RegisterIntegerPref(prefs::kChildScreenTimeMilliseconds, 0);
}
TimeDelta DeviceStatusCollector::GetActiveChildScreenTime() {
if (!user_manager::UserManager::Get()->IsLoggedInAsChildUser())
return TimeDelta::FromSeconds(0);
UpdateChildUsageTime();
return TimeDelta::FromMilliseconds(
pref_service_->GetInteger(prefs::kChildScreenTimeMilliseconds));
} }
void DeviceStatusCollector::CheckIdleState() { void DeviceStatusCollector::CheckIdleState() {
...@@ -929,7 +986,7 @@ void DeviceStatusCollector::ClearCachedResourceUsage() { ...@@ -929,7 +986,7 @@ void DeviceStatusCollector::ClearCachedResourceUsage() {
void DeviceStatusCollector::IdleStateCallback(ui::IdleState state) { void DeviceStatusCollector::IdleStateCallback(ui::IdleState state) {
// Do nothing if device activity reporting is disabled or if it's a child // Do nothing if device activity reporting is disabled or if it's a child
// account. Usage time for child accounts are calculated differently. // account. Usage time for child accounts are calculated differently.
if (!report_activity_times_ || if (!report_activity_times_ || !is_enterprise_reporting_ ||
user_manager::UserManager::Get()->IsLoggedInAsChildUser()) { user_manager::UserManager::Get()->IsLoggedInAsChildUser()) {
return; return;
} }
...@@ -1147,8 +1204,9 @@ bool DeviceStatusCollector::IncludeEmailsInActivityReports() const { ...@@ -1147,8 +1204,9 @@ bool DeviceStatusCollector::IncludeEmailsInActivityReports() const {
bool DeviceStatusCollector::GetActivityTimes( bool DeviceStatusCollector::GetActivityTimes(
em::DeviceStatusReportRequest* status) { em::DeviceStatusReportRequest* status) {
if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) {
UpdateChildUsageTime(); UpdateChildUsageTime();
}
// If user reporting is off, data should be aggregated per day. // If user reporting is off, data should be aggregated per day.
// Signed-in user is reported in non-enterprise reporting. // Signed-in user is reported in non-enterprise reporting.
......
...@@ -139,6 +139,10 @@ class DeviceStatusCollector : public session_manager::SessionManagerObserver, ...@@ -139,6 +139,10 @@ class DeviceStatusCollector : public session_manager::SessionManagerObserver,
// The total number of hardware resource usage samples cached internally. // The total number of hardware resource usage samples cached internally.
static const unsigned int kMaxResourceUsageSamples = 10; static const unsigned int kMaxResourceUsageSamples = 10;
// Returns the amount of time the child has used so far today. If the user is
// not a child or if there is no user logged in, it returns 0.
base::TimeDelta GetActiveChildScreenTime();
protected: protected:
// Check whether the user has been idle for a certain period of time. // Check whether the user has been idle for a certain period of time.
virtual void CheckIdleState(); virtual void CheckIdleState();
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include "chromeos/system/fake_statistics_provider.h" #include "chromeos/system/fake_statistics_provider.h"
#include "components/account_id/account_id.h" #include "components/account_id/account_id.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h" #include "components/prefs/testing_pref_service.h"
#include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/scoped_user_manager.h"
...@@ -2436,6 +2437,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ...@@ -2436,6 +2437,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
ASSERT_EQ(1, device_status_.active_period_size()); ASSERT_EQ(1, device_status_.active_period_size());
EXPECT_EQ(5 * ActivePeriodMilliseconds(), EXPECT_EQ(5 * ActivePeriodMilliseconds(),
GetActiveMilliseconds(device_status_)); GetActiveMilliseconds(device_status_));
EXPECT_EQ(
5 * ActivePeriodMilliseconds(),
profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds));
EXPECT_EQ(user_account_id_.GetUserEmail(), EXPECT_EQ(user_account_id_.GetUserEmail(),
device_status_.active_period(0).user_email()); device_status_.active_period(0).user_email());
} }
...@@ -2458,6 +2462,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ...@@ -2458,6 +2462,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
ASSERT_EQ(1, device_status_.active_period_size()); ASSERT_EQ(1, device_status_.active_period_size());
EXPECT_EQ(4 * ActivePeriodMilliseconds(), EXPECT_EQ(4 * ActivePeriodMilliseconds(),
GetActiveMilliseconds(device_status_)); GetActiveMilliseconds(device_status_));
EXPECT_EQ(
4 * ActivePeriodMilliseconds(),
profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds));
EXPECT_EQ(user_account_id_.GetUserEmail(), EXPECT_EQ(user_account_id_.GetUserEmail(),
device_status_.active_period(0).user_email()); device_status_.active_period(0).user_email());
} }
...@@ -2482,6 +2489,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ...@@ -2482,6 +2489,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
ASSERT_EQ(1, device_status_.active_period_size()); ASSERT_EQ(1, device_status_.active_period_size());
EXPECT_EQ(5 * ActivePeriodMilliseconds(), EXPECT_EQ(5 * ActivePeriodMilliseconds(),
GetActiveMilliseconds(device_status_)); GetActiveMilliseconds(device_status_));
EXPECT_EQ(
5 * ActivePeriodMilliseconds(),
profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds));
EXPECT_EQ(user_account_id_.GetUserEmail(), EXPECT_EQ(user_account_id_.GetUserEmail(),
device_status_.active_period(0).user_email()); device_status_.active_period(0).user_email());
} }
...@@ -2519,6 +2529,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ActivityKeptInPref) { ...@@ -2519,6 +2529,9 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ActivityKeptInPref) {
GetStatus(); GetStatus();
EXPECT_EQ(12 * ActivePeriodMilliseconds(), EXPECT_EQ(12 * ActivePeriodMilliseconds(),
GetActiveMilliseconds(device_status_)); GetActiveMilliseconds(device_status_));
EXPECT_EQ(
12 * ActivePeriodMilliseconds(),
profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds));
} }
TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
...@@ -2543,10 +2556,49 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ...@@ -2543,10 +2556,49 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
EXPECT_EQ(1, device_status_.active_period_size()); EXPECT_EQ(1, device_status_.active_period_size());
EXPECT_EQ(5 * ActivePeriodMilliseconds(), EXPECT_EQ(5 * ActivePeriodMilliseconds(),
GetActiveMilliseconds(device_status_)); GetActiveMilliseconds(device_status_));
EXPECT_EQ(
5 * ActivePeriodMilliseconds(),
profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds));
// Nothing should be written to local state, because it is only used for // Nothing should be written to local state, because it is only used for
// enterprise reporting. // enterprise reporting.
EXPECT_TRUE(local_state_.GetDictionary(prefs::kDeviceActivityTimes)->empty()); EXPECT_TRUE(local_state_.GetDictionary(prefs::kDeviceActivityTimes)->empty());
} }
TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
ActivityCrossingMidnight) {
DeviceStateTransitions test_states[] = {
DeviceStateTransitions::kEnterSessionActive,
DeviceStateTransitions::kLeaveSessionActive};
// Set the baseline time to 15 seconds before midnight, so the activity is
// split between two days.
status_collector_->SetBaselineTime(Time::Now().LocalMidnight() -
TimeDelta::FromSeconds(15));
SimulateStateChanges(test_states,
sizeof(test_states) / sizeof(DeviceStateTransitions));
GetStatus();
ASSERT_EQ(2, device_status_.active_period_size());
em::ActiveTimePeriod period0 = device_status_.active_period(0);
em::ActiveTimePeriod period1 = device_status_.active_period(1);
EXPECT_EQ(ActivePeriodMilliseconds() - 15000, period0.active_duration());
EXPECT_EQ(15000, period1.active_duration());
em::TimePeriod time_period0 = period0.time_period();
em::TimePeriod time_period1 = period1.time_period();
EXPECT_EQ(time_period0.end_timestamp(), time_period1.start_timestamp());
// Ensure that the start and end times for the period are a day apart.
EXPECT_EQ(time_period0.end_timestamp() - time_period0.start_timestamp(),
kMillisecondsPerDay);
EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(),
kMillisecondsPerDay);
EXPECT_EQ(
0.5 * ActivePeriodMilliseconds(),
profile_pref_service_.GetInteger(prefs::kChildScreenTimeMilliseconds));
}
} // namespace policy } // namespace policy
...@@ -829,19 +829,6 @@ const char kTextToSpeechPitch[] = "settings.tts.speech_pitch"; ...@@ -829,19 +829,6 @@ const char kTextToSpeechPitch[] = "settings.tts.speech_pitch";
// system volume, and higher than 1.0 is louder. // system volume, and higher than 1.0 is louder.
const char kTextToSpeechVolume[] = "settings.tts.speech_volume"; const char kTextToSpeechVolume[] = "settings.tts.speech_volume";
// This is a timestamp to keep track of the screen start time when a unichrome
// user starts using the device for the first time of the day. Used to calculate
// the screen time limit and this will be refreshed daily.
const char kFirstScreenStartTime[] = "screen_time.first_screen.start_time";
// This is a timestamp to keep track of the screen start time for the current
// active screen. The pref is used to restore the screen start time after
// browser crashes and device reboots.
const char kCurrentScreenStartTime[] = "screen_time.current_screen.start_time";
// How much screen time in minutes has been used.
const char kScreenTimeMinutesUsed[] = "screen_time.time_usage";
// A dictionary preference holding the usage time limit definitions for a user. // A dictionary preference holding the usage time limit definitions for a user.
const char kUsageTimeLimit[] = "screen_time.limit"; const char kUsageTimeLimit[] = "screen_time.limit";
...@@ -873,6 +860,15 @@ const char kTPMFirmwareUpdateCleanupDismissed[] = ...@@ -873,6 +860,15 @@ const char kTPMFirmwareUpdateCleanupDismissed[] =
const char kNetBiosShareDiscoveryEnabled[] = const char kNetBiosShareDiscoveryEnabled[] =
"network_file_shares.netbios_discovery.enabled"; "network_file_shares.netbios_discovery.enabled";
// Amount of screen time that a child user has used in the current day.
const char kChildScreenTimeMilliseconds[] = "child_screen_time";
// Last time the kChildScreenTimeMilliseconds was saved.
const char kLastChildScreenTimeSaved[] = "last_child_screen_time_saved";
// Last time that the kChildScreenTime pref was reset.
const char kLastChildScreenTimeReset[] = "last_child_screen_time_reset";
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
// A boolean pref set to true if a Home button to open the Home pages should be // A boolean pref set to true if a Home button to open the Home pages should be
......
...@@ -270,9 +270,6 @@ extern const char kTextToSpeechLangToVoiceName[]; ...@@ -270,9 +270,6 @@ extern const char kTextToSpeechLangToVoiceName[];
extern const char kTextToSpeechRate[]; extern const char kTextToSpeechRate[];
extern const char kTextToSpeechPitch[]; extern const char kTextToSpeechPitch[];
extern const char kTextToSpeechVolume[]; extern const char kTextToSpeechVolume[];
extern const char kFirstScreenStartTime[];
extern const char kCurrentScreenStartTime[];
extern const char kScreenTimeMinutesUsed[];
extern const char kUsageTimeLimit[]; extern const char kUsageTimeLimit[];
extern const char kScreenTimeLastState[]; extern const char kScreenTimeLastState[];
extern const char kEnableSyncConsent[]; extern const char kEnableSyncConsent[];
...@@ -280,6 +277,9 @@ extern const char kNetworkFileSharesAllowed[]; ...@@ -280,6 +277,9 @@ extern const char kNetworkFileSharesAllowed[];
extern const char kManagedSessionEnabled[]; extern const char kManagedSessionEnabled[];
extern const char kTPMFirmwareUpdateCleanupDismissed[]; extern const char kTPMFirmwareUpdateCleanupDismissed[];
extern const char kNetBiosShareDiscoveryEnabled[]; extern const char kNetBiosShareDiscoveryEnabled[];
extern const char kChildScreenTimeMilliseconds[];
extern const char kLastChildScreenTimeSaved[];
extern const char kLastChildScreenTimeReset[];
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
extern const char kShowHomeButton[]; extern const char kShowHomeButton[];
extern const char kSpeechRecognitionFilterProfanities[]; extern const char kSpeechRecognitionFilterProfanities[];
......
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