blob: f87a05e4bca0270482420b2bbd89c78a2591c787 [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// };
50template<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.
Gilad Arnold46eb5f62014-05-20 13:21:25 -070058 PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p,
59 const std::string& errmsg)
60 : Variable<T>(name, kVariableModePoll), ref_(ref), is_set_p_(is_set_p),
Gilad Arnold9f7ab352014-04-16 15:27:37 -070061 errmsg_(errmsg) {}
Gilad Arnold46eb5f62014-05-20 13:21:25 -070062 PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p)
63 : PollCopyVariable(name, ref, is_set_p, std::string()) {}
64 PollCopyVariable(const std::string& name, const T& ref)
65 : PollCopyVariable(name, ref, nullptr) {}
Gilad Arnold9f7ab352014-04-16 15:27:37 -070066
Gilad Arnold46eb5f62014-05-20 13:21:25 -070067 PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
68 const T& ref, const bool* is_set_p,
69 const std::string& errmsg)
Gilad Arnold9f7ab352014-04-16 15:27:37 -070070 : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
71 errmsg_(errmsg) {}
Gilad Arnold46eb5f62014-05-20 13:21:25 -070072 PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
73 const T& ref, const bool* is_set_p)
74 : PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {}
75 PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
76 const T& ref)
77 : PollCopyVariable(name, poll_interval, ref, nullptr) {}
Alex Deymo81f30e82014-01-08 14:33:06 -080078
Alex Deymo81f30e82014-01-08 14:33:06 -080079 protected:
Alex Deymo63784a52014-05-28 10:46:14 -070080 FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
81 FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);
Alex Deymo81f30e82014-01-08 14:33:06 -080082
83 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -080084 inline const T* GetValue(base::TimeDelta /* timeout */,
85 std::string* errmsg) override {
Gilad Arnold9f7ab352014-04-16 15:27:37 -070086 if (is_set_p_ && !(*is_set_p_)) {
Gilad Arnold46eb5f62014-05-20 13:21:25 -070087 if (errmsg) {
88 if (errmsg_.empty())
89 *errmsg = "No value set for " + this->GetName();
90 else
91 *errmsg = errmsg_;
92 }
Gilad Arnold9f7ab352014-04-16 15:27:37 -070093 return nullptr;
94 }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080095 return new T(ref_);
96 }
Alex Deymo81f30e82014-01-08 14:33:06 -080097
98 private:
99 // Reference to the object to be copied by GetValue().
100 const T& ref_;
Gilad Arnold9f7ab352014-04-16 15:27:37 -0700101
102 // A pointer to a flag indicating whether the value is set. If null, then the
103 // value is assumed to be set.
104 const bool* const is_set_p_;
105
106 // An error message to be returned when attempting to get an unset value.
107 const std::string errmsg_;
Alex Deymo81f30e82014-01-08 14:33:06 -0800108};
109
Alex Deymobd04b142014-03-18 15:00:05 -0700110// Variable class returning a constant value that is cached on the variable when
111// it is created.
112template<typename T>
113class ConstCopyVariable : public Variable<T> {
114 public:
115 // Creates the variable returning copies of the passed |obj|. The value passed
116 // is copied in this variable, and new copies of it will be returned by
117 // GetValue().
118 ConstCopyVariable(const std::string& name, const T& obj)
119 : Variable<T>(name, kVariableModeConst), obj_(obj) {}
120
121 protected:
Alex Deymobd04b142014-03-18 15:00:05 -0700122 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -0800123 const T* GetValue(base::TimeDelta /* timeout */,
124 std::string* /* errmsg */) override {
Alex Deymobd04b142014-03-18 15:00:05 -0700125 return new T(obj_);
126 }
127
128 private:
129 // Value to be copied by GetValue().
130 const T obj_;
131};
132
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700133// Variable class returning a copy of a value returned by a given function. The
134// function is called every time the variable is being polled.
135template<typename T>
136class CallCopyVariable : public Variable<T> {
137 public:
138 CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
139 : Variable<T>(name, kVariableModePoll), func_(func) {}
140 CallCopyVariable(const std::string& name,
141 const base::TimeDelta poll_interval,
142 base::Callback<T(void)> func)
143 : Variable<T>(name, poll_interval), func_(func) {}
144
145 protected:
146 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -0800147 const T* GetValue(base::TimeDelta /* timeout */,
148 std::string* /* errmsg */) override {
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700149 if (func_.is_null())
150 return nullptr;
151 return new T(func_.Run());
152 }
153
154 private:
Alex Deymo63784a52014-05-28 10:46:14 -0700155 FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700156
157 // The function to be called, stored as a base::Callback.
158 base::Callback<T(void)> func_;
159
160 DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
161};
162
163
Alex Deymoc83baf62014-04-02 17:43:35 -0700164// A Variable class to implement simple Async variables. It provides two methods
165// SetValue and UnsetValue to modify the current value of the variable and
166// notify the registered observers whenever the value changed.
167//
Alex Vakulenko072359c2014-07-18 11:41:07 -0700168// The type T needs to be copy-constructible, default-constructible and have an
Alex Deymoc83baf62014-04-02 17:43:35 -0700169// operator== (to determine if the value changed), which makes this class
170// suitable for basic types.
171template<typename T>
172class AsyncCopyVariable : public Variable<T> {
173 public:
174 explicit AsyncCopyVariable(const std::string& name)
175 : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
176
177 AsyncCopyVariable(const std::string& name, const T value)
178 : Variable<T>(name, kVariableModeAsync),
179 has_value_(true), value_(value) {}
180
181 void SetValue(const T& new_value) {
182 bool should_notify = !(has_value_ && new_value == value_);
183 value_ = new_value;
184 has_value_ = true;
185 if (should_notify)
186 this->NotifyValueChanged();
187 }
188
189 void UnsetValue() {
190 if (has_value_) {
191 has_value_ = false;
192 this->NotifyValueChanged();
193 }
194 }
195
196 protected:
Alex Deymoc83baf62014-04-02 17:43:35 -0700197 // Variable override.
Alex Deymo610277e2014-11-11 21:18:11 -0800198 const T* GetValue(base::TimeDelta /* timeout */,
199 std::string* errmsg) override {
Alex Deymoc83baf62014-04-02 17:43:35 -0700200 if (!has_value_) {
201 if (errmsg)
202 *errmsg = "No value set for " + this->GetName();
203 return nullptr;
204 }
205 return new T(value_);
206 }
207
208 private:
209 // Whether the variable has a value set.
210 bool has_value_;
211
212 // Copy of the object to be returned by GetValue().
213 T value_;
214};
215
Alex Deymo63784a52014-05-28 10:46:14 -0700216} // namespace chromeos_update_manager
Alex Deymo81f30e82014-01-08 14:33:06 -0800217
Gilad Arnold48415f12014-06-27 07:10:58 -0700218#endif // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_