blob: ad9f0c14b0b61bde178f004689e81527a9076659 [file] [log] [blame]
Alex Deymo81f30e82014-01-08 14:33:06 -08001// 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
Gilad Arnoldb33e1982014-01-27 14:46:27 -08005// Generic and provider-independent Variable subclasses. These variables can be
Alex Deymo81f30e82014-01-08 14:33:06 -08006// used by any state provider to implement simple variables to avoid repeat the
7// same common code on different state providers.
8
Gilad Arnold48415f12014-06-27 07:10:58 -07009#ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
10#define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
Alex Deymo81f30e82014-01-08 14:33:06 -080011
Gilad Arnold46eb5f62014-05-20 13:21:25 -070012#include <string>
13
Gilad Arnoldc16fca22014-05-20 15:10:40 -070014#include <base/callback.h>
15
Alex Deymo63784a52014-05-28 10:46:14 -070016#include "update_engine/update_manager/variable.h"
Alex Deymo81f30e82014-01-08 14:33:06 -080017
Alex Deymo63784a52014-05-28 10:46:14 -070018namespace chromeos_update_manager {
Alex Deymo81f30e82014-01-08 14:33:06 -080019
20// Variable class returning a copy of a given object using the copy constructor.
21// This template class can be used to define variables that expose as a variable
22// any fixed object, such as the a provider's private member. The variable will
23// create copies of the provided object using the copy constructor of that
24// class.
25//
Gilad Arnoldb33e1982014-01-27 14:46:27 -080026// For example, a state provider exposing a private member as a variable can
27// implement this as follows:
Alex Deymo81f30e82014-01-08 14:33:06 -080028//
Alex Deymo81f30e82014-01-08 14:33:06 -080029// class SomethingProvider {
30// public:
31// SomethingProvider(...) {
Gilad Arnold46eb5f62014-05-20 13:21:25 -070032// var_something_foo = new PollCopyVariable<MyType>(foo_);
Alex Deymo81f30e82014-01-08 14:33:06 -080033// }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080034// ...
Alex Deymo81f30e82014-01-08 14:33:06 -080035// private:
Gilad Arnoldb33e1982014-01-27 14:46:27 -080036// MyType foo_;
Alex Deymo81f30e82014-01-08 14:33:06 -080037// };
38template<typename T>
Gilad Arnold46eb5f62014-05-20 13:21:25 -070039class PollCopyVariable : public Variable<T> {
Alex Deymo81f30e82014-01-08 14:33:06 -080040 public:
Gilad Arnold9f7ab352014-04-16 15:27:37 -070041 // Creates the variable returning copies of the passed |ref|. The reference to
42 // this object is kept and it should be available whenever the GetValue()
43 // method is called. If |is_set_p| is not null, then this flag will be
44 // consulted prior to returning the value, and an |errmsg| will be returned if
45 // it is not set.
Gilad Arnold46eb5f62014-05-20 13:21:25 -070046 PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p,
47 const std::string& errmsg)
48 : Variable<T>(name, kVariableModePoll), ref_(ref), is_set_p_(is_set_p),
Gilad Arnold9f7ab352014-04-16 15:27:37 -070049 errmsg_(errmsg) {}
Gilad Arnold46eb5f62014-05-20 13:21:25 -070050 PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p)
51 : PollCopyVariable(name, ref, is_set_p, std::string()) {}
52 PollCopyVariable(const std::string& name, const T& ref)
53 : PollCopyVariable(name, ref, nullptr) {}
Gilad Arnold9f7ab352014-04-16 15:27:37 -070054
Gilad Arnold46eb5f62014-05-20 13:21:25 -070055 PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
56 const T& ref, const bool* is_set_p,
57 const std::string& errmsg)
Gilad Arnold9f7ab352014-04-16 15:27:37 -070058 : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
59 errmsg_(errmsg) {}
Gilad Arnold46eb5f62014-05-20 13:21:25 -070060 PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
61 const T& ref, const bool* is_set_p)
62 : PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {}
63 PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
64 const T& ref)
65 : PollCopyVariable(name, poll_interval, ref, nullptr) {}
Alex Deymo81f30e82014-01-08 14:33:06 -080066
Alex Deymo81f30e82014-01-08 14:33:06 -080067 protected:
Alex Deymo63784a52014-05-28 10:46:14 -070068 FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
69 FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);
Alex Deymo81f30e82014-01-08 14:33:06 -080070
71 // Variable override.
Gilad Arnold9f7ab352014-04-16 15:27:37 -070072 virtual inline const T* GetValue(base::TimeDelta /* timeout */,
73 std::string* errmsg) {
74 if (is_set_p_ && !(*is_set_p_)) {
Gilad Arnold46eb5f62014-05-20 13:21:25 -070075 if (errmsg) {
76 if (errmsg_.empty())
77 *errmsg = "No value set for " + this->GetName();
78 else
79 *errmsg = errmsg_;
80 }
Gilad Arnold9f7ab352014-04-16 15:27:37 -070081 return nullptr;
82 }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080083 return new T(ref_);
84 }
Alex Deymo81f30e82014-01-08 14:33:06 -080085
86 private:
87 // Reference to the object to be copied by GetValue().
88 const T& ref_;
Gilad Arnold9f7ab352014-04-16 15:27:37 -070089
90 // A pointer to a flag indicating whether the value is set. If null, then the
91 // value is assumed to be set.
92 const bool* const is_set_p_;
93
94 // An error message to be returned when attempting to get an unset value.
95 const std::string errmsg_;
Alex Deymo81f30e82014-01-08 14:33:06 -080096};
97
Alex Deymobd04b142014-03-18 15:00:05 -070098// Variable class returning a constant value that is cached on the variable when
99// it is created.
100template<typename T>
101class ConstCopyVariable : public Variable<T> {
102 public:
103 // Creates the variable returning copies of the passed |obj|. The value passed
104 // is copied in this variable, and new copies of it will be returned by
105 // GetValue().
106 ConstCopyVariable(const std::string& name, const T& obj)
107 : Variable<T>(name, kVariableModeConst), obj_(obj) {}
108
109 protected:
Alex Deymobd04b142014-03-18 15:00:05 -0700110 // Variable override.
111 virtual const T* GetValue(base::TimeDelta /* timeout */,
112 std::string* /* errmsg */) {
113 return new T(obj_);
114 }
115
116 private:
117 // Value to be copied by GetValue().
118 const T obj_;
119};
120
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700121// Variable class returning a copy of a value returned by a given function. The
122// function is called every time the variable is being polled.
123template<typename T>
124class CallCopyVariable : public Variable<T> {
125 public:
126 CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
127 : Variable<T>(name, kVariableModePoll), func_(func) {}
128 CallCopyVariable(const std::string& name,
129 const base::TimeDelta poll_interval,
130 base::Callback<T(void)> func)
131 : Variable<T>(name, poll_interval), func_(func) {}
132
133 protected:
134 // Variable override.
135 virtual const T* GetValue(base::TimeDelta /* timeout */,
136 std::string* /* errmsg */) {
137 if (func_.is_null())
138 return nullptr;
139 return new T(func_.Run());
140 }
141
142 private:
Alex Deymo63784a52014-05-28 10:46:14 -0700143 FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700144
145 // The function to be called, stored as a base::Callback.
146 base::Callback<T(void)> func_;
147
148 DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
149};
150
151
Alex Deymoc83baf62014-04-02 17:43:35 -0700152// A Variable class to implement simple Async variables. It provides two methods
153// SetValue and UnsetValue to modify the current value of the variable and
154// notify the registered observers whenever the value changed.
155//
Alex Vakulenko072359c2014-07-18 11:41:07 -0700156// The type T needs to be copy-constructible, default-constructible and have an
Alex Deymoc83baf62014-04-02 17:43:35 -0700157// operator== (to determine if the value changed), which makes this class
158// suitable for basic types.
159template<typename T>
160class AsyncCopyVariable : public Variable<T> {
161 public:
162 explicit AsyncCopyVariable(const std::string& name)
163 : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
164
165 AsyncCopyVariable(const std::string& name, const T value)
166 : Variable<T>(name, kVariableModeAsync),
167 has_value_(true), value_(value) {}
168
169 void SetValue(const T& new_value) {
170 bool should_notify = !(has_value_ && new_value == value_);
171 value_ = new_value;
172 has_value_ = true;
173 if (should_notify)
174 this->NotifyValueChanged();
175 }
176
177 void UnsetValue() {
178 if (has_value_) {
179 has_value_ = false;
180 this->NotifyValueChanged();
181 }
182 }
183
184 protected:
Alex Deymoc83baf62014-04-02 17:43:35 -0700185 // Variable override.
186 virtual const T* GetValue(base::TimeDelta /* timeout */,
187 std::string* errmsg) {
188 if (!has_value_) {
189 if (errmsg)
190 *errmsg = "No value set for " + this->GetName();
191 return nullptr;
192 }
193 return new T(value_);
194 }
195
196 private:
197 // Whether the variable has a value set.
198 bool has_value_;
199
200 // Copy of the object to be returned by GetValue().
201 T value_;
202};
203
Alex Deymo63784a52014-05-28 10:46:14 -0700204} // namespace chromeos_update_manager
Alex Deymo81f30e82014-01-08 14:33:06 -0800205
Gilad Arnold48415f12014-06-27 07:10:58 -0700206#endif // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_