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_system_provider.h" 18 19 #include <base/bind.h> 20 #include <base/callback.h> 21 #include <base/logging.h> 22 #include <base/time/time.h> 23 #if USE_CHROME_KIOSK_APP 24 #include <libcros/dbus-proxies.h> 25 #endif // USE_CHROME_KIOSK_APP 26 27 #include "update_engine/common/utils.h" 28 #include "update_engine/update_manager/generic_variables.h" 29 #include "update_engine/update_manager/variable.h" 30 31 using std::string; 32 33 namespace chromeos_update_manager { 34 35 namespace { 36 37 // The maximum number of consecutive failures before returning the default 38 // constructor value for T instead of failure. 39 const int kRetryPollVariableMaxRetry = 5; 40 41 // The polling interval to be used whenever GetValue() returns an error. 42 const int kRetryPollVariableRetryIntervalSeconds = 5 * 60; 43 44 // The RetryPollVariable variable is a polling variable that allows the function 45 // returning the value to fail a few times and shortens the polling rate when 46 // that happens. 47 template <typename T> 48 class RetryPollVariable : public Variable<T> { 49 public: 50 RetryPollVariable(const string& name, 51 const base::TimeDelta poll_interval, 52 base::Callback<bool(T* res)> func) 53 : Variable<T>(name, poll_interval), 54 func_(func), 55 base_interval_(poll_interval) { 56 DCHECK_LT(kRetryPollVariableRetryIntervalSeconds, 57 base_interval_.InSeconds()); 58 } 59 60 protected: 61 // Variable override. 62 const T* GetValue(base::TimeDelta /* timeout */, 63 string* /* errmsg */) override { 64 std::unique_ptr<T> result(new T()); 65 if (!func_.Run(result.get())) { 66 if (failed_attempts_ >= kRetryPollVariableMaxRetry) { 67 // Give up on the retries, set back the desired polling interval and 68 // return the default. 69 this->SetPollInterval(base_interval_); 70 return result.release(); 71 } 72 this->SetPollInterval( 73 base::TimeDelta::FromSeconds(kRetryPollVariableRetryIntervalSeconds)); 74 failed_attempts_++; 75 return nullptr; 76 } 77 failed_attempts_ = 0; 78 this->SetPollInterval(base_interval_); 79 return result.release(); 80 } 81 82 private: 83 // The function to be called, stored as a base::Callback. 84 base::Callback<bool(T*)> func_; 85 86 // The desired polling interval when |func_| works and returns true. 87 base::TimeDelta base_interval_; 88 89 // The number of consecutive failed attempts made. 90 int failed_attempts_ = 0; 91 92 DISALLOW_COPY_AND_ASSIGN(RetryPollVariable); 93 }; 94 95 } // namespace 96 97 bool RealSystemProvider::Init() { 98 var_is_normal_boot_mode_.reset( 99 new ConstCopyVariable<bool>("is_normal_boot_mode", 100 hardware_->IsNormalBootMode())); 101 102 var_is_official_build_.reset( 103 new ConstCopyVariable<bool>("is_official_build", 104 hardware_->IsOfficialBuild())); 105 106 var_is_oobe_complete_.reset( 107 new CallCopyVariable<bool>( 108 "is_oobe_complete", 109 base::Bind(&chromeos_update_engine::HardwareInterface::IsOOBEComplete, 110 base::Unretained(hardware_), nullptr))); 111 112 var_num_slots_.reset( 113 new ConstCopyVariable<unsigned int>( 114 "num_slots", boot_control_->GetNumSlots())); 115 116 var_kiosk_required_platform_version_.reset(new RetryPollVariable<string>( 117 "kiosk_required_platform_version", 118 base::TimeDelta::FromHours(5), // Same as Chrome's CWS poll. 119 base::Bind(&RealSystemProvider::GetKioskAppRequiredPlatformVersion, 120 base::Unretained(this)))); 121 122 return true; 123 } 124 125 bool RealSystemProvider::GetKioskAppRequiredPlatformVersion( 126 string* required_platform_version) { 127 #if USE_CHROME_KIOSK_APP 128 brillo::ErrorPtr error; 129 if (!libcros_proxy_->GetKioskAppRequiredPlatformVersion( 130 required_platform_version, &error)) { 131 LOG(WARNING) << "Failed to get kiosk required platform version"; 132 required_platform_version->clear(); 133 return false; 134 } 135 #endif // USE_CHROME_KIOSK_APP 136 137 return true; 138 } 139 140 } // namespace chromeos_update_manager 141