blob: afbdcbee8197eed65ff3a8005e6090d60ae75816 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
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//
Alex Deymo81f30e82014-01-08 14:33:06 -080016
Gilad Arnoldb33e1982014-01-27 14:46:27 -080017// Generic and provider-independent Variable subclasses. These variables can be
Alex Deymo81f30e82014-01-08 14:33:06 -080018// used by any state provider to implement simple variables to avoid repeat the
19// same common code on different state providers.
20
Gilad Arnold48415f12014-06-27 07:10:58 -070021#ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
22#define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
Alex Deymo81f30e82014-01-08 14:33:06 -080023
Gilad Arnold46eb5f62014-05-20 13:21:25 -070024#include <string>
25
Gilad Arnoldc16fca22014-05-20 15:10:40 -070026#include <base/callback.h>
27
Alex Deymo63784a52014-05-28 10:46:14 -070028#include "update_engine/update_manager/variable.h"
Alex Deymo81f30e82014-01-08 14:33:06 -080029
Alex Deymo63784a52014-05-28 10:46:14 -070030namespace chromeos_update_manager {
Alex Deymo81f30e82014-01-08 14:33:06 -080031
32// Variable class returning a copy of a given object using the copy constructor.
33// This template class can be used to define variables that expose as a variable
34// any fixed object, such as the a provider's private member. The variable will
35// create copies of the provided object using the copy constructor of that
36// class.
37//
Gilad Arnoldb33e1982014-01-27 14:46:27 -080038// For example, a state provider exposing a private member as a variable can
39// implement this as follows:
Alex Deymo81f30e82014-01-08 14:33:06 -080040//
Alex Deymo81f30e82014-01-08 14:33:06 -080041// class SomethingProvider {
42// public:
43// SomethingProvider(...) {
Gilad Arnold46eb5f62014-05-20 13:21:25 -070044// var_something_foo = new PollCopyVariable<MyType>(foo_);
Alex Deymo81f30e82014-01-08 14:33:06 -080045// }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080046// ...
Alex Deymo81f30e82014-01-08 14:33:06 -080047// private:
Gilad Arnoldb33e1982014-01-27 14:46:27 -080048// MyType foo_;
Alex Deymo81f30e82014-01-08 14:33:06 -080049// };
Amin Hassani4b717432019-01-14 16:24:20 -080050template <typename T>
Gilad Arnold46eb5f62014-05-20 13:21:25 -070051class PollCopyVariable : public Variable<T> {
Alex Deymo81f30e82014-01-08 14:33:06 -080052 public:
Gilad Arnold9f7ab352014-04-16 15:27:37 -070053 // Creates the variable returning copies of the passed |ref|. The reference to
54 // this object is kept and it should be available whenever the GetValue()
55 // method is called. If |is_set_p| is not null, then this flag will be
56 // consulted prior to returning the value, and an |errmsg| will be returned if
57 // it is not set.
Amin Hassani4b717432019-01-14 16:24:20 -080058 PollCopyVariable(const std::string& name,
59 const T& ref,
60 const bool* is_set_p,
Gilad Arnold46eb5f62014-05-20 13:21:25 -070061 const std::string& errmsg)
Amin Hassani4b717432019-01-14 16:24:20 -080062 : Variable<T>(name, kVariableModePoll),
63 ref_(ref),
64 is_set_p_(is_set_p),
Gilad Arnold9f7ab352014-04-16 15:27:37 -070065 errmsg_(errmsg) {}
Gilad Arnold46eb5f62014-05-20 13:21:25 -070066 PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p)
67 : PollCopyVariable(name, ref, is_set_p, std::string()) {}
68 PollCopyVariable(const std::string& name, const T& ref)
69 : PollCopyVariable(name, ref, nullptr) {}
Gilad Arnold9f7ab352014-04-16 15:27:37 -070070
Amin Hassani4b717432019-01-14 16:24:20 -080071 PollCopyVariable(const std::string& name,
72 const base::TimeDelta poll_interval,
73 const T& ref,
74 const bool* is_set_p,
Gilad Arnold46eb5f62014-05-20 13:21:25 -070075 const std::string& errmsg)
Amin Hassani4b717432019-01-14 16:24:20 -080076 : Variable<T>(name, poll_interval),
77 ref_(ref),
78 is_set_p_(is_set_p),
Gilad Arnold9f7ab352014-04-16 15:27:37 -070079 errmsg_(errmsg) {}
Amin Hassani4b717432019-01-14 16:24:20 -080080 PollCopyVariable(const std::string& name,
81 const base::TimeDelta poll_interval,
82 const T& ref,
83 const bool* is_set_p)
Gilad Arnold46eb5f62014-05-20 13:21:25 -070084 : PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {}
Amin Hassani4b717432019-01-14 16:24:20 -080085 PollCopyVariable(const std::string& name,
86 const base::TimeDelta poll_interval,
Gilad Arnold46eb5f62014-05-20 13:21:25 -070087 const T& ref)
88 : PollCopyVariable(name, poll_interval, ref, nullptr) {}
Alex Deymo81f30e82014-01-08 14:33:06 -080089
Alex Deymo81f30e82014-01-08 14:33:06 -080090 protected:
Alex Deymo63784a52014-05-28 10:46:14 -070091 FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
92 FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);
Alex Deymo81f30e82014-01-08 14:33:06 -080093
94 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -080095 inline const T* GetValue(base::TimeDelta /* timeout */,
96 std::string* errmsg) override {
Gilad Arnold9f7ab352014-04-16 15:27:37 -070097 if (is_set_p_ && !(*is_set_p_)) {
Gilad Arnold46eb5f62014-05-20 13:21:25 -070098 if (errmsg) {
99 if (errmsg_.empty())
100 *errmsg = "No value set for " + this->GetName();
101 else
102 *errmsg = errmsg_;
103 }
Gilad Arnold9f7ab352014-04-16 15:27:37 -0700104 return nullptr;
105 }
Gilad Arnoldb33e1982014-01-27 14:46:27 -0800106 return new T(ref_);
107 }
Alex Deymo81f30e82014-01-08 14:33:06 -0800108
109 private:
110 // Reference to the object to be copied by GetValue().
111 const T& ref_;
Gilad Arnold9f7ab352014-04-16 15:27:37 -0700112
113 // A pointer to a flag indicating whether the value is set. If null, then the
114 // value is assumed to be set.
115 const bool* const is_set_p_;
116
117 // An error message to be returned when attempting to get an unset value.
118 const std::string errmsg_;
Alex Deymo81f30e82014-01-08 14:33:06 -0800119};
120
Alex Deymobd04b142014-03-18 15:00:05 -0700121// Variable class returning a constant value that is cached on the variable when
122// it is created.
Amin Hassani4b717432019-01-14 16:24:20 -0800123template <typename T>
Alex Deymobd04b142014-03-18 15:00:05 -0700124class ConstCopyVariable : public Variable<T> {
125 public:
126 // Creates the variable returning copies of the passed |obj|. The value passed
127 // is copied in this variable, and new copies of it will be returned by
128 // GetValue().
129 ConstCopyVariable(const std::string& name, const T& obj)
130 : Variable<T>(name, kVariableModeConst), obj_(obj) {}
131
132 protected:
Alex Deymobd04b142014-03-18 15:00:05 -0700133 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -0800134 const T* GetValue(base::TimeDelta /* timeout */,
135 std::string* /* errmsg */) override {
Alex Deymobd04b142014-03-18 15:00:05 -0700136 return new T(obj_);
137 }
138
139 private:
140 // Value to be copied by GetValue().
141 const T obj_;
142};
143
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700144// Variable class returning a copy of a value returned by a given function. The
145// function is called every time the variable is being polled.
Amin Hassani4b717432019-01-14 16:24:20 -0800146template <typename T>
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700147class CallCopyVariable : public Variable<T> {
148 public:
149 CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
150 : Variable<T>(name, kVariableModePoll), func_(func) {}
151 CallCopyVariable(const std::string& name,
152 const base::TimeDelta poll_interval,
153 base::Callback<T(void)> func)
154 : Variable<T>(name, poll_interval), func_(func) {}
155
156 protected:
157 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -0800158 const T* GetValue(base::TimeDelta /* timeout */,
159 std::string* /* errmsg */) override {
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700160 if (func_.is_null())
161 return nullptr;
162 return new T(func_.Run());
163 }
164
165 private:
Alex Deymo63784a52014-05-28 10:46:14 -0700166 FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700167
168 // The function to be called, stored as a base::Callback.
169 base::Callback<T(void)> func_;
170
171 DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
172};
173
Alex Deymoc83baf62014-04-02 17:43:35 -0700174// A Variable class to implement simple Async variables. It provides two methods
175// SetValue and UnsetValue to modify the current value of the variable and
176// notify the registered observers whenever the value changed.
177//
Alex Vakulenko072359c2014-07-18 11:41:07 -0700178// The type T needs to be copy-constructible, default-constructible and have an
Alex Deymoc83baf62014-04-02 17:43:35 -0700179// operator== (to determine if the value changed), which makes this class
180// suitable for basic types.
Amin Hassani4b717432019-01-14 16:24:20 -0800181template <typename T>
Alex Deymoc83baf62014-04-02 17:43:35 -0700182class AsyncCopyVariable : public Variable<T> {
183 public:
184 explicit AsyncCopyVariable(const std::string& name)
185 : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
186
187 AsyncCopyVariable(const std::string& name, const T value)
188 : Variable<T>(name, kVariableModeAsync),
Amin Hassani4b717432019-01-14 16:24:20 -0800189 has_value_(true),
190 value_(value) {}
Alex Deymoc83baf62014-04-02 17:43:35 -0700191
192 void SetValue(const T& new_value) {
193 bool should_notify = !(has_value_ && new_value == value_);
194 value_ = new_value;
195 has_value_ = true;
196 if (should_notify)
197 this->NotifyValueChanged();
198 }
199
200 void UnsetValue() {
201 if (has_value_) {
202 has_value_ = false;
203 this->NotifyValueChanged();
204 }
205 }
206
207 protected:
Alex Deymoc83baf62014-04-02 17:43:35 -0700208 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -0800209 const T* GetValue(base::TimeDelta /* timeout */,
210 std::string* errmsg) override {
Alex Deymoc83baf62014-04-02 17:43:35 -0700211 if (!has_value_) {
212 if (errmsg)
213 *errmsg = "No value set for " + this->GetName();
214 return nullptr;
215 }
216 return new T(value_);
217 }
218
219 private:
220 // Whether the variable has a value set.
221 bool has_value_;
222
223 // Copy of the object to be returned by GetValue().
224 T value_;
225};
226
Alex Deymo63784a52014-05-28 10:46:14 -0700227} // namespace chromeos_update_manager
Alex Deymo81f30e82014-01-08 14:33:06 -0800228
Gilad Arnold48415f12014-06-27 07:10:58 -0700229#endif // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_