You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
7.3 KiB
218 lines
7.3 KiB
// |
|
// 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/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::Callback<T(void)> func) |
|
: Variable<T>(name, kVariableModePoll), func_(func) {} |
|
CallCopyVariable(const std::string& name, |
|
const base::TimeDelta poll_interval, |
|
base::Callback<T(void)> func) |
|
: Variable<T>(name, poll_interval), func_(func) {} |
|
|
|
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::Callback<T(void)> func_; |
|
|
|
DISALLOW_COPY_AND_ASSIGN(CallCopyVariable); |
|
}; |
|
|
|
|
|
// 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_
|
|
|