1// 2// Copyright (C) 2014 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "update_engine/update_manager/real_device_policy_provider.h" 18 19#include <stdint.h> 20 21#include <base/location.h> 22#include <base/logging.h> 23#include <base/time/time.h> 24#include <policy/device_policy.h> 25 26#include "update_engine/common/utils.h" 27#include "update_engine/update_manager/generic_variables.h" 28#include "update_engine/update_manager/real_shill_provider.h" 29 30using base::TimeDelta; 31using brillo::MessageLoop; 32using policy::DevicePolicy; 33using std::set; 34using std::string; 35 36namespace { 37 38const int kDevicePolicyRefreshRateInMinutes = 60; 39 40} // namespace 41 42namespace chromeos_update_manager { 43 44RealDevicePolicyProvider::~RealDevicePolicyProvider() { 45 MessageLoop::current()->CancelTask(scheduled_refresh_); 46} 47 48bool RealDevicePolicyProvider::Init() { 49 CHECK(policy_provider_ != nullptr); 50 51 // On Init() we try to get the device policy and keep updating it. 52 RefreshDevicePolicyAndReschedule(); 53 54 // We also listen for signals from the session manager to force a device 55 // policy refresh. 56 session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler( 57 base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal, 58 base::Unretained(this)), 59 base::Bind(&RealDevicePolicyProvider::OnSignalConnected, 60 base::Unretained(this))); 61 return true; 62} 63 64void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal( 65 const string& success) { 66 if (success != "success") { 67 LOG(WARNING) << "Received device policy updated signal with a failure."; 68 } 69 // We refresh the policy file even if the payload string is kSignalFailure. 70 LOG(INFO) << "Reloading and re-scheduling device policy due to signal " 71 "received."; 72 MessageLoop::current()->CancelTask(scheduled_refresh_); 73 scheduled_refresh_ = MessageLoop::kTaskIdNull; 74 RefreshDevicePolicyAndReschedule(); 75} 76 77void RealDevicePolicyProvider::OnSignalConnected(const string& interface_name, 78 const string& signal_name, 79 bool successful) { 80 if (!successful) { 81 LOG(WARNING) << "We couldn't connect to SessionManager signal for updates " 82 "on the device policy blob. We will reload the policy file " 83 "periodically."; 84 } 85 // We do a one-time refresh of the DevicePolicy just in case we missed a 86 // signal between the first refresh and the time the signal handler was 87 // actually connected. 88 RefreshDevicePolicy(); 89} 90 91void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() { 92 RefreshDevicePolicy(); 93 scheduled_refresh_ = MessageLoop::current()->PostDelayedTask( 94 FROM_HERE, 95 base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule, 96 base::Unretained(this)), 97 TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes)); 98} 99 100template<typename T> 101void RealDevicePolicyProvider::UpdateVariable( 102 AsyncCopyVariable<T>* var, 103 bool (DevicePolicy::*getter_method)(T*) const) { 104 T new_value; 105 if (policy_provider_->device_policy_is_loaded() && 106 (policy_provider_->GetDevicePolicy().*getter_method)(&new_value)) { 107 var->SetValue(new_value); 108 } else { 109 var->UnsetValue(); 110 } 111} 112 113template<typename T> 114void RealDevicePolicyProvider::UpdateVariable( 115 AsyncCopyVariable<T>* var, 116 bool (RealDevicePolicyProvider::*getter_method)(T*) const) { 117 T new_value; 118 if (policy_provider_->device_policy_is_loaded() && 119 (this->*getter_method)(&new_value)) { 120 var->SetValue(new_value); 121 } else { 122 var->UnsetValue(); 123 } 124} 125 126bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate( 127 set<ConnectionType>* allowed_types) const { 128 set<string> allowed_types_str; 129 if (!policy_provider_->GetDevicePolicy() 130 .GetAllowedConnectionTypesForUpdate(&allowed_types_str)) { 131 return false; 132 } 133 allowed_types->clear(); 134 for (auto& type_str : allowed_types_str) { 135 ConnectionType type = 136 RealShillProvider::ParseConnectionType(type_str.c_str()); 137 if (type != ConnectionType::kUnknown) { 138 allowed_types->insert(type); 139 } else { 140 LOG(WARNING) << "Policy includes unknown connection type: " << type_str; 141 } 142 } 143 return true; 144} 145 146bool RealDevicePolicyProvider::ConvertScatterFactor( 147 TimeDelta* scatter_factor) const { 148 int64_t scatter_factor_in_seconds; 149 if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds( 150 &scatter_factor_in_seconds)) { 151 return false; 152 } 153 if (scatter_factor_in_seconds < 0) { 154 LOG(WARNING) << "Ignoring negative scatter factor: " 155 << scatter_factor_in_seconds; 156 return false; 157 } 158 *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds); 159 return true; 160} 161 162void RealDevicePolicyProvider::RefreshDevicePolicy() { 163 if (!policy_provider_->Reload()) { 164 LOG(INFO) << "No device policies/settings present."; 165 } 166 167 var_device_policy_is_loaded_.SetValue( 168 policy_provider_->device_policy_is_loaded()); 169 170 UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel); 171 UpdateVariable(&var_release_channel_delegated_, 172 &DevicePolicy::GetReleaseChannelDelegated); 173 UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled); 174 UpdateVariable(&var_target_version_prefix_, 175 &DevicePolicy::GetTargetVersionPrefix); 176 UpdateVariable(&var_scatter_factor_, 177 &RealDevicePolicyProvider::ConvertScatterFactor); 178 UpdateVariable( 179 &var_allowed_connection_types_for_update_, 180 &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate); 181 UpdateVariable(&var_owner_, &DevicePolicy::GetOwner); 182 UpdateVariable(&var_http_downloads_enabled_, 183 &DevicePolicy::GetHttpDownloadsEnabled); 184 UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled); 185} 186 187} // namespace chromeos_update_manager 188