Home | History | Annotate | Download | only in update_manager
      1 //
      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 //
     16 
     17 // Generic and provider-independent Variable subclasses. These variables can be
     18 // used by any state provider to implement simple variables to avoid repeat the
     19 // same common code on different state providers.
     20 
     21 #ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
     22 #define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
     23 
     24 #include <string>
     25 
     26 #include <base/callback.h>
     27 
     28 #include "update_engine/update_manager/variable.h"
     29 
     30 namespace chromeos_update_manager {
     31 
     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 //
     38 // For example, a state provider exposing a private member as a variable can
     39 // implement this as follows:
     40 //
     41 //   class SomethingProvider {
     42 //    public:
     43 //      SomethingProvider(...) {
     44 //        var_something_foo = new PollCopyVariable<MyType>(foo_);
     45 //      }
     46 //      ...
     47 //    private:
     48 //     MyType foo_;
     49 //   };
     50 template<typename T>
     51 class PollCopyVariable : public Variable<T> {
     52  public:
     53   // 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.
     58   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),
     61         errmsg_(errmsg) {}
     62   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) {}
     66 
     67   PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
     68                    const T& ref, const bool* is_set_p,
     69                    const std::string& errmsg)
     70       : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
     71         errmsg_(errmsg) {}
     72   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) {}
     78 
     79  protected:
     80   FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
     81   FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);
     82 
     83   // Variable override.
     84   inline const T* GetValue(base::TimeDelta /* timeout */,
     85                            std::string* errmsg) override {
     86     if (is_set_p_ && !(*is_set_p_)) {
     87       if (errmsg) {
     88         if (errmsg_.empty())
     89           *errmsg = "No value set for " + this->GetName();
     90         else
     91           *errmsg = errmsg_;
     92       }
     93       return nullptr;
     94     }
     95     return new T(ref_);
     96   }
     97 
     98  private:
     99   // Reference to the object to be copied by GetValue().
    100   const T& ref_;
    101 
    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_;
    108 };
    109 
    110 // Variable class returning a constant value that is cached on the variable when
    111 // it is created.
    112 template<typename T>
    113 class 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:
    122   // Variable override.
    123   const T* GetValue(base::TimeDelta /* timeout */,
    124                     std::string* /* errmsg */) override {
    125     return new T(obj_);
    126   }
    127 
    128  private:
    129   // Value to be copied by GetValue().
    130   const T obj_;
    131 };
    132 
    133 // 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.
    135 template<typename T>
    136 class 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.
    147   const T* GetValue(base::TimeDelta /* timeout */,
    148                     std::string* /* errmsg */) override {
    149     if (func_.is_null())
    150       return nullptr;
    151     return new T(func_.Run());
    152   }
    153 
    154  private:
    155   FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);
    156 
    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 
    164 // 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 //
    168 // The type T needs to be copy-constructible, default-constructible and have an
    169 // operator== (to determine if the value changed), which makes this class
    170 // suitable for basic types.
    171 template<typename T>
    172 class 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:
    197   // Variable override.
    198   const T* GetValue(base::TimeDelta /* timeout */,
    199                     std::string* errmsg) override {
    200     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 
    216 }  // namespace chromeos_update_manager
    217 
    218 #endif  // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
    219