Commit 07318f0b authored by Polina Bondarenko's avatar Polina Bondarenko Committed by Commit Bot

arc: DeviceArcDataSnapshotHours policy impl.

Add SnapshotHoursPolicyService to handle policy changes.

BUG=b:170187468
TEST=components_unittests

Change-Id: I1918d55d6e53b0085473f7bf650cf949767ed4b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2514148Reviewed-by: default avatarRoman Sorokin [CET] <rsorokin@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Commit-Queue: Polina Bondarenko <pbond@chromium.org>
Auto-Submit: Polina Bondarenko <pbond@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825794}
parent f397a0d8
......@@ -12,6 +12,7 @@ namespace em = enterprise_management;
namespace policy {
namespace {
constexpr base::TimeDelta kWeek = base::TimeDelta::FromDays(7);
constexpr base::TimeDelta kDay = base::TimeDelta::FromDays(1);
constexpr base::TimeDelta kHour = base::TimeDelta::FromHours(1);
......@@ -31,6 +32,11 @@ WeeklyTime GetWeeklyTimeFromExploded(
} // namespace
// static
const char WeeklyTime::kDayOfWeek[] = "day_of_week";
const char WeeklyTime::kTime[] = "time";
const char WeeklyTime::kTimezoneOffset[] = "timezon_offset";
WeeklyTime::WeeklyTime(int day_of_week,
int milliseconds,
base::Optional<int> timezone_offset)
......@@ -49,10 +55,10 @@ WeeklyTime& WeeklyTime::operator=(const WeeklyTime& rhs) = default;
std::unique_ptr<base::DictionaryValue> WeeklyTime::ToValue() const {
auto weekly_time = std::make_unique<base::DictionaryValue>();
weekly_time->SetInteger("day_of_week", day_of_week_);
weekly_time->SetInteger("time", milliseconds_);
weekly_time->SetInteger(kDayOfWeek, day_of_week_);
weekly_time->SetInteger(kTime, milliseconds_);
if (timezone_offset_)
weekly_time->SetInteger("timezone_offset", timezone_offset_.value());
weekly_time->SetInteger(kTimezoneOffset, timezone_offset_.value());
return weekly_time;
}
......@@ -137,4 +143,35 @@ std::unique_ptr<WeeklyTime> WeeklyTime::ExtractFromProto(
timezone_offset);
}
// static
std::unique_ptr<WeeklyTime> WeeklyTime::ExtractFromValue(
const base::Value* value,
base::Optional<int> timezone_offset) {
if (!value) {
LOG(ERROR) << "Passed nullptr value.";
return nullptr;
}
auto day_of_week = value->FindIntKey(kDayOfWeek);
if (!day_of_week.has_value() || day_of_week.value() < 1 ||
day_of_week.value() > 7) {
LOG(ERROR) << "Day of week is absent or invalid";
return nullptr;
}
auto time_of_day = value->FindIntKey(kTime);
if (!time_of_day.has_value()) {
LOG(ERROR) << "Time is absent";
return nullptr;
}
if (!(time_of_day.value() >= 0 &&
time_of_day.value() < kDay.InMilliseconds())) {
LOG(ERROR) << "Invalid time value: " << time_of_day.value()
<< ", the value should be in [0; " << kDay.InMilliseconds()
<< ").";
return nullptr;
}
return std::make_unique<WeeklyTime>(day_of_week.value(), time_of_day.value(),
timezone_offset);
}
} // namespace policy
......@@ -21,6 +21,11 @@ namespace policy {
// beginning of the day.
class CHROMEOS_EXPORT WeeklyTime {
public:
// Dictionary value key constants for testing.
static const char kDayOfWeek[];
static const char kTime[];
static const char kTimezoneOffset[];
WeeklyTime(int day_of_week,
int milliseconds,
base::Optional<int> timezone_offset);
......@@ -77,6 +82,16 @@ class CHROMEOS_EXPORT WeeklyTime {
const enterprise_management::WeeklyTimeProto& container,
base::Optional<int> timezone_offset);
// Return WeeklyTime structure from Value in format:
// { "day_of_week" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday,
// etc.)
// "time" : int # in milliseconds from the beginning of the day.
// }.
// Return nullptr if WeeklyTime structure isn't correct.
static std::unique_ptr<WeeklyTime> ExtractFromValue(
const base::Value* value,
base::Optional<int> timezone_offset);
// Return the current time in GMT in WeeklyTime structure.
static WeeklyTime GetCurrentGmtWeeklyTime(base::Clock* clock);
......
......@@ -11,6 +11,10 @@ namespace em = enterprise_management;
namespace policy {
// static
const char WeeklyTimeInterval::kStart[] = "start";
const char WeeklyTimeInterval::kEnd[] = "end";
WeeklyTimeInterval::WeeklyTimeInterval(const WeeklyTime& start,
const WeeklyTime& end)
: start_(start), end_(end) {
......@@ -25,8 +29,8 @@ WeeklyTimeInterval& WeeklyTimeInterval::operator=(
std::unique_ptr<base::DictionaryValue> WeeklyTimeInterval::ToValue() const {
auto interval = std::make_unique<base::DictionaryValue>();
interval->SetDictionary("start", start_.ToValue());
interval->SetDictionary("end", end_.ToValue());
interval->SetDictionary(kStart, start_.ToValue());
interval->SetDictionary(kEnd, end_.ToValue());
return interval;
}
......@@ -54,4 +58,21 @@ std::unique_ptr<WeeklyTimeInterval> WeeklyTimeInterval::ExtractFromProto(
return std::make_unique<WeeklyTimeInterval>(*start, *end);
}
// static
std::unique_ptr<WeeklyTimeInterval> WeeklyTimeInterval::ExtractFromValue(
const base::Value* value,
base::Optional<int> timezone_offset) {
if (!value || !value->FindDictKey(kStart) || !value->FindDictKey(kEnd)) {
LOG(WARNING) << "Interval without start or/and end.";
return nullptr;
}
auto start =
WeeklyTime::ExtractFromValue(value->FindDictKey(kStart), timezone_offset);
auto end =
WeeklyTime::ExtractFromValue(value->FindDictKey(kEnd), timezone_offset);
if (!start || !end)
return nullptr;
return std::make_unique<WeeklyTimeInterval>(*start, *end);
}
} // namespace policy
......@@ -21,6 +21,10 @@ namespace policy {
// Both WeeklyTimes need to have the same timezone_offset.
class CHROMEOS_EXPORT WeeklyTimeInterval {
public:
// Dictionary value key constants for testing.
static const char kStart[];
static const char kEnd[];
WeeklyTimeInterval(const WeeklyTime& start, const WeeklyTime& end);
WeeklyTimeInterval(const WeeklyTimeInterval& rhs);
......@@ -60,6 +64,20 @@ class CHROMEOS_EXPORT WeeklyTimeInterval {
const enterprise_management::WeeklyTimeIntervalProto& container,
base::Optional<int> timezone_offset);
// Return time interval made from Value in format:
// { "start" : WeeklyTime,
// "end" : WeeklyTime }
// WeeklyTime dictionary format:
// { "day_of_week" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday,
// etc.)
// "time" : int # in milliseconds from the beginning of the day.
// "timezone_offset" : int # in milliseconds, how much time ahead of GMT.
// }
// Return nullptr if value contains an invalid interval.
static std::unique_ptr<WeeklyTimeInterval> ExtractFromValue(
const base::Value* value,
base::Optional<int> timezone_offset);
WeeklyTime start() const { return start_; }
WeeklyTime end() const { return end_; }
......
......@@ -76,8 +76,10 @@ TEST_P(SingleWeeklyTimeIntervalTest, ToValue) {
WeeklyTimeInterval interval = WeeklyTimeInterval(start, end);
std::unique_ptr<base::DictionaryValue> interval_value = interval.ToValue();
base::DictionaryValue expected_interval_value;
expected_interval_value.SetDictionary("start", start.ToValue());
expected_interval_value.SetDictionary("end", end.ToValue());
expected_interval_value.SetDictionary(WeeklyTimeInterval::kStart,
start.ToValue());
expected_interval_value.SetDictionary(WeeklyTimeInterval::kEnd,
end.ToValue());
EXPECT_EQ(*interval_value, expected_interval_value);
}
......@@ -146,6 +148,90 @@ TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromProto_Valid) {
EXPECT_EQ(result->start().timezone_offset(), 0);
}
TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_Empty) {
base::DictionaryValue value;
auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0);
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_NoEnd) {
base::DictionaryValue value;
base::DictionaryValue start;
EXPECT_TRUE(
start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[start_day_of_week()]));
EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time()));
value.SetKey(WeeklyTimeInterval::kStart, std::move(start));
auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0);
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_NoStart) {
base::DictionaryValue value;
base::DictionaryValue end;
EXPECT_TRUE(
end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[end_day_of_week()]));
EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time()));
value.SetKey(WeeklyTimeInterval::kEnd, std::move(end));
auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0);
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_InvalidStart) {
base::DictionaryValue value;
base::DictionaryValue start;
EXPECT_TRUE(start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[0]));
EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time()));
value.SetKey(WeeklyTimeInterval::kStart, std::move(start));
base::DictionaryValue end;
EXPECT_TRUE(
end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[end_day_of_week()]));
EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time()));
value.SetKey(WeeklyTimeInterval::kEnd, std::move(end));
auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0);
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_InvalidEnd) {
base::DictionaryValue value;
base::DictionaryValue start;
EXPECT_TRUE(
start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[start_day_of_week()]));
EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time()));
value.SetKey(WeeklyTimeInterval::kStart, std::move(start));
base::DictionaryValue end;
EXPECT_TRUE(end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[0]));
EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time()));
value.SetKey(WeeklyTimeInterval::kEnd, std::move(end));
auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0);
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_Valid) {
base::DictionaryValue value;
base::DictionaryValue start;
EXPECT_TRUE(
start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[start_day_of_week()]));
EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time()));
value.SetKey(WeeklyTimeInterval::kStart, std::move(start));
base::DictionaryValue end;
EXPECT_TRUE(
end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[end_day_of_week()]));
EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time()));
value.SetKey(WeeklyTimeInterval::kEnd, std::move(end));
auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0);
ASSERT_TRUE(result);
EXPECT_EQ(result->start().day_of_week(), start_day_of_week());
EXPECT_EQ(result->start().milliseconds(), start_time());
EXPECT_EQ(result->end().day_of_week(), end_day_of_week());
EXPECT_EQ(result->end().milliseconds(), end_time());
EXPECT_EQ(result->start().timezone_offset(), 0);
}
INSTANTIATE_TEST_SUITE_P(OneMinuteInterval,
SingleWeeklyTimeIntervalTest,
testing::Values(std::make_tuple(kWednesday,
......
......@@ -79,10 +79,11 @@ TEST_P(SingleWeeklyTimeTest, ToValue) {
std::unique_ptr<base::DictionaryValue> weekly_time_value =
weekly_time.ToValue();
base::DictionaryValue expected_weekly_time;
expected_weekly_time.SetInteger("day_of_week", day_of_week());
expected_weekly_time.SetInteger("time", minutes() * kMinute.InMilliseconds());
expected_weekly_time.SetInteger(WeeklyTime::kDayOfWeek, day_of_week());
expected_weekly_time.SetInteger(WeeklyTime::kTime,
minutes() * kMinute.InMilliseconds());
if (timezone_offset()) {
expected_weekly_time.SetInteger("timezone_offset",
expected_weekly_time.SetInteger(WeeklyTime::kTimezoneOffset,
timezone_offset().value());
}
EXPECT_EQ(*weekly_time_value, expected_weekly_time);
......@@ -117,6 +118,50 @@ TEST_P(SingleWeeklyTimeTest, ExtractFromProto_Valid) {
EXPECT_EQ(result->timezone_offset(), timezone_offset());
}
TEST_P(SingleWeeklyTimeTest, ExtractFromValue_UnspecifiedDay) {
int milliseconds = minutes() * kMinute.InMilliseconds();
base::DictionaryValue value;
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[0]));
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, milliseconds));
auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset());
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeTest, ExtractFromValue_InvalidDay) {
int milliseconds = minutes() * kMinute.InMilliseconds();
base::DictionaryValue value;
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kDayOfWeek, -1));
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, milliseconds));
auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset());
ASSERT_FALSE(result);
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kDayOfWeek, 8));
result = WeeklyTime::ExtractFromValue(&value, timezone_offset());
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeTest, ExtractFromValue_InvalidTime) {
base::DictionaryValue value;
EXPECT_TRUE(
value.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[day_of_week()]));
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, -1));
auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset());
ASSERT_FALSE(result);
}
TEST_P(SingleWeeklyTimeTest, ExtractFromValue_Valid) {
int milliseconds = minutes() * kMinute.InMilliseconds();
base::DictionaryValue value;
EXPECT_TRUE(
value.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[day_of_week()]));
EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, milliseconds));
auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset());
ASSERT_TRUE(result);
EXPECT_EQ(result->day_of_week(), day_of_week());
EXPECT_EQ(result->milliseconds(), milliseconds);
EXPECT_EQ(result->timezone_offset(), timezone_offset());
}
INSTANTIATE_TEST_SUITE_P(
TheSmallestCase,
SingleWeeklyTimeTest,
......
......@@ -27,6 +27,8 @@ static_library("arc") {
"enterprise/arc_data_snapshotd_bridge.h",
"enterprise/arc_data_snapshotd_manager.cc",
"enterprise/arc_data_snapshotd_manager.h",
"enterprise/snapshot_hours_policy_service.cc",
"enterprise/snapshot_hours_policy_service.h",
"ime/arc_ime_bridge.h",
"ime/arc_ime_bridge_impl.cc",
"ime/arc_ime_bridge_impl.h",
......@@ -103,6 +105,8 @@ static_library("arc") {
"//ash/keyboard/ui",
"//ash/public/cpp",
"//base",
"//base/util/timer",
"//chromeos",
"//chromeos/audio",
"//chromeos/constants",
"//chromeos/dbus",
......@@ -386,6 +390,7 @@ source_set("unit_tests") {
"clipboard/arc_clipboard_bridge_unittest.cc",
"enterprise/arc_data_snapshotd_bridge_unittest.cc",
"enterprise/arc_data_snapshotd_manager_unittest.cc",
"enterprise/snapshot_hours_policy_service_unittest.cc",
"ime/arc_ime_service_unittest.cc",
"ime/key_event_result_receiver_unittest.cc",
"intent_helper/activity_icon_loader_unittest.cc",
......@@ -417,6 +422,8 @@ source_set("unit_tests") {
"//ash/public/cpp",
"//base",
"//base/test:test_support",
"//base/util/timer",
"//chromeos",
"//chromeos/constants",
"//chromeos/cryptohome:test_support",
"//chromeos/dbus:test_support",
......
......@@ -4,6 +4,7 @@ include_rules = [
"+chromeos/cryptohome",
"+chromeos/dbus",
"+chromeos/memory",
"+chromeos/policy",
"+chromeos/system",
"+components/guest_os",
"+components/account_id",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/enterprise/snapshot_hours_policy_service.h"
#include <utility>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/time/default_clock.h"
#include "base/time/tick_clock.h"
#include "base/values.h"
#include "chromeos/policy/weekly_time/time_utils.h"
#include "components/arc/arc_prefs.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
namespace arc {
namespace data_snapshotd {
SnapshotHoursPolicyService::SnapshotHoursPolicyService(PrefService* local_state)
: local_state_(local_state) {
DCHECK(local_state_);
pref_change_registrar_.Init(local_state_);
pref_change_registrar_.Add(
prefs::kArcSnapshotHours,
base::BindRepeating(&SnapshotHoursPolicyService::UpdatePolicy,
weak_ptr_factory_.GetWeakPtr()));
UpdatePolicy();
}
SnapshotHoursPolicyService::~SnapshotHoursPolicyService() = default;
void SnapshotHoursPolicyService::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void SnapshotHoursPolicyService::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void SnapshotHoursPolicyService::StartObservingPrimaryProfilePrefs(
PrefService* profile_prefs) {
if (!user_manager::UserManager::Get() ||
!user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()) {
// Do not care about ArcEnabled policy for other than MGS.
return;
}
profile_prefs_ = profile_prefs;
profile_pref_change_registrar_.Init(profile_prefs_);
profile_pref_change_registrar_.Add(
prefs::kArcEnabled,
base::BindRepeating(&SnapshotHoursPolicyService::UpdatePolicy,
weak_ptr_factory_.GetWeakPtr()));
UpdatePolicy();
}
void SnapshotHoursPolicyService::StopObservingPrimaryProfilePrefs() {
if (!profile_prefs_)
return;
profile_pref_change_registrar_.RemoveAll();
profile_prefs_ = nullptr;
UpdatePolicy();
}
void SnapshotHoursPolicyService::UpdatePolicy() {
intervals_.clear();
base::ScopedClosureRunner snapshot_disabler(
base::BindOnce(&SnapshotHoursPolicyService::DisableSnapshots,
weak_ptr_factory_.GetWeakPtr()));
if (!IsArcEnabled())
return;
const auto* dict = local_state_->GetDictionary(prefs::kArcSnapshotHours);
if (!dict)
return;
const auto* timezone = dict->FindStringKey("timezone");
if (!timezone)
return;
int offset;
if (!policy::weekly_time_utils::GetOffsetFromTimezoneToGmt(
*timezone, base::DefaultClock::GetInstance(), &offset)) {
return;
}
const auto* intervals = dict->FindListKey("intervals");
if (!intervals)
return;
for (const auto& entry : intervals->GetList()) {
if (!entry.is_dict())
continue;
auto interval =
policy::WeeklyTimeInterval::ExtractFromValue(&entry, -offset);
if (interval)
intervals_.push_back(*interval);
}
intervals_ = policy::weekly_time_utils::ConvertIntervalsToGmt(intervals_);
if (intervals_.empty())
return;
ignore_result(snapshot_disabler.Release());
EnableSnapshots();
}
void SnapshotHoursPolicyService::DisableSnapshots() {
if (!is_snapshot_enabled_)
return;
is_snapshot_enabled_ = false;
StopTimer();
SetEndTime(base::Time());
NotifySnapshotsDisabled();
}
void SnapshotHoursPolicyService::EnableSnapshots() {
if (is_snapshot_enabled_)
return;
is_snapshot_enabled_ = true;
UpdateTimer();
NotifySnapshotsEnabled();
}
void SnapshotHoursPolicyService::UpdateTimer() {
auto current_time = policy::WeeklyTime::GetCurrentGmtWeeklyTime(
base::DefaultClock::GetInstance());
for (const auto& interval : intervals_) {
if (interval.Contains(current_time)) {
auto remaining_timer_duration =
current_time.GetDurationTo(interval.end());
SetEndTime(base::Time::Now() + remaining_timer_duration);
StartTimer(remaining_timer_duration);
return;
}
}
StartTimer(policy::weekly_time_utils::GetDeltaTillNextTimeInterval(
current_time, intervals_));
SetEndTime(base::Time());
}
void SnapshotHoursPolicyService::StartTimer(base::TimeDelta delay) {
DCHECK_GT(delay, base::TimeDelta());
timer_.Start(FROM_HERE, base::DefaultClock::GetInstance()->Now() + delay,
base::BindOnce(&SnapshotHoursPolicyService::UpdateTimer,
weak_ptr_factory_.GetWeakPtr()));
}
void SnapshotHoursPolicyService::StopTimer() {
timer_.Stop();
}
void SnapshotHoursPolicyService::SetEndTime(base::Time end_time) {
if (snapshot_update_end_time_ == end_time)
return;
snapshot_update_end_time_ = end_time;
NotifySnapshotUpdateEndTimeChanged();
}
void SnapshotHoursPolicyService::NotifySnapshotsDisabled() {
for (auto& observer : observers_)
observer.OnSnapshotsDisabled();
}
void SnapshotHoursPolicyService::NotifySnapshotsEnabled() {
for (auto& observer : observers_)
observer.OnSnapshotsEnabled();
}
void SnapshotHoursPolicyService::NotifySnapshotUpdateEndTimeChanged() {
for (auto& observer : observers_)
observer.OnSnapshotUpdateEndTimeChanged();
}
bool SnapshotHoursPolicyService::IsArcEnabled() const {
// Assume ARC is enabled if there is no profile prefs.
return !profile_prefs_ || profile_prefs_->GetBoolean(prefs::kArcEnabled);
}
} // namespace data_snapshotd
} // namespace arc
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_ARC_ENTERPRISE_SNAPSHOT_HOURS_POLICY_SERVICE_H_
#define COMPONENTS_ARC_ENTERPRISE_SNAPSHOT_HOURS_POLICY_SERVICE_H_
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "base/util/timer/wall_clock_timer.h"
#include "chromeos/policy/weekly_time/weekly_time_interval.h"
#include "components/prefs/pref_change_registrar.h"
class PrefService;
namespace arc {
namespace data_snapshotd {
// This class handles "DeviceArcDataSnapshotHours" policy, enables/disables ARC
// data snapshot feature, handles ARC data snapshot update intervals.
//
// ArcDataSnapshotdManager is an owner of this object.
class SnapshotHoursPolicyService {
public:
// Observer interface.
class Observer : public base::CheckedObserver {
public:
// Called once ARC data snapshot feature gets disabled by policy.
virtual void OnSnapshotsDisabled() {}
// Called once ARC data snapshot feature gets enabled by policy.
virtual void OnSnapshotsEnabled() {}
// Called once the interval for allowed ARC data snapshot update has
// started/finished.
// The observer can get an end time for started interval via
// snapshot_update_end_time().
virtual void OnSnapshotUpdateEndTimeChanged() {}
};
explicit SnapshotHoursPolicyService(PrefService* local_state);
SnapshotHoursPolicyService(const SnapshotHoursPolicyService&) = delete;
SnapshotHoursPolicyService& operator=(const SnapshotHoursPolicyService&) =
delete;
~SnapshotHoursPolicyService();
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Starts observing primary profile prefs only for MGS.
void StartObservingPrimaryProfilePrefs(PrefService* profile_prefs);
// Stops observing primary profile prefs.
void StopObservingPrimaryProfilePrefs();
// Returns the end time of the current interval when ARC data snapshot update
// is possible.
// Returns null outside of the interval.
base::Time snapshot_update_end_time() const {
return snapshot_update_end_time_;
}
bool is_snapshot_enabled() const { return is_snapshot_enabled_; }
const std::vector<policy::WeeklyTimeInterval>& get_intervals_for_testing()
const {
return intervals_;
}
const util::WallClockTimer* get_timer_for_testing() const { return &timer_; }
private:
// Processes the policy update: either ArcEnabled and
// DeviceArcDataSnapshotHours.
void UpdatePolicy();
// Disables ARC data snapshot feature and notifies observers if necessary.
void DisableSnapshots();
// Enables ARC data snaoshot feature and notifies observers if necessary.
void EnableSnapshots();
// Updates ARC data snapshot update timer according to the policy.
void UpdateTimer();
// Starts timer with |delay|.
void StartTimer(base::TimeDelta delay);
// Stops timer.
void StopTimer();
// Changes |snapshot_update_end_time_| and notifies observers if necessary.
void SetEndTime(base::Time end_time);
// Notifies observers about relevant events.
void NotifySnapshotsDisabled();
void NotifySnapshotsEnabled();
void NotifySnapshotUpdateEndTimeChanged();
// Returns false if ARC is disabled for a logged-in MGS, otherwise returns
// true.
bool IsArcEnabled() const;
// The feature is disabled when either kArcDataSnapshotHours policy is not set
// or ARC is disabled by policy for MGS.
bool is_snapshot_enabled_ = false;
// Not owned.
PrefService* const local_state_ = nullptr;
// Owned by primary profile.
PrefService* profile_prefs_ = nullptr;
// Registrar for pref changes in local_state_.
PrefChangeRegistrar pref_change_registrar_;
// Registrar for pref changes in profile_prefs_.
PrefChangeRegistrar profile_pref_change_registrar_;
// The end time of the current interval if ARC data snapshot update is
// possible. The value is null outside of all intervals.
base::Time snapshot_update_end_time_;
base::ObserverList<Observer> observers_;
// Current "ArcDataSnapshotHours" time intervals.
std::vector<policy::WeeklyTimeInterval> intervals_;
// Timer for updating ARC data snapshot at the begin of next interval or at
// the end of current interval.
util::WallClockTimer timer_;
base::WeakPtrFactory<SnapshotHoursPolicyService> weak_ptr_factory_{this};
};
} // namespace data_snapshotd
} // namespace arc
#endif // COMPONENTS_ARC_ENTERPRISE_SNAPSHOT_HOURS_POLICY_SERVICE_H_
......@@ -259,7 +259,8 @@ bool FakeUserManager::IsLoggedInAsUserWithGaiaAccount() const {
}
bool FakeUserManager::IsLoggedInAsPublicAccount() const {
return false;
const User* active_user = GetActiveUser();
return active_user && active_user->GetType() == USER_TYPE_PUBLIC_ACCOUNT;
}
bool FakeUserManager::IsLoggedInAsGuest() const {
......
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