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 <vector> 22 23 #include <base/location.h> 24 #include <base/logging.h> 25 #include <base/time/time.h> 26 #include <policy/device_policy.h> 27 28 #include "update_engine/common/utils.h" 29 #include "update_engine/connection_utils.h" 30 #include "update_engine/update_manager/generic_variables.h" 31 32 using base::TimeDelta; 33 using brillo::MessageLoop; 34 using chromeos_update_engine::ConnectionType; 35 using policy::DevicePolicy; 36 using std::set; 37 using std::string; 38 using std::vector; 39 40 namespace { 41 42 const int kDevicePolicyRefreshRateInMinutes = 60; 43 44 } // namespace 45 46 namespace chromeos_update_manager { 47 48 RealDevicePolicyProvider::~RealDevicePolicyProvider() { 49 MessageLoop::current()->CancelTask(scheduled_refresh_); 50 } 51 52 bool RealDevicePolicyProvider::Init() { 53 CHECK(policy_provider_ != nullptr); 54 55 // On Init() we try to get the device policy and keep updating it. 56 RefreshDevicePolicyAndReschedule(); 57 58 #if USE_DBUS 59 // We also listen for signals from the session manager to force a device 60 // policy refresh. 61 session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler( 62 base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal, 63 base::Unretained(this)), 64 base::Bind(&RealDevicePolicyProvider::OnSignalConnected, 65 base::Unretained(this))); 66 #endif // USE_DBUS 67 return true; 68 } 69 70 void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal( 71 const string& success) { 72 if (success != "success") { 73 LOG(WARNING) << "Received device policy updated signal with a failure."; 74 } 75 // We refresh the policy file even if the payload string is kSignalFailure. 76 LOG(INFO) << "Reloading and re-scheduling device policy due to signal " 77 "received."; 78 MessageLoop::current()->CancelTask(scheduled_refresh_); 79 scheduled_refresh_ = MessageLoop::kTaskIdNull; 80 RefreshDevicePolicyAndReschedule(); 81 } 82 83 void RealDevicePolicyProvider::OnSignalConnected(const string& interface_name, 84 const string& signal_name, 85 bool successful) { 86 if (!successful) { 87 LOG(WARNING) << "We couldn't connect to SessionManager signal for updates " 88 "on the device policy blob. We will reload the policy file " 89 "periodically."; 90 } 91 // We do a one-time refresh of the DevicePolicy just in case we missed a 92 // signal between the first refresh and the time the signal handler was 93 // actually connected. 94 RefreshDevicePolicy(); 95 } 96 97 void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() { 98 RefreshDevicePolicy(); 99 scheduled_refresh_ = MessageLoop::current()->PostDelayedTask( 100 FROM_HERE, 101 base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule, 102 base::Unretained(this)), 103 TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes)); 104 } 105 106 template <typename T> 107 void RealDevicePolicyProvider::UpdateVariable( 108 AsyncCopyVariable<T>* var, bool (DevicePolicy::*getter_method)(T*) const) { 109 T new_value; 110 if (policy_provider_->device_policy_is_loaded() && 111 (policy_provider_->GetDevicePolicy().*getter_method)(&new_value)) { 112 var->SetValue(new_value); 113 } else { 114 var->UnsetValue(); 115 } 116 } 117 118 template <typename T> 119 void RealDevicePolicyProvider::UpdateVariable( 120 AsyncCopyVariable<T>* var, 121 bool (RealDevicePolicyProvider::*getter_method)(T*) const) { 122 T new_value; 123 if (policy_provider_->device_policy_is_loaded() && 124 (this->*getter_method)(&new_value)) { 125 var->SetValue(new_value); 126 } else { 127 var->UnsetValue(); 128 } 129 } 130 131 bool RealDevicePolicyProvider::ConvertRollbackToTargetVersion( 132 RollbackToTargetVersion* rollback_to_target_version) const { 133 int rollback_to_target_version_int; 134 if (!policy_provider_->GetDevicePolicy().GetRollbackToTargetVersion( 135 &rollback_to_target_version_int)) { 136 return false; 137 } 138 if (rollback_to_target_version_int < 0 || 139 rollback_to_target_version_int >= 140 static_cast<int>(RollbackToTargetVersion::kMaxValue)) { 141 return false; 142 } 143 *rollback_to_target_version = 144 static_cast<RollbackToTargetVersion>(rollback_to_target_version_int); 145 return true; 146 } 147 148 bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate( 149 set<ConnectionType>* allowed_types) const { 150 set<string> allowed_types_str; 151 if (!policy_provider_->GetDevicePolicy().GetAllowedConnectionTypesForUpdate( 152 &allowed_types_str)) { 153 return false; 154 } 155 allowed_types->clear(); 156 for (auto& type_str : allowed_types_str) { 157 ConnectionType type = 158 chromeos_update_engine::connection_utils::ParseConnectionType(type_str); 159 if (type != ConnectionType::kUnknown) { 160 allowed_types->insert(type); 161 } else { 162 LOG(WARNING) << "Policy includes unknown connection type: " << type_str; 163 } 164 } 165 return true; 166 } 167 168 bool RealDevicePolicyProvider::ConvertScatterFactor( 169 TimeDelta* scatter_factor) const { 170 int64_t scatter_factor_in_seconds; 171 if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds( 172 &scatter_factor_in_seconds)) { 173 return false; 174 } 175 if (scatter_factor_in_seconds < 0) { 176 LOG(WARNING) << "Ignoring negative scatter factor: " 177 << scatter_factor_in_seconds; 178 return false; 179 } 180 *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds); 181 return true; 182 } 183 184 bool RealDevicePolicyProvider::ConvertDisallowedTimeIntervals( 185 WeeklyTimeIntervalVector* disallowed_intervals_out) const { 186 vector<DevicePolicy::WeeklyTimeInterval> parsed_intervals; 187 if (!policy_provider_->GetDevicePolicy().GetDisallowedTimeIntervals( 188 &parsed_intervals)) { 189 return false; 190 } 191 192 disallowed_intervals_out->clear(); 193 for (const auto& interval : parsed_intervals) { 194 disallowed_intervals_out->emplace_back( 195 WeeklyTime(interval.start_day_of_week, interval.start_time), 196 WeeklyTime(interval.end_day_of_week, interval.end_time)); 197 } 198 return true; 199 } 200 201 void RealDevicePolicyProvider::RefreshDevicePolicy() { 202 if (!policy_provider_->Reload()) { 203 LOG(INFO) << "No device policies/settings present."; 204 } 205 206 var_device_policy_is_loaded_.SetValue( 207 policy_provider_->device_policy_is_loaded()); 208 209 UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel); 210 UpdateVariable(&var_release_channel_delegated_, 211 &DevicePolicy::GetReleaseChannelDelegated); 212 UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled); 213 UpdateVariable(&var_target_version_prefix_, 214 &DevicePolicy::GetTargetVersionPrefix); 215 UpdateVariable(&var_rollback_to_target_version_, 216 &RealDevicePolicyProvider::ConvertRollbackToTargetVersion); 217 UpdateVariable(&var_rollback_allowed_milestones_, 218 &DevicePolicy::GetRollbackAllowedMilestones); 219 if (policy_provider_->IsConsumerDevice()) { 220 // For consumer devices (which won't ever have policy), set value to 0. 221 var_rollback_allowed_milestones_.SetValue(0); 222 } 223 UpdateVariable(&var_scatter_factor_, 224 &RealDevicePolicyProvider::ConvertScatterFactor); 225 UpdateVariable( 226 &var_allowed_connection_types_for_update_, 227 &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate); 228 UpdateVariable(&var_owner_, &DevicePolicy::GetOwner); 229 UpdateVariable(&var_http_downloads_enabled_, 230 &DevicePolicy::GetHttpDownloadsEnabled); 231 UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled); 232 UpdateVariable(&var_allow_kiosk_app_control_chrome_version_, 233 &DevicePolicy::GetAllowKioskAppControlChromeVersion); 234 UpdateVariable(&var_auto_launched_kiosk_app_id_, 235 &DevicePolicy::GetAutoLaunchedKioskAppId); 236 UpdateVariable(&var_disallowed_time_intervals_, 237 &RealDevicePolicyProvider::ConvertDisallowedTimeIntervals); 238 } 239 240 } // namespace chromeos_update_manager 241