Home | History | Annotate | Download | only in update_manager
      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 
     30 using base::TimeDelta;
     31 using brillo::MessageLoop;
     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 
     42 namespace chromeos_update_manager {
     43 
     44 RealDevicePolicyProvider::~RealDevicePolicyProvider() {
     45   MessageLoop::current()->CancelTask(scheduled_refresh_);
     46 }
     47 
     48 bool 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 
     64 void 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 
     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();
     89 }
     90 
     91 void 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 
    100 template<typename T>
    101 void 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 
    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) {
    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 
    146 bool 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 
    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);
    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