You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
6.5 KiB
192 lines
6.5 KiB
// |
|
// Copyright (C) 2014 The Android Open Source Project |
|
// |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
// |
|
|
|
#include "update_engine/update_manager/real_device_policy_provider.h" |
|
|
|
#include <stdint.h> |
|
|
|
#include <base/location.h> |
|
#include <base/logging.h> |
|
#include <base/time/time.h> |
|
#include <policy/device_policy.h> |
|
|
|
#include "update_engine/common/utils.h" |
|
#include "update_engine/connection_utils.h" |
|
#include "update_engine/update_manager/generic_variables.h" |
|
|
|
using base::TimeDelta; |
|
using brillo::MessageLoop; |
|
using chromeos_update_engine::ConnectionType; |
|
using policy::DevicePolicy; |
|
using std::set; |
|
using std::string; |
|
|
|
namespace { |
|
|
|
const int kDevicePolicyRefreshRateInMinutes = 60; |
|
|
|
} // namespace |
|
|
|
namespace chromeos_update_manager { |
|
|
|
RealDevicePolicyProvider::~RealDevicePolicyProvider() { |
|
MessageLoop::current()->CancelTask(scheduled_refresh_); |
|
} |
|
|
|
bool RealDevicePolicyProvider::Init() { |
|
CHECK(policy_provider_ != nullptr); |
|
|
|
// On Init() we try to get the device policy and keep updating it. |
|
RefreshDevicePolicyAndReschedule(); |
|
|
|
#if USE_DBUS |
|
// We also listen for signals from the session manager to force a device |
|
// policy refresh. |
|
session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler( |
|
base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal, |
|
base::Unretained(this)), |
|
base::Bind(&RealDevicePolicyProvider::OnSignalConnected, |
|
base::Unretained(this))); |
|
#endif // USE_DBUS |
|
return true; |
|
} |
|
|
|
void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal( |
|
const string& success) { |
|
if (success != "success") { |
|
LOG(WARNING) << "Received device policy updated signal with a failure."; |
|
} |
|
// We refresh the policy file even if the payload string is kSignalFailure. |
|
LOG(INFO) << "Reloading and re-scheduling device policy due to signal " |
|
"received."; |
|
MessageLoop::current()->CancelTask(scheduled_refresh_); |
|
scheduled_refresh_ = MessageLoop::kTaskIdNull; |
|
RefreshDevicePolicyAndReschedule(); |
|
} |
|
|
|
void RealDevicePolicyProvider::OnSignalConnected(const string& interface_name, |
|
const string& signal_name, |
|
bool successful) { |
|
if (!successful) { |
|
LOG(WARNING) << "We couldn't connect to SessionManager signal for updates " |
|
"on the device policy blob. We will reload the policy file " |
|
"periodically."; |
|
} |
|
// We do a one-time refresh of the DevicePolicy just in case we missed a |
|
// signal between the first refresh and the time the signal handler was |
|
// actually connected. |
|
RefreshDevicePolicy(); |
|
} |
|
|
|
void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() { |
|
RefreshDevicePolicy(); |
|
scheduled_refresh_ = MessageLoop::current()->PostDelayedTask( |
|
FROM_HERE, |
|
base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule, |
|
base::Unretained(this)), |
|
TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes)); |
|
} |
|
|
|
template<typename T> |
|
void RealDevicePolicyProvider::UpdateVariable( |
|
AsyncCopyVariable<T>* var, |
|
bool (DevicePolicy::*getter_method)(T*) const) { |
|
T new_value; |
|
if (policy_provider_->device_policy_is_loaded() && |
|
(policy_provider_->GetDevicePolicy().*getter_method)(&new_value)) { |
|
var->SetValue(new_value); |
|
} else { |
|
var->UnsetValue(); |
|
} |
|
} |
|
|
|
template<typename T> |
|
void RealDevicePolicyProvider::UpdateVariable( |
|
AsyncCopyVariable<T>* var, |
|
bool (RealDevicePolicyProvider::*getter_method)(T*) const) { |
|
T new_value; |
|
if (policy_provider_->device_policy_is_loaded() && |
|
(this->*getter_method)(&new_value)) { |
|
var->SetValue(new_value); |
|
} else { |
|
var->UnsetValue(); |
|
} |
|
} |
|
|
|
bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate( |
|
set<ConnectionType>* allowed_types) const { |
|
set<string> allowed_types_str; |
|
if (!policy_provider_->GetDevicePolicy() |
|
.GetAllowedConnectionTypesForUpdate(&allowed_types_str)) { |
|
return false; |
|
} |
|
allowed_types->clear(); |
|
for (auto& type_str : allowed_types_str) { |
|
ConnectionType type = |
|
chromeos_update_engine::connection_utils::ParseConnectionType(type_str); |
|
if (type != ConnectionType::kUnknown) { |
|
allowed_types->insert(type); |
|
} else { |
|
LOG(WARNING) << "Policy includes unknown connection type: " << type_str; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
bool RealDevicePolicyProvider::ConvertScatterFactor( |
|
TimeDelta* scatter_factor) const { |
|
int64_t scatter_factor_in_seconds; |
|
if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds( |
|
&scatter_factor_in_seconds)) { |
|
return false; |
|
} |
|
if (scatter_factor_in_seconds < 0) { |
|
LOG(WARNING) << "Ignoring negative scatter factor: " |
|
<< scatter_factor_in_seconds; |
|
return false; |
|
} |
|
*scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds); |
|
return true; |
|
} |
|
|
|
void RealDevicePolicyProvider::RefreshDevicePolicy() { |
|
if (!policy_provider_->Reload()) { |
|
LOG(INFO) << "No device policies/settings present."; |
|
} |
|
|
|
var_device_policy_is_loaded_.SetValue( |
|
policy_provider_->device_policy_is_loaded()); |
|
|
|
UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel); |
|
UpdateVariable(&var_release_channel_delegated_, |
|
&DevicePolicy::GetReleaseChannelDelegated); |
|
UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled); |
|
UpdateVariable(&var_target_version_prefix_, |
|
&DevicePolicy::GetTargetVersionPrefix); |
|
UpdateVariable(&var_scatter_factor_, |
|
&RealDevicePolicyProvider::ConvertScatterFactor); |
|
UpdateVariable( |
|
&var_allowed_connection_types_for_update_, |
|
&RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate); |
|
UpdateVariable(&var_owner_, &DevicePolicy::GetOwner); |
|
UpdateVariable(&var_http_downloads_enabled_, |
|
&DevicePolicy::GetHttpDownloadsEnabled); |
|
UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled); |
|
UpdateVariable(&var_allow_kiosk_app_control_chrome_version_, |
|
&DevicePolicy::GetAllowKioskAppControlChromeVersion); |
|
} |
|
|
|
} // namespace chromeos_update_manager
|
|
|