-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeneric_variables.h
230 lines (201 loc) · 7.61 KB
/
generic_variables.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Generic and provider-independent Variable subclasses. These variables can be
// used by any state provider to implement simple variables to avoid repeat the
// same common code on different state providers.
#ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
#define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
#include <string>
#include <base/functional/callback.h>
#include "update_engine/update_manager/variable.h"
namespace chromeos_update_manager {
// Variable class returning a copy of a given object using the copy constructor.
// This template class can be used to define variables that expose as a variable
// any fixed object, such as the a provider's private member. The variable will
// create copies of the provided object using the copy constructor of that
// class.
//
// For example, a state provider exposing a private member as a variable can
// implement this as follows:
//
// class SomethingProvider {
// public:
// SomethingProvider(...) {
// var_something_foo = new PollCopyVariable<MyType>(foo_);
// }
// ...
// private:
// MyType foo_;
// };
template <typename T>
class PollCopyVariable : public Variable<T> {
public:
// Creates the variable returning copies of the passed |ref|. The reference to
// this object is kept and it should be available whenever the GetValue()
// method is called. If |is_set_p| is not null, then this flag will be
// consulted prior to returning the value, and an |errmsg| will be returned if
// it is not set.
PollCopyVariable(const std::string& name,
const T& ref,
const bool* is_set_p,
const std::string& errmsg)
: Variable<T>(name, kVariableModePoll),
ref_(ref),
is_set_p_(is_set_p),
errmsg_(errmsg) {}
PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p)
: PollCopyVariable(name, ref, is_set_p, std::string()) {}
PollCopyVariable(const std::string& name, const T& ref)
: PollCopyVariable(name, ref, nullptr) {}
PollCopyVariable(const std::string& name,
const base::TimeDelta poll_interval,
const T& ref,
const bool* is_set_p,
const std::string& errmsg)
: Variable<T>(name, poll_interval),
ref_(ref),
is_set_p_(is_set_p),
errmsg_(errmsg) {}
PollCopyVariable(const std::string& name,
const base::TimeDelta poll_interval,
const T& ref,
const bool* is_set_p)
: PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {}
PollCopyVariable(const std::string& name,
const base::TimeDelta poll_interval,
const T& ref)
: PollCopyVariable(name, poll_interval, ref, nullptr) {}
protected:
FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);
// Variable override.
inline const T* GetValue(base::TimeDelta /* timeout */,
std::string* errmsg) override {
if (is_set_p_ && !(*is_set_p_)) {
if (errmsg) {
if (errmsg_.empty())
*errmsg = "No value set for " + this->GetName();
else
*errmsg = errmsg_;
}
return nullptr;
}
return new T(ref_);
}
private:
// Reference to the object to be copied by GetValue().
const T& ref_;
// A pointer to a flag indicating whether the value is set. If null, then the
// value is assumed to be set.
const bool* const is_set_p_;
// An error message to be returned when attempting to get an unset value.
const std::string errmsg_;
};
// Variable class returning a constant value that is cached on the variable when
// it is created.
template <typename T>
class ConstCopyVariable : public Variable<T> {
public:
// Creates the variable returning copies of the passed |obj|. The value passed
// is copied in this variable, and new copies of it will be returned by
// GetValue().
ConstCopyVariable(const std::string& name, const T& obj)
: Variable<T>(name, kVariableModeConst), obj_(obj) {}
protected:
// Variable override.
const T* GetValue(base::TimeDelta /* timeout */,
std::string* /* errmsg */) override {
return new T(obj_);
}
private:
// Value to be copied by GetValue().
const T obj_;
};
// Variable class returning a copy of a value returned by a given function. The
// function is called every time the variable is being polled.
template <typename T>
class CallCopyVariable : public Variable<T> {
public:
CallCopyVariable(const std::string& name,
base::RepeatingCallback<T(void)> func)
: Variable<T>(name, kVariableModePoll), func_(func) {}
CallCopyVariable(const std::string& name,
const base::TimeDelta poll_interval,
base::RepeatingCallback<T(void)> func)
: Variable<T>(name, poll_interval), func_(func) {}
CallCopyVariable(const CallCopyVariable&) = delete;
CallCopyVariable& operator=(const CallCopyVariable&) = delete;
protected:
// Variable override.
const T* GetValue(base::TimeDelta /* timeout */,
std::string* /* errmsg */) override {
if (func_.is_null())
return nullptr;
return new T(func_.Run());
}
private:
FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);
// The function to be called, stored as a base::Callback.
base::RepeatingCallback<T(void)> func_;
};
// A Variable class to implement simple Async variables. It provides two methods
// SetValue and UnsetValue to modify the current value of the variable and
// notify the registered observers whenever the value changed.
//
// The type T needs to be copy-constructible, default-constructible and have an
// operator== (to determine if the value changed), which makes this class
// suitable for basic types.
template <typename T>
class AsyncCopyVariable : public Variable<T> {
public:
explicit AsyncCopyVariable(const std::string& name)
: Variable<T>(name, kVariableModeAsync), has_value_(false) {}
AsyncCopyVariable(const std::string& name, const T value)
: Variable<T>(name, kVariableModeAsync),
has_value_(true),
value_(value) {}
void SetValue(const T& new_value) {
bool should_notify = !(has_value_ && new_value == value_);
value_ = new_value;
has_value_ = true;
if (should_notify)
this->NotifyValueChanged();
}
void UnsetValue() {
if (has_value_) {
has_value_ = false;
this->NotifyValueChanged();
}
}
protected:
// Variable override.
const T* GetValue(base::TimeDelta /* timeout */,
std::string* errmsg) override {
if (!has_value_) {
if (errmsg)
*errmsg = "No value set for " + this->GetName();
return nullptr;
}
return new T(value_);
}
private:
// Whether the variable has a value set.
bool has_value_;
// Copy of the object to be returned by GetValue().
T value_;
};
} // namespace chromeos_update_manager
#endif // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_