generic_variables.h revision c16fca2f1b263872e12503eab4621250ef1f1e1c
1// Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Generic and provider-independent Variable subclasses. These variables can be 6// used by any state provider to implement simple variables to avoid repeat the 7// same common code on different state providers. 8 9#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_ 10#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_ 11 12#include <base/callback.h> 13 14#include "update_engine/policy_manager/variable.h" 15 16namespace { 17 18const char* kCopyVariableDefaultErrMsg = "Requested value is not set"; 19 20} // namespace 21 22 23namespace chromeos_policy_manager { 24 25// Variable class returning a copy of a given object using the copy constructor. 26// This template class can be used to define variables that expose as a variable 27// any fixed object, such as the a provider's private member. The variable will 28// create copies of the provided object using the copy constructor of that 29// class. 30// 31// For example, a state provider exposing a private member as a variable can 32// implement this as follows: 33// 34// class SomethingProvider { 35// public: 36// SomethingProvider(...) { 37// var_something_foo = new CopyVariable<MyType>(foo_); 38// } 39// ... 40// private: 41// MyType foo_; 42// }; 43template<typename T> 44class CopyVariable : public Variable<T> { 45 public: 46 // Creates the variable returning copies of the passed |ref|. The reference to 47 // this object is kept and it should be available whenever the GetValue() 48 // method is called. If |is_set_p| is not null, then this flag will be 49 // consulted prior to returning the value, and an |errmsg| will be returned if 50 // it is not set. 51 CopyVariable(const std::string& name, VariableMode mode, const T& ref, 52 const bool* is_set_p, const std::string& errmsg) 53 : Variable<T>(name, mode), ref_(ref), is_set_p_(is_set_p), 54 errmsg_(errmsg) {} 55 CopyVariable(const std::string& name, VariableMode mode, const T& ref, 56 const bool* is_set_p) 57 : CopyVariable(name, mode, ref, is_set_p, kCopyVariableDefaultErrMsg) {} 58 CopyVariable(const std::string& name, VariableMode mode, const T& ref) 59 : CopyVariable(name, mode, ref, nullptr) {} 60 61 CopyVariable(const std::string& name, const base::TimeDelta poll_interval, 62 const T& ref, const bool* is_set_p, const std::string& errmsg) 63 : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p), 64 errmsg_(errmsg) {} 65 CopyVariable(const std::string& name, const base::TimeDelta poll_interval, 66 const T& ref, const bool* is_set_p) 67 : CopyVariable(name, poll_interval, ref, is_set_p, 68 kCopyVariableDefaultErrMsg) {} 69 CopyVariable(const std::string& name, const base::TimeDelta poll_interval, 70 const T& ref) 71 : CopyVariable(name, poll_interval, ref, nullptr) {} 72 73 protected: 74 FRIEND_TEST(PmCopyVariableTest, SimpleTest); 75 FRIEND_TEST(PmCopyVariableTest, UseCopyConstructorTest); 76 77 // Variable override. 78 virtual inline const T* GetValue(base::TimeDelta /* timeout */, 79 std::string* errmsg) { 80 if (is_set_p_ && !(*is_set_p_)) { 81 if (errmsg) 82 *errmsg = errmsg_; 83 return nullptr; 84 } 85 return new T(ref_); 86 } 87 88 private: 89 // Reference to the object to be copied by GetValue(). 90 const T& ref_; 91 92 // A pointer to a flag indicating whether the value is set. If null, then the 93 // value is assumed to be set. 94 const bool* const is_set_p_; 95 96 // An error message to be returned when attempting to get an unset value. 97 const std::string errmsg_; 98}; 99 100// Variable class returning a constant value that is cached on the variable when 101// it is created. 102template<typename T> 103class ConstCopyVariable : public Variable<T> { 104 public: 105 // Creates the variable returning copies of the passed |obj|. The value passed 106 // is copied in this variable, and new copies of it will be returned by 107 // GetValue(). 108 ConstCopyVariable(const std::string& name, const T& obj) 109 : Variable<T>(name, kVariableModeConst), obj_(obj) {} 110 111 protected: 112 // Variable override. 113 virtual const T* GetValue(base::TimeDelta /* timeout */, 114 std::string* /* errmsg */) { 115 return new T(obj_); 116 } 117 118 private: 119 // Value to be copied by GetValue(). 120 const T obj_; 121}; 122 123// Variable class returning a copy of a value returned by a given function. The 124// function is called every time the variable is being polled. 125template<typename T> 126class CallCopyVariable : public Variable<T> { 127 public: 128 CallCopyVariable(const std::string& name, base::Callback<T(void)> func) 129 : Variable<T>(name, kVariableModePoll), func_(func) {} 130 CallCopyVariable(const std::string& name, 131 const base::TimeDelta poll_interval, 132 base::Callback<T(void)> func) 133 : Variable<T>(name, poll_interval), func_(func) {} 134 135 protected: 136 // Variable override. 137 virtual const T* GetValue(base::TimeDelta /* timeout */, 138 std::string* /* errmsg */) { 139 if (func_.is_null()) 140 return nullptr; 141 return new T(func_.Run()); 142 } 143 144 private: 145 FRIEND_TEST(PmCallCopyVariableTest, SimpleTest); 146 147 // The function to be called, stored as a base::Callback. 148 base::Callback<T(void)> func_; 149 150 DISALLOW_COPY_AND_ASSIGN(CallCopyVariable); 151}; 152 153 154// A Variable class to implement simple Async variables. It provides two methods 155// SetValue and UnsetValue to modify the current value of the variable and 156// notify the registered observers whenever the value changed. 157// 158// The type T needs to be copy-constructable, default-constructable and have an 159// operator== (to determine if the value changed), which makes this class 160// suitable for basic types. 161template<typename T> 162class AsyncCopyVariable : public Variable<T> { 163 public: 164 explicit AsyncCopyVariable(const std::string& name) 165 : Variable<T>(name, kVariableModeAsync), has_value_(false) {} 166 167 AsyncCopyVariable(const std::string& name, const T value) 168 : Variable<T>(name, kVariableModeAsync), 169 has_value_(true), value_(value) {} 170 171 void SetValue(const T& new_value) { 172 bool should_notify = !(has_value_ && new_value == value_); 173 value_ = new_value; 174 has_value_ = true; 175 if (should_notify) 176 this->NotifyValueChanged(); 177 } 178 179 void UnsetValue() { 180 if (has_value_) { 181 has_value_ = false; 182 this->NotifyValueChanged(); 183 } 184 } 185 186 protected: 187 // Variable override. 188 virtual const T* GetValue(base::TimeDelta /* timeout */, 189 std::string* errmsg) { 190 if (!has_value_) { 191 if (errmsg) 192 *errmsg = "No value set for " + this->GetName(); 193 return nullptr; 194 } 195 return new T(value_); 196 } 197 198 private: 199 // Whether the variable has a value set. 200 bool has_value_; 201 202 // Copy of the object to be returned by GetValue(). 203 T value_; 204}; 205 206} // namespace chromeos_policy_manager 207 208#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_ 209