blob: 9110c9a18bb207ad6fe77635f1273d025c55d18f [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
Alex Deymo6e97bb22014-02-05 16:46:16 -080012#include "update_engine/policy_manager/variable.h"
Alex Deymo81f30e82014-01-08 14:33:06 -080013
Gilad Arnold9f7ab352014-04-16 15:27:37 -070014namespace {
15
16const char* kCopyVariableDefaultErrMsg = "Requested value is not set";
17
18} // namespace
19
20
Alex Deymo81f30e82014-01-08 14:33:06 -080021namespace chromeos_policy_manager {
22
23// Variable class returning a copy of a given object using the copy constructor.
24// This template class can be used to define variables that expose as a variable
25// any fixed object, such as the a provider's private member. The variable will
26// create copies of the provided object using the copy constructor of that
27// class.
28//
Gilad Arnoldb33e1982014-01-27 14:46:27 -080029// For example, a state provider exposing a private member as a variable can
30// implement this as follows:
Alex Deymo81f30e82014-01-08 14:33:06 -080031//
Alex Deymo81f30e82014-01-08 14:33:06 -080032// class SomethingProvider {
33// public:
34// SomethingProvider(...) {
Gilad Arnoldb33e1982014-01-27 14:46:27 -080035// var_something_foo = new CopyVariable<MyType>(foo_);
Alex Deymo81f30e82014-01-08 14:33:06 -080036// }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080037// ...
Alex Deymo81f30e82014-01-08 14:33:06 -080038// private:
Gilad Arnoldb33e1982014-01-27 14:46:27 -080039// MyType foo_;
Alex Deymo81f30e82014-01-08 14:33:06 -080040// };
41template<typename T>
42class CopyVariable : public Variable<T> {
43 public:
Gilad Arnold9f7ab352014-04-16 15:27:37 -070044 // Creates the variable returning copies of the passed |ref|. The reference to
45 // this object is kept and it should be available whenever the GetValue()
46 // method is called. If |is_set_p| is not null, then this flag will be
47 // consulted prior to returning the value, and an |errmsg| will be returned if
48 // it is not set.
49 CopyVariable(const std::string& name, VariableMode mode, const T& ref,
50 const bool* is_set_p, const std::string& errmsg)
51 : Variable<T>(name, mode), ref_(ref), is_set_p_(is_set_p),
52 errmsg_(errmsg) {}
53 CopyVariable(const std::string& name, VariableMode mode, const T& ref,
54 const bool* is_set_p)
55 : CopyVariable(name, mode, ref, is_set_p, kCopyVariableDefaultErrMsg) {}
Alex Deymo0e433692014-02-20 07:23:03 -080056 CopyVariable(const std::string& name, VariableMode mode, const T& ref)
Gilad Arnold9f7ab352014-04-16 15:27:37 -070057 : CopyVariable(name, mode, ref, nullptr) {}
58
59 CopyVariable(const std::string& name, const base::TimeDelta poll_interval,
60 const T& ref, const bool* is_set_p, const std::string& errmsg)
61 : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
62 errmsg_(errmsg) {}
63 CopyVariable(const std::string& name, const base::TimeDelta poll_interval,
64 const T& ref, const bool* is_set_p)
65 : CopyVariable(name, poll_interval, ref, is_set_p,
66 kCopyVariableDefaultErrMsg) {}
Gilad Arnoldb6a039f2014-03-26 12:12:39 -070067 CopyVariable(const std::string& name, const base::TimeDelta poll_interval,
Alex Deymoa8033932014-02-25 10:33:13 -080068 const T& ref)
Gilad Arnold9f7ab352014-04-16 15:27:37 -070069 : CopyVariable(name, poll_interval, ref, nullptr) {}
Alex Deymo81f30e82014-01-08 14:33:06 -080070
Alex Deymo81f30e82014-01-08 14:33:06 -080071 protected:
Gilad Arnoldb33e1982014-01-27 14:46:27 -080072 friend class PmCopyVariableTest;
73 FRIEND_TEST(PmCopyVariableTest, SimpleTest);
Gilad Arnold9f7ab352014-04-16 15:27:37 -070074 FRIEND_TEST(PmCopyVariableTest, SetFlagTest);
Gilad Arnoldb33e1982014-01-27 14:46:27 -080075 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:
112 friend class PmConstCopyVariableTest;
113 FRIEND_TEST(PmConstCopyVariableTest, SimpleTest);
114
115 // Variable override.
116 virtual const T* GetValue(base::TimeDelta /* timeout */,
117 std::string* /* errmsg */) {
118 return new T(obj_);
119 }
120
121 private:
122 // Value to be copied by GetValue().
123 const T obj_;
124};
125
Alex Deymoc83baf62014-04-02 17:43:35 -0700126// A Variable class to implement simple Async variables. It provides two methods
127// SetValue and UnsetValue to modify the current value of the variable and
128// notify the registered observers whenever the value changed.
129//
130// The type T needs to be copy-constructable, default-constructable and have an
131// operator== (to determine if the value changed), which makes this class
132// suitable for basic types.
133template<typename T>
134class AsyncCopyVariable : public Variable<T> {
135 public:
136 explicit AsyncCopyVariable(const std::string& name)
137 : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
138
139 AsyncCopyVariable(const std::string& name, const T value)
140 : Variable<T>(name, kVariableModeAsync),
141 has_value_(true), value_(value) {}
142
143 void SetValue(const T& new_value) {
144 bool should_notify = !(has_value_ && new_value == value_);
145 value_ = new_value;
146 has_value_ = true;
147 if (should_notify)
148 this->NotifyValueChanged();
149 }
150
151 void UnsetValue() {
152 if (has_value_) {
153 has_value_ = false;
154 this->NotifyValueChanged();
155 }
156 }
157
158 protected:
159 friend class PmAsyncCopyVariableTest;
160 FRIEND_TEST(PmAsyncCopyVariableTest, ConstructorTest);
161 FRIEND_TEST(PmAsyncCopyVariableTest, SetValueTest);
162 FRIEND_TEST(PmAsyncCopyVariableTest, UnsetValueTest);
163
164 // Variable override.
165 virtual const T* GetValue(base::TimeDelta /* timeout */,
166 std::string* errmsg) {
167 if (!has_value_) {
168 if (errmsg)
169 *errmsg = "No value set for " + this->GetName();
170 return nullptr;
171 }
172 return new T(value_);
173 }
174
175 private:
176 // Whether the variable has a value set.
177 bool has_value_;
178
179 // Copy of the object to be returned by GetValue().
180 T value_;
181};
182
Alex Deymo81f30e82014-01-08 14:33:06 -0800183} // namespace chromeos_policy_manager
184
Gilad Arnold2cbb3852014-03-07 12:40:50 -0800185#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_