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/connection_utils.h" 28 #include "update_engine/update_manager/generic_variables.h" 29 30 using base::TimeDelta; 31 using brillo::MessageLoop; 32 using chromeos_update_engine::ConnectionType; 33 using policy::DevicePolicy; 34 using std::set; 35 using std::string; 36 37 namespace { 38 39 const int kDevicePolicyRefreshRateInMinutes = 60; 40 41 } // namespace 42 43 namespace chromeos_update_manager { 44 45 RealDevicePolicyProvider::~RealDevicePolicyProvider() { 46 MessageLoop::current()->CancelTask(scheduled_refresh_); 47 } 48 49 bool RealDevicePolicyProvider::Init() { 50 CHECK(policy_provider_ != nullptr); 51 52 // On Init() we try to get the device policy and keep updating it. 53 RefreshDevicePolicyAndReschedule(); 54 55 #if USE_DBUS 56 // We also listen for signals from the session manager to force a device 57 // policy refresh. 58 session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler( 59 base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal, 60 base::Unretained(this)), 61 base::Bind(&RealDevicePolicyProvider::OnSignalConnected, 62 base::Unretained(this))); 63 #endif // USE_DBUS 64 return true; 65 } 66 67 void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal( 68 const string& success) { 69 if (success != "success") { 70 LOG(WARNING) << "Received device policy updated signal with a failure."; 71 } 72 // We refresh the policy file even if the payload string is kSignalFailure. 73 LOG(INFO) << "Reloading and re-scheduling device policy due to signal " 74 "received."; 75 MessageLoop::current()->CancelTask(scheduled_refresh_); 76 scheduled_refresh_ = MessageLoop::kTaskIdNull; 77 RefreshDevicePolicyAndReschedule(); 78 } 79 80 void RealDevicePolicyProvider::OnSignalConnected(const string& interface_name, 81 const string& signal_name, 82 bool successful) { 83 if (!successful) { 84 LOG(WARNING) << "We couldn't connect to SessionManager signal for updates " 85 "on the device policy blob. We will reload the policy file " 86 "periodically."; 87 } 88 // We do a one-time refresh of the DevicePolicy just in case we missed a 89 // signal between the first refresh and the time the signal handler was 90 // actually connected. 91 RefreshDevicePolicy(); 92 } 93 94 void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() { 95 RefreshDevicePolicy(); 96 scheduled_refresh_ = MessageLoop::current()->PostDelayedTask( 97 FROM_HERE, 98 base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule, 99 base::Unretained(this)), 100 TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes)); 101 } 102 103 template<typename T> 104 void RealDevicePolicyProvider::UpdateVariable( 105 AsyncCopyVariable<T>* var, 106 bool (DevicePolicy::*getter_method)(T*) const) { 107 T new_value; 108 if (policy_provider_->device_policy_is_loaded() && 109 (policy_provider_->GetDevicePolicy().*getter_method)(&new_value)) { 110 var->SetValue(new_value); 111 } else { 112 var->UnsetValue(); 113 } 114 } 115 116 template<typename T> 117 void RealDevicePolicyProvider::UpdateVariable( 118 AsyncCopyVariable<T>* var, 119 bool (RealDevicePolicyProvider::*getter_method)(T*) const) { 120 T new_value; 121 if (policy_provider_->device_policy_is_loaded() && 122 (this->*getter_method)(&new_value)) { 123 var->SetValue(new_value); 124 } else { 125 var->UnsetValue(); 126 } 127 } 128 129 bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate( 130 set<ConnectionType>* allowed_types) const { 131 set<string> allowed_types_str; 132 if (!policy_provider_->GetDevicePolicy() 133 .GetAllowedConnectionTypesForUpdate(&allowed_types_str)) { 134 return false; 135 } 136 allowed_types->clear(); 137 for (auto& type_str : allowed_types_str) { 138 ConnectionType type = 139 chromeos_update_engine::connection_utils::ParseConnectionType(type_str); 140 if (type != ConnectionType::kUnknown) { 141 allowed_types->insert(type); 142 } else { 143 LOG(WARNING) << "Policy includes unknown connection type: " << type_str; 144 } 145 } 146 return true; 147 } 148 149 bool RealDevicePolicyProvider::ConvertScatterFactor( 150 TimeDelta* scatter_factor) const { 151 int64_t scatter_factor_in_seconds; 152 if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds( 153 &scatter_factor_in_seconds)) { 154 return false; 155 } 156 if (scatter_factor_in_seconds < 0) { 157 LOG(WARNING) << "Ignoring negative scatter factor: " 158 << scatter_factor_in_seconds; 159 return false; 160 } 161 *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds); 162 return true; 163 } 164 165 void RealDevicePolicyProvider::RefreshDevicePolicy() { 166 if (!policy_provider_->Reload()) { 167 LOG(INFO) << "No device policies/settings present."; 168 } 169 170 var_device_policy_is_loaded_.SetValue( 171 policy_provider_->device_policy_is_loaded()); 172 173 UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel); 174 UpdateVariable(&var_release_channel_delegated_, 175 &DevicePolicy::GetReleaseChannelDelegated); 176 UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled); 177 UpdateVariable(&var_target_version_prefix_, 178 &DevicePolicy::GetTargetVersionPrefix); 179 UpdateVariable(&var_scatter_factor_, 180 &RealDevicePolicyProvider::ConvertScatterFactor); 181 UpdateVariable( 182 &var_allowed_connection_types_for_update_, 183 &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate); 184 UpdateVariable(&var_owner_, &DevicePolicy::GetOwner); 185 UpdateVariable(&var_http_downloads_enabled_, 186 &DevicePolicy::GetHttpDownloadsEnabled); 187 UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled); 188 UpdateVariable(&var_allow_kiosk_app_control_chrome_version_, 189 &DevicePolicy::GetAllowKioskAppControlChromeVersion); 190 } 191 192 } // namespace chromeos_update_manager 193