| // Copyright 2016 The Chromium OS 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 "authpolicy/policy/device_policy_encoder.h" |
| |
| #include <limits> |
| #include <memory> |
| #include <utility> |
| |
| #include <base/bind.h> |
| #include <base/callback.h> |
| #include <base/callback_helpers.h> |
| #include <base/check.h> |
| #include <base/json/json_reader.h> |
| #include <base/stl_util.h> |
| #include <base/strings/string_number_conversions.h> |
| #include <components/policy/core/common/registry_dict.h> |
| #include <dbus/shill/dbus-constants.h> |
| #include <google/protobuf/repeated_field.h> |
| |
| #include "bindings/chrome_device_policy.pb.h" |
| #include "bindings/policy_constants.h" |
| |
| namespace em = enterprise_management; |
| |
| namespace policy { |
| using ::google::protobuf::RepeatedPtrField; |
| |
| // Types must be defined in order of definition in |
| // AutoUpdateSettingsProto_ConnectionType for the static_assert to work as |
| // expected. |
| constexpr std::pair<const char*, int> kConnectionTypes[] = { |
| std::make_pair( |
| shill::kTypeEthernet, |
| em::AutoUpdateSettingsProto_ConnectionType_CONNECTION_TYPE_ETHERNET), |
| std::make_pair( |
| shill::kTypeWifi, |
| em::AutoUpdateSettingsProto_ConnectionType_CONNECTION_TYPE_WIFI), |
| std::make_pair( |
| shill::kTypeCellular, |
| em::AutoUpdateSettingsProto_ConnectionType_CONNECTION_TYPE_CELLULAR)}; |
| |
| constexpr size_t kConnectionTypesSize = base::size(kConnectionTypes); |
| |
| // Integer range for DeviceLoginScreenScreenMagnifierType policy. |
| constexpr int kScreenMagnifierTypeRangeMin = 0; |
| constexpr int kScreenMagnifierTypeRangeMax = 2; |
| |
| // Integer range for kDeviceCrostiniArcAdbSideloadingAllowed policy. |
| constexpr int kDeviceCrostiniArcAdbSideloadingAllowedRangeMin = 0; |
| constexpr int kDeviceCrostiniArcAdbSideloadingAllowedRangeMax = 2; |
| |
| // Integer range for DeviceChromeVariations policy. |
| constexpr int kChromeVariationsRangeMin = 0; |
| constexpr int kChromeVariationsRangeMax = 2; |
| |
| static_assert(em::AutoUpdateSettingsProto_ConnectionType_ConnectionType_MAX == |
| kConnectionTypes[kConnectionTypesSize - 1].second, |
| "Add all supported values here"); |
| |
| namespace { |
| |
| // Translates string connection types to enums. |
| bool DecodeConnectionType(const std::string& value, |
| em::AutoUpdateSettingsProto_ConnectionType* type) { |
| DCHECK(type); |
| |
| for (size_t n = 0; n < base::size(kConnectionTypes); ++n) { |
| if (value.compare(kConnectionTypes[n].first) == 0) { |
| int int_type = kConnectionTypes[n].second; |
| DCHECK(em::AutoUpdateSettingsProto_ConnectionType_IsValid(int_type)); |
| *type = static_cast<em::AutoUpdateSettingsProto_ConnectionType>(int_type); |
| return true; |
| } |
| } |
| |
| LOG(ERROR) << "Invalid connection type '" << value << "'."; |
| return false; |
| } |
| |
| // Parses the |json| string to a dictionary type base::Value. Returns nullopt on |
| // error and sets the |error| string. |
| base::Optional<base::Value> JsonToDictionary(const std::string& json, |
| std::string* error) { |
| DCHECK(error); |
| auto root = base::JSONReader::ReadAndReturnValueWithError( |
| json, base::JSON_ALLOW_TRAILING_COMMAS); |
| if (!root.value) { |
| *error = root.error_message; |
| return base::nullopt; |
| } |
| |
| if (!root.value->is_dict()) { |
| *error = "JSON is not a dictionary: '" + json + "'"; |
| return base::nullopt; |
| } |
| return std::move(root.value); |
| } |
| |
| #define CONVERT_DAY_OF_WEEK(day_of_week) \ |
| if (str == #day_of_week) \ |
| return base::make_optional(em::WeeklyTimeProto::day_of_week); |
| |
| base::Optional<em::WeeklyTimeProto::DayOfWeek> StringToDayOfWeek( |
| const std::string& str) { |
| CONVERT_DAY_OF_WEEK(MONDAY); |
| CONVERT_DAY_OF_WEEK(TUESDAY); |
| CONVERT_DAY_OF_WEEK(WEDNESDAY); |
| CONVERT_DAY_OF_WEEK(THURSDAY); |
| CONVERT_DAY_OF_WEEK(FRIDAY); |
| CONVERT_DAY_OF_WEEK(SATURDAY); |
| CONVERT_DAY_OF_WEEK(SUNDAY); |
| return base::nullopt; |
| } |
| |
| #undef CONVERT_WEEKDAY |
| |
| // Converts a dictionary |value| to a WeeklyTimeProto |proto|. |
| bool EncodeWeeklyTimeProto(const base::Value& value, |
| em::WeeklyTimeProto* proto) { |
| if (!value.is_dict()) |
| return false; |
| |
| const std::string* day_of_week_str = value.FindStringKey("day_of_week"); |
| if (!day_of_week_str) |
| return false; |
| |
| auto day_of_week = StringToDayOfWeek(*day_of_week_str); |
| auto time = value.FindIntKey("time"); |
| if (!day_of_week.has_value() || !time.has_value()) |
| return false; |
| |
| proto->set_day_of_week(*day_of_week); |
| proto->set_time(*time); |
| return true; |
| } |
| |
| // Converts the dictionary |value| to a WeeklyTimeIntervalProto |proto|. |
| bool EncodeWeeklyTimeIntervalProto(const base::Value& value, |
| em::WeeklyTimeIntervalProto* proto) { |
| if (!value.is_dict()) |
| return false; |
| |
| const base::Value* start = value.FindDictKey("start"); |
| if (!start) |
| return false; |
| |
| const base::Value* end = value.FindDictKey("end"); |
| if (!end) |
| return false; |
| |
| DCHECK(start && end); |
| return EncodeWeeklyTimeProto(*start, proto->mutable_start()) && |
| EncodeWeeklyTimeProto(*end, proto->mutable_end()); |
| } |
| |
| void CopyStringListPolicy(const std::vector<std::string>& list, |
| RepeatedPtrField<std::string>* proto_list) { |
| *proto_list = {list.begin(), list.end()}; |
| } |
| |
| // Copies either `new_list` (preferred) or `old_list` to the specified |
| // proto_list. At least one of new_list or old_list must have a value. |
| void CopyStringListPolicyWithFallback( |
| const base::Optional<std::vector<std::string>>& new_list, |
| const base::Optional<std::vector<std::string>>& old_list, |
| RepeatedPtrField<std::string>* proto_list) { |
| if (new_list) { |
| CopyStringListPolicy(new_list.value(), proto_list); |
| } else { |
| DCHECK(old_list); |
| CopyStringListPolicy(old_list.value(), proto_list); |
| } |
| } |
| |
| } // namespace |
| |
| DevicePolicyEncoder::DevicePolicyEncoder(const RegistryDict* dict, |
| const PolicyLevel level) |
| : dict_(dict), level_(level) {} |
| |
| void DevicePolicyEncoder::EncodePolicy( |
| em::ChromeDeviceSettingsProto* policy) const { |
| LOG_IF(INFO, log_policy_values_) |
| << authpolicy::kColorPolicy << "Device policy (" |
| << (level_ == POLICY_LEVEL_RECOMMENDED ? "recommended" : "mandatory") |
| << ")" << authpolicy::kColorReset; |
| if (level_ == POLICY_LEVEL_MANDATORY) { |
| // All of the following policies support only mandatory level, so there's no |
| // benefit on trying re-encoding them when the supported level is |
| // recommended. |
| EncodeLoginPolicies(policy); |
| EncodeNetworkPolicies(policy); |
| EncodeAutoUpdatePolicies(policy); |
| EncodeAccessibilityPolicies(policy); |
| EncodeGenericPolicies(policy); |
| } |
| EncodePoliciesWithPolicyOptions(policy); |
| } |
| |
| void DevicePolicyEncoder::EncodeLoginPolicies( |
| em::ChromeDeviceSettingsProto* policy) const { |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceGuestModeEnabled)) |
| policy->mutable_guest_mode_enabled()->set_guest_mode_enabled(value.value()); |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceRebootOnShutdown)) |
| policy->mutable_reboot_on_shutdown()->set_reboot_on_shutdown(value.value()); |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceShowUserNamesOnSignin)) |
| policy->mutable_show_user_names()->set_show_user_names(value.value()); |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceAllowNewUsers)) |
| policy->mutable_allow_new_users()->set_allow_new_users(value.value()); |
| // The original policy has been replaced by an inclusively named version. For |
| // backwards compatibility, copy the original policy to the newly named proto |
| // if no value exists for the newly named proto. |
| base::Optional<std::vector<std::string>> user_allowlist_values = |
| EncodeStringList(key::kDeviceUserAllowlist); |
| base::Optional<std::vector<std::string>> user_whitelist_values = |
| EncodeStringList(key::kDeviceUserWhitelist); |
| if (user_allowlist_values || user_whitelist_values) { |
| CopyStringListPolicyWithFallback( |
| user_allowlist_values, user_whitelist_values, |
| policy->mutable_user_allowlist()->mutable_user_allowlist()); |
| } |
| if (user_whitelist_values) { |
| CopyStringListPolicy( |
| user_whitelist_values.value(), |
| policy->mutable_user_whitelist()->mutable_user_whitelist()); |
| } |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceEphemeralUsersEnabled)) |
| policy->mutable_ephemeral_users_enabled()->set_ephemeral_users_enabled( |
| value.value()); |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceAllowBluetooth)) |
| policy->mutable_allow_bluetooth()->set_allow_bluetooth(value.value()); |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kDeviceLoginScreenExtensions)) { |
| *policy->mutable_device_login_screen_extensions() |
| ->mutable_device_login_screen_extensions() = {values.value().begin(), |
| values.value().end()}; |
| } |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceLoginScreenDomainAutoComplete)) { |
| policy->mutable_login_screen_domain_auto_complete() |
| ->set_login_screen_domain_auto_complete(value.value()); |
| } |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kDeviceLoginScreenLocales)) { |
| *policy->mutable_login_screen_locales()->mutable_login_screen_locales() = { |
| values.value().begin(), values.value().end()}; |
| } |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kDeviceLoginScreenInputMethods)) { |
| *policy->mutable_login_screen_input_methods() |
| ->mutable_login_screen_input_methods() = {values.value().begin(), |
| values.value().end()}; |
| } |
| if (base::Optional<std::vector<std::string>> values = EncodeStringList( |
| key::kDeviceLoginScreenAutoSelectCertificateForUrls)) { |
| *policy->mutable_device_login_screen_auto_select_certificate_for_urls() |
| ->mutable_login_screen_auto_select_certificate_rules() = { |
| values.value().begin(), values.value().end()}; |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceRebootOnUserSignout)) { |
| policy->mutable_device_reboot_on_user_signout()->set_reboot_on_signout_mode( |
| static_cast<em::DeviceRebootOnUserSignoutProto_RebootOnSignoutMode>( |
| value.value())); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDevicePowerwashAllowed)) { |
| policy->mutable_device_powerwash_allowed()->set_device_powerwash_allowed( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = EncodeIntegerInRange( |
| key::kDeviceChromeVariations, kChromeVariationsRangeMin, |
| kChromeVariationsRangeMax)) { |
| policy->mutable_device_chrome_variations_type()->set_value(value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenPrivacyScreenEnabled)) { |
| policy->mutable_device_login_screen_privacy_screen_enabled()->set_enabled( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceShowNumericKeyboardForPassword)) { |
| policy->mutable_device_show_numeric_keyboard_for_password()->set_value( |
| value.value()); |
| } |
| |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kDeviceWebBasedAttestationAllowedUrls)) { |
| *policy->mutable_device_web_based_attestation_allowed_urls() |
| ->mutable_value() |
| ->mutable_entries() = {values.value().begin(), values.value().end()}; |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceMinimumVersion)) |
| policy->mutable_device_minimum_version()->set_value(value.value()); |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceMinimumVersionAueMessage)) { |
| policy->mutable_device_minimum_version_aue_message()->set_value( |
| value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kRequiredClientCertificateForDevice)) { |
| policy->mutable_required_client_certificate_for_device() |
| ->set_required_client_certificate_for_device(value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kSystemProxySettings)) { |
| std::string error; |
| base::Optional<base::Value> dict_value = |
| JsonToDictionary(value.value(), &error); |
| if (!dict_value) { |
| LOG(ERROR) << "Failed to parse string as dictionary: '" |
| << (!error.empty() ? error : value.value()) << "' for policy '" |
| << key::kSystemProxySettings << "', ignoring."; |
| } else { |
| policy->mutable_system_proxy_settings()->set_system_proxy_settings( |
| value.value()); |
| } |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kManagedGuestSessionPrivacyWarningsEnabled)) { |
| policy->mutable_managed_guest_session_privacy_warnings()->set_enabled( |
| value.value()); |
| } |
| } |
| |
| void DevicePolicyEncoder::EncodeNetworkPolicies( |
| em::ChromeDeviceSettingsProto* policy) const { |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceDataRoamingEnabled)) { |
| policy->mutable_data_roaming_enabled()->set_data_roaming_enabled( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceWiFiFastTransitionEnabled)) { |
| policy->mutable_device_wifi_fast_transition_enabled() |
| ->set_device_wifi_fast_transition_enabled(value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceOpenNetworkConfiguration)) { |
| policy->mutable_open_network_configuration() |
| ->set_open_network_configuration(value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceHostnameTemplate)) { |
| policy->mutable_network_hostname()->set_device_hostname_template( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceKerberosEncryptionTypes)) { |
| policy->mutable_device_kerberos_encryption_types()->set_types( |
| static_cast<em::DeviceKerberosEncryptionTypesProto_Types>( |
| value.value())); |
| } |
| } |
| |
| void DevicePolicyEncoder::EncodeAutoUpdatePolicies( |
| em::ChromeDeviceSettingsProto* policy) const { |
| if (base::Optional<std::string> value = |
| EncodeString(key::kChromeOsReleaseChannel)) |
| policy->mutable_release_channel()->set_release_channel(value.value()); |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kChromeOsReleaseChannelDelegated)) { |
| policy->mutable_release_channel()->set_release_channel_delegated( |
| value.value()); |
| } |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceReleaseLtsTag)) { |
| policy->mutable_release_channel()->set_release_lts_tag(value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceAutoUpdateDisabled)) |
| policy->mutable_auto_update_settings()->set_update_disabled(value.value()); |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceTargetVersionPrefix)) { |
| policy->mutable_auto_update_settings()->set_target_version_prefix( |
| value.value()); |
| } |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceRollbackToTargetVersion)) { |
| policy->mutable_auto_update_settings()->set_rollback_to_target_version( |
| static_cast<em::AutoUpdateSettingsProto_RollbackToTargetVersion>( |
| value.value())); |
| } |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceRollbackAllowedMilestones)) { |
| policy->mutable_auto_update_settings()->set_rollback_allowed_milestones( |
| value.value()); |
| } |
| |
| // target_version_display_name is not actually a policy, but a display |
| // string for target_version_prefix, so we ignore it. It seems to be |
| // unreferenced as well. |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceUpdateScatterFactor)) { |
| policy->mutable_auto_update_settings()->set_scatter_factor_in_seconds( |
| value.value()); |
| } |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kDeviceUpdateAllowedConnectionTypes)) { |
| auto list = policy->mutable_auto_update_settings(); |
| list->clear_allowed_connection_types(); |
| for (const std::string& value : values.value()) { |
| em::AutoUpdateSettingsProto_ConnectionType type; |
| if (DecodeConnectionType(value, &type)) |
| list->add_allowed_connection_types(type); |
| } |
| } |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceUpdateHttpDownloadsEnabled)) { |
| policy->mutable_auto_update_settings()->set_http_downloads_enabled( |
| value.value()); |
| } |
| if (base::Optional<bool> value = EncodeBoolean(key::kRebootAfterUpdate)) { |
| policy->mutable_auto_update_settings()->set_reboot_after_update( |
| value.value()); |
| } |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceAutoUpdateP2PEnabled)) |
| policy->mutable_auto_update_settings()->set_p2p_enabled(value.value()); |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceAutoUpdateTimeRestrictions)) { |
| policy->mutable_auto_update_settings()->set_disallowed_time_intervals( |
| value.value()); |
| } |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceUpdateStagingSchedule)) |
| policy->mutable_auto_update_settings()->set_staging_schedule(value.value()); |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceQuickFixBuildToken)) { |
| policy->mutable_auto_update_settings()->set_device_quick_fix_build_token( |
| value.value()); |
| } |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceLoginScreenWebUsbAllowDevicesForUrls)) { |
| policy->mutable_device_login_screen_webusb_allow_devices_for_urls() |
| ->set_device_login_screen_webusb_allow_devices_for_urls(value.value()); |
| } |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceChannelDowngradeBehavior)) { |
| if (em::AutoUpdateSettingsProto::ChannelDowngradeBehavior_IsValid( |
| value.value())) { |
| policy->mutable_auto_update_settings()->set_channel_downgrade_behavior( |
| static_cast<em::AutoUpdateSettingsProto::ChannelDowngradeBehavior>( |
| value.value())); |
| } else { |
| LOG(ERROR) << "Invalid enum value " << value.value() << " for policy " |
| << key::kDeviceChannelDowngradeBehavior; |
| } |
| } |
| } |
| |
| void DevicePolicyEncoder::EncodeAccessibilityPolicies( |
| em::ChromeDeviceSettingsProto* policy) const { |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenDefaultLargeCursorEnabled)) { |
| policy->mutable_accessibility_settings() |
| ->set_login_screen_default_large_cursor_enabled(value.value()); |
| } |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled)) { |
| policy->mutable_accessibility_settings() |
| ->set_login_screen_default_spoken_feedback_enabled(value.value()); |
| } |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenDefaultHighContrastEnabled)) { |
| policy->mutable_accessibility_settings() |
| ->set_login_screen_default_high_contrast_enabled(value.value()); |
| } |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceLoginScreenDefaultScreenMagnifierType)) { |
| policy->mutable_accessibility_settings() |
| ->set_login_screen_default_screen_magnifier_type( |
| static_cast<em::AccessibilitySettingsProto_ScreenMagnifierType>( |
| value.value())); |
| } |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled)) { |
| policy->mutable_accessibility_settings() |
| ->set_login_screen_default_virtual_keyboard_enabled(value.value()); |
| } |
| } |
| |
| void DevicePolicyEncoder::EncodePoliciesWithPolicyOptions( |
| em::ChromeDeviceSettingsProto* policy) const { |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenLargeCursorEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_large_cursor_enabled( |
| value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_large_cursor_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenAutoclickEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_autoclick_enabled(value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_autoclick_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenCaretHighlightEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_caret_highlight_enabled( |
| value.value()); |
| SetPolicyOptions( |
| accessibility_settings |
| ->mutable_login_screen_caret_highlight_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenCursorHighlightEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_cursor_highlight_enabled( |
| value.value()); |
| SetPolicyOptions( |
| accessibility_settings |
| ->mutable_login_screen_cursor_highlight_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenDictationEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_dictation_enabled(value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_dictation_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenHighContrastEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_high_contrast_enabled( |
| value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_high_contrast_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenMonoAudioEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_mono_audio_enabled(value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_mono_audio_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenSelectToSpeakEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_select_to_speak_enabled( |
| value.value()); |
| SetPolicyOptions( |
| accessibility_settings |
| ->mutable_login_screen_select_to_speak_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenSpokenFeedbackEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_spoken_feedback_enabled( |
| value.value()); |
| SetPolicyOptions( |
| accessibility_settings |
| ->mutable_login_screen_spoken_feedback_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenStickyKeysEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_sticky_keys_enabled(value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_sticky_keys_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceLoginScreenVirtualKeyboardEnabled)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_virtual_keyboard_enabled( |
| value.value()); |
| SetPolicyOptions( |
| accessibility_settings |
| ->mutable_login_screen_virtual_keyboard_enabled_options(), |
| level_); |
| } |
| |
| if (base::Optional<int> value = EncodeIntegerInRange( |
| key::kDeviceLoginScreenScreenMagnifierType, |
| kScreenMagnifierTypeRangeMin, kScreenMagnifierTypeRangeMax)) { |
| em::AccessibilitySettingsProto* accessibility_settings = |
| policy->mutable_accessibility_settings(); |
| accessibility_settings->set_login_screen_screen_magnifier_type( |
| value.value()); |
| SetPolicyOptions(accessibility_settings |
| ->mutable_login_screen_screen_magnifier_type_options(), |
| level_); |
| } |
| } |
| |
| void DevicePolicyEncoder::EncodeGenericPolicies( |
| em::ChromeDeviceSettingsProto* policy) const { |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDevicePolicyRefreshRate)) { |
| policy->mutable_device_policy_refresh_rate() |
| ->set_device_policy_refresh_rate(value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceMetricsReportingEnabled)) |
| policy->mutable_metrics_enabled()->set_metrics_enabled(value.value()); |
| |
| if (base::Optional<std::string> value = EncodeString(key::kSystemTimezone)) |
| policy->mutable_system_timezone()->set_timezone(value.value()); |
| if (base::Optional<int> value = |
| EncodeInteger(key::kSystemTimezoneAutomaticDetection)) { |
| policy->mutable_system_timezone()->set_timezone_detection_type( |
| static_cast<em::SystemTimezoneProto_AutomaticTimezoneDetectionType>( |
| value.value())); |
| } |
| if (base::Optional<bool> value = EncodeBoolean(key::kSystemUse24HourClock)) |
| policy->mutable_use_24hour_clock()->set_use_24hour_clock(value.value()); |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceAllowRedeemChromeOsRegistrationOffers)) { |
| policy->mutable_allow_redeem_offers()->set_allow_redeem_offers( |
| value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceVariationsRestrictParameter)) |
| policy->mutable_variations_parameter()->set_parameter(value.value()); |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceLoginScreenPowerManagement)) { |
| policy->mutable_login_screen_power_management() |
| ->set_login_screen_power_management(value.value()); |
| } |
| |
| if (base::Optional<int> value = EncodeInteger(key::kDisplayRotationDefault)) { |
| policy->mutable_display_rotation_default()->set_display_rotation_default( |
| static_cast<em::DisplayRotationDefaultProto_Rotation>(value.value())); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceDisplayResolution)) { |
| policy->mutable_device_display_resolution()->set_device_display_resolution( |
| value.value()); |
| } |
| |
| // The original policy has been replaced by an inclusively named version. For |
| // backwards compatibility, copy the original policy to the newly named proto |
| // if no value exists for the newly named proto. |
| base::Optional<std::vector<std::string>> usb_detachable_allowlist_values = |
| EncodeStringList(key::kUsbDetachableAllowlist); |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kUsbDetachableWhitelist)) { |
| auto whitelist = policy->mutable_usb_detachable_whitelist(); |
| auto allowlist = policy->mutable_usb_detachable_allowlist(); |
| DCHECK(!whitelist->id_size()); |
| if (!usb_detachable_allowlist_values) { |
| DCHECK(!allowlist->id_size()); |
| } |
| for (const std::string& value : values.value()) { |
| std::string error; |
| base::Optional<base::Value> dict_value = JsonToDictionary(value, &error); |
| if (!dict_value) { |
| LOG(ERROR) << "Failed to parse string as dictionary: '" |
| << (!error.empty() ? error : value) << "' for policy '" |
| << key::kUsbDetachableWhitelist << "', ignoring."; |
| continue; |
| } |
| |
| base::Optional<int> vid = dict_value->FindIntKey("vendor_id"); |
| base::Optional<int> pid = dict_value->FindIntKey("product_id"); |
| if (!vid.has_value() || !pid.has_value()) { |
| LOG(ERROR) << "Invalid JSON string '" |
| << (!error.empty() ? error : value) << "' for policy '" |
| << key::kUsbDetachableWhitelist << "', ignoring. Expected: " |
| << "'{\"vendor_id\"=<vid>, \"product_id\"=<pid>}'."; |
| continue; |
| } |
| |
| em::UsbDeviceIdProto* whitelist_entry = whitelist->add_id(); |
| whitelist_entry->set_vendor_id(*vid); |
| whitelist_entry->set_product_id(*pid); |
| |
| if (!usb_detachable_allowlist_values) { |
| em::UsbDeviceIdInclusiveProto* allowlist_entry = allowlist->add_id(); |
| allowlist_entry->set_vendor_id(*vid); |
| allowlist_entry->set_product_id(*pid); |
| } |
| } |
| } |
| |
| if (usb_detachable_allowlist_values) { |
| auto list = policy->mutable_usb_detachable_allowlist(); |
| DCHECK(!list->id_size()); |
| for (const std::string& value : usb_detachable_allowlist_values.value()) { |
| std::string error; |
| base::Optional<base::Value> dict_value = JsonToDictionary(value, &error); |
| if (!dict_value) { |
| LOG(ERROR) << "Failed to parse string as dictionary: '" |
| << (!error.empty() ? error : value) << "' for policy '" |
| << key::kUsbDetachableAllowlist << "', ignoring."; |
| continue; |
| } |
| base::Optional<int> vid = dict_value->FindIntKey("vendor_id"); |
| base::Optional<int> pid = dict_value->FindIntKey("product_id"); |
| if (!vid.has_value() || !pid.has_value()) { |
| LOG(ERROR) << "Invalid JSON string '" |
| << (!error.empty() ? error : value) << "' for policy '" |
| << key::kUsbDetachableAllowlist << "', ignoring. Expected: " |
| << "'{\"vendor_id\": <vid>, \"product_id\": <pid>}'."; |
| continue; |
| } |
| |
| em::UsbDeviceIdInclusiveProto* entry = list->add_id(); |
| entry->set_vendor_id(*vid); |
| entry->set_product_id(*pid); |
| } |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceQuirksDownloadEnabled)) { |
| policy->mutable_quirks_download_enabled()->set_quirks_download_enabled( |
| value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceWallpaperImage)) { |
| policy->mutable_device_wallpaper_image()->set_device_wallpaper_image( |
| value.value()); |
| } |
| |
| if (base::Optional<std::string> value = EncodeString(key::kDeviceOffHours)) { |
| std::string error; |
| base::Optional<base::Value> dict_value = |
| JsonToDictionary(value.value(), &error); |
| bool is_error = !dict_value; |
| auto proto = std::make_unique<em::DeviceOffHoursProto>(); |
| if (!is_error) { |
| const base::Value* intervals = dict_value->FindListKey("intervals"); |
| const base::Value* ignored_policy_proto_tags = |
| dict_value->FindListKey("ignored_policy_proto_tags"); |
| const std::string* timezone = dict_value->FindStringKey("timezone"); |
| is_error = !intervals || !ignored_policy_proto_tags || !timezone; |
| |
| if (!is_error) { |
| proto->set_timezone(*timezone); |
| |
| for (const base::Value& entry : intervals->GetList()) { |
| is_error |= |
| !EncodeWeeklyTimeIntervalProto(entry, proto->add_intervals()); |
| } |
| |
| for (const base::Value& entry : ignored_policy_proto_tags->GetList()) { |
| int tag = 0; |
| if (entry.is_int()) |
| tag = entry.GetInt(); |
| else |
| is_error = true; |
| proto->add_ignored_policy_proto_tags(tag); |
| } |
| } |
| } |
| |
| if (is_error) { |
| LOG(ERROR) << "Invalid JSON string '" |
| << (!error.empty() ? error : value.value()) << "' for policy '" |
| << key::kDeviceOffHours << "', ignoring. " |
| << "See policy_templates.json for example."; |
| } else { |
| policy->set_allocated_device_off_hours(proto.release()); |
| } |
| } |
| |
| if (base::Optional<std::string> value = EncodeString(key::kCastReceiverName)) |
| policy->mutable_cast_receiver_name()->set_name(value.value()); |
| |
| // The original policy has been replaced by an inclusively named version. For |
| // backwards compatibility, copy the original policy to the newly named proto |
| // if no value exists for the newly named proto. |
| base::Optional<std::string> device_printers_value = |
| EncodeString(key::kDevicePrinters); |
| base::Optional<std::string> device_native_printers_value = |
| EncodeString(key::kDeviceNativePrinters); |
| if (device_printers_value || device_native_printers_value) { |
| policy->mutable_device_printers()->set_external_policy( |
| device_printers_value ? device_printers_value.value() |
| : device_native_printers_value.value()); |
| } |
| if (device_native_printers_value) { |
| policy->mutable_native_device_printers()->set_external_policy( |
| device_native_printers_value.value()); |
| } |
| |
| // The original policy has been replaced by an inclusively named version. For |
| // backwards compatibility, copy the original policy to the newly named proto |
| // if no value exists for the newly named proto. |
| base::Optional<int> device_printers_access_mode_value = |
| EncodeInteger(key::kDevicePrintersAccessMode); |
| base::Optional<int> device_native_printers_access_mode_value = |
| EncodeInteger(key::kDeviceNativePrintersAccessMode); |
| if (device_printers_access_mode_value || |
| device_native_printers_access_mode_value) { |
| policy->mutable_device_printers_access_mode()->set_access_mode( |
| static_cast<em::DevicePrintersAccessModeProto_AccessMode>( |
| device_printers_access_mode_value |
| ? device_printers_access_mode_value.value() |
| : device_native_printers_access_mode_value.value())); |
| } |
| if (device_native_printers_access_mode_value) { |
| policy->mutable_native_device_printers_access_mode()->set_access_mode( |
| static_cast<em::DeviceNativePrintersAccessModeProto_AccessMode>( |
| device_native_printers_access_mode_value.value())); |
| } |
| |
| // The original policy has been replaced by an inclusively named version. For |
| // backwards compatibility, copy the original policy to the newly named proto |
| // if no value exists for the newly named proto. |
| base::Optional<std::vector<std::string>> device_printers_blocklist_value = |
| EncodeStringList(key::kDevicePrintersBlocklist); |
| base::Optional<std::vector<std::string>> |
| device_native_printers_blacklist_value = |
| EncodeStringList(key::kDeviceNativePrintersBlacklist); |
| if (device_printers_blocklist_value || |
| device_native_printers_blacklist_value) { |
| CopyStringListPolicyWithFallback( |
| device_printers_blocklist_value, device_native_printers_blacklist_value, |
| policy->mutable_device_printers_blocklist()->mutable_blocklist()); |
| } |
| if (device_native_printers_blacklist_value) { |
| CopyStringListPolicy(device_native_printers_blacklist_value.value(), |
| policy->mutable_native_device_printers_blacklist() |
| ->mutable_blacklist()); |
| } |
| |
| // The original policy has been replaced by an inclusively named version. For |
| // backwards compatibility, copy the original policy to the newly named proto |
| // if no value exists for the newly named proto. |
| base::Optional<std::vector<std::string>> device_printers_allowlist_value = |
| EncodeStringList(key::kDevicePrintersAllowlist); |
| base::Optional<std::vector<std::string>> |
| device_native_printers_whitelist_value = |
| EncodeStringList(key::kDeviceNativePrintersWhitelist); |
| if (device_printers_allowlist_value || |
| device_native_printers_whitelist_value) { |
| CopyStringListPolicyWithFallback( |
| device_printers_allowlist_value, device_native_printers_whitelist_value, |
| policy->mutable_device_printers_allowlist()->mutable_allowlist()); |
| } |
| if (device_native_printers_whitelist_value) { |
| CopyStringListPolicy(device_native_printers_whitelist_value.value(), |
| policy->mutable_native_device_printers_whitelist() |
| ->mutable_whitelist()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceExternalPrintServers)) { |
| policy->mutable_external_print_servers()->set_external_policy( |
| value.value()); |
| } |
| if (base::Optional<std::vector<std::string>> values = |
| EncodeStringList(key::kDeviceExternalPrintServersAllowlist)) { |
| *policy->mutable_external_print_servers_allowlist()->mutable_allowlist() = { |
| values.value().begin(), values.value().end()}; |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kTPMFirmwareUpdateSettings)) { |
| std::string error; |
| base::Optional<base::Value> dict_value = |
| JsonToDictionary(value.value(), &error); |
| if (!dict_value) { |
| LOG(ERROR) << "Failed to parse string as dictionary: '" |
| << (!error.empty() ? error : value.value()) << "' for policy '" |
| << key::kTPMFirmwareUpdateSettings << "', ignoring."; |
| } else { |
| em::TPMFirmwareUpdateSettingsProto* settings = |
| policy->mutable_tpm_firmware_update_settings(); |
| for (const auto& item : dict_value->DictItems()) { |
| if (!item.second.is_bool()) { |
| LOG(WARNING) << "Invalid value at: " << item.first; |
| continue; |
| } |
| bool flag = item.second.GetBool(); |
| if (item.first == "allow-user-initiated-powerwash") |
| settings->set_allow_user_initiated_powerwash(flag); |
| else if (item.first == "allow-user-initiated-preserve-device-state") |
| settings->set_allow_user_initiated_preserve_device_state(flag); |
| else |
| LOG(WARNING) << "Unknown JSON key: " << item.first; |
| } |
| } |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kUnaffiliatedArcAllowed)) { |
| policy->mutable_unaffiliated_arc_allowed()->set_unaffiliated_arc_allowed( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceUserPolicyLoopbackProcessingMode)) { |
| policy->mutable_device_user_policy_loopback_processing_mode()->set_mode( |
| static_cast<em::DeviceUserPolicyLoopbackProcessingModeProto::Mode>( |
| value.value())); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kVirtualMachinesAllowed)) { |
| policy->mutable_virtual_machines_allowed()->set_virtual_machines_allowed( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceMachinePasswordChangeRate)) { |
| policy->mutable_device_machine_password_change_rate()->set_rate_days( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = EncodeInteger(key::kDeviceGpoCacheLifetime)) { |
| policy->mutable_device_gpo_cache_lifetime()->set_lifetime_hours( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceAuthDataCacheLifetime)) { |
| policy->mutable_device_auth_data_cache_lifetime()->set_lifetime_hours( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceUnaffiliatedCrostiniAllowed)) { |
| policy->mutable_device_unaffiliated_crostini_allowed() |
| ->set_device_unaffiliated_crostini_allowed(value.value()); |
| } |
| |
| if (base::Optional<bool> value = EncodeBoolean(key::kPluginVmAllowed)) |
| policy->mutable_plugin_vm_allowed()->set_plugin_vm_allowed(value.value()); |
| if (base::Optional<std::string> value = |
| EncodeString(key::kPluginVmLicenseKey)) { |
| policy->mutable_plugin_vm_license_key()->set_plugin_vm_license_key( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceWilcoDtcAllowed)) { |
| policy->mutable_device_wilco_dtc_allowed()->set_device_wilco_dtc_allowed( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceBootOnAcEnabled)) |
| policy->mutable_device_boot_on_ac()->set_enabled(value.value()); |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDevicePowerPeakShiftBatteryThreshold)) { |
| policy->mutable_device_power_peak_shift()->set_battery_threshold( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDevicePowerPeakShiftEnabled)) |
| policy->mutable_device_power_peak_shift()->set_enabled(value.value()); |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDevicePowerPeakShiftDayConfig)) |
| policy->mutable_device_power_peak_shift()->set_day_configs(value.value()); |
| |
| if (base::Optional<bool> value = EncodeBoolean(key::kDeviceWiFiAllowed)) { |
| policy->mutable_device_wifi_allowed()->set_device_wifi_allowed( |
| value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceWilcoDtcConfiguration)) { |
| policy->mutable_device_wilco_dtc_configuration() |
| ->set_device_wilco_dtc_configuration(value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceDockMacAddressSource)) { |
| policy->mutable_device_dock_mac_address_source()->set_source( |
| static_cast<em::DeviceDockMacAddressSourceProto::Source>( |
| value.value())); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceAdvancedBatteryChargeModeEnabled)) { |
| policy->mutable_device_advanced_battery_charge_mode()->set_enabled( |
| value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceAdvancedBatteryChargeModeDayConfig)) { |
| policy->mutable_device_advanced_battery_charge_mode()->set_day_configs( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceBatteryChargeMode)) { |
| policy->mutable_device_battery_charge_mode()->set_battery_charge_mode( |
| static_cast<em::DeviceBatteryChargeModeProto_BatteryChargeMode>( |
| value.value())); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceBatteryChargeCustomStartCharging)) { |
| policy->mutable_device_battery_charge_mode()->set_custom_charge_start( |
| value.value()); |
| } |
| |
| if (base::Optional<int> value = |
| EncodeInteger(key::kDeviceBatteryChargeCustomStopCharging)) { |
| policy->mutable_device_battery_charge_mode()->set_custom_charge_stop( |
| value.value()); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceUsbPowerShareEnabled)) |
| policy->mutable_device_usb_power_share()->set_enabled(value.value()); |
| |
| if (base::Optional<int> value = EncodeIntegerInRange( |
| key::kDeviceCrostiniArcAdbSideloadingAllowed, |
| kDeviceCrostiniArcAdbSideloadingAllowedRangeMin, |
| kDeviceCrostiniArcAdbSideloadingAllowedRangeMax)) { |
| policy->mutable_device_crostini_arc_adb_sideloading_allowed()->set_mode( |
| static_cast< |
| em::DeviceCrostiniArcAdbSideloadingAllowedProto::AllowanceMode>( |
| value.value())); |
| } |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceShowLowDiskSpaceNotification)) |
| policy->mutable_device_show_low_disk_space_notification() |
| ->set_device_show_low_disk_space_notification(value.value()); |
| |
| if (base::Optional<bool> value = |
| EncodeBoolean(key::kDeviceFamilyLinkAccountsAllowed)) { |
| policy->mutable_family_link_accounts_allowed() |
| ->set_family_link_accounts_allowed(value.value()); |
| } |
| |
| if (base::Optional<std::string> value = |
| EncodeString(key::kDeviceArcDataSnapshotHours)) { |
| std::string error; |
| base::Optional<base::Value> dict_value = |
| JsonToDictionary(value.value(), &error); |
| if (!dict_value) { |
| LOG(ERROR) << "Failed to parse string as dictionary: '" |
| << (!error.empty() ? error : value.value()) << "' for policy '" |
| << key::kDeviceArcDataSnapshotHours << "', ignoring."; |
| } else { |
| policy->mutable_arc_data_snapshot_hours()->set_arc_data_snapshot_hours( |
| value.value()); |
| } |
| } |
| } |
| |
| base::Optional<bool> DevicePolicyEncoder::EncodeBoolean( |
| const char* policy_name) const { |
| return EncodeBooleanPolicy(policy_name, GetValueFromDictCallback(dict_), |
| log_policy_values_); |
| } |
| |
| base::Optional<int> DevicePolicyEncoder::EncodeInteger( |
| const char* policy_name) const { |
| return EncodeIntegerInRange(policy_name, std::numeric_limits<int>::min(), |
| std::numeric_limits<int>::max()); |
| } |
| |
| base::Optional<int> DevicePolicyEncoder::EncodeIntegerInRange( |
| const char* policy_name, int range_min, int range_max) const { |
| return EncodeIntegerInRangePolicy(policy_name, |
| GetValueFromDictCallback(dict_), range_min, |
| range_max, log_policy_values_); |
| } |
| |
| base::Optional<std::string> DevicePolicyEncoder::EncodeString( |
| const char* policy_name) const { |
| return EncodeStringPolicy(policy_name, GetValueFromDictCallback(dict_), |
| log_policy_values_); |
| } |
| |
| base::Optional<std::vector<std::string>> DevicePolicyEncoder::EncodeStringList( |
| const char* policy_name) const { |
| const RegistryDict* key = dict_->GetKey(policy_name); |
| if (!key) |
| return base::nullopt; |
| |
| return EncodeStringListPolicy(policy_name, GetValueFromDictCallback(key), |
| log_policy_values_); |
| } |
| |
| } // namespace policy |