1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
1681f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
17b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// Generic and provider-independent Variable subclasses. These variables can be
1881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// used by any state provider to implement simple variables to avoid repeat the
1981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// same common code on different state providers.
2081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
2148415f1f6c6c356bfa9ac85b76d8ebcf053f7157Gilad Arnold#ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
2248415f1f6c6c356bfa9ac85b76d8ebcf053f7157Gilad Arnold#define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
2381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
2446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold#include <string>
2546eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold
26c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold#include <base/callback.h>
27c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
2863784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/variable.h"
2981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
3063784a578dd26880454d70797519358a2326291bAlex Deymonamespace chromeos_update_manager {
3181f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
3281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// Variable class returning a copy of a given object using the copy constructor.
3381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// This template class can be used to define variables that expose as a variable
3481f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// any fixed object, such as the a provider's private member. The variable will
3581f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// create copies of the provided object using the copy constructor of that
3681f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo// class.
3781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//
38b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// For example, a state provider exposing a private member as a variable can
39b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold// implement this as follows:
4081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//
4181f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//   class SomethingProvider {
4281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//    public:
4381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//      SomethingProvider(...) {
4446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold//        var_something_foo = new PollCopyVariable<MyType>(foo_);
4581f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//      }
46b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold//      ...
4781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//    private:
48b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold//     MyType foo_;
4981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo//   };
5081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymotemplate<typename T>
5146eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnoldclass PollCopyVariable : public Variable<T> {
5281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo public:
539f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // Creates the variable returning copies of the passed |ref|. The reference to
549f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // this object is kept and it should be available whenever the GetValue()
559f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // method is called. If |is_set_p| is not null, then this flag will be
569f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // consulted prior to returning the value, and an |errmsg| will be returned if
579f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // it is not set.
5846eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold  PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p,
5946eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold                   const std::string& errmsg)
6046eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      : Variable<T>(name, kVariableModePoll), ref_(ref), is_set_p_(is_set_p),
619f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold        errmsg_(errmsg) {}
6246eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold  PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p)
6346eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      : PollCopyVariable(name, ref, is_set_p, std::string()) {}
6446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold  PollCopyVariable(const std::string& name, const T& ref)
6546eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      : PollCopyVariable(name, ref, nullptr) {}
6646eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold
6746eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold  PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
6846eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold                   const T& ref, const bool* is_set_p,
6946eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold                   const std::string& errmsg)
709f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold      : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
719f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold        errmsg_(errmsg) {}
7246eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold  PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
7346eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold                   const T& ref, const bool* is_set_p)
7446eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      : PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {}
7546eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold  PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
7646eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold                   const T& ref)
7746eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      : PollCopyVariable(name, poll_interval, ref, nullptr) {}
7881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
7981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo protected:
8063784a578dd26880454d70797519358a2326291bAlex Deymo  FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
8163784a578dd26880454d70797519358a2326291bAlex Deymo  FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);
8281f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
8381f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo  // Variable override.
84610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  inline const T* GetValue(base::TimeDelta /* timeout */,
85610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo                           std::string* errmsg) override {
869f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold    if (is_set_p_ && !(*is_set_p_)) {
8746eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      if (errmsg) {
8846eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold        if (errmsg_.empty())
8946eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold          *errmsg = "No value set for " + this->GetName();
9046eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold        else
9146eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold          *errmsg = errmsg_;
9246eb5f6eabcbde324e059b48031eaa9af11ff236Gilad Arnold      }
939f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold      return nullptr;
949f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold    }
95b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold    return new T(ref_);
96b33e19855d4c64cdde1e5d79fbb457a4a6b57aa1Gilad Arnold  }
9781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
9881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo private:
9981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo  // Reference to the object to be copied by GetValue().
10081f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo  const T& ref_;
1019f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold
1029f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // A pointer to a flag indicating whether the value is set. If null, then the
1039f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // value is assumed to be set.
1049f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  const bool* const is_set_p_;
1059f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold
1069f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  // An error message to be returned when attempting to get an unset value.
1079f7ab3509e0bc4988d33bbb2b66f3dbd31dde91aGilad Arnold  const std::string errmsg_;
10881f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo};
10981f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
110bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo// Variable class returning a constant value that is cached on the variable when
111bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo// it is created.
112bd04b14e73e442db112710f2c03917e32edbee82Alex Deymotemplate<typename T>
113bd04b14e73e442db112710f2c03917e32edbee82Alex Deymoclass ConstCopyVariable : public Variable<T> {
114bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo public:
115bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  // Creates the variable returning copies of the passed |obj|. The value passed
116bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  // is copied in this variable, and new copies of it will be returned by
117bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  // GetValue().
118bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  ConstCopyVariable(const std::string& name, const T& obj)
119bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo      : Variable<T>(name, kVariableModeConst), obj_(obj) {}
120bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo
121bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo protected:
122bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  // Variable override.
123610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  const T* GetValue(base::TimeDelta /* timeout */,
124610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo                    std::string* /* errmsg */) override {
125bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo    return new T(obj_);
126bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  }
127bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo
128bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo private:
129bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  // Value to be copied by GetValue().
130bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo  const T obj_;
131bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo};
132bd04b14e73e442db112710f2c03917e32edbee82Alex Deymo
133c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold// Variable class returning a copy of a value returned by a given function. The
134c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold// function is called every time the variable is being polled.
135c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnoldtemplate<typename T>
136c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnoldclass CallCopyVariable : public Variable<T> {
137c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold public:
138c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
139c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold      : Variable<T>(name, kVariableModePoll), func_(func) {}
140c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  CallCopyVariable(const std::string& name,
141c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold                   const base::TimeDelta poll_interval,
142c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold                   base::Callback<T(void)> func)
143c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold      : Variable<T>(name, poll_interval), func_(func) {}
144c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
145c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold protected:
146c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  // Variable override.
147610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  const T* GetValue(base::TimeDelta /* timeout */,
148610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo                    std::string* /* errmsg */) override {
149c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold    if (func_.is_null())
150c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold      return nullptr;
151c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold    return new T(func_.Run());
152c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  }
153c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
154c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold private:
15563784a578dd26880454d70797519358a2326291bAlex Deymo  FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);
156c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
157c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  // The function to be called, stored as a base::Callback.
158c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  base::Callback<T(void)> func_;
159c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
160c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold  DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
161c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold};
162c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
163c16fca2f1b263872e12503eab4621250ef1f1e1cGilad Arnold
164c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// A Variable class to implement simple Async variables. It provides two methods
165c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// SetValue and UnsetValue to modify the current value of the variable and
166c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// notify the registered observers whenever the value changed.
167c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo//
168072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko// The type T needs to be copy-constructible, default-constructible and have an
169c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// operator== (to determine if the value changed), which makes this class
170c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo// suitable for basic types.
171c83baf63f764104e9472e74f293baf0982ac0280Alex Deymotemplate<typename T>
172c83baf63f764104e9472e74f293baf0982ac0280Alex Deymoclass AsyncCopyVariable : public Variable<T> {
173c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo public:
174c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  explicit AsyncCopyVariable(const std::string& name)
175c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      : Variable<T>(name, kVariableModeAsync), has_value_(false) {}
176c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
177c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  AsyncCopyVariable(const std::string& name, const T value)
178c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      : Variable<T>(name, kVariableModeAsync),
179c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo        has_value_(true), value_(value) {}
180c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
181c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  void SetValue(const T& new_value) {
182c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    bool should_notify = !(has_value_ && new_value == value_);
183c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    value_ = new_value;
184c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    has_value_ = true;
185c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    if (should_notify)
186c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      this->NotifyValueChanged();
187c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  }
188c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
189c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  void UnsetValue() {
190c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    if (has_value_) {
191c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      has_value_ = false;
192c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      this->NotifyValueChanged();
193c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    }
194c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  }
195c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
196c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo protected:
197c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  // Variable override.
198610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  const T* GetValue(base::TimeDelta /* timeout */,
199610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo                    std::string* errmsg) override {
200c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    if (!has_value_) {
201c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      if (errmsg)
202c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo        *errmsg = "No value set for " + this->GetName();
203c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo      return nullptr;
204c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    }
205c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo    return new T(value_);
206c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  }
207c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
208c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo private:
209c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  // Whether the variable has a value set.
210c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  bool has_value_;
211c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
212c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  // Copy of the object to be returned by GetValue().
213c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo  T value_;
214c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo};
215c83baf63f764104e9472e74f293baf0982ac0280Alex Deymo
21663784a578dd26880454d70797519358a2326291bAlex Deymo}  // namespace chromeos_update_manager
21781f30e8d9f0c2650425798f2d732b208f3544ba0Alex Deymo
21848415f1f6c6c356bfa9ac85b76d8ebcf053f7157Gilad Arnold#endif  // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
219