PM: Add a time provider.
This implements a time provider interface, as well as a real and a fake
implementation.
BUG=chromium:341205
TEST=Unit tests.
Change-Id: Ibc6a865ab868e0f8c760c003dc970b7987896a36
Reviewed-on: https://chromium-review.googlesource.com/190247
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/policy_manager/fake_state.cc b/policy_manager/fake_state.cc
index 977e9d3..19df440 100644
--- a/policy_manager/fake_state.cc
+++ b/policy_manager/fake_state.cc
@@ -5,12 +5,14 @@
#include "update_engine/policy_manager/fake_random_provider.h"
#include "update_engine/policy_manager/fake_shill_provider.h"
#include "update_engine/policy_manager/fake_state.h"
+#include "update_engine/policy_manager/fake_time_provider.h"
namespace chromeos_policy_manager {
FakeState::FakeState() {
set_random_provider(new FakeRandomProvider());
set_shill_provider(new FakeShillProvider());
+ set_time_provider(new FakeTimeProvider());
}
} // namespace chromeos_policy_manager
diff --git a/policy_manager/fake_time_provider.h b/policy_manager/fake_time_provider.h
new file mode 100644
index 0000000..6797f5c
--- /dev/null
+++ b/policy_manager/fake_time_provider.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_FAKE_TIME_PROVIDER_H_
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_FAKE_TIME_PROVIDER_H_
+
+#include "update_engine/policy_manager/fake_variable.h"
+#include "update_engine/policy_manager/time_provider.h"
+
+namespace chromeos_policy_manager {
+
+// Fake implementation of the TimeProvider base class.
+class FakeTimeProvider : public TimeProvider {
+ public:
+ FakeTimeProvider() {}
+
+ protected:
+ virtual bool DoInit() {
+ set_var_curr_date(
+ new FakeVariable<base::Time>("curr_date", kVariableModePoll));
+ set_var_curr_hour(
+ new FakeVariable<int>("curr_hour", kVariableModePoll));
+ return true;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeTimeProvider);
+};
+
+} // namespace chromeos_policy_manager
+
+#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_FAKE_TIME_PROVIDER_H_
diff --git a/policy_manager/real_state.cc b/policy_manager/real_state.cc
index 8f99869..2f9f3cc 100644
--- a/policy_manager/real_state.cc
+++ b/policy_manager/real_state.cc
@@ -6,13 +6,16 @@
#include "update_engine/policy_manager/real_random_provider.h"
#include "update_engine/policy_manager/real_shill_provider.h"
+#include "update_engine/policy_manager/real_time_provider.h"
namespace chromeos_policy_manager {
RealState::RealState(RandomProvider* random_provider,
- ShillProvider* shill_provider) {
+ ShillProvider* shill_provider,
+ TimeProvider* time_provider) {
set_random_provider(random_provider);
set_shill_provider(shill_provider);
+ set_time_provider(time_provider);
}
} // namespace chromeos_policy_manager
diff --git a/policy_manager/real_state.h b/policy_manager/real_state.h
index e2eddd7..c0f1ac6 100644
--- a/policy_manager/real_state.h
+++ b/policy_manager/real_state.h
@@ -15,7 +15,8 @@
class RealState : public State {
public:
// Instantiate with given providers, assuming ownership of them.
- RealState(RandomProvider* random_provider, ShillProvider* shill_provider);
+ RealState(RandomProvider* random_provider, ShillProvider* shill_provider,
+ TimeProvider* time_provider);
~RealState() {}
diff --git a/policy_manager/real_state_unittest.cc b/policy_manager/real_state_unittest.cc
index 6078223..0362688 100644
--- a/policy_manager/real_state_unittest.cc
+++ b/policy_manager/real_state_unittest.cc
@@ -6,13 +6,15 @@
#include "update_engine/policy_manager/fake_random_provider.h"
#include "update_engine/policy_manager/fake_shill_provider.h"
+#include "update_engine/policy_manager/fake_time_provider.h"
#include "update_engine/policy_manager/real_state.h"
#include "update_engine/policy_manager/pmtest_utils.h"
namespace chromeos_policy_manager {
TEST(PmRealStateTest, InitTest) {
- RealState state(new FakeRandomProvider(), new FakeShillProvider());
+ RealState state(new FakeRandomProvider(), new FakeShillProvider(),
+ new FakeTimeProvider());
EXPECT_TRUE(state.Init());
// Check that the providers are being initialized. Beyond ensuring that we get
@@ -22,6 +24,8 @@
PMTEST_EXPECT_NOT_NULL(state.random_provider()->var_seed());
PMTEST_ASSERT_NOT_NULL(state.shill_provider());
PMTEST_EXPECT_NOT_NULL(state.shill_provider()->var_is_connected());
+ PMTEST_ASSERT_NOT_NULL(state.time_provider());
+ PMTEST_ASSERT_NOT_NULL(state.time_provider()->var_curr_date());
}
} // namespace chromeos_policy_manager
diff --git a/policy_manager/real_time_provider.cc b/policy_manager/real_time_provider.cc
new file mode 100644
index 0000000..0c20e2e
--- /dev/null
+++ b/policy_manager/real_time_provider.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/policy_manager/real_time_provider.h"
+
+#include <base/time.h>
+
+#include "update_engine/clock_interface.h"
+
+using base::Time;
+using base::TimeDelta;
+using chromeos_update_engine::ClockInterface;
+using std::string;
+
+namespace chromeos_policy_manager {
+
+// A variable returning the current date.
+class CurrDateVariable : public Variable<Time> {
+ public:
+ // TODO(garnold) Turn this into an async variable with the needed callback
+ // logic for when it value changes.
+ CurrDateVariable(const string& name, ClockInterface* clock)
+ : Variable<Time>(name, TimeDelta::FromHours(1)), clock_(clock) {}
+
+ protected:
+ virtual const Time* GetValue(base::TimeDelta /* timeout */,
+ string* /* errmsg */) {
+ Time::Exploded now_exp;
+ clock_->GetWallclockTime().LocalExplode(&now_exp);
+ now_exp.hour = now_exp.minute = now_exp.second = now_exp.millisecond = 0;
+ return new Time(Time::FromLocalExploded(now_exp));
+ }
+
+ private:
+ ClockInterface* clock_;
+
+ DISALLOW_COPY_AND_ASSIGN(CurrDateVariable);
+};
+
+// A variable returning the current hour in local time.
+class CurrHourVariable : public Variable<int> {
+ public:
+ // TODO(garnold) Turn this into an async variable with the needed callback
+ // logic for when it value changes.
+ CurrHourVariable(const string& name, ClockInterface* clock)
+ : Variable<int>(name, TimeDelta::FromMinutes(5)), clock_(clock) {}
+
+ protected:
+ virtual const int* GetValue(base::TimeDelta /* timeout */,
+ string* /* errmsg */) {
+ Time::Exploded exploded;
+ clock_->GetWallclockTime().LocalExplode(&exploded);
+ return new int(exploded.hour);
+ }
+
+ private:
+ ClockInterface* clock_;
+
+ DISALLOW_COPY_AND_ASSIGN(CurrHourVariable);
+};
+
+bool RealTimeProvider::DoInit() {
+ set_var_curr_date(new CurrDateVariable("curr_date", clock_));
+ set_var_curr_hour(new CurrHourVariable("curr_hour", clock_));
+ return true;
+}
+
+} // namespace chromeos_policy_manager
diff --git a/policy_manager/real_time_provider.h b/policy_manager/real_time_provider.h
new file mode 100644
index 0000000..447f435
--- /dev/null
+++ b/policy_manager/real_time_provider.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_REAL_TIME_PROVIDER_H_
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_REAL_TIME_PROVIDER_H_
+
+#include <base/time.h>
+
+#include "update_engine/clock_interface.h"
+#include "update_engine/policy_manager/time_provider.h"
+
+namespace chromeos_policy_manager {
+
+// TimeProvider concrete implementation.
+class RealTimeProvider : public TimeProvider {
+ public:
+ RealTimeProvider(chromeos_update_engine::ClockInterface* clock)
+ : clock_(clock) {}
+
+ protected:
+ virtual bool DoInit();
+
+ private:
+ // A clock abstraction (mockable).
+ chromeos_update_engine::ClockInterface* const clock_;
+
+ DISALLOW_COPY_AND_ASSIGN(RealTimeProvider);
+};
+
+} // namespace chromeos_policy_manager
+
+#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_REAL_TIME_PROVIDER_H_
diff --git a/policy_manager/real_time_provider_unittest.cc b/policy_manager/real_time_provider_unittest.cc
new file mode 100644
index 0000000..1ac9083
--- /dev/null
+++ b/policy_manager/real_time_provider_unittest.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <base/logging.h>
+#include <base/memory/scoped_ptr.h>
+#include <base/time.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/fake_clock.h"
+#include "update_engine/policy_manager/pmtest_utils.h"
+#include "update_engine/policy_manager/real_time_provider.h"
+
+using base::Time;
+using base::TimeDelta;
+using chromeos_update_engine::FakeClock;
+
+namespace chromeos_policy_manager {
+
+class PmRealTimeProviderTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ // The provider initializes correctly.
+ provider_.reset(new RealTimeProvider(&fake_clock_));
+ PMTEST_ASSERT_NOT_NULL(provider_.get());
+ ASSERT_TRUE(provider_->Init());
+ }
+
+ // Generates a fixed timestamp for use in faking the current time.
+ Time CurrTime() {
+ Time::Exploded now_exp;
+ now_exp.year = 2014;
+ now_exp.month = 3;
+ now_exp.day_of_week = 2;
+ now_exp.day_of_month = 18;
+ now_exp.hour = 8;
+ now_exp.minute = 5;
+ now_exp.second = 33;
+ now_exp.millisecond = 675;
+ return Time::FromLocalExploded(now_exp);
+ }
+
+ const TimeDelta default_timeout_ = TimeDelta::FromSeconds(1);
+ FakeClock fake_clock_;
+ scoped_ptr<RealTimeProvider> provider_;
+};
+
+TEST_F(PmRealTimeProviderTest, CurrDateValid) {
+ const Time now = CurrTime();
+ Time::Exploded expected;
+ now.LocalExplode(&expected);
+ fake_clock_.SetWallclockTime(now);
+ scoped_ptr<const Time> curr_date(
+ provider_->var_curr_date()->GetValue(default_timeout_, NULL));
+ PMTEST_ASSERT_NOT_NULL(curr_date.get());
+
+ Time::Exploded actual;
+ curr_date->LocalExplode(&actual);
+ EXPECT_EQ(expected.year, actual.year);
+ EXPECT_EQ(expected.month, actual.month);
+ EXPECT_EQ(expected.day_of_week, actual.day_of_week);
+ EXPECT_EQ(expected.day_of_month, actual.day_of_month);
+ EXPECT_EQ(0, actual.hour);
+ EXPECT_EQ(0, actual.minute);
+ EXPECT_EQ(0, actual.second);
+ EXPECT_EQ(0, actual.millisecond);
+}
+
+TEST_F(PmRealTimeProviderTest, CurrHourValid) {
+ const Time now = CurrTime();
+ Time::Exploded expected;
+ now.LocalExplode(&expected);
+ fake_clock_.SetWallclockTime(now);
+ scoped_ptr<const int> curr_hour(
+ provider_->var_curr_hour()->GetValue(default_timeout_, NULL));
+ PMTEST_ASSERT_NOT_NULL(curr_hour.get());
+
+ EXPECT_EQ(expected.hour, *curr_hour);
+}
+
+} // namespace chromeos_policy_manager
diff --git a/policy_manager/state.h b/policy_manager/state.h
index 4950b56..fb847a7 100644
--- a/policy_manager/state.h
+++ b/policy_manager/state.h
@@ -7,6 +7,7 @@
#include "update_engine/policy_manager/random_provider.h"
#include "update_engine/policy_manager/shill_provider.h"
+#include "update_engine/policy_manager/time_provider.h"
namespace chromeos_policy_manager {
@@ -20,12 +21,14 @@
// succeeded.
bool Init() {
return (random_provider_ && random_provider_->Init() &&
- shill_provider_ && shill_provider_->Init());
+ shill_provider_ && shill_provider_->Init() &&
+ time_provider_ && time_provider_->Init());
}
// These functions return the given provider.
RandomProvider* random_provider() { return random_provider_.get(); }
ShillProvider* shill_provider() { return shill_provider_.get(); }
+ TimeProvider* time_provider() { return time_provider_.get(); }
protected:
// Initialize the private scoped_ptr for each provider.
@@ -37,10 +40,15 @@
return shill_provider_.reset(shill_provider);
}
+ void set_time_provider(TimeProvider* time_provider) {
+ return time_provider_.reset(time_provider);
+ }
+
private:
// Instances of the providers.
scoped_ptr<RandomProvider> random_provider_;
scoped_ptr<ShillProvider> shill_provider_;
+ scoped_ptr<TimeProvider> time_provider_;
};
} // namespace chromeos_policy_manager
diff --git a/policy_manager/time_provider.h b/policy_manager/time_provider.h
new file mode 100644
index 0000000..d09097b
--- /dev/null
+++ b/policy_manager/time_provider.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_TIME_PROVIDER_H_
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_TIME_PROVIDER_H_
+
+#include <base/memory/scoped_ptr.h>
+#include <base/time.h>
+
+#include "update_engine/policy_manager/provider.h"
+#include "update_engine/policy_manager/variable.h"
+
+namespace chromeos_policy_manager {
+
+// Provider for time related information.
+class TimeProvider : public Provider {
+ public:
+ // Returns the current date. The time of day component will be zero.
+ Variable<base::Time>* var_curr_date() const {
+ return var_curr_date_.get();
+ }
+
+ // Returns the current hour (0 to 23) in local time. The type is int to keep
+ // consistent with base::Time.
+ Variable<int>* var_curr_hour() const {
+ return var_curr_hour_.get();
+ }
+
+ // TODO(garnold) Implement a method/variable for querying whether a given
+ // point in time was reached.
+
+ protected:
+ TimeProvider() {}
+
+ void set_var_curr_date(Variable<base::Time>* var_curr_date) {
+ var_curr_date_.reset(var_curr_date);
+ }
+
+ void set_var_curr_hour(Variable<int>* var_curr_hour) {
+ var_curr_hour_.reset(var_curr_hour);
+ }
+
+ private:
+ scoped_ptr<Variable<base::Time>> var_curr_date_;
+ scoped_ptr<Variable<int>> var_curr_hour_;
+
+ DISALLOW_COPY_AND_ASSIGN(TimeProvider);
+};
+
+} // namespace chromeos_policy_manager
+
+#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_TIME_PROVIDER_H_
diff --git a/policy_manager/variable.h b/policy_manager/variable.h
index be3fdb1..b00eca4 100644
--- a/policy_manager/variable.h
+++ b/policy_manager/variable.h
@@ -145,6 +145,9 @@
FRIEND_TEST(PmRealShillProviderTest, ReadChangedValuesConnectedViaEthernet);
FRIEND_TEST(PmRealShillProviderTest, ReadChangedValuesConnectedViaVpn);
FRIEND_TEST(PmRealShillProviderTest, ReadChangedValuesConnectedTwoSignals);
+ friend class PmRealTimeProviderTest;
+ FRIEND_TEST(PmRealTimeProviderTest, CurrDateValid);
+ FRIEND_TEST(PmRealTimeProviderTest, CurrHourValid);
Variable(const std::string& name, VariableMode mode)
: BaseVariable(name, mode) {}