Alex Deymo | aea4c1c | 2015-08-19 20:24:43 -0700 | [diff] [blame] | 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 | // |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 16 | |
Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 17 | #include "update_engine/update_manager/real_device_policy_provider.h" |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 18 | |
Ben Chan | dcf5a1d | 2014-08-07 09:34:12 -0700 | [diff] [blame] | 19 | #include <stdint.h> |
| 20 | |
Alex Deymo | 0bb2341 | 2015-06-19 00:04:46 -0700 | [diff] [blame] | 21 | #include <base/location.h> |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 22 | #include <base/logging.h> |
| 23 | #include <base/time/time.h> |
| 24 | #include <policy/device_policy.h> |
| 25 | |
Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 26 | #include "update_engine/update_manager/generic_variables.h" |
| 27 | #include "update_engine/update_manager/real_shill_provider.h" |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 28 | #include "update_engine/utils.h" |
| 29 | |
| 30 | using base::TimeDelta; |
Alex Deymo | 509dd53 | 2015-06-10 14:11:05 -0700 | [diff] [blame] | 31 | using chromeos::MessageLoop; |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 32 | using policy::DevicePolicy; |
| 33 | using std::set; |
| 34 | using std::string; |
| 35 | |
| 36 | namespace { |
| 37 | |
| 38 | const int kDevicePolicyRefreshRateInMinutes = 60; |
| 39 | |
| 40 | } // namespace |
| 41 | |
Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 42 | namespace chromeos_update_manager { |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 43 | |
| 44 | RealDevicePolicyProvider::~RealDevicePolicyProvider() { |
Alex Deymo | 509dd53 | 2015-06-10 14:11:05 -0700 | [diff] [blame] | 45 | MessageLoop::current()->CancelTask(scheduled_refresh_); |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 46 | } |
| 47 | |
Alex Deymo | 42c30c3 | 2014-04-24 18:41:18 -0700 | [diff] [blame] | 48 | bool RealDevicePolicyProvider::Init() { |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 49 | CHECK(policy_provider_ != nullptr); |
| 50 | |
| 51 | // On Init() we try to get the device policy and keep updating it. |
| 52 | RefreshDevicePolicyAndReschedule(); |
| 53 | |
Alex Deymo | 9b7ae1a | 2014-12-15 10:35:56 -0800 | [diff] [blame] | 54 | // We also listen for signals from the session manager to force a device |
| 55 | // policy refresh. |
Alex Deymo | 3053450 | 2015-07-20 15:06:33 -0700 | [diff] [blame] | 56 | session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler( |
| 57 | base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal, |
| 58 | base::Unretained(this)), |
| 59 | base::Bind(&RealDevicePolicyProvider::OnSignalConnected, |
| 60 | base::Unretained(this))); |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 61 | return true; |
| 62 | } |
| 63 | |
Alex Deymo | 3053450 | 2015-07-20 15:06:33 -0700 | [diff] [blame] | 64 | void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal( |
| 65 | const string& success) { |
| 66 | if (success != "success") { |
| 67 | LOG(WARNING) << "Received device policy updated signal with a failure."; |
| 68 | } |
Alex Deymo | 9b7ae1a | 2014-12-15 10:35:56 -0800 | [diff] [blame] | 69 | // We refresh the policy file even if the payload string is kSignalFailure. |
Alex Deymo | 3053450 | 2015-07-20 15:06:33 -0700 | [diff] [blame] | 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 | |
| 77 | void 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(); |
Alex Deymo | 9b7ae1a | 2014-12-15 10:35:56 -0800 | [diff] [blame] | 89 | } |
| 90 | |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 91 | void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() { |
| 92 | RefreshDevicePolicy(); |
Alex Deymo | 509dd53 | 2015-06-10 14:11:05 -0700 | [diff] [blame] | 93 | scheduled_refresh_ = MessageLoop::current()->PostDelayedTask( |
Alex Deymo | 0bb2341 | 2015-06-19 00:04:46 -0700 | [diff] [blame] | 94 | FROM_HERE, |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 95 | base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule, |
| 96 | base::Unretained(this)), |
| 97 | TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes)); |
| 98 | } |
| 99 | |
| 100 | template<typename T> |
| 101 | void RealDevicePolicyProvider::UpdateVariable( |
| 102 | AsyncCopyVariable<T>* var, |
Alex Deymo | f329b93 | 2014-10-30 01:37:48 -0700 | [diff] [blame] | 103 | bool (DevicePolicy::*getter_method)(T*) const) { |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 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 | |
| 113 | template<typename T> |
| 114 | void 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 | |
| 126 | bool 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) { |
Gilad Arnold | ef120fa | 2014-04-09 12:52:10 -0700 | [diff] [blame] | 135 | ConnectionType type = |
| 136 | RealShillProvider::ParseConnectionType(type_str.c_str()); |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 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 | |
| 146 | bool RealDevicePolicyProvider::ConvertScatterFactor( |
Alex Deymo | f329b93 | 2014-10-30 01:37:48 -0700 | [diff] [blame] | 147 | TimeDelta* scatter_factor) const { |
Ben Chan | dcf5a1d | 2014-08-07 09:34:12 -0700 | [diff] [blame] | 148 | int64_t scatter_factor_in_seconds; |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 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 | } |
Alex Deymo | f329b93 | 2014-10-30 01:37:48 -0700 | [diff] [blame] | 158 | *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds); |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 159 | return true; |
| 160 | } |
| 161 | |
| 162 | void 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); |
Gilad Arnold | ef8d087 | 2014-10-03 14:14:06 -0700 | [diff] [blame] | 181 | UpdateVariable(&var_owner_, &DevicePolicy::GetOwner); |
Alex Deymo | c83baf6 | 2014-04-02 17:43:35 -0700 | [diff] [blame] | 182 | UpdateVariable(&var_http_downloads_enabled_, |
| 183 | &DevicePolicy::GetHttpDownloadsEnabled); |
| 184 | UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled); |
| 185 | } |
| 186 | |
Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 187 | } // namespace chromeos_update_manager |