// // 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_system_provider.h" #include #include #include #include #include #include "update_engine/common/boot_control_interface.h" #include "update_engine/common/hardware_interface.h" #include "update_engine/common/system_state.h" #include "update_engine/common/utils.h" #include "update_engine/cros/omaha_request_params.h" #include "update_engine/update_manager/generic_variables.h" #include "update_engine/update_manager/variable.h" using chromeos_update_engine::SystemState; using std::string; namespace chromeos_update_manager { namespace { // The maximum number of consecutive failures before returning the default // constructor value for T instead of failure. const int kRetryPollVariableMaxRetry = 5; // The polling interval to be used whenever GetValue() returns an error. const int kRetryPollVariableRetryIntervalSeconds = 5 * 60; // The RetryPollVariable variable is a polling variable that allows the function // returning the value to fail a few times and shortens the polling rate when // that happens. template class RetryPollVariable : public Variable { public: RetryPollVariable(const string& name, const base::TimeDelta poll_interval, base::Callback func) : Variable(name, poll_interval), func_(func), base_interval_(poll_interval) { DCHECK_LT(kRetryPollVariableRetryIntervalSeconds, base_interval_.InSeconds()); } protected: // Variable override. const T* GetValue(base::TimeDelta /* timeout */, string* /* errmsg */) override { std::unique_ptr result(new T()); if (!func_.Run(result.get())) { if (failed_attempts_ >= kRetryPollVariableMaxRetry) { // Give up on the retries and set back the desired polling interval. this->SetPollInterval(base_interval_); // Release the result instead of returning a |nullptr| to indicate that // the result could not be fetched. return result.release(); } this->SetPollInterval( base::TimeDelta::FromSeconds(kRetryPollVariableRetryIntervalSeconds)); failed_attempts_++; return nullptr; } failed_attempts_ = 0; this->SetPollInterval(base_interval_); return result.release(); } private: // The function to be called, stored as a base::Callback. base::Callback func_; // The desired polling interval when |func_| works and returns true. base::TimeDelta base_interval_; // The number of consecutive failed attempts made. int failed_attempts_ = 0; DISALLOW_COPY_AND_ASSIGN(RetryPollVariable); }; } // namespace bool RealSystemProvider::Init() { var_is_normal_boot_mode_.reset(new ConstCopyVariable( "is_normal_boot_mode", SystemState::Get()->hardware()->IsNormalBootMode())); var_is_official_build_.reset(new ConstCopyVariable( "is_official_build", SystemState::Get()->hardware()->IsOfficialBuild())); var_is_oobe_complete_.reset(new CallCopyVariable( "is_oobe_complete", base::Bind(&chromeos_update_engine::HardwareInterface::IsOOBEComplete, base::Unretained(SystemState::Get()->hardware()), nullptr))); var_num_slots_.reset(new ConstCopyVariable( "num_slots", SystemState::Get()->boot_control()->GetNumSlots())); var_kiosk_required_platform_version_.reset(new RetryPollVariable( "kiosk_required_platform_version", base::TimeDelta::FromHours(5), // Same as Chrome's CWS poll. base::Bind(&RealSystemProvider::GetKioskAppRequiredPlatformVersion, base::Unretained(this)))); var_chromeos_version_.reset(new ConstCopyVariable( "chromeos_version", base::Version(SystemState::Get()->request_params()->app_version()))); return true; } bool RealSystemProvider::GetKioskAppRequiredPlatformVersion( string* required_platform_version) { brillo::ErrorPtr error; if (!kiosk_app_proxy_->GetRequiredPlatformVersion(required_platform_version, &error)) { LOG(WARNING) << "Failed to get kiosk required platform version"; required_platform_version->clear(); return false; } return true; } } // namespace chromeos_update_manager