Skip to content

Commit

Permalink
Add converter for DeviceOffHoursProto
Browse files Browse the repository at this point in the history
Add converter from DeviceOffHoursProto
to DictionaryValue which is used in
device settings provider and
device policy decoder

Bug: 739713
Change-Id: I3ddd2a605a19a0d357ccc145636e2c90edf08a68
Reviewed-on: https://chromium-review.googlesource.com/623308
Commit-Queue: Daria Iakovleva <yakovleva@google.com>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: Sergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#497359}
  • Loading branch information
Daria Yakovleva authored and Commit Bot committed Aug 25, 2017
1 parent 37d4f63 commit 9faf87c
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 59 deletions.
2 changes: 2 additions & 0 deletions chrome/browser/chromeos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,8 @@ source_set("chromeos") {
"policy/device_local_account_policy_store.h",
"policy/device_network_configuration_updater.cc",
"policy/device_network_configuration_updater.h",
"policy/device_off_hours_controller.cc",
"policy/device_off_hours_controller.h",
"policy/device_policy_decoder_chromeos.cc",
"policy/device_policy_decoder_chromeos.h",
"policy/device_policy_remover.h",
Expand Down
127 changes: 127 additions & 0 deletions chrome/browser/chromeos/policy/device_off_hours_controller.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2017 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 "chrome/browser/chromeos/policy/device_off_hours_controller.h"

#include <string>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/time/time.h"

namespace em = enterprise_management;

namespace policy {
namespace {

// WeeklyTime class contains weekday and time in milliseconds.
struct WeeklyTime {
WeeklyTime(int weekday, int milliseconds)
: weekday(weekday), milliseconds(milliseconds) {}

std::unique_ptr<base::DictionaryValue> ToValue() const {
auto weekly_time = base::MakeUnique<base::DictionaryValue>();
weekly_time->SetInteger("weekday", weekday);
weekly_time->SetInteger("time", milliseconds);
return weekly_time;
}

// Number of weekday (1 = Monday, 2 = Tuesday, etc.)
int weekday;
// Time of day in milliseconds from the beginning of the day.
int milliseconds;
};

// Time interval struct, interval = [start, end]
struct Interval {
Interval(const WeeklyTime& start, const WeeklyTime& end)
: start(start), end(end) {}

std::unique_ptr<base::DictionaryValue> ToValue() const {
auto interval = base::MakeUnique<base::DictionaryValue>();
interval->SetDictionary("start", start.ToValue());
interval->SetDictionary("end", end.ToValue());
return interval;
}

WeeklyTime start;
WeeklyTime end;
};

// Get and return WeeklyTime structure from WeeklyTimeProto
// Return nullptr if WeeklyTime structure isn't correct
std::unique_ptr<WeeklyTime> GetWeeklyTime(
const em::WeeklyTimeProto& container) {
if (!container.has_weekday() ||
container.weekday() == em::WeeklyTimeProto::DAY_OF_WEEK_UNSPECIFIED) {
LOG(ERROR) << "Day of week in interval is absent or unspecified.";
return nullptr;
}
if (!container.has_time()) {
LOG(ERROR) << "Time in interval is absent.";
return nullptr;
}
const int kMillisecondsInDay = base::TimeDelta::FromDays(1).InMilliseconds();
int time_of_day = container.time();
if (!(time_of_day >= 0 && time_of_day < kMillisecondsInDay)) {
LOG(ERROR) << "Invalid time value: " << time_of_day
<< ", the value should be in [0; " << kMillisecondsInDay << ").";
return nullptr;
}
return base::MakeUnique<WeeklyTime>(container.weekday(), time_of_day);
}

// Get and return list of time intervals from DeviceOffHoursProto structure
std::vector<Interval> GetIntervals(const em::DeviceOffHoursProto& container) {
std::vector<Interval> intervals;
for (const auto& entry : container.interval()) {
if (!entry.has_start() || !entry.has_end()) {
LOG(WARNING) << "Skipping interval without start or/and end.";
continue;
}
auto start = GetWeeklyTime(entry.start());
auto end = GetWeeklyTime(entry.end());
if (start && end) {
intervals.push_back(Interval(*start, *end));
}
}
return intervals;
}

std::vector<std::string> GetIgnoredPolicies(
const em::DeviceOffHoursProto& container) {
std::vector<std::string> ignored_policies;
return std::vector<std::string>(container.ignored_policy().begin(),
container.ignored_policy().end());
}

} // namespace

namespace off_hours {

std::unique_ptr<base::DictionaryValue> ConvertPolicyProtoToValue(
const em::DeviceOffHoursProto& container) {
if (!container.has_timezone())
return nullptr;
auto off_hours = base::MakeUnique<base::DictionaryValue>();
off_hours->SetString("timezone", container.timezone());
std::vector<Interval> intervals = GetIntervals(container);
auto intervals_value = base::MakeUnique<base::ListValue>();
for (const auto& interval : intervals) {
intervals_value->Append(interval.ToValue());
}
off_hours->SetList("intervals", std::move(intervals_value));
std::vector<std::string> ignored_policies = GetIgnoredPolicies(container);
auto ignored_policies_value = base::MakeUnique<base::ListValue>();
for (const auto& policy : ignored_policies) {
ignored_policies_value->AppendString(policy);
}
off_hours->SetList("ignored_policies", std::move(ignored_policies_value));
return off_hours;
}

} // namespace off_hours
} // namespace policy
33 changes: 33 additions & 0 deletions chrome/browser/chromeos/policy/device_off_hours_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2017 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 CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_OFF_HOURS_CONTROLLER_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_OFF_HOURS_CONTROLLER_H_

#include <memory>

#include "base/values.h"
#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"

namespace policy {
namespace off_hours {

// Return DictionaryValue in format:
// { "timezone" : string,
// "intervals" : list of Intervals,
// "ignored_policies" : string list }
// Interval dictionary format:
// { "start" : WeeklyTime,
// "end" : WeeklyTime }
// WeeklyTime dictionary format:
// { "weekday" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday, etc.)
// "time" : int # in milliseconds from the beginning of the day.
// }
std::unique_ptr<base::DictionaryValue> ConvertPolicyProtoToValue(
const enterprise_management::DeviceOffHoursProto& container);

} // namespace off_hours
} // namespace policy

#endif // CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_OFF_HOURS_CONTROLLER_H_
66 changes: 7 additions & 59 deletions chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/policy/device_off_hours_controller.h"
#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/update_engine_client.h"
Expand Down Expand Up @@ -111,31 +111,6 @@ std::unique_ptr<base::Value> DecodeConnectionType(int value) {
return base::MakeUnique<base::Value>(kConnectionTypes[value]);
}

// Parse Timestamp to Dictionary
std::unique_ptr<base::DictionaryValue> ParseWeeklyTime(
const em::WeeklyTimeProto& weekly_time) {
auto weekly_time_res = base::MakeUnique<base::DictionaryValue>();
if (!weekly_time.has_weekday() ||
weekly_time.weekday() == em::WeeklyTimeProto::DAY_OF_WEEK_UNSPECIFIED) {
LOG(ERROR) << "Day of week in interval absent or unspecified.";
return nullptr;
}
if (!weekly_time.has_time()) {
LOG(ERROR) << "Time in interval can't be absent.";
return nullptr;
}
weekly_time_res->SetInteger("weekday", weekly_time.weekday());
int time_of_day = weekly_time.time();
const int kMillisecondsInDay = base::TimeDelta::FromDays(1).InMilliseconds();
if (!(time_of_day >= 0 && time_of_day < kMillisecondsInDay)) {
LOG(ERROR) << "Invalid time value: " << time_of_day
<< ", the value should be in [0; " << kMillisecondsInDay << ").";
return nullptr;
}
weekly_time_res->SetInteger("time", time_of_day);
return weekly_time_res;
}

void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy,
PolicyMap* policies) {
if (policy.has_guest_mode_enabled()) {
Expand Down Expand Up @@ -913,39 +888,12 @@ void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
}

if (policy.has_device_off_hours()) {
const em::DeviceOffHoursProto& container(policy.device_off_hours());
auto off_hours = base::MakeUnique<base::DictionaryValue>();
auto intervals = base::MakeUnique<base::ListValue>();
for (const auto& entry : container.interval()) {
auto interval = base::MakeUnique<base::DictionaryValue>();
if (entry.has_start()) {
auto start = ParseWeeklyTime(entry.start());
if (!start) {
continue;
}
interval->SetDictionary("start", std::move(start));
}
if (entry.has_end()) {
auto end = ParseWeeklyTime(entry.end());
if (!end) {
continue;
}
interval->SetDictionary("end", std::move(end));
}
intervals->Append(std::move(interval));
}
off_hours->SetList("intervals", std::move(intervals));
auto policy = base::MakeUnique<base::ListValue>();
for (const auto& entry : container.ignored_policy()) {
policy->AppendString(entry);
}
off_hours->SetList("ignored_policies", std::move(policy));
if (container.has_timezone()) {
off_hours->SetString("timezone", container.timezone());
}
policies->Set(key::kDeviceOffHours, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
std::move(off_hours), nullptr);
auto off_hours_policy =
off_hours::ConvertPolicyProtoToValue(policy.device_off_hours());
if (off_hours_policy)
policies->Set(key::kDeviceOffHours, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
std::move(off_hours_policy), nullptr);
}

if (policy.has_cast_receiver_name()) {
Expand Down
9 changes: 9 additions & 0 deletions chrome/browser/chromeos/settings/device_settings_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/policy/device_off_hours_controller.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_cache.h"
#include "chrome/browser/metrics/metrics_reporting_state.h"
Expand Down Expand Up @@ -100,6 +101,7 @@ const char* const kKnownSettings[] = {
kVariationsRestrictParameter,
kDeviceLoginScreenLocales,
kDeviceLoginScreenInputMethods,
kDeviceOffHours,
};

void DecodeLoginPolicies(
Expand Down Expand Up @@ -565,6 +567,13 @@ void DecodeGenericPolicies(
policy.device_wallpaper_image().device_wallpaper_image()));
new_values_cache->SetValue(kDeviceWallpaperImage, std::move(dict_val));
}

if (policy.has_device_off_hours()) {
auto off_hours_policy =
policy::off_hours::ConvertPolicyProtoToValue(policy.device_off_hours());
if (off_hours_policy)
new_values_cache->SetValue(kDeviceOffHours, std::move(off_hours_policy));
}
}

void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
Expand Down
16 changes: 16 additions & 0 deletions chromeos/settings/cros_settings_names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,20 @@ const char kDeviceLoginScreenInputMethods[] =
// A boolean pref that matches enable-per-user-time-zone chrome://flags value.
const char kPerUserTimezoneEnabled[] = "cros.flags.per_user_timezone_enabled";

// A dictionary pref containing time intervals and ignored policies.
// It's used to allow less restricted usage of Chrome OS during off-hours.
// This pref is set by an admin policy.
// Pref format:
// { "timezone" : string,
// "intervals" : list of Intervals,
// "ignored_policies" : string list }
// Interval dictionary format:
// { "start" : WeeklyTime,
// "end" : WeeklyTime }
// WeeklyTime dictionary format:
// { "weekday" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday, etc.)
// "time" : int # in milliseconds from the beginning of the day.
// }
const char kDeviceOffHours[] = "cros.device_off_hours";

} // namespace chromeos
2 changes: 2 additions & 0 deletions chromeos/settings/cros_settings_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ CHROMEOS_EXPORT extern const char kDeviceLoginScreenInputMethods[];

CHROMEOS_EXPORT extern const char kPerUserTimezoneEnabled[];

CHROMEOS_EXPORT extern const char kDeviceOffHours[];

} // namespace chromeos

#endif // CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_

0 comments on commit 9faf87c

Please sign in to comment.