Add 'timeMs' field to /privet/info local API

Added the local device time field to the Info response. The timestamp
is a time in milliseconds since Epoch (similar to how the time is
used with the cloud server).

BUG: 26160070
Change-Id: I3059f2880dc2aa4c1990bbe662e8c1057b1aadc1
Reviewed-on: https://weave-review.googlesource.com/1922
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/src/privet/privet_handler.cc b/src/privet/privet_handler.cc
index b71ea15..d172312 100644
--- a/src/privet/privet_handler.cc
+++ b/src/privet/privet_handler.cc
@@ -70,6 +70,7 @@
 const char kInfoWifiHostedSsidKey[] = "hostedSsid";
 
 const char kInfoUptimeKey[] = "uptime";
+const char kInfoTimeMsKey[] = "timeMs";
 
 const char kPairingKey[] = "pairing";
 const char kPairingSessionIdKey[] = "sessionId";
@@ -340,11 +341,14 @@
 PrivetHandler::PrivetHandler(CloudDelegate* cloud,
                              DeviceDelegate* device,
                              SecurityDelegate* security,
-                             WifiDelegate* wifi)
-    : cloud_(cloud), device_(device), security_(security), wifi_(wifi) {
+                             WifiDelegate* wifi,
+                             base::Clock* clock)
+    : cloud_(cloud), device_(device), security_(security), wifi_(wifi),
+      clock_(clock ? clock : &default_clock_) {
   CHECK(cloud_);
   CHECK(device_);
   CHECK(security_);
+  CHECK(clock_);
   cloud_observer_.Add(cloud_);
 
   AddHandler("/privet/info", &PrivetHandler::HandleInfo, AuthScope::kNone);
@@ -466,7 +470,7 @@
     time += base::TimeDelta::FromSeconds(kAccessTokenExpirationSeconds);
     time +=
         base::TimeDelta::FromSeconds(kAccessTokenExpirationThresholdSeconds);
-    if (time < base::Time::Now()) {
+    if (time < clock_->Now()) {
       Error::AddToPrintf(&error, FROM_HERE, errors::kDomain,
                          errors::kAuthorizationExpired, "Token expired: %s",
                          token.c_str());
@@ -544,6 +548,7 @@
   output.Set(kGcdKey, CreateGcdSection(*cloud_).release());
 
   output.SetInteger(kInfoUptimeKey, device_->GetUptime().InSeconds());
+  output.SetString(kInfoTimeMsKey, std::to_string(clock_->Now().ToJavaTime()));
 
   callback.Run(http::kOk, output);
 }
diff --git a/src/privet/privet_handler.h b/src/privet/privet_handler.h
index fc024d1..5241233 100644
--- a/src/privet/privet_handler.h
+++ b/src/privet/privet_handler.h
@@ -12,6 +12,7 @@
 #include <base/macros.h>
 #include <base/memory/weak_ptr.h>
 #include <base/scoped_observer.h>
+#include <base/time/default_clock.h>
 
 #include "src/privet/cloud_delegate.h"
 
@@ -42,7 +43,8 @@
   PrivetHandler(CloudDelegate* cloud,
                 DeviceDelegate* device,
                 SecurityDelegate* pairing,
-                WifiDelegate* wifi);
+                WifiDelegate* wifi,
+                base::Clock* clock = nullptr);
   ~PrivetHandler() override;
 
   void OnTraitDefsChanged() override;
@@ -134,6 +136,8 @@
   DeviceDelegate* device_{nullptr};
   SecurityDelegate* security_{nullptr};
   WifiDelegate* wifi_{nullptr};
+  base::DefaultClock default_clock_;
+  base::Clock* clock_{nullptr};
 
   struct HandlerParameters {
     ApiHandler handler;
diff --git a/src/privet/privet_handler_unittest.cc b/src/privet/privet_handler_unittest.cc
index 09146e8..da64ab9 100644
--- a/src/privet/privet_handler_unittest.cc
+++ b/src/privet/privet_handler_unittest.cc
@@ -19,6 +19,7 @@
 
 #include "src/privet/constants.h"
 #include "src/privet/mock_delegates.h"
+#include "src/test/mock_clock.h"
 
 using testing::_;
 using testing::DoAll;
@@ -92,8 +93,12 @@
 
  protected:
   void SetUp() override {
+    EXPECT_CALL(clock_, Now())
+        .WillRepeatedly(Return(base::Time::FromTimeT(1410000000)));
+
     auth_header_ = "Privet anonymous";
-    handler_.reset(new PrivetHandler(&cloud_, &device_, &security_, &wifi_));
+    handler_.reset(new PrivetHandler(&cloud_, &device_, &security_, &wifi_,
+                                     &clock_));
   }
 
   const base::DictionaryValue& HandleRequest(
@@ -124,7 +129,8 @@
   int GetResponseCount() const { return response_count_; }
 
   void SetNoWifiAndGcd() {
-    handler_.reset(new PrivetHandler(&cloud_, &device_, &security_, nullptr));
+    handler_.reset(new PrivetHandler(&cloud_, &device_, &security_, nullptr,
+                                     &clock_));
     EXPECT_CALL(cloud_, GetCloudId()).WillRepeatedly(Return(""));
     EXPECT_CALL(cloud_, GetConnectionState())
         .WillRepeatedly(ReturnRef(gcd_disabled_state_));
@@ -136,6 +142,7 @@
         .WillRepeatedly(DoAll(Invoke(set_error), Return(false)));
   }
 
+  test::MockClock clock_;
   testing::StrictMock<MockCloudDelegate> cloud_;
   testing::StrictMock<MockDeviceDelegate> device_;
   testing::StrictMock<MockSecurityDelegate> security_;
@@ -240,7 +247,8 @@
       'id': '',
       'status': 'disabled'
     },
-    'uptime': 3600
+    'uptime': 3600,
+    'timeMs': '1410000000000'
   })";
   EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/info", "{}"));
 }
@@ -301,7 +309,8 @@
       'id': 'TestCloudId',
       'status': 'online'
     },
-    'uptime': 3600
+    'uptime': 3600,
+    'timeMs': '1410000000000'
   })";
   EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/info", "{}"));
 }