blob: 530951998ed11b6abf8a3480dcd379933db4457a [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_TEST(PmCopyVariableTest, SimpleTest);
73 FRIEND_TEST(PmCopyVariableTest, UseCopyConstructorTest);
Alex Deymo81f30e82014-01-08 14:33:06 -080074
75 // Variable override.
Gilad Arnold9f7ab352014-04-16 15:27:37 -070076 virtual inline const T* GetValue(base::TimeDelta /* timeout */,
77 std::string* errmsg) {
78 if (is_set_p_ && !(*is_set_p_)) {
79 if (errmsg)
80 *errmsg = errmsg_;
81 return nullptr;
82 }
Gilad Arnoldb33e1982014-01-27 14:46:27 -080083 return new T(ref_);
84 }
Alex Deymo81f30e82014-01-08 14:33:06 -080085
86 private:
87 // Reference to the object to be copied by GetValue().
88 const T& ref_;
Gilad Arnold9f7ab352014-04-16 15:27:37 -070089
90 // A pointer to a flag indicating whether the value is set. If null, then the
91 // value is assumed to be set.
92 const bool* const is_set_p_;
93
94 // An error message to be returned when attempting to get an unset value.
95 const std::string errmsg_;
Alex Deymo81f30e82014-01-08 14:33:06 -080096};
97
Alex Deymobd04b142014-03-18 15:00:05 -070098// Variable class returning a constant value that is cached on the variable when
99// it is created.
100template<typename T>
101class ConstCopyVariable : public Variable<T> {
102 public:
103 // Creates the variable returning copies of the passed |obj|. The value passed
104 // is copied in this variable, and new copies of it will be returned by
105 // GetValue().
106 ConstCopyVariable(const std::string& name, const T& obj)
107 : Variable<T>(name, kVariableModeConst), obj_(obj) {}
108
109 protected:
Alex Deymobd04b142014-03-18 15:00:05 -0700110 // Variable override.
111 virtual const T* GetValue(base::TimeDelta /* timeout */,
112 std::string* /* errmsg */) {
113 return new T(obj_);
114 }
115
116 private:
117 // Value to be copied by GetValue().
118 const T obj_;
119};
120
Alex Deymoc83baf62014-04-02 17:43:35 -0700121// A Variable class to implement simple Async variables. It provides two methods
122// SetValue and UnsetValue to modify the current value of the variable and
123// notify the registered observers whenever the value changed.
124//
125// The type T needs to be copy-constructable, default-constructable and have an
126// operator== (to determine if the value changed), which makes this class
127// suitable for basic types.
128template<typename T>
129class AsyncCopyVariable : public Variable<T> {
130 public:
131 explicit AsyncCopyVariable(const std::string& name)
132 : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
133
134 AsyncCopyVariable(const std::string& name, const T value)
135 : Variable<T>(name, kVariableModeAsync),
136 has_value_(true), value_(value) {}
137
138 void SetValue(const T& new_value) {
139 bool should_notify = !(has_value_ && new_value == value_);
140 value_ = new_value;
141 has_value_ = true;
142 if (should_notify)
143 this->NotifyValueChanged();
144 }
145
146 void UnsetValue() {
147 if (has_value_) {
148 has_value_ = false;
149 this->NotifyValueChanged();
150 }
151 }
152
153 protected:
Alex Deymoc83baf62014-04-02 17:43:35 -0700154 // Variable override.
155 virtual const T* GetValue(base::TimeDelta /* timeout */,
156 std::string* errmsg) {
157 if (!has_value_) {
158 if (errmsg)
159 *errmsg = "No value set for " + this->GetName();
160 return nullptr;
161 }
162 return new T(value_);
163 }
164
165 private:
166 // Whether the variable has a value set.
167 bool has_value_;
168
169 // Copy of the object to be returned by GetValue().
170 T value_;
171};
172
Alex Deymo81f30e82014-01-08 14:33:06 -0800173} // namespace chromeos_policy_manager
174
Gilad Arnold2cbb3852014-03-07 12:40:50 -0800175#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_GENERIC_VARIABLES_H_