blob: 42e991de15a54f58d82d62f9bba17623d751db25 [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 Arnold2cbb3852014-03-07 12:40:50 -08009#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_
10#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_
Alex Deymo81f30e82014-01-08 14:33:06 -080011
Gilad Arnoldc16fca22014-05-20 15:10:40 -070012#include <base/callback.h>
13
Alex Deymo6e97bb22014-02-05 16:46:16 -080014#include "update_engine/policy_manager/variable.h"
Alex Deymo81f30e82014-01-08 14:33:06 -080015
Gilad Arnold9f7ab352014-04-16 15:27:37 -070016namespace {
17
18const char* kCopyVariableDefaultErrMsg = "Requested value is not set";
19
20} // namespace
21
22
Alex Deymo81f30e82014-01-08 14:33:06 -080023namespace chromeos_policy_manager {
24
25// Variable class returning a copy of a given object using the copy constructor.
26// This template class can be used to define variables that expose as a variable
27// any fixed object, such as the a provider's private member. The variable will
28// create copies of the provided object using the copy constructor of that
29// class.
30//
Gilad Arnoldb33e1982014-01-27 14:46:27 -080031// For example, a state provider exposing a private member as a variable can
32// implement this as follows:
Alex Deymo81f30e82014-01-08 14:33:06 -080033//
Alex Deymo81f30e82014-01-08 14:33:06 -080034// class SomethingProvider {
35// public:
36// SomethingProvider(...) {
Gilad Arnoldb33e1982014-01-27 14:46:27 -080037// var_something_foo = new CopyVariable<MyType>(foo_);
Alex Deymo81f30e82014-01-08 14:33:06 -080038// }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080039// ...
Alex Deymo81f30e82014-01-08 14:33:06 -080040// private:
Gilad Arnoldb33e1982014-01-27 14:46:27 -080041// MyType foo_;
Alex Deymo81f30e82014-01-08 14:33:06 -080042// };
43template<typename T>
44class CopyVariable : public Variable<T> {
45 public:
Gilad Arnold9f7ab352014-04-16 15:27:37 -070046 // Creates the variable returning copies of the passed |ref|. The reference to
47 // this object is kept and it should be available whenever the GetValue()
48 // method is called. If |is_set_p| is not null, then this flag will be
49 // consulted prior to returning the value, and an |errmsg| will be returned if
50 // it is not set.
51 CopyVariable(const std::string& name, VariableMode mode, const T& ref,
52 const bool* is_set_p, const std::string& errmsg)
53 : Variable<T>(name, mode), ref_(ref), is_set_p_(is_set_p),
54 errmsg_(errmsg) {}
55 CopyVariable(const std::string& name, VariableMode mode, const T& ref,
56 const bool* is_set_p)
57 : CopyVariable(name, mode, ref, is_set_p, kCopyVariableDefaultErrMsg) {}
Alex Deymo0e433692014-02-20 07:23:03 -080058 CopyVariable(const std::string& name, VariableMode mode, const T& ref)
Gilad Arnold9f7ab352014-04-16 15:27:37 -070059 : CopyVariable(name, mode, ref, nullptr) {}
60
61 CopyVariable(const std::string& name, const base::TimeDelta poll_interval,
62 const T& ref, const bool* is_set_p, const std::string& errmsg)
63 : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
64 errmsg_(errmsg) {}
65 CopyVariable(const std::string& name, const base::TimeDelta poll_interval,
66 const T& ref, const bool* is_set_p)
67 : CopyVariable(name, poll_interval, ref, is_set_p,
68 kCopyVariableDefaultErrMsg) {}
Gilad Arnoldb6a039f2014-03-26 12:12:39 -070069 CopyVariable(const std::string& name, const base::TimeDelta poll_interval,
Alex Deymoa8033932014-02-25 10:33:13 -080070 const T& ref)
Gilad Arnold9f7ab352014-04-16 15:27:37 -070071 : CopyVariable(name, poll_interval, ref, nullptr) {}
Alex Deymo81f30e82014-01-08 14:33:06 -080072
Alex Deymo81f30e82014-01-08 14:33:06 -080073 protected:
Gilad Arnoldb33e1982014-01-27 14:46:27 -080074 FRIEND_TEST(PmCopyVariableTest, SimpleTest);
75 FRIEND_TEST(PmCopyVariableTest, UseCopyConstructorTest);
Alex Deymo81f30e82014-01-08 14:33:06 -080076
77 // Variable override.
Gilad Arnold9f7ab352014-04-16 15:27:37 -070078 virtual inline const T* GetValue(base::TimeDelta /* timeout */,
79 std::string* errmsg) {
80 if (is_set_p_ && !(*is_set_p_)) {
81 if (errmsg)
82 *errmsg = errmsg_;
83 return nullptr;
84 }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080085 return new T(ref_);
86 }
Alex Deymo81f30e82014-01-08 14:33:06 -080087
88 private:
89 // Reference to the object to be copied by GetValue().
90 const T& ref_;
Gilad Arnold9f7ab352014-04-16 15:27:37 -070091
92 // A pointer to a flag indicating whether the value is set. If null, then the
93 // value is assumed to be set.
94 const bool* const is_set_p_;
95
96 // An error message to be returned when attempting to get an unset value.
97 const std::string errmsg_;
Alex Deymo81f30e82014-01-08 14:33:06 -080098};
99
Alex Deymobd04b142014-03-18 15:00:05 -0700100// Variable class returning a constant value that is cached on the variable when
101// it is created.
102template<typename T>
103class ConstCopyVariable : public Variable<T> {
104 public:
105 // Creates the variable returning copies of the passed |obj|. The value passed
106 // is copied in this variable, and new copies of it will be returned by
107 // GetValue().
108 ConstCopyVariable(const std::string& name, const T& obj)
109 : Variable<T>(name, kVariableModeConst), obj_(obj) {}
110
111 protected:
Alex Deymobd04b142014-03-18 15:00:05 -0700112 // Variable override.
113 virtual const T* GetValue(base::TimeDelta /* timeout */,
114 std::string* /* errmsg */) {
115 return new T(obj_);
116 }
117
118 private:
119 // Value to be copied by GetValue().
120 const T obj_;
121};
122
Gilad Arnoldc16fca22014-05-20 15:10:40 -0700123// Variable class returning a copy of a value returned by a given function. The
124// function is called every time the variable is being polled.
125template<typename T>
126class CallCopyVariable : public Variable<T> {
127 public:
128 CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
129 : Variable<T>(name, kVariableModePoll), func_(func) {}
130 CallCopyVariable(const std::string& name,
131 const base::TimeDelta poll_interval,
132 base::Callback<T(void)> func)
133 : Variable<T>(name, poll_interval), func_(func) {}
134
135 protected:
136 // Variable override.
137 virtual const T* GetValue(base::TimeDelta /* timeout */,
138 std::string* /* errmsg */) {
139 if (func_.is_null())
140 return nullptr;
141 return new T(func_.Run());
142 }
143
144 private:
145 FRIEND_TEST(PmCallCopyVariableTest, SimpleTest);
146
147 // The function to be called, stored as a base::Callback.
148 base::Callback<T(void)> func_;
149
150 DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
151};
152
153
Alex Deymoc83baf62014-04-02 17:43:35 -0700154// A Variable class to implement simple Async variables. It provides two methods
155// SetValue and UnsetValue to modify the current value of the variable and
156// notify the registered observers whenever the value changed.
157//
158// The type T needs to be copy-constructable, default-constructable and have an
159// operator== (to determine if the value changed), which makes this class
160// suitable for basic types.
161template<typename T>
162class AsyncCopyVariable : public Variable<T> {
163 public:
164 explicit AsyncCopyVariable(const std::string& name)
165 : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
166
167 AsyncCopyVariable(const std::string& name, const T value)
168 : Variable<T>(name, kVariableModeAsync),
169 has_value_(true), value_(value) {}
170
171 void SetValue(const T& new_value) {
172 bool should_notify = !(has_value_ && new_value == value_);
173 value_ = new_value;
174 has_value_ = true;
175 if (should_notify)
176 this->NotifyValueChanged();
177 }
178
179 void UnsetValue() {
180 if (has_value_) {
181 has_value_ = false;
182 this->NotifyValueChanged();
183 }
184 }
185
186 protected:
Alex Deymoc83baf62014-04-02 17:43:35 -0700187 // Variable override.
188 virtual const T* GetValue(base::TimeDelta /* timeout */,
189 std::string* errmsg) {
190 if (!has_value_) {
191 if (errmsg)
192 *errmsg = "No value set for " + this->GetName();
193 return nullptr;
194 }
195 return new T(value_);
196 }
197
198 private:
199 // Whether the variable has a value set.
200 bool has_value_;
201
202 // Copy of the object to be returned by GetValue().
203 T value_;
204};
205
Alex Deymo81f30e82014-01-08 14:33:06 -0800206} // namespace chromeos_policy_manager
207
Gilad Arnold2cbb3852014-03-07 12:40:50 -0800208#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_