update_engine: Move scattering wait period store/load to PayloadState.

This is needed for decoupling the inference/use of this value from its
storing/loading, as we shift the former into the Update Manager.

BUG=chromium:384087
TEST=Unit tests.

Change-Id: I4b278dc817b6f148d5638122f934e9d1e280bfae
Reviewed-on: https://chromium-review.googlesource.com/221250
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/mock_payload_state.h b/mock_payload_state.h
index bef2997..c317543 100644
--- a/mock_payload_state.h
+++ b/mock_payload_state.h
@@ -36,6 +36,7 @@
   MOCK_METHOD0(P2PNewAttempt, void());
   MOCK_METHOD0(P2PAttemptAllowed, bool());
   MOCK_METHOD1(SetUsingP2PForDownloading, void(bool value));
+  MOCK_METHOD1(SetScatteringWaitPeriod, void(base::TimeDelta));
 
   // Getters.
   MOCK_METHOD0(GetResponseSignature, std::string());
@@ -55,6 +56,7 @@
   MOCK_METHOD0(GetP2PNumAttempts, int());
   MOCK_METHOD0(GetP2PFirstAttemptTimestamp, base::Time());
   MOCK_METHOD0(GetUsingP2PForDownloading, bool());
+  MOCK_METHOD0(GetScatteringWaitPeriod, base::TimeDelta());
 };
 
 }  // namespace chromeos_update_engine
diff --git a/payload_state.cc b/payload_state.cc
index b58f9a8..fcd4dab 100644
--- a/payload_state.cc
+++ b/payload_state.cc
@@ -906,6 +906,7 @@
   ResetRollbackVersion();
   SetP2PNumAttempts(0);
   SetP2PFirstAttemptTimestamp(Time());  // Set to null time
+  SetScatteringWaitPeriod(base::TimeDelta());
 }
 
 void PayloadState::ResetRollbackVersion() {
@@ -1025,6 +1026,24 @@
   UpdateCurrentDownloadSource();
 }
 
+void PayloadState::LoadScatteringWaitPeriod() {
+  SetScatteringWaitPeriod(
+      TimeDelta::FromSeconds(GetPersistedValue(kPrefsWallClockWaitPeriod)));
+}
+
+void PayloadState::SetScatteringWaitPeriod(base::TimeDelta wait_period) {
+  CHECK(prefs_);
+  scattering_wait_period_ = wait_period;
+  LOG(INFO) << "Scattering Wait Period (seconds) = "
+            << scattering_wait_period_.InSeconds();
+  if (scattering_wait_period_.InSeconds() > 0) {
+    prefs_->SetInt64(kPrefsWallClockWaitPeriod,
+                     scattering_wait_period_.InSeconds());
+  } else {
+    prefs_->Delete(kPrefsWallClockWaitPeriod);
+  }
+}
+
 void PayloadState::LoadUrlSwitchCount() {
   SetUrlSwitchCount(GetPersistedValue(kPrefsUrlSwitchCount));
 }
diff --git a/payload_state.h b/payload_state.h
index 99e7d84..8eb541c 100644
--- a/payload_state.h
+++ b/payload_state.h
@@ -113,6 +113,12 @@
     return using_p2p_for_downloading_;
   }
 
+  base::TimeDelta GetScatteringWaitPeriod() override {
+    return scattering_wait_period_;
+  }
+
+  void SetScatteringWaitPeriod(base::TimeDelta wait_period) override;
+
  private:
   enum class AttemptType {
     kUpdate,
@@ -386,6 +392,9 @@
   // Sets the |kPrefsP2PFirstAttemptTimestamp| state variable to |time|.
   void SetP2PFirstAttemptTimestamp(const base::Time& time);
 
+  // Loads the persisted scattering wallclock-based wait period.
+  void LoadScatteringWaitPeriod();
+
   // The global state of the system.
   SystemState* system_state_;
 
@@ -529,6 +538,9 @@
   // Whether we're currently rolling back.
   AttemptType attempt_type_;
 
+  // The current scattering wallclock-based wait period.
+  base::TimeDelta scattering_wait_period_;
+
   DISALLOW_COPY_AND_ASSIGN(PayloadState);
 };
 
diff --git a/payload_state_interface.h b/payload_state_interface.h
index 36b8130..c706e98 100644
--- a/payload_state_interface.h
+++ b/payload_state_interface.h
@@ -163,6 +163,12 @@
 
   // Gets the value previously set with SetUsingP2PForDownloading().
   virtual bool GetUsingP2PForDownloading() = 0;
+
+  // Returns the current (persisted) scattering wallclock-based wait period.
+  virtual base::TimeDelta GetScatteringWaitPeriod() = 0;
+
+  // Sets and persists the scattering wallclock-based wait period.
+  virtual void SetScatteringWaitPeriod(base::TimeDelta wait_period) = 0;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/update_attempter.cc b/update_attempter.cc
index 9a91d51..b36c11a 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -564,8 +564,8 @@
   // fails, we'll still be able to scatter based on our in-memory value.
   // The persistence only helps in ensuring a good overall distribution
   // across multiple devices if they tend to reboot too often.
-  prefs_->SetInt64(kPrefsWallClockWaitPeriod,
-                   omaha_request_params_->waiting_period().InSeconds());
+  system_state_->payload_state()->SetScatteringWaitPeriod(
+      omaha_request_params_->waiting_period());
 }
 
 void UpdateAttempter::BuildPostInstallActions(
@@ -979,7 +979,7 @@
     // after reboot so that the same device is not favored or punished in any
     // way.
     prefs_->Delete(kPrefsUpdateCheckCount);
-    prefs_->Delete(kPrefsWallClockWaitPeriod);
+    system_state_->payload_state()->SetScatteringWaitPeriod(TimeDelta());
     prefs_->Delete(kPrefsUpdateFirstSeenAt);
 
     SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT);