1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1681f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 17b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// Generic and provider-independent Variable subclasses. These variables can be 1881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// used by any state provider to implement simple variables to avoid repeat the 1981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// same common code on different state providers. 2081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 2148415f1f6c6c356bfa9ac85b76d8ebcf053f7157Gilad Arnold#ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_ 2248415f1f6c6c356bfa9ac85b76d8ebcf053f7157Gilad Arnold#define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_ 2381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 2446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold#include <string> 2546eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold 26c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold#include <base/callback.h> 27c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 2863784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/variable.h" 2981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 3063784a578dd26880454d70797519358a2326291bAlex Deymonamespace chromeos_update_manager { 3181f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 3281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// Variable class returning a copy of a given object using the copy constructor. 3381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// This template class can be used to define variables that expose as a variable 3481f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// any fixed object, such as the a provider's private member. The variable will 3581f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// create copies of the provided object using the copy constructor of that 3681f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// class. 3781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// 38b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// For example, a state provider exposing a private member as a variable can 39b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// implement this as follows: 4081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// 4181f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// class SomethingProvider { 4281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// public: 4381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// SomethingProvider(...) { 4446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold// var_something_foo = new PollCopyVariable<MyType>(foo_); 4581f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// } 46b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// ... 4781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// private: 48b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// MyType foo_; 4981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// }; 5081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymotemplate<typename T> 5146eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnoldclass PollCopyVariable : public Variable<T> { 5281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo public: 539f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // Creates the variable returning copies of the passed |ref|. The reference to 549f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // this object is kept and it should be available whenever the GetValue() 559f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // method is called. If |is_set_p| is not null, then this flag will be 569f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // consulted prior to returning the value, and an |errmsg| will be returned if 579f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // it is not set. 5846eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p, 5946eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold const std::string& errmsg) 6046eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold : Variable<T>(name, kVariableModePoll), ref_(ref), is_set_p_(is_set_p), 619f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold errmsg_(errmsg) {} 6246eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p) 6346eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold : PollCopyVariable(name, ref, is_set_p, std::string()) {} 6446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold PollCopyVariable(const std::string& name, const T& ref) 6546eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold : PollCopyVariable(name, ref, nullptr) {} 6646eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold 6746eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval, 6846eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold const T& ref, const bool* is_set_p, 6946eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold const std::string& errmsg) 709f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p), 719f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold errmsg_(errmsg) {} 7246eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval, 7346eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold const T& ref, const bool* is_set_p) 7446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold : PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {} 7546eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval, 7646eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold const T& ref) 7746eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold : PollCopyVariable(name, poll_interval, ref, nullptr) {} 7881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 7981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo protected: 8063784a578dd26880454d70797519358a2326291bAlex Deymo FRIEND_TEST(UmPollCopyVariableTest, SimpleTest); 8163784a578dd26880454d70797519358a2326291bAlex Deymo FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest); 8281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 8381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo // Variable override. 84610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo inline const T* GetValue(base::TimeDelta /* timeout */, 85610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo std::string* errmsg) override { 869f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold if (is_set_p_ && !(*is_set_p_)) { 8746eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold if (errmsg) { 8846eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold if (errmsg_.empty()) 8946eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold *errmsg = "No value set for " + this->GetName(); 9046eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold else 9146eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold *errmsg = errmsg_; 9246eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold } 939f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold return nullptr; 949f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold } 95b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold return new T(ref_); 96b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold } 9781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 9881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo private: 9981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo // Reference to the object to be copied by GetValue(). 10081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo const T& ref_; 1019f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold 1029f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // A pointer to a flag indicating whether the value is set. If null, then the 1039f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // value is assumed to be set. 1049f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold const bool* const is_set_p_; 1059f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold 1069f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold // An error message to be returned when attempting to get an unset value. 1079f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold const std::string errmsg_; 10881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo}; 10981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 110bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo// Variable class returning a constant value that is cached on the variable when 111bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo// it is created. 112bd04b14e73e442db112710f2c03917e32edbee82Alex Deymotemplate<typename T> 113bd04b14e73e442db112710f2c03917e32edbee82Alex Deymoclass ConstCopyVariable : public Variable<T> { 114bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo public: 115bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo // Creates the variable returning copies of the passed |obj|. The value passed 116bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo // is copied in this variable, and new copies of it will be returned by 117bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo // GetValue(). 118bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo ConstCopyVariable(const std::string& name, const T& obj) 119bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo : Variable<T>(name, kVariableModeConst), obj_(obj) {} 120bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo 121bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo protected: 122bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo // Variable override. 123610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo const T* GetValue(base::TimeDelta /* timeout */, 124610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo std::string* /* errmsg */) override { 125bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo return new T(obj_); 126bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo } 127bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo 128bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo private: 129bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo // Value to be copied by GetValue(). 130bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo const T obj_; 131bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo}; 132bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo 133c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold// Variable class returning a copy of a value returned by a given function. The 134c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold// function is called every time the variable is being polled. 135c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnoldtemplate<typename T> 136c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnoldclass CallCopyVariable : public Variable<T> { 137c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold public: 138c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold CallCopyVariable(const std::string& name, base::Callback<T(void)> func) 139c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold : Variable<T>(name, kVariableModePoll), func_(func) {} 140c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold CallCopyVariable(const std::string& name, 141c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold const base::TimeDelta poll_interval, 142c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold base::Callback<T(void)> func) 143c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold : Variable<T>(name, poll_interval), func_(func) {} 144c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 145c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold protected: 146c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold // Variable override. 147610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo const T* GetValue(base::TimeDelta /* timeout */, 148610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo std::string* /* errmsg */) override { 149c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold if (func_.is_null()) 150c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold return nullptr; 151c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold return new T(func_.Run()); 152c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold } 153c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 154c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold private: 15563784a578dd26880454d70797519358a2326291bAlex Deymo FRIEND_TEST(UmCallCopyVariableTest, SimpleTest); 156c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 157c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold // The function to be called, stored as a base::Callback. 158c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold base::Callback<T(void)> func_; 159c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 160c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold DISALLOW_COPY_AND_ASSIGN(CallCopyVariable); 161c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold}; 162c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 163c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold 164c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// A Variable class to implement simple Async variables. It provides two methods 165c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// SetValue and UnsetValue to modify the current value of the variable and 166c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// notify the registered observers whenever the value changed. 167c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// 168072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko// The type T needs to be copy-constructible, default-constructible and have an 169c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// operator== (to determine if the value changed), which makes this class 170c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// suitable for basic types. 171c83baf63f764104e9472e74f293baf0982ac0280Alex Deymotemplate<typename T> 172c83baf63f764104e9472e74f293baf0982ac0280Alex Deymoclass AsyncCopyVariable : public Variable<T> { 173c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo public: 174c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo explicit AsyncCopyVariable(const std::string& name) 175c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo : Variable<T>(name, kVariableModeAsync), has_value_(false) {} 176c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 177c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo AsyncCopyVariable(const std::string& name, const T value) 178c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo : Variable<T>(name, kVariableModeAsync), 179c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo has_value_(true), value_(value) {} 180c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 181c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo void SetValue(const T& new_value) { 182c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo bool should_notify = !(has_value_ && new_value == value_); 183c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo value_ = new_value; 184c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo has_value_ = true; 185c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo if (should_notify) 186c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo this->NotifyValueChanged(); 187c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo } 188c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 189c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo void UnsetValue() { 190c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo if (has_value_) { 191c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo has_value_ = false; 192c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo this->NotifyValueChanged(); 193c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo } 194c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo } 195c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 196c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo protected: 197c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo // Variable override. 198610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo const T* GetValue(base::TimeDelta /* timeout */, 199610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo std::string* errmsg) override { 200c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo if (!has_value_) { 201c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo if (errmsg) 202c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo *errmsg = "No value set for " + this->GetName(); 203c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo return nullptr; 204c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo } 205c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo return new T(value_); 206c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo } 207c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 208c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo private: 209c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo // Whether the variable has a value set. 210c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo bool has_value_; 211c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 212c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo // Copy of the object to be returned by GetValue(). 213c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo T value_; 214c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo}; 215c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo 21663784a578dd26880454d70797519358a2326291bAlex Deymo} // namespace chromeos_update_manager 21781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo 21848415f1f6c6c356bfa9ac85b76d8ebcf053f7157Gilad Arnold#endif // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_ 219