• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/connection_utils.h"
29 #include "update_engine/common/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 
~RealDevicePolicyProvider()48 RealDevicePolicyProvider::~RealDevicePolicyProvider() {
49   MessageLoop::current()->CancelTask(scheduled_refresh_);
50 }
51 
Init()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 
OnPropertyChangedCompletedSignal(const string & success)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 
OnSignalConnected(const string & interface_name,const string & signal_name,bool successful)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 
RefreshDevicePolicyAndReschedule()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>
UpdateVariable(AsyncCopyVariable<T> * var,bool (DevicePolicy::* getter)(T *)const)107 void RealDevicePolicyProvider::UpdateVariable(
108     AsyncCopyVariable<T>* var,
109     // NOLINTNEXTLINE(readability/casting)
110     bool (DevicePolicy::*getter)(T*) const) {
111   T new_value;
112   if (policy_provider_->device_policy_is_loaded() &&
113       (policy_provider_->GetDevicePolicy().*getter)(&new_value)) {
114     var->SetValue(new_value);
115   } else {
116     var->UnsetValue();
117   }
118 }
119 
120 template <typename T>
UpdateVariable(AsyncCopyVariable<T> * var,bool (RealDevicePolicyProvider::* getter)(T *)const)121 void RealDevicePolicyProvider::UpdateVariable(
122     AsyncCopyVariable<T>* var,
123     bool (RealDevicePolicyProvider::*getter)(T*) const) {
124   T new_value;
125   if (policy_provider_->device_policy_is_loaded() &&
126       (this->*getter)(&new_value)) {
127     var->SetValue(new_value);
128   } else {
129     var->UnsetValue();
130   }
131 }
132 
ConvertRollbackToTargetVersion(RollbackToTargetVersion * rollback_to_target_version) const133 bool RealDevicePolicyProvider::ConvertRollbackToTargetVersion(
134     RollbackToTargetVersion* rollback_to_target_version) const {
135   int rollback_to_target_version_int;
136   if (!policy_provider_->GetDevicePolicy().GetRollbackToTargetVersion(
137           &rollback_to_target_version_int)) {
138     return false;
139   }
140   if (rollback_to_target_version_int < 0 ||
141       rollback_to_target_version_int >=
142           static_cast<int>(RollbackToTargetVersion::kMaxValue)) {
143     return false;
144   }
145   *rollback_to_target_version =
146       static_cast<RollbackToTargetVersion>(rollback_to_target_version_int);
147   return true;
148 }
149 
ConvertAllowedConnectionTypesForUpdate(set<ConnectionType> * allowed_types) const150 bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate(
151     set<ConnectionType>* allowed_types) const {
152   set<string> allowed_types_str;
153   if (!policy_provider_->GetDevicePolicy().GetAllowedConnectionTypesForUpdate(
154           &allowed_types_str)) {
155     return false;
156   }
157   allowed_types->clear();
158   for (auto& type_str : allowed_types_str) {
159     ConnectionType type =
160         chromeos_update_engine::connection_utils::ParseConnectionType(type_str);
161     if (type != ConnectionType::kUnknown) {
162       allowed_types->insert(type);
163     } else {
164       LOG(WARNING) << "Policy includes unknown connection type: " << type_str;
165     }
166   }
167   return true;
168 }
169 
ConvertScatterFactor(TimeDelta * scatter_factor) const170 bool RealDevicePolicyProvider::ConvertScatterFactor(
171     TimeDelta* scatter_factor) const {
172   int64_t scatter_factor_in_seconds;
173   if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds(
174           &scatter_factor_in_seconds)) {
175     return false;
176   }
177   if (scatter_factor_in_seconds < 0) {
178     LOG(WARNING) << "Ignoring negative scatter factor: "
179                  << scatter_factor_in_seconds;
180     return false;
181   }
182   *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds);
183   return true;
184 }
185 
ConvertDisallowedTimeIntervals(WeeklyTimeIntervalVector * disallowed_intervals_out) const186 bool RealDevicePolicyProvider::ConvertDisallowedTimeIntervals(
187     WeeklyTimeIntervalVector* disallowed_intervals_out) const {
188   vector<DevicePolicy::WeeklyTimeInterval> parsed_intervals;
189   if (!policy_provider_->GetDevicePolicy().GetDisallowedTimeIntervals(
190           &parsed_intervals)) {
191     return false;
192   }
193 
194   disallowed_intervals_out->clear();
195   for (const auto& interval : parsed_intervals) {
196     disallowed_intervals_out->emplace_back(
197         WeeklyTime(interval.start_day_of_week, interval.start_time),
198         WeeklyTime(interval.end_day_of_week, interval.end_time));
199   }
200   return true;
201 }
202 
ConvertHasOwner(bool * has_owner) const203 bool RealDevicePolicyProvider::ConvertHasOwner(bool* has_owner) const {
204   string owner;
205   if (!policy_provider_->GetDevicePolicy().GetOwner(&owner)) {
206     return false;
207   }
208   *has_owner = !owner.empty();
209   return true;
210 }
211 
ConvertChannelDowngradeBehavior(ChannelDowngradeBehavior * channel_downgrade_behavior) const212 bool RealDevicePolicyProvider::ConvertChannelDowngradeBehavior(
213     ChannelDowngradeBehavior* channel_downgrade_behavior) const {
214   int behavior;
215   if (!policy_provider_->GetDevicePolicy().GetChannelDowngradeBehavior(
216           &behavior)) {
217     return false;
218   }
219   if (behavior < static_cast<int>(ChannelDowngradeBehavior::kFirstValue) ||
220       behavior > static_cast<int>(ChannelDowngradeBehavior::kLastValue)) {
221     return false;
222   }
223   *channel_downgrade_behavior = static_cast<ChannelDowngradeBehavior>(behavior);
224   return true;
225 }
226 
RefreshDevicePolicy()227 void RealDevicePolicyProvider::RefreshDevicePolicy() {
228   if (!policy_provider_->Reload()) {
229     LOG(INFO) << "No device policies/settings present.";
230   }
231 
232   var_device_policy_is_loaded_.SetValue(
233       policy_provider_->device_policy_is_loaded());
234 
235   UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel);
236   UpdateVariable(&var_release_channel_delegated_,
237                  &DevicePolicy::GetReleaseChannelDelegated);
238   UpdateVariable(&var_release_lts_tag_, &DevicePolicy::GetReleaseLtsTag);
239   UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled);
240   UpdateVariable(&var_target_version_prefix_,
241                  &DevicePolicy::GetTargetVersionPrefix);
242   UpdateVariable(&var_rollback_to_target_version_,
243                  &RealDevicePolicyProvider::ConvertRollbackToTargetVersion);
244   UpdateVariable(&var_rollback_allowed_milestones_,
245                  &DevicePolicy::GetRollbackAllowedMilestones);
246   if (policy_provider_->IsConsumerDevice()) {
247     // For consumer devices (which won't ever have policy), set value to 0.
248     var_rollback_allowed_milestones_.SetValue(0);
249   }
250   UpdateVariable(&var_scatter_factor_,
251                  &RealDevicePolicyProvider::ConvertScatterFactor);
252   UpdateVariable(
253       &var_allowed_connection_types_for_update_,
254       &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate);
255   UpdateVariable(&var_has_owner_, &RealDevicePolicyProvider::ConvertHasOwner);
256   UpdateVariable(&var_http_downloads_enabled_,
257                  &DevicePolicy::GetHttpDownloadsEnabled);
258   UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled);
259   UpdateVariable(&var_allow_kiosk_app_control_chrome_version_,
260                  &DevicePolicy::GetAllowKioskAppControlChromeVersion);
261   UpdateVariable(&var_auto_launched_kiosk_app_id_,
262                  &DevicePolicy::GetAutoLaunchedKioskAppId);
263   UpdateVariable(&var_disallowed_time_intervals_,
264                  &RealDevicePolicyProvider::ConvertDisallowedTimeIntervals);
265   UpdateVariable(&var_channel_downgrade_behavior_,
266                  &RealDevicePolicyProvider::ConvertChannelDowngradeBehavior);
267   UpdateVariable(&var_device_minimum_version_,
268                  &DevicePolicy::GetHighestDeviceMinimumVersion);
269   UpdateVariable(&var_quick_fix_build_token_,
270                  &DevicePolicy::GetDeviceQuickFixBuildToken);
271 }
272 
273 }  // namespace chromeos_update_manager
274