Merge "Merge remote-tracking branch 'aosp/upstream-master' into merge"
diff --git a/Android.bp b/Android.bp
index 888a4b4..e192a63 100644
--- a/Android.bp
+++ b/Android.bp
@@ -29,8 +29,6 @@
 
     cflags: [
         "-DBASE_VER=576279",
-        "-DUSE_CHROME_NETWORK_PROXY=0",
-        "-DUSE_CHROME_KIOSK_APP=0",
         "-DUSE_HWID_OVERRIDE=0",
         "-D_FILE_OFFSET_BITS=64",
         "-D_POSIX_C_SOURCE=199309L",
@@ -189,7 +187,6 @@
         "common/subprocess.cc",
         "common/terminator.cc",
         "common/utils.cc",
-        "download_action.cc",
         "payload_consumer/bzip_extent_writer.cc",
         "payload_consumer/cached_file_descriptor.cc",
         "payload_consumer/certificate_parser_android.cc",
@@ -332,6 +329,7 @@
 
     srcs: [
         ":libupdate_engine_aidl",
+        "common/system_state.cc",
         "aosp/binder_service_android.cc",
         "aosp/binder_service_stable_android.cc",
         "aosp/daemon_android.cc",
@@ -341,6 +339,7 @@
         "aosp/network_selector_android.cc",
         "aosp/update_attempter_android.cc",
         "certificate_checker.cc",
+        "download_action.cc",
         "libcurl_http_fetcher.cc",
         "metrics_utils.cc",
         "update_boot_flags_action.cc",
@@ -395,6 +394,8 @@
         "aosp/update_attempter_android.cc",
         "common/metrics_reporter_stub.cc",
         "common/network_selector_stub.cc",
+        "common/system_state.cc",
+        "download_action.cc",
         "metrics_utils.cc",
         "update_boot_flags_action.cc",
         "update_status_utils.cc",
@@ -527,6 +528,8 @@
     host_supported: true,
 
     srcs: [
+        "common/system_state.cc",
+        "download_action.cc",
         "payload_generator/ab_generator.cc",
         "payload_generator/annotated_operation.cc",
         "payload_generator/blob_file_writer.cc",
@@ -736,6 +739,7 @@
         "payload_consumer/file_descriptor_utils_unittest.cc",
         "payload_consumer/file_writer_unittest.cc",
         "payload_consumer/filesystem_verifier_action_unittest.cc",
+        "payload_consumer/install_plan_unittest.cc",
         "payload_consumer/partition_update_generator_android_unittest.cc",
         "payload_consumer/postinstall_runner_action_unittest.cc",
         "payload_consumer/verity_writer_android_unittest.cc",
diff --git a/BUILD.gn b/BUILD.gn
index 6e282f5..1ddae22 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -61,17 +61,9 @@
 pkg_config("target_defaults") {
   cflags_cc = [
     "-fno-strict-aliasing",
-    "-std=gnu++17",
     "-Wnon-virtual-dtor",
   ]
-  cflags = [
-    "-g",
-    "-ffunction-sections",
-    "-Wall",
-    "-Wextra",
-    "-Werror",
-    "-Wno-unused-parameter",
-  ]
+  cflags = [ "-ffunction-sections" ]
   ldflags = [ "-Wl,--gc-sections" ]
   defines = [
     "__CHROMEOS__",
@@ -81,9 +73,6 @@
     "USE_DBUS=${use.dbus}",
     "USE_FEC=0",
     "USE_HWID_OVERRIDE=${use.hwid_override}",
-    "USE_CHROME_KIOSK_APP=${use.chrome_kiosk_app}",
-    "USE_CHROME_NETWORK_PROXY=${use.chrome_network_proxy}",
-    "USE_SHILL=1",
   ]
   include_dirs = [
     # We need this include dir because we include all the local code as
@@ -149,7 +138,6 @@
     "common/terminator.cc",
     "common/utils.cc",
     "cros/platform_constants_chromeos.cc",
-    "download_action.cc",
     "payload_consumer/bzip_extent_writer.cc",
     "payload_consumer/cached_file_descriptor.cc",
     "payload_consumer/certificate_parser_stub.cc",
@@ -199,6 +187,7 @@
   sources = [
     "certificate_checker.cc",
     "common/connection_utils.cc",
+    "common/system_state.cc",
     "cros/boot_control_chromeos.cc",
     "cros/common_service.cc",
     "cros/connection_manager.cc",
@@ -221,6 +210,7 @@
     "cros/requisition_util.cc",
     "cros/shill_proxy.cc",
     "cros/update_attempter.cc",
+    "download_action.cc",
     "libcurl_http_fetcher.cc",
     "metrics_utils.cc",
     "update_boot_flags_action.cc",
@@ -229,8 +219,10 @@
     "update_manager/default_policy.cc",
     "update_manager/enough_slots_ab_updates_policy_impl.cc",
     "update_manager/enterprise_device_policy_impl.cc",
+    "update_manager/enterprise_rollback_policy_impl.cc",
     "update_manager/evaluation_context.cc",
     "update_manager/interactive_update_policy_impl.cc",
+    "update_manager/minimum_version_policy_impl.cc",
     "update_manager/next_update_check_policy_impl.cc",
     "update_manager/official_build_check_policy_impl.cc",
     "update_manager/out_of_box_experience_policy_impl.cc",
@@ -246,6 +238,7 @@
     "update_manager/staging_utils.cc",
     "update_manager/state_factory.cc",
     "update_manager/update_manager.cc",
+    "update_manager/update_time_restrictions_monitor.cc",
     "update_manager/update_time_restrictions_policy_impl.cc",
     "update_manager/weekly_time.cc",
     "update_status_utils.cc",
@@ -273,6 +266,7 @@
   deps = [
     ":libpayload_consumer",
     ":update_engine-dbus-adaptor",
+    ":update_engine-dbus-kiosk-app-client",
     ":update_metadata-protos",
   ]
 
@@ -284,10 +278,6 @@
     sources += [ "cros/chrome_browser_proxy_resolver.cc" ]
   }
 
-  if (use.chrome_kiosk_app) {
-    deps += [ ":update_engine-dbus-kiosk-app-client" ]
-  }
-
   if (use.dlc) {
     sources += [
       "cros/dlcservice_chromeos.cc",
@@ -338,6 +328,9 @@
 static_library("libpayload_generator") {
   sources = [
     "common/file_fetcher.cc",
+    "common/system_state.cc",
+    "cros/real_system_state.cc",
+    "download_action.cc",
     "payload_generator/ab_generator.cc",
     "payload_generator/annotated_operation.cc",
     "payload_generator/blob_file_writer.cc",
@@ -511,6 +504,7 @@
       "payload_consumer/file_descriptor_utils_unittest.cc",
       "payload_consumer/file_writer_unittest.cc",
       "payload_consumer/filesystem_verifier_action_unittest.cc",
+      "payload_consumer/install_plan_unittest.cc",
       "payload_consumer/postinstall_runner_action_unittest.cc",
       "payload_consumer/xz_extent_writer_unittest.cc",
       "payload_generator/ab_generator_unittest.cc",
@@ -535,8 +529,10 @@
       "update_manager/boxed_value_unittest.cc",
       "update_manager/chromeos_policy_unittest.cc",
       "update_manager/enterprise_device_policy_impl_unittest.cc",
+      "update_manager/enterprise_rollback_policy_impl_unittest.cc",
       "update_manager/evaluation_context_unittest.cc",
       "update_manager/generic_variables_unittest.cc",
+      "update_manager/minimum_version_policy_impl_unittest.cc",
       "update_manager/prng_unittest.cc",
       "update_manager/real_device_policy_provider_unittest.cc",
       "update_manager/real_random_provider_unittest.cc",
@@ -546,6 +542,7 @@
       "update_manager/real_updater_provider_unittest.cc",
       "update_manager/staging_utils_unittest.cc",
       "update_manager/update_manager_unittest.cc",
+      "update_manager/update_time_restrictions_monitor_unittest.cc",
       "update_manager/update_time_restrictions_policy_impl_unittest.cc",
       "update_manager/variable_unittest.cc",
       "update_manager/weekly_time_unittest.cc",
diff --git a/aosp/metrics_reporter_android.cc b/aosp/metrics_reporter_android.cc
index ea3bb6d..22ebf0d 100644
--- a/aosp/metrics_reporter_android.cc
+++ b/aosp/metrics_reporter_android.cc
@@ -61,7 +61,6 @@
 }  // namespace metrics
 
 void MetricsReporterAndroid::ReportUpdateAttemptMetrics(
-    SystemState* /* system_state */,
     int attempt_number,
     PayloadType payload_type,
     base::TimeDelta duration,
diff --git a/aosp/metrics_reporter_android.h b/aosp/metrics_reporter_android.h
index 4a173bf..729542e 100644
--- a/aosp/metrics_reporter_android.h
+++ b/aosp/metrics_reporter_android.h
@@ -39,13 +39,11 @@
   void ReportDailyMetrics(base::TimeDelta os_age) override {}
 
   void ReportUpdateCheckMetrics(
-      SystemState* system_state,
       metrics::CheckResult result,
       metrics::CheckReaction reaction,
       metrics::DownloadErrorCode download_error_code) override {}
 
-  void ReportUpdateAttemptMetrics(SystemState* system_state,
-                                  int attempt_number,
+  void ReportUpdateAttemptMetrics(int attempt_number,
                                   PayloadType payload_type,
                                   base::TimeDelta duration,
                                   base::TimeDelta duration_uptime,
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index 7ed3249..eb1ebe0 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -733,7 +733,6 @@
       std::make_unique<DownloadAction>(prefs_,
                                        boot_control_,
                                        hardware_,
-                                       nullptr,  // system_state, not used.
                                        fetcher,  // passes ownership
                                        true /* interactive */);
   download_action->set_delegate(this);
@@ -804,7 +803,6 @@
   TimeDelta duration_uptime = clock_->GetMonotonicTime() - monotonic_time_start;
 
   metrics_reporter_->ReportUpdateAttemptMetrics(
-      nullptr,  // system_state
       static_cast<int>(attempt_number),
       payload_type,
       duration,
diff --git a/aosp/update_attempter_android_unittest.cc b/aosp/update_attempter_android_unittest.cc
index bb44450..fc30268 100644
--- a/aosp/update_attempter_android_unittest.cc
+++ b/aosp/update_attempter_android_unittest.cc
@@ -138,8 +138,7 @@
   TimeDelta duration_uptime = up_time - Time::FromInternalValue(12345);
   EXPECT_CALL(
       *metrics_reporter_,
-      ReportUpdateAttemptMetrics(_,
-                                 2,
+      ReportUpdateAttemptMetrics(2,
                                  _,
                                  duration,
                                  duration_uptime,
diff --git a/common/clock.cc b/common/clock.cc
index 05c495c..0821a56 100644
--- a/common/clock.cc
+++ b/common/clock.cc
@@ -20,11 +20,11 @@
 
 namespace chromeos_update_engine {
 
-base::Time Clock::GetWallclockTime() {
+base::Time Clock::GetWallclockTime() const {
   return base::Time::Now();
 }
 
-base::Time Clock::GetMonotonicTime() {
+base::Time Clock::GetMonotonicTime() const {
   struct timespec now_ts;
   if (clock_gettime(CLOCK_MONOTONIC_RAW, &now_ts) != 0) {
     // Avoid logging this as an error as call-sites may call this very
@@ -40,7 +40,7 @@
   return base::Time::FromTimeVal(now_tv);
 }
 
-base::Time Clock::GetBootTime() {
+base::Time Clock::GetBootTime() const {
   struct timespec now_ts;
   if (clock_gettime(CLOCK_BOOTTIME, &now_ts) != 0) {
     // Avoid logging this as an error as call-sites may call this very
diff --git a/common/clock.h b/common/clock.h
index 2f373a7..4021fa1 100644
--- a/common/clock.h
+++ b/common/clock.h
@@ -24,13 +24,11 @@
 // Implements a clock.
 class Clock : public ClockInterface {
  public:
-  Clock() {}
+  Clock() = default;
 
-  base::Time GetWallclockTime() override;
-
-  base::Time GetMonotonicTime() override;
-
-  base::Time GetBootTime() override;
+  base::Time GetWallclockTime() const override;
+  base::Time GetMonotonicTime() const override;
+  base::Time GetBootTime() const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Clock);
diff --git a/common/clock_interface.h b/common/clock_interface.h
index 2228983..176505d 100644
--- a/common/clock_interface.h
+++ b/common/clock_interface.h
@@ -32,21 +32,21 @@
   virtual ~ClockInterface() = default;
 
   // Gets the current time e.g. similar to base::Time::Now().
-  virtual base::Time GetWallclockTime() = 0;
+  virtual base::Time GetWallclockTime() const = 0;
 
   // Returns monotonic time since some unspecified starting point. It
   // is not increased when the system is sleeping nor is it affected
   // by NTP or the user changing the time.
   //
   // (This is a simple wrapper around clock_gettime(2) / CLOCK_MONOTONIC_RAW.)
-  virtual base::Time GetMonotonicTime() = 0;
+  virtual base::Time GetMonotonicTime() const = 0;
 
   // Returns monotonic time since some unspecified starting point. It
   // is increased when the system is sleeping but it's not affected
   // by NTP or the user changing the time.
   //
   // (This is a simple wrapper around clock_gettime(2) / CLOCK_BOOTTIME.)
-  virtual base::Time GetBootTime() = 0;
+  virtual base::Time GetBootTime() const = 0;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/common/constants.cc b/common/constants.cc
index 8883668..a9cf238 100644
--- a/common/constants.cc
+++ b/common/constants.cc
@@ -71,6 +71,7 @@
 const char kPrefsPingActive[] = "active";
 const char kPrefsPingLastActive[] = "date_last_active";
 const char kPrefsPingLastRollcall[] = "date_last_rollcall";
+const char kPrefsLastFp[] = "last-fp";
 const char kPrefsPostInstallSucceeded[] = "post-install-succeeded";
 const char kPrefsPreviousVersion[] = "previous-version";
 const char kPrefsResumedUpdateFailures[] = "resumed-update-failures";
diff --git a/common/constants.h b/common/constants.h
index f468b55..64447ce 100644
--- a/common/constants.h
+++ b/common/constants.h
@@ -73,6 +73,7 @@
 extern const char kPrefsPingActive[];
 extern const char kPrefsPingLastActive[];
 extern const char kPrefsPingLastRollcall[];
+extern const char kPrefsLastFp[];
 extern const char kPrefsPostInstallSucceeded[];
 extern const char kPrefsPreviousVersion[];
 extern const char kPrefsResumedUpdateFailures[];
diff --git a/common/daemon_state_interface.h b/common/daemon_state_interface.h
index 9509fa2..831e38b 100644
--- a/common/daemon_state_interface.h
+++ b/common/daemon_state_interface.h
@@ -19,7 +19,6 @@
 
 #include "update_engine/common/service_observer_interface.h"
 
-#include <memory>
 #include <set>
 
 namespace chromeos_update_engine {
@@ -42,6 +41,8 @@
 
  protected:
   DaemonStateInterface() = default;
+
+  DISALLOW_COPY_AND_ASSIGN(DaemonStateInterface);
 };
 
 }  // namespace chromeos_update_engine
diff --git a/common/download_action.h b/common/download_action.h
index c167c2d..18e5853 100644
--- a/common/download_action.h
+++ b/common/download_action.h
@@ -28,7 +28,6 @@
 #include "update_engine/common/boot_control_interface.h"
 #include "update_engine/common/http_fetcher.h"
 #include "update_engine/common/multi_range_http_fetcher.h"
-#include "update_engine/common/system_state.h"
 #include "update_engine/payload_consumer/delta_performer.h"
 #include "update_engine/payload_consumer/install_plan.h"
 
@@ -71,12 +70,11 @@
 
   // Takes ownership of the passed in HttpFetcher. Useful for testing.
   // A good calling pattern is:
-  // DownloadAction(prefs, boot_contol, hardware, system_state,
+  // DownloadAction(prefs, boot_contol, hardware,
   //                new WhateverHttpFetcher, false);
   DownloadAction(PrefsInterface* prefs,
                  BootControlInterface* boot_control,
                  HardwareInterface* hardware,
-                 SystemState* system_state,
                  HttpFetcher* http_fetcher,
                  bool interactive);
   ~DownloadAction() override;
@@ -141,14 +139,11 @@
   // Pointer to the current payload in install_plan_.payloads.
   InstallPlan::Payload* payload_{nullptr};
 
-  // SystemState required pointers.
+  // Required pointers.
   PrefsInterface* prefs_;
   BootControlInterface* boot_control_;
   HardwareInterface* hardware_;
 
-  // Global context for the system.
-  SystemState* system_state_;
-
   // Pointer to the MultiRangeHttpFetcher that does the http work.
   std::unique_ptr<MultiRangeHttpFetcher> http_fetcher_;
 
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index 855d6e8..4f46f74 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -26,6 +26,7 @@
 #include "update_engine/common/action.h"
 #include "update_engine/common/cleanup_previous_update_action_delegate.h"
 #include "update_engine/common/error_code.h"
+#include "update_engine/common/prefs_interface.h"
 #include "update_engine/payload_consumer/file_descriptor.h"
 #include "update_engine/update_metadata.pb.h"
 
@@ -54,7 +55,6 @@
 };
 
 class BootControlInterface;
-class PrefsInterface;
 
 class DynamicPartitionControlInterface {
  public:
diff --git a/common/excluder_interface.h b/common/excluder_interface.h
index 3985bba..1dfd227 100644
--- a/common/excluder_interface.h
+++ b/common/excluder_interface.h
@@ -26,6 +26,8 @@
 
 class PrefsInterface;
 
+// TODO(b/171829801): Move this interface to 'cros' directory. 'aosp' in no way
+// is using this. Not even the stub implementation.
 class ExcluderInterface {
  public:
   virtual ~ExcluderInterface() = default;
@@ -53,7 +55,7 @@
   ExcluderInterface() = default;
 };
 
-std::unique_ptr<ExcluderInterface> CreateExcluder(PrefsInterface* prefs);
+std::unique_ptr<ExcluderInterface> CreateExcluder();
 
 }  // namespace chromeos_update_engine
 
diff --git a/common/excluder_stub.cc b/common/excluder_stub.cc
index a251765..2b987fd 100644
--- a/common/excluder_stub.cc
+++ b/common/excluder_stub.cc
@@ -24,7 +24,7 @@
 
 namespace chromeos_update_engine {
 
-std::unique_ptr<ExcluderInterface> CreateExcluder(PrefsInterface* prefs) {
+std::unique_ptr<ExcluderInterface> CreateExcluder() {
   return std::make_unique<ExcluderStub>();
 }
 
diff --git a/common/fake_clock.h b/common/fake_clock.h
index 165ec4d..9c47b57 100644
--- a/common/fake_clock.h
+++ b/common/fake_clock.h
@@ -26,11 +26,11 @@
  public:
   FakeClock() {}
 
-  base::Time GetWallclockTime() override { return wallclock_time_; }
+  base::Time GetWallclockTime() const override { return wallclock_time_; }
 
-  base::Time GetMonotonicTime() override { return monotonic_time_; }
+  base::Time GetMonotonicTime() const override { return monotonic_time_; }
 
-  base::Time GetBootTime() override { return boot_time_; }
+  base::Time GetBootTime() const override { return boot_time_; }
 
   void SetWallclockTime(const base::Time& time) { wallclock_time_ = time; }
 
diff --git a/common/fake_prefs.cc b/common/fake_prefs.cc
index 73559c5..275667e 100644
--- a/common/fake_prefs.cc
+++ b/common/fake_prefs.cc
@@ -106,6 +106,22 @@
   return true;
 }
 
+bool FakePrefs::Delete(const string& key, const vector<string>& nss) {
+  bool success = Delete(key);
+  for (const auto& ns : nss) {
+    vector<string> ns_keys;
+    success = GetSubKeys(ns, &ns_keys) && success;
+    for (const auto& sub_key : ns_keys) {
+      auto last_key_seperator = sub_key.find_last_of(kKeySeparator);
+      if (last_key_seperator != string::npos &&
+          key == sub_key.substr(last_key_seperator + 1)) {
+        success = Delete(sub_key) && success;
+      }
+    }
+  }
+  return success;
+}
+
 bool FakePrefs::GetSubKeys(const string& ns, vector<string>* keys) const {
   for (const auto& pr : values_)
     if (pr.first.compare(0, ns.length(), ns) == 0)
diff --git a/common/fake_prefs.h b/common/fake_prefs.h
index b24ff4d..9af2550 100644
--- a/common/fake_prefs.h
+++ b/common/fake_prefs.h
@@ -48,6 +48,8 @@
 
   bool Exists(const std::string& key) const override;
   bool Delete(const std::string& key) override;
+  bool Delete(const std::string& key,
+              const std::vector<std::string>& nss) override;
 
   bool GetSubKeys(const std::string& ns,
                   std::vector<std::string>* keys) const override;
diff --git a/common/metrics_reporter_interface.h b/common/metrics_reporter_interface.h
index d7c5347..08636e3 100644
--- a/common/metrics_reporter_interface.h
+++ b/common/metrics_reporter_interface.h
@@ -25,19 +25,12 @@
 #include "update_engine/common/constants.h"
 #include "update_engine/common/error_code.h"
 #include "update_engine/common/metrics_constants.h"
-#include "update_engine/common/system_state.h"
 
 namespace chromeos_update_engine {
 
 enum class ServerToCheck;
 enum class CertificateCheckResult;
 
-namespace metrics {
-
-std::unique_ptr<MetricsReporterInterface> CreateMetricsReporter();
-
-}  // namespace metrics
-
 class MetricsReporterInterface {
  public:
   virtual ~MetricsReporterInterface() = default;
@@ -92,7 +85,6 @@
   // if it's set, |kMetricCheckRollbackTargetVersion| reports the same, but only
   // if rollback is also allowed using enterprise policy.
   virtual void ReportUpdateCheckMetrics(
-      SystemState* system_state,
       metrics::CheckResult result,
       metrics::CheckReaction reaction,
       metrics::DownloadErrorCode download_error_code) = 0;
@@ -120,8 +112,7 @@
   // |kMetricAttemptTimeSinceLastAttemptUptimeMinutes| metrics are
   // automatically calculated and reported by maintaining persistent and
   // process-local state variables.
-  virtual void ReportUpdateAttemptMetrics(SystemState* system_state,
-                                          int attempt_number,
+  virtual void ReportUpdateAttemptMetrics(int attempt_number,
                                           PayloadType payload_type,
                                           base::TimeDelta duration,
                                           base::TimeDelta duration_uptime,
@@ -242,6 +233,12 @@
       bool has_time_restriction_policy, int time_to_update_days) = 0;
 };
 
+namespace metrics {
+
+std::unique_ptr<MetricsReporterInterface> CreateMetricsReporter();
+
+}  // namespace metrics
+
 }  // namespace chromeos_update_engine
 
 #endif  // UPDATE_ENGINE_COMMON_METRICS_REPORTER_INTERFACE_H_
diff --git a/common/metrics_reporter_stub.h b/common/metrics_reporter_stub.h
index 1470aaa..80cf469 100644
--- a/common/metrics_reporter_stub.h
+++ b/common/metrics_reporter_stub.h
@@ -39,13 +39,11 @@
   void ReportDailyMetrics(base::TimeDelta os_age) override {}
 
   void ReportUpdateCheckMetrics(
-      SystemState* system_state,
       metrics::CheckResult result,
       metrics::CheckReaction reaction,
       metrics::DownloadErrorCode download_error_code) override {}
 
-  void ReportUpdateAttemptMetrics(SystemState* system_state,
-                                  int attempt_number,
+  void ReportUpdateAttemptMetrics(int attempt_number,
                                   PayloadType payload_type,
                                   base::TimeDelta duration,
                                   base::TimeDelta duration_uptime,
diff --git a/common/mock_metrics_reporter.h b/common/mock_metrics_reporter.h
index 922d1ee..1bb1e84 100644
--- a/common/mock_metrics_reporter.h
+++ b/common/mock_metrics_reporter.h
@@ -36,15 +36,13 @@
 
   MOCK_METHOD1(ReportDailyMetrics, void(base::TimeDelta os_age));
 
-  MOCK_METHOD4(ReportUpdateCheckMetrics,
-               void(SystemState* system_state,
-                    metrics::CheckResult result,
+  MOCK_METHOD3(ReportUpdateCheckMetrics,
+               void(metrics::CheckResult result,
                     metrics::CheckReaction reaction,
                     metrics::DownloadErrorCode download_error_code));
 
-  MOCK_METHOD8(ReportUpdateAttemptMetrics,
-               void(SystemState* system_state,
-                    int attempt_number,
+  MOCK_METHOD7(ReportUpdateAttemptMetrics,
+               void(int attempt_number,
                     PayloadType payload_type,
                     base::TimeDelta duration,
                     base::TimeDelta duration_uptime,
diff --git a/common/mock_prefs.h b/common/mock_prefs.h
index 62417a8..c91664e 100644
--- a/common/mock_prefs.h
+++ b/common/mock_prefs.h
@@ -41,6 +41,9 @@
 
   MOCK_CONST_METHOD1(Exists, bool(const std::string& key));
   MOCK_METHOD1(Delete, bool(const std::string& key));
+  MOCK_METHOD2(Delete,
+               bool(const std::string& key,
+                    const std::vector<std::string>& nss));
 
   MOCK_CONST_METHOD2(GetSubKeys,
                      bool(const std::string&, std::vector<std::string>*));
diff --git a/common/prefs.cc b/common/prefs.cc
index 615014f..84fe536 100644
--- a/common/prefs.cc
+++ b/common/prefs.cc
@@ -34,8 +34,6 @@
 
 namespace {
 
-const char kKeySeparator = '/';
-
 void DeleteEmptyDirectories(const base::FilePath& path) {
   base::FileEnumerator path_enum(
       path, false /* recursive */, base::FileEnumerator::DIRECTORIES);
@@ -43,7 +41,11 @@
        dir_path = path_enum.Next()) {
     DeleteEmptyDirectories(dir_path);
     if (base::IsDirectoryEmpty(dir_path))
+#if BASE_VER < 800000
       base::DeleteFile(dir_path, false);
+#else
+      base::DeleteFile(dir_path);
+#endif
   }
 }
 
@@ -112,6 +114,24 @@
   return true;
 }
 
+bool PrefsBase::Delete(const string& pref_key, const vector<string>& nss) {
+  // Delete pref key for platform.
+  bool success = Delete(pref_key);
+  // Delete pref key in each namespace.
+  for (const auto& ns : nss) {
+    vector<string> namespace_keys;
+    success = GetSubKeys(ns, &namespace_keys) && success;
+    for (const auto& key : namespace_keys) {
+      auto last_key_seperator = key.find_last_of(kKeySeparator);
+      if (last_key_seperator != string::npos &&
+          pref_key == key.substr(last_key_seperator + 1)) {
+        success = Delete(key) && success;
+      }
+    }
+  }
+  return success;
+}
+
 bool PrefsBase::GetSubKeys(const string& ns, vector<string>* keys) const {
   return storage_->GetSubKeys(ns, keys);
 }
@@ -194,7 +214,11 @@
 bool Prefs::FileStorage::DeleteKey(const string& key) {
   base::FilePath filename;
   TEST_AND_RETURN_FALSE(GetFileNameForKey(key, &filename));
+#if BASE_VER < 800000
   TEST_AND_RETURN_FALSE(base::DeleteFile(filename, false));
+#else
+  TEST_AND_RETURN_FALSE(base::DeleteFile(filename));
+#endif
   return true;
 }
 
diff --git a/common/prefs.h b/common/prefs.h
index 3fc1d89..d6ef668 100644
--- a/common/prefs.h
+++ b/common/prefs.h
@@ -74,6 +74,8 @@
 
   bool Exists(const std::string& key) const override;
   bool Delete(const std::string& key) override;
+  bool Delete(const std::string& pref_key,
+              const std::vector<std::string>& nss) override;
 
   bool GetSubKeys(const std::string& ns,
                   std::vector<std::string>* keys) const override;
diff --git a/common/prefs_interface.h b/common/prefs_interface.h
index 1311cb4..866d0ca 100644
--- a/common/prefs_interface.h
+++ b/common/prefs_interface.h
@@ -80,6 +80,12 @@
   // this key. Calling with non-existent keys does nothing.
   virtual bool Delete(const std::string& key) = 0;
 
+  // Deletes the pref key from platform and given namespace subdirectories.
+  // Keys are matched against end of pref keys in each namespace.
+  // Returns true if all deletes were successful.
+  virtual bool Delete(const std::string& pref_key,
+                      const std::vector<std::string>& nss) = 0;
+
   // Creates a key which is part of a sub preference.
   static std::string CreateSubKey(const std::vector<std::string>& ns_with_key);
 
@@ -98,6 +104,10 @@
   // anymore for future Set*() and Delete() method calls.
   virtual void RemoveObserver(const std::string& key,
                               ObserverInterface* observer) = 0;
+
+ protected:
+  // Key separator used to create sub key and get file names,
+  static const char kKeySeparator = '/';
 };
 
 }  // namespace chromeos_update_engine
diff --git a/common/prefs_unittest.cc b/common/prefs_unittest.cc
index 6dd26c0..a5f46e5 100644
--- a/common/prefs_unittest.cc
+++ b/common/prefs_unittest.cc
@@ -118,6 +118,23 @@
     for (const auto& key : keys0corner)
       EXPECT_TRUE(common_prefs_->Delete(key));
     EXPECT_FALSE(common_prefs_->Exists(key0corner));
+
+    // Test sub directory namespace.
+    const string kDlcPrefsSubDir = "foo-dir";
+    key1A = common_prefs_->CreateSubKey({kDlcPrefsSubDir, "dlc1", "keyA"});
+    EXPECT_TRUE(common_prefs_->SetString(key1A, "fp_1A"));
+    key1B = common_prefs_->CreateSubKey({kDlcPrefsSubDir, "dlc1", "keyB"});
+    EXPECT_TRUE(common_prefs_->SetString(key1B, "fp_1B"));
+    auto key2A = common_prefs_->CreateSubKey({kDlcPrefsSubDir, "dlc2", "keyA"});
+    EXPECT_TRUE(common_prefs_->SetString(key2A, "fp_A2"));
+
+    vector<string> fpKeys;
+    EXPECT_TRUE(common_prefs_->GetSubKeys(kDlcPrefsSubDir, &fpKeys));
+    EXPECT_EQ(fpKeys.size(), 3UL);
+    EXPECT_TRUE(common_prefs_->Delete(fpKeys[0]));
+    EXPECT_TRUE(common_prefs_->Delete(fpKeys[1]));
+    EXPECT_TRUE(common_prefs_->Delete(fpKeys[2]));
+    EXPECT_FALSE(common_prefs_->Exists(key1A));
   }
 
   PrefsInterface* common_prefs_;
@@ -423,6 +440,71 @@
   EXPECT_FALSE(base::PathExists(prefs_dir_.Append(name_space)));
 }
 
+TEST_F(PrefsTest, DeletePrefs) {
+  const string kPrefsSubDir = "foo-dir";
+  const string kFpKey = "kPrefFp";
+  const string kNotFpKey = "NotkPrefFp";
+  const string kOtherKey = "kPrefNotFp";
+
+  EXPECT_TRUE(prefs_.SetString(kFpKey, "3.000"));
+  EXPECT_TRUE(prefs_.SetString(kOtherKey, "not_fp_val"));
+
+  auto key1_fp = prefs_.CreateSubKey({kPrefsSubDir, "id-1", kFpKey});
+  EXPECT_TRUE(prefs_.SetString(key1_fp, "3.7"));
+  auto key_not_fp = prefs_.CreateSubKey({kPrefsSubDir, "id-1", kOtherKey});
+  EXPECT_TRUE(prefs_.SetString(key_not_fp, "not_fp_val"));
+  auto key2_fp = prefs_.CreateSubKey({kPrefsSubDir, "id-2", kFpKey});
+  EXPECT_TRUE(prefs_.SetString(key2_fp, "3.9"));
+  auto key3_fp = prefs_.CreateSubKey({kPrefsSubDir, "id-3", kFpKey});
+  EXPECT_TRUE(prefs_.SetString(key3_fp, "3.45"));
+
+  // Pref key does not match full subkey at end, should not delete.
+  auto key_middle_fp = prefs_.CreateSubKey({kPrefsSubDir, kFpKey, kOtherKey});
+  EXPECT_TRUE(prefs_.SetString(key_middle_fp, "not_fp_val"));
+  auto key_end_not_fp = prefs_.CreateSubKey({kPrefsSubDir, "id-1", kNotFpKey});
+  EXPECT_TRUE(prefs_.SetString(key_end_not_fp, "not_fp_val"));
+
+  // Delete key in platform and one namespace.
+  prefs_.Delete(kFpKey, {kPrefsSubDir});
+
+  EXPECT_FALSE(prefs_.Exists(kFpKey));
+  EXPECT_FALSE(prefs_.Exists(key1_fp));
+  EXPECT_FALSE(prefs_.Exists(key2_fp));
+  EXPECT_FALSE(prefs_.Exists(key3_fp));
+
+  // Check other keys are not deleted.
+  EXPECT_TRUE(prefs_.Exists(kOtherKey));
+  EXPECT_TRUE(prefs_.Exists(key_not_fp));
+  EXPECT_TRUE(prefs_.Exists(key_middle_fp));
+  EXPECT_TRUE(prefs_.Exists(key_end_not_fp));
+}
+
+TEST_F(PrefsTest, DeleteMultipleNamespaces) {
+  const string kFirstSubDir = "foo-dir";
+  const string kSecondarySubDir = "bar-dir";
+  const string kTertiarySubDir = "ter-dir";
+  const string kFpKey = "kPrefFp";
+
+  EXPECT_TRUE(prefs_.SetString(kFpKey, "3.000"));
+  // Set pref key in different namespaces.
+  auto key1_fp = prefs_.CreateSubKey({kFirstSubDir, "id-1", kFpKey});
+  EXPECT_TRUE(prefs_.SetString(key1_fp, "3.7"));
+  auto key2_fp = prefs_.CreateSubKey({kSecondarySubDir, "id-3", kFpKey});
+  EXPECT_TRUE(prefs_.SetString(key2_fp, "7.45"));
+  auto key3_fp = prefs_.CreateSubKey({kTertiarySubDir, "id-3", kFpKey});
+  EXPECT_TRUE(prefs_.SetString(key3_fp, "7.45"));
+
+  // Delete key in platform and given namespaces.
+  prefs_.Delete(kFpKey, {kFirstSubDir, kSecondarySubDir});
+
+  EXPECT_FALSE(prefs_.Exists(kFpKey));
+  EXPECT_FALSE(prefs_.Exists(key1_fp));
+  EXPECT_FALSE(prefs_.Exists(key2_fp));
+
+  // Tertiary namespace not given to delete. Key should still exist.
+  EXPECT_TRUE(prefs_.Exists(key3_fp));
+}
+
 class MockPrefsObserver : public PrefsInterface::ObserverInterface {
  public:
   MOCK_METHOD1(OnPrefSet, void(const string&));
diff --git a/common/system_state.cc b/common/system_state.cc
new file mode 100644
index 0000000..cff1dfe
--- /dev/null
+++ b/common/system_state.cc
@@ -0,0 +1,23 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/common/system_state.h"
+
+namespace chromeos_update_engine {
+
+SystemState* SystemState::g_pointer_ = nullptr;
+
+}  // namespace chromeos_update_engine
diff --git a/common/system_state.h b/common/system_state.h
index 7a67046..8a9c865 100644
--- a/common/system_state.h
+++ b/common/system_state.h
@@ -17,6 +17,13 @@
 #ifndef UPDATE_ENGINE_COMMON_SYSTEM_STATE_H_
 #define UPDATE_ENGINE_COMMON_SYSTEM_STATE_H_
 
+#include <memory>
+
+#include <base/logging.h>
+
+#include "update_engine/common/clock_interface.h"
+#include "update_engine/common/prefs_interface.h"
+
 namespace chromeos_update_manager {
 
 class UpdateManager;
@@ -35,7 +42,6 @@
 // any circular references in header file inclusion. Hence forward-declaring
 // the required classes.
 class BootControlInterface;
-class ClockInterface;
 class ConnectionManagerInterface;
 class DlcServiceInterface;
 class HardwareInterface;
@@ -44,20 +50,20 @@
 class P2PManager;
 class PayloadStateInterface;
 class PowerManagerInterface;
-class PrefsInterface;
 class UpdateAttempter;
 
 // An interface to global system context, including platform resources,
 // the current state of the system, high-level objects whose lifetime is same
 // as main, system interfaces, etc.
 // Carved out separately so it can be mocked for unit tests.
-// Currently it has only one method, but we should start migrating other
-// methods to use this as and when needed to unit test them.
-// TODO(jaysri): Consider renaming this to something like GlobalContext.
 class SystemState {
  public:
-  // Destructs this object.
-  virtual ~SystemState() {}
+  virtual ~SystemState() = default;
+
+  static SystemState* Get() {
+    CHECK(g_pointer_ != nullptr);
+    return g_pointer_;
+  }
 
   // Sets or gets the latest device policy.
   virtual void set_device_policy(const policy::DevicePolicy* device_policy) = 0;
@@ -113,6 +119,9 @@
 
   // Returns a pointer to the DlcServiceInterface singleton.
   virtual DlcServiceInterface* dlcservice() = 0;
+
+ protected:
+  static SystemState* g_pointer_;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/common/utils.cc b/common/utils.cc
index 1ac42dc..3a89c2a 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -52,7 +52,6 @@
 #include <base/strings/stringprintf.h>
 #include <brillo/data_encoding.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/common/constants.h"
 #include "update_engine/common/platform_constants.h"
 #include "update_engine/common/prefs_interface.h"
diff --git a/cros/common_service.cc b/cros/common_service.cc
index aecad8b..e5ee828 100644
--- a/cros/common_service.cc
+++ b/cros/common_service.cc
@@ -26,9 +26,9 @@
 #include <brillo/strings/string_utils.h>
 #include <policy/device_policy.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/prefs.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/connection_manager_interface.h"
 #include "update_engine/cros/omaha_request_params.h"
@@ -66,8 +66,7 @@
 const char* const UpdateEngineService::kErrorFailed =
     "org.chromium.UpdateEngine.Error.Failed";
 
-UpdateEngineService::UpdateEngineService(SystemState* system_state)
-    : system_state_(system_state) {}
+UpdateEngineService::UpdateEngineService() = default;
 
 // org::chromium::UpdateEngineInterfaceInterface methods implementation.
 
@@ -79,7 +78,7 @@
             << "RestrictDownload="
             << ((flags & UpdateAttemptFlags::kFlagRestrictDownload) ? "yes"
                                                                     : "no");
-  system_state_->update_attempter()->SetUpdateAttemptFlags(flags);
+  SystemState::Get()->update_attempter()->SetUpdateAttemptFlags(flags);
   return true;
 }
 
@@ -98,7 +97,7 @@
             << "interactive=" << (interactive ? "yes " : "no ")
             << "RestrictDownload=" << (restrict_downloads ? "yes " : "no ");
 
-  *out_result = system_state_->update_attempter()->CheckForUpdate(
+  *out_result = SystemState::Get()->update_attempter()->CheckForUpdate(
       in_app_version, in_omaha_url, flags);
   return true;
 }
@@ -106,7 +105,8 @@
 bool UpdateEngineService::AttemptInstall(brillo::ErrorPtr* error,
                                          const string& omaha_url,
                                          const vector<string>& dlc_ids) {
-  if (!system_state_->update_attempter()->CheckForInstall(dlc_ids, omaha_url)) {
+  if (!SystemState::Get()->update_attempter()->CheckForInstall(dlc_ids,
+                                                               omaha_url)) {
     // TODO(xiaochu): support more detailed error messages.
     LogAndSetError(error, FROM_HERE, "Could not schedule install operation.");
     return false;
@@ -117,7 +117,7 @@
 bool UpdateEngineService::AttemptRollback(ErrorPtr* error, bool in_powerwash) {
   LOG(INFO) << "Attempting rollback to non-active partitions.";
 
-  if (!system_state_->update_attempter()->Rollback(in_powerwash)) {
+  if (!SystemState::Get()->update_attempter()->Rollback(in_powerwash)) {
     // TODO(dgarrett): Give a more specific error code/reason.
     LogAndSetError(error, FROM_HERE, "Rollback attempt failed.");
     return false;
@@ -127,14 +127,14 @@
 
 bool UpdateEngineService::CanRollback(ErrorPtr* /* error */,
                                       bool* out_can_rollback) {
-  bool can_rollback = system_state_->update_attempter()->CanRollback();
+  bool can_rollback = SystemState::Get()->update_attempter()->CanRollback();
   LOG(INFO) << "Checking to see if we can rollback . Result: " << can_rollback;
   *out_can_rollback = can_rollback;
   return true;
 }
 
 bool UpdateEngineService::ResetStatus(ErrorPtr* error) {
-  if (!system_state_->update_attempter()->ResetStatus()) {
+  if (!SystemState::Get()->update_attempter()->ResetStatus()) {
     // TODO(dgarrett): Give a more specific error code/reason.
     LogAndSetError(error, FROM_HERE, "ResetStatus failed.");
     return false;
@@ -145,8 +145,8 @@
 bool UpdateEngineService::SetDlcActiveValue(brillo::ErrorPtr* error,
                                             bool is_active,
                                             const string& dlc_id) {
-  if (!system_state_->update_attempter()->SetDlcActiveValue(is_active,
-                                                            dlc_id)) {
+  if (!SystemState::Get()->update_attempter()->SetDlcActiveValue(is_active,
+                                                                 dlc_id)) {
     LogAndSetError(error, FROM_HERE, "SetDlcActiveValue failed.");
     return false;
   }
@@ -155,7 +155,7 @@
 
 bool UpdateEngineService::GetStatus(ErrorPtr* error,
                                     UpdateEngineStatus* out_status) {
-  if (!system_state_->update_attempter()->GetStatus(out_status)) {
+  if (!SystemState::Get()->update_attempter()->GetStatus(out_status)) {
     LogAndSetError(error, FROM_HERE, "GetStatus failed.");
     return false;
   }
@@ -163,7 +163,7 @@
 }
 
 bool UpdateEngineService::RebootIfNeeded(ErrorPtr* error) {
-  if (!system_state_->update_attempter()->RebootIfNeeded()) {
+  if (!SystemState::Get()->update_attempter()->RebootIfNeeded()) {
     // TODO(dgarrett): Give a more specific error code/reason.
     LogAndSetError(error, FROM_HERE, "Reboot not needed, or attempt failed.");
     return false;
@@ -174,15 +174,16 @@
 bool UpdateEngineService::SetChannel(ErrorPtr* error,
                                      const string& in_target_channel,
                                      bool in_is_powerwash_allowed) {
-  const policy::DevicePolicy* device_policy = system_state_->device_policy();
+  const policy::DevicePolicy* device_policy =
+      SystemState::Get()->device_policy();
 
   // The device_policy is loaded in a lazy way before an update check. Load it
   // now from the libbrillo cache if it wasn't already loaded.
   if (!device_policy) {
-    UpdateAttempter* update_attempter = system_state_->update_attempter();
+    UpdateAttempter* update_attempter = SystemState::Get()->update_attempter();
     if (update_attempter) {
       update_attempter->RefreshDevicePolicy();
-      device_policy = system_state_->device_policy();
+      device_policy = SystemState::Get()->device_policy();
     }
   }
 
@@ -198,7 +199,7 @@
 
   LOG(INFO) << "Setting destination channel to: " << in_target_channel;
   string error_message;
-  if (!system_state_->request_params()->SetTargetChannel(
+  if (!SystemState::Get()->request_params()->SetTargetChannel(
           in_target_channel, in_is_powerwash_allowed, &error_message)) {
     LogAndSetError(error, FROM_HERE, error_message);
     return false;
@@ -209,7 +210,7 @@
 bool UpdateEngineService::GetChannel(ErrorPtr* /* error */,
                                      bool in_get_current_channel,
                                      string* out_channel) {
-  OmahaRequestParams* rp = system_state_->request_params();
+  OmahaRequestParams* rp = SystemState::Get()->request_params();
   *out_channel =
       (in_get_current_channel ? rp->current_channel() : rp->target_channel());
   return true;
@@ -217,12 +218,11 @@
 
 bool UpdateEngineService::SetCohortHint(ErrorPtr* error,
                                         const string& in_cohort_hint) {
-  PrefsInterface* prefs = system_state_->prefs();
-
   // It is ok to override the cohort hint with an invalid value since it is
   // stored in stateful partition. The code reading it should sanitize it
   // anyway.
-  if (!prefs->SetString(kPrefsOmahaCohortHint, in_cohort_hint)) {
+  if (!SystemState::Get()->prefs()->SetString(kPrefsOmahaCohortHint,
+                                              in_cohort_hint)) {
     LogAndSetError(
         error,
         FROM_HERE,
@@ -235,8 +235,7 @@
 
 bool UpdateEngineService::GetCohortHint(ErrorPtr* error,
                                         string* out_cohort_hint) {
-  PrefsInterface* prefs = system_state_->prefs();
-
+  const auto* prefs = SystemState::Get()->prefs();
   *out_cohort_hint = "";
   if (prefs->Exists(kPrefsOmahaCohortHint) &&
       !prefs->GetString(kPrefsOmahaCohortHint, out_cohort_hint)) {
@@ -248,9 +247,7 @@
 
 bool UpdateEngineService::SetP2PUpdatePermission(ErrorPtr* error,
                                                  bool in_enabled) {
-  PrefsInterface* prefs = system_state_->prefs();
-
-  if (!prefs->SetBoolean(kPrefsP2PEnabled, in_enabled)) {
+  if (!SystemState::Get()->prefs()->SetBoolean(kPrefsP2PEnabled, in_enabled)) {
     LogAndSetError(
         error,
         FROM_HERE,
@@ -263,8 +260,7 @@
 
 bool UpdateEngineService::GetP2PUpdatePermission(ErrorPtr* error,
                                                  bool* out_enabled) {
-  PrefsInterface* prefs = system_state_->prefs();
-
+  const auto* prefs = SystemState::Get()->prefs();
   bool p2p_pref = false;  // Default if no setting is present.
   if (prefs->Exists(kPrefsP2PEnabled) &&
       !prefs->GetBoolean(kPrefsP2PEnabled, &p2p_pref)) {
@@ -279,7 +275,7 @@
 bool UpdateEngineService::SetUpdateOverCellularPermission(ErrorPtr* error,
                                                           bool in_allowed) {
   ConnectionManagerInterface* connection_manager =
-      system_state_->connection_manager();
+      SystemState::Get()->connection_manager();
 
   // Check if this setting is allowed by the device policy.
   if (connection_manager->IsAllowedConnectionTypesForUpdateSet()) {
@@ -292,11 +288,8 @@
 
   // If the policy wasn't loaded yet, then it is still OK to change the local
   // setting because the policy will be checked again during the update check.
-
-  PrefsInterface* prefs = system_state_->prefs();
-
-  if (!prefs ||
-      !prefs->SetBoolean(kPrefsUpdateOverCellularPermission, in_allowed)) {
+  if (!SystemState::Get()->prefs()->SetBoolean(
+          kPrefsUpdateOverCellularPermission, in_allowed)) {
     LogAndSetError(error,
                    FROM_HERE,
                    string("Error setting the update over cellular to ") +
@@ -311,7 +304,7 @@
     const std::string& target_version,
     int64_t target_size) {
   ConnectionManagerInterface* connection_manager =
-      system_state_->connection_manager();
+      SystemState::Get()->connection_manager();
 
   // Check if this setting is allowed by the device policy.
   if (connection_manager->IsAllowedConnectionTypesForUpdateSet()) {
@@ -325,10 +318,8 @@
   // If the policy wasn't loaded yet, then it is still OK to change the local
   // setting because the policy will be checked again during the update check.
 
-  PrefsInterface* prefs = system_state_->prefs();
-
-  if (!prefs ||
-      !prefs->SetString(kPrefsUpdateOverCellularTargetVersion,
+  auto* prefs = SystemState::Get()->prefs();
+  if (!prefs->SetString(kPrefsUpdateOverCellularTargetVersion,
                         target_version) ||
       !prefs->SetInt64(kPrefsUpdateOverCellularTargetSize, target_size)) {
     LogAndSetError(
@@ -341,16 +332,15 @@
 bool UpdateEngineService::GetUpdateOverCellularPermission(ErrorPtr* error,
                                                           bool* out_allowed) {
   ConnectionManagerInterface* connection_manager =
-      system_state_->connection_manager();
+      SystemState::Get()->connection_manager();
 
   if (connection_manager->IsAllowedConnectionTypesForUpdateSet()) {
     // We have device policy, so ignore the user preferences.
     *out_allowed = connection_manager->IsUpdateAllowedOver(
         ConnectionType::kCellular, ConnectionTethering::kUnknown);
   } else {
-    PrefsInterface* prefs = system_state_->prefs();
-
-    if (!prefs || !prefs->Exists(kPrefsUpdateOverCellularPermission)) {
+    const auto* prefs = SystemState::Get()->prefs();
+    if (!prefs->Exists(kPrefsUpdateOverCellularPermission)) {
       // Update is not allowed as user preference is not set or not available.
       *out_allowed = false;
       return true;
@@ -372,26 +362,26 @@
 bool UpdateEngineService::GetDurationSinceUpdate(ErrorPtr* error,
                                                  int64_t* out_usec_wallclock) {
   base::Time time;
-  if (!system_state_->update_attempter()->GetBootTimeAtUpdate(&time)) {
+  if (!SystemState::Get()->update_attempter()->GetBootTimeAtUpdate(&time)) {
     LogAndSetError(error, FROM_HERE, "No pending update.");
     return false;
   }
 
-  ClockInterface* clock = system_state_->clock();
+  const auto* clock = SystemState::Get()->clock();
   *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
   return true;
 }
 
 bool UpdateEngineService::GetPrevVersion(ErrorPtr* /* error */,
                                          string* out_prev_version) {
-  *out_prev_version = system_state_->update_attempter()->GetPrevVersion();
+  *out_prev_version = SystemState::Get()->update_attempter()->GetPrevVersion();
   return true;
 }
 
 bool UpdateEngineService::GetRollbackPartition(
     ErrorPtr* /* error */, string* out_rollback_partition_name) {
   BootControlInterface::Slot rollback_slot =
-      system_state_->update_attempter()->GetRollbackSlot();
+      SystemState::Get()->update_attempter()->GetRollbackSlot();
 
   if (rollback_slot == BootControlInterface::kInvalidSlot) {
     out_rollback_partition_name->clear();
@@ -399,7 +389,7 @@
   }
 
   string name;
-  if (!system_state_->boot_control()->GetPartitionDevice(
+  if (!SystemState::Get()->boot_control()->GetPartitionDevice(
           "KERNEL", rollback_slot, &name)) {
     LOG(ERROR) << "Invalid rollback device";
     return false;
@@ -413,7 +403,7 @@
 bool UpdateEngineService::GetLastAttemptError(ErrorPtr* /* error */,
                                               int32_t* out_last_attempt_error) {
   ErrorCode error_code =
-      system_state_->update_attempter()->GetAttemptErrorCode();
+      SystemState::Get()->update_attempter()->GetAttemptErrorCode();
   *out_last_attempt_error = static_cast<int>(error_code);
   return true;
 }
diff --git a/cros/common_service.h b/cros/common_service.h
index 6169d9c..2c176c5 100644
--- a/cros/common_service.h
+++ b/cros/common_service.h
@@ -26,7 +26,6 @@
 #include <brillo/errors/error.h>
 
 #include "update_engine/client_library/include/update_engine/update_status.h"
-#include "update_engine/common/system_state.h"
 
 namespace chromeos_update_engine {
 
@@ -38,7 +37,7 @@
   // Generic service error.
   static const char* const kErrorFailed;
 
-  explicit UpdateEngineService(SystemState* system_state);
+  UpdateEngineService();
   virtual ~UpdateEngineService() = default;
 
   // Set flags that influence how updates and checks are performed.  These
@@ -160,9 +159,6 @@
   // Returns the last UpdateAttempt error.
   bool GetLastAttemptError(brillo::ErrorPtr* error,
                            int32_t* out_last_attempt_error);
-
- private:
-  SystemState* system_state_;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/cros/common_service_unittest.cc b/cros/common_service_unittest.cc
index 733ec0a..0644643 100644
--- a/cros/common_service_unittest.cc
+++ b/cros/common_service_unittest.cc
@@ -24,7 +24,6 @@
 #include <policy/libpolicy.h>
 #include <policy/mock_device_policy.h>
 
-#include "update_engine/common/fake_prefs.h"
 #include "update_engine/cros/fake_system_state.h"
 #include "update_engine/cros/omaha_utils.h"
 
@@ -39,17 +38,14 @@
 
 class UpdateEngineServiceTest : public ::testing::Test {
  protected:
-  UpdateEngineServiceTest()
-      : mock_update_attempter_(fake_system_state_.mock_update_attempter()),
-        common_service_(&fake_system_state_) {}
+  UpdateEngineServiceTest() = default;
 
-  void SetUp() override { fake_system_state_.set_device_policy(nullptr); }
+  void SetUp() override {
+    FakeSystemState::CreateInstance();
+    FakeSystemState::Get()->set_device_policy(nullptr);
+    mock_update_attempter_ = FakeSystemState::Get()->mock_update_attempter();
+  }
 
-  // Fake/mock infrastructure.
-  FakeSystemState fake_system_state_;
-  policy::MockDevicePolicy mock_device_policy_;
-
-  // Shortcut for fake_system_state_.mock_update_attempter().
   MockUpdateAttempter* mock_update_attempter_;
 
   brillo::ErrorPtr error_;
@@ -119,7 +115,7 @@
 TEST_F(UpdateEngineServiceTest, SetChannelWithNoPolicy) {
   EXPECT_CALL(*mock_update_attempter_, RefreshDevicePolicy());
   // If SetTargetChannel is called it means the policy check passed.
-  EXPECT_CALL(*fake_system_state_.mock_request_params(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_request_params(),
               SetTargetChannel("stable-channel", true, _))
       .WillOnce(Return(true));
   EXPECT_TRUE(common_service_.SetChannel(&error_, "stable-channel", true));
@@ -129,10 +125,10 @@
 // When the policy is present, the delegated value should be checked.
 TEST_F(UpdateEngineServiceTest, SetChannelWithDelegatedPolicy) {
   policy::MockDevicePolicy mock_device_policy;
-  fake_system_state_.set_device_policy(&mock_device_policy);
+  FakeSystemState::Get()->set_device_policy(&mock_device_policy);
   EXPECT_CALL(mock_device_policy, GetReleaseChannelDelegated(_))
       .WillOnce(DoAll(SetArgPointee<0>(true), Return(true)));
-  EXPECT_CALL(*fake_system_state_.mock_request_params(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_request_params(),
               SetTargetChannel("beta-channel", true, _))
       .WillOnce(Return(true));
 
@@ -144,7 +140,7 @@
 // raised.
 TEST_F(UpdateEngineServiceTest, SetChannelWithInvalidChannel) {
   EXPECT_CALL(*mock_update_attempter_, RefreshDevicePolicy());
-  EXPECT_CALL(*fake_system_state_.mock_request_params(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_request_params(),
               SetTargetChannel("foo-channel", true, _))
       .WillOnce(Return(false));
 
@@ -155,8 +151,8 @@
 }
 
 TEST_F(UpdateEngineServiceTest, GetChannel) {
-  fake_system_state_.mock_request_params()->set_current_channel("current");
-  fake_system_state_.mock_request_params()->set_target_channel("target");
+  FakeSystemState::Get()->mock_request_params()->set_current_channel("current");
+  FakeSystemState::Get()->mock_request_params()->set_target_channel("target");
   string channel;
   EXPECT_TRUE(common_service_.GetChannel(
       &error_, true /* get_current_channel */, &channel));
diff --git a/cros/connection_manager.cc b/cros/connection_manager.cc
index 331f76b..6a5c63b 100644
--- a/cros/connection_manager.cc
+++ b/cros/connection_manager.cc
@@ -41,16 +41,14 @@
 namespace chromeos_update_engine {
 
 namespace connection_manager {
-std::unique_ptr<ConnectionManagerInterface> CreateConnectionManager(
-    SystemState* system_state) {
+std::unique_ptr<ConnectionManagerInterface> CreateConnectionManager() {
   return std::unique_ptr<ConnectionManagerInterface>(
-      new ConnectionManager(new ShillProxy(), system_state));
+      new ConnectionManager(new ShillProxy()));
 }
 }  // namespace connection_manager
 
-ConnectionManager::ConnectionManager(ShillProxyInterface* shill_proxy,
-                                     SystemState* system_state)
-    : shill_proxy_(shill_proxy), system_state_(system_state) {}
+ConnectionManager::ConnectionManager(ShillProxyInterface* shill_proxy)
+    : shill_proxy_(shill_proxy) {}
 
 bool ConnectionManager::IsUpdateAllowedOver(
     ConnectionType type, ConnectionTethering tethering) const {
@@ -64,15 +62,16 @@
         << "Current connection is confirmed tethered, using Cellular setting.";
   }
 
-  const policy::DevicePolicy* device_policy = system_state_->device_policy();
+  const policy::DevicePolicy* device_policy =
+      SystemState::Get()->device_policy();
 
   // The device_policy is loaded in a lazy way before an update check. Load
   // it now from the libbrillo cache if it wasn't already loaded.
   if (!device_policy) {
-    UpdateAttempter* update_attempter = system_state_->update_attempter();
+    UpdateAttempter* update_attempter = SystemState::Get()->update_attempter();
     if (update_attempter) {
       update_attempter->RefreshDevicePolicy();
-      device_policy = system_state_->device_policy();
+      device_policy = SystemState::Get()->device_policy();
     }
   }
 
@@ -109,7 +108,8 @@
 }
 
 bool ConnectionManager::IsAllowedConnectionTypesForUpdateSet() const {
-  const policy::DevicePolicy* device_policy = system_state_->device_policy();
+  const policy::DevicePolicy* device_policy =
+      SystemState::Get()->device_policy();
   if (!device_policy) {
     LOG(INFO) << "There's no device policy loaded yet.";
     return false;
diff --git a/cros/connection_manager.h b/cros/connection_manager.h
index b1fb961..bb54ff7 100644
--- a/cros/connection_manager.h
+++ b/cros/connection_manager.h
@@ -35,8 +35,7 @@
  public:
   // Constructs a new ConnectionManager object initialized with the
   // given system state.
-  ConnectionManager(ShillProxyInterface* shill_proxy,
-                    SystemState* system_state);
+  explicit ConnectionManager(ShillProxyInterface* shill_proxy);
   ~ConnectionManager() override = default;
 
   // ConnectionManagerInterface overrides.
@@ -58,9 +57,6 @@
   // The mockable interface to access the shill DBus proxies.
   std::unique_ptr<ShillProxyInterface> shill_proxy_;
 
-  // The global context for update_engine.
-  SystemState* system_state_;
-
   DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
 };
 
diff --git a/cros/connection_manager_interface.h b/cros/connection_manager_interface.h
index 6dd9fbd..dc6c983 100644
--- a/cros/connection_manager_interface.h
+++ b/cros/connection_manager_interface.h
@@ -25,8 +25,6 @@
 
 namespace chromeos_update_engine {
 
-class SystemState;
-
 // This class exposes a generic interface to the connection manager
 // (e.g FlimFlam, Shill, etc.) to consolidate all connection-related
 // logic in update_engine.
@@ -59,8 +57,7 @@
 
 namespace connection_manager {
 // Factory function which creates a ConnectionManager.
-std::unique_ptr<ConnectionManagerInterface> CreateConnectionManager(
-    SystemState* system_state);
+std::unique_ptr<ConnectionManagerInterface> CreateConnectionManager();
 }  // namespace connection_manager
 
 }  // namespace chromeos_update_engine
diff --git a/cros/connection_manager_unittest.cc b/cros/connection_manager_unittest.cc
index 3f1ee5a..46da8cc 100644
--- a/cros/connection_manager_unittest.cc
+++ b/cros/connection_manager_unittest.cc
@@ -52,7 +52,8 @@
 
   void SetUp() override {
     loop_.SetAsCurrent();
-    fake_system_state_.set_connection_manager(&cmut_);
+    FakeSystemState::CreateInstance();
+    FakeSystemState::Get()->set_connection_manager(&cmut_);
   }
 
   void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); }
@@ -81,11 +82,10 @@
                                 ConnectionTethering expected_tethering);
 
   brillo::FakeMessageLoop loop_{nullptr};
-  FakeSystemState fake_system_state_;
   FakeShillProxy* fake_shill_proxy_;
 
   // ConnectionManager under test.
-  ConnectionManager cmut_{fake_shill_proxy_, &fake_system_state_};
+  ConnectionManager cmut_{fake_shill_proxy_};
 };
 
 void ConnectionManagerTest::SetManagerReply(const char* default_service,
@@ -227,7 +227,7 @@
 TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
   policy::MockDevicePolicy allow_3g_policy;
 
-  fake_system_state_.set_device_policy(&allow_3g_policy);
+  FakeSystemState::Get()->set_device_policy(&allow_3g_policy);
 
   // This test tests cellular (3G) being the only connection type being allowed.
   set<string> allowed_set;
@@ -244,7 +244,7 @@
 TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
   policy::MockDevicePolicy allow_3g_policy;
 
-  fake_system_state_.set_device_policy(&allow_3g_policy);
+  FakeSystemState::Get()->set_device_policy(&allow_3g_policy);
 
   // This test tests multiple connection types being allowed, with
   // 3G one among them. Only Cellular is currently enforced by the policy
@@ -276,7 +276,7 @@
 TEST_F(ConnectionManagerTest, AllowUpdatesOverCellularByDefaultTest) {
   policy::MockDevicePolicy device_policy;
   // Set an empty device policy.
-  fake_system_state_.set_device_policy(&device_policy);
+  FakeSystemState::Get()->set_device_policy(&device_policy);
 
   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(ConnectionType::kCellular,
                                         ConnectionTethering::kUnknown));
@@ -285,7 +285,7 @@
 TEST_F(ConnectionManagerTest, AllowUpdatesOverTetheredNetworkByDefaultTest) {
   policy::MockDevicePolicy device_policy;
   // Set an empty device policy.
-  fake_system_state_.set_device_policy(&device_policy);
+  FakeSystemState::Get()->set_device_policy(&device_policy);
 
   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(ConnectionType::kWifi,
                                         ConnectionTethering::kConfirmed));
@@ -298,7 +298,7 @@
 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
   policy::MockDevicePolicy block_3g_policy;
 
-  fake_system_state_.set_device_policy(&block_3g_policy);
+  FakeSystemState::Get()->set_device_policy(&block_3g_policy);
 
   // Test that updates for 3G are blocked while updates are allowed
   // over several other types.
@@ -317,7 +317,7 @@
 TEST_F(ConnectionManagerTest, AllowUpdatesOver3GIfPolicyIsNotSet) {
   policy::MockDevicePolicy device_policy;
 
-  fake_system_state_.set_device_policy(&device_policy);
+  FakeSystemState::Get()->set_device_policy(&device_policy);
 
   // Return false for GetAllowedConnectionTypesForUpdate and see
   // that updates are allowed as device policy is not set. Further
@@ -331,7 +331,7 @@
 }
 
 TEST_F(ConnectionManagerTest, AllowUpdatesOverCellularIfPolicyFailsToBeLoaded) {
-  fake_system_state_.set_device_policy(nullptr);
+  FakeSystemState::Get()->set_device_policy(nullptr);
 
   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(ConnectionType::kCellular,
                                         ConnectionTethering::kUnknown));
diff --git a/cros/daemon_chromeos.cc b/cros/daemon_chromeos.cc
index a7cad8c..366fb9a 100644
--- a/cros/daemon_chromeos.cc
+++ b/cros/daemon_chromeos.cc
@@ -41,18 +41,15 @@
   if (exit_code != EX_OK)
     return exit_code;
 
-  // Initialize update engine global state but continue if something fails.
-  // TODO(deymo): Move the daemon_state_ initialization to a factory method
-  // avoiding the explicit re-usage of the |bus| instance, shared between
-  // D-Bus service and D-Bus client calls.
-  RealSystemState* real_system_state = new RealSystemState();
-  daemon_state_.reset(real_system_state);
-  LOG_IF(ERROR, !real_system_state->Initialize())
-      << "Failed to initialize system state.";
+  // Initialize update engine global state.
+  // TODO(deymo): Move the initialization to a factory method avoiding the
+  // explicit re-usage of the |bus| instance, shared between D-Bus service and
+  // D-Bus client calls.
+  RealSystemState::SetInstance(&system_state_);
 
   // Create the DBus service.
-  dbus_adaptor_.reset(new UpdateEngineAdaptor(real_system_state));
-  daemon_state_->AddObserver(dbus_adaptor_.get());
+  dbus_adaptor_.reset(new UpdateEngineAdaptor());
+  SystemState::Get()->update_attempter()->AddObserver(dbus_adaptor_.get());
 
   dbus_adaptor_->RegisterAsync(
       base::Bind(&DaemonChromeOS::OnDBusRegistered, base::Unretained(this)));
@@ -76,7 +73,7 @@
     QuitWithExitCode(1);
     return;
   }
-  daemon_state_->StartUpdater();
+  SystemState::Get()->update_attempter()->StartUpdater();
 }
 
 }  // namespace chromeos_update_engine
diff --git a/cros/daemon_chromeos.h b/cros/daemon_chromeos.h
index 5d568c7..b23c2a6 100644
--- a/cros/daemon_chromeos.h
+++ b/cros/daemon_chromeos.h
@@ -23,6 +23,7 @@
 #include "update_engine/common/daemon_state_interface.h"
 #include "update_engine/common/subprocess.h"
 #include "update_engine/cros/dbus_service.h"
+#include "update_engine/cros/real_system_state.h"
 
 namespace chromeos_update_engine {
 
@@ -39,6 +40,13 @@
   // initialization.
   void OnDBusRegistered(bool succeeded);
 
+  // |SystemState| is a global context, but we can't have a static singleton of
+  // its object because the style guide does not allow that (it has non-trivial
+  // dtor). We need an instance of |SystemState| in this class instead and have
+  // a global pointer to it. This is better to be defined as the first variable
+  // of this class so it is initialized first and destructed last.
+  RealSystemState system_state_;
+
   // Main D-Bus service adaptor.
   std::unique_ptr<UpdateEngineAdaptor> dbus_adaptor_;
 
@@ -47,10 +55,6 @@
   // the main() function.
   Subprocess subprocess_;
 
-  // The daemon state with all the required daemon classes for the configured
-  // platform.
-  std::unique_ptr<DaemonStateInterface> daemon_state_;
-
   DISALLOW_COPY_AND_ASSIGN(DaemonChromeOS);
 };
 
diff --git a/cros/dbus_service.cc b/cros/dbus_service.cc
index d115195..1eb7b3c 100644
--- a/cros/dbus_service.cc
+++ b/cros/dbus_service.cc
@@ -52,8 +52,8 @@
 }
 }  // namespace
 
-DBusUpdateEngineService::DBusUpdateEngineService(SystemState* system_state)
-    : common_(new UpdateEngineService{system_state}) {}
+DBusUpdateEngineService::DBusUpdateEngineService()
+    : common_(new UpdateEngineService()) {}
 
 // org::chromium::UpdateEngineInterfaceInterface methods implementation.
 
@@ -192,10 +192,10 @@
   return common_->GetLastAttemptError(error, out_last_attempt_error);
 }
 
-UpdateEngineAdaptor::UpdateEngineAdaptor(SystemState* system_state)
+UpdateEngineAdaptor::UpdateEngineAdaptor()
     : org::chromium::UpdateEngineInterfaceAdaptor(&dbus_service_),
       bus_(DBusConnection::Get()->GetDBus()),
-      dbus_service_(system_state),
+      dbus_service_(),
       dbus_object_(nullptr,
                    bus_,
                    dbus::ObjectPath(update_engine::kUpdateEngineServicePath)) {}
diff --git a/cros/dbus_service.h b/cros/dbus_service.h
index 9e4457f..3ad6589 100644
--- a/cros/dbus_service.h
+++ b/cros/dbus_service.h
@@ -38,7 +38,7 @@
 class DBusUpdateEngineService
     : public org::chromium::UpdateEngineInterfaceInterface {
  public:
-  explicit DBusUpdateEngineService(SystemState* system_state);
+  DBusUpdateEngineService();
   virtual ~DBusUpdateEngineService() = default;
 
   // Implementation of org::chromium::UpdateEngineInterfaceInterface.
@@ -165,7 +165,7 @@
 class UpdateEngineAdaptor : public org::chromium::UpdateEngineInterfaceAdaptor,
                             public ServiceObserverInterface {
  public:
-  explicit UpdateEngineAdaptor(SystemState* system_state);
+  UpdateEngineAdaptor();
   ~UpdateEngineAdaptor() = default;
 
   // Register the DBus object with the update engine service asynchronously.
diff --git a/cros/excluder_chromeos.cc b/cros/excluder_chromeos.cc
index 4796525..35154d6 100644
--- a/cros/excluder_chromeos.cc
+++ b/cros/excluder_chromeos.cc
@@ -25,7 +25,6 @@
 #include <base/strings/string_split.h>
 
 #include "update_engine/common/constants.h"
-#include "update_engine/common/prefs.h"
 #include "update_engine/common/system_state.h"
 
 using std::string;
@@ -33,29 +32,30 @@
 
 namespace chromeos_update_engine {
 
-std::unique_ptr<ExcluderInterface> CreateExcluder(PrefsInterface* prefs) {
-  return std::make_unique<ExcluderChromeOS>(prefs);
+std::unique_ptr<ExcluderInterface> CreateExcluder() {
+  return std::make_unique<ExcluderChromeOS>();
 }
 
-ExcluderChromeOS::ExcluderChromeOS(PrefsInterface* prefs) : prefs_(prefs) {}
-
 bool ExcluderChromeOS::Exclude(const string& name) {
-  auto key = prefs_->CreateSubKey({kExclusionPrefsSubDir, name});
-  return prefs_->SetString(key, "");
+  auto* prefs = SystemState::Get()->prefs();
+  auto key = prefs->CreateSubKey({kExclusionPrefsSubDir, name});
+  return prefs->SetString(key, "");
 }
 
 bool ExcluderChromeOS::IsExcluded(const string& name) {
-  auto key = prefs_->CreateSubKey({kExclusionPrefsSubDir, name});
-  return prefs_->Exists(key);
+  auto* prefs = SystemState::Get()->prefs();
+  auto key = prefs->CreateSubKey({kExclusionPrefsSubDir, name});
+  return prefs->Exists(key);
 }
 
 bool ExcluderChromeOS::Reset() {
+  auto* prefs = SystemState::Get()->prefs();
   bool ret = true;
   vector<string> keys;
-  if (!prefs_->GetSubKeys(kExclusionPrefsSubDir, &keys))
+  if (!prefs->GetSubKeys(kExclusionPrefsSubDir, &keys))
     return false;
   for (const auto& key : keys)
-    if (!(ret &= prefs_->Delete(key)))
+    if (!(ret &= prefs->Delete(key)))
       LOG(ERROR) << "Failed to delete exclusion pref for " << key;
   return ret;
 }
diff --git a/cros/excluder_chromeos.h b/cros/excluder_chromeos.h
index 2480066..7d3efc9 100644
--- a/cros/excluder_chromeos.h
+++ b/cros/excluder_chromeos.h
@@ -29,7 +29,7 @@
 // The Chrome OS implementation of the |ExcluderInterface|.
 class ExcluderChromeOS : public ExcluderInterface {
  public:
-  explicit ExcluderChromeOS(PrefsInterface* prefs);
+  ExcluderChromeOS() = default;
   ~ExcluderChromeOS() = default;
 
   // |ExcluderInterface| overrides.
@@ -42,9 +42,6 @@
   ExcluderChromeOS& operator=(const ExcluderChromeOS&) = delete;
   ExcluderChromeOS(ExcluderChromeOS&&) = delete;
   ExcluderChromeOS& operator=(ExcluderChromeOS&&) = delete;
-
- private:
-  PrefsInterface* prefs_;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/cros/excluder_chromeos_unittest.cc b/cros/excluder_chromeos_unittest.cc
index 3602e56..fd70818 100644
--- a/cros/excluder_chromeos_unittest.cc
+++ b/cros/excluder_chromeos_unittest.cc
@@ -16,51 +16,39 @@
 
 #include "update_engine/cros/excluder_chromeos.h"
 
-#include <memory>
-
-#include <base/files/file_util.h>
-#include <base/files/scoped_temp_dir.h>
 #include <gtest/gtest.h>
 
-#include "update_engine/common/prefs.h"
-
-using std::string;
-using std::unique_ptr;
+#include "update_engine/cros/fake_system_state.h"
 
 namespace chromeos_update_engine {
 
+namespace {
 constexpr char kFakeHash[] =
     "71ff43d76e2488e394e46872f5b066cc25e394c2c3e3790dd319517883b33db1";
+}  // namespace
 
 class ExcluderChromeOSTest : public ::testing::Test {
  protected:
-  void SetUp() override {
-    ASSERT_TRUE(tempdir_.CreateUniqueTempDir());
-    ASSERT_TRUE(base::PathExists(tempdir_.GetPath()));
-    ASSERT_TRUE(prefs_.Init(tempdir_.GetPath()));
-    excluder_ = std::make_unique<ExcluderChromeOS>(&prefs_);
-  }
+  void SetUp() override { FakeSystemState::CreateInstance(); }
 
-  base::ScopedTempDir tempdir_;
-  Prefs prefs_;
-  unique_ptr<ExcluderChromeOS> excluder_;
+  ExcluderChromeOS excluder_;
 };
 
 TEST_F(ExcluderChromeOSTest, ExclusionCheck) {
-  EXPECT_FALSE(excluder_->IsExcluded(kFakeHash));
-  EXPECT_TRUE(excluder_->Exclude(kFakeHash));
-  EXPECT_TRUE(excluder_->IsExcluded(kFakeHash));
+  EXPECT_FALSE(excluder_.IsExcluded(kFakeHash));
+  EXPECT_TRUE(excluder_.Exclude(kFakeHash));
+  EXPECT_TRUE(excluder_.IsExcluded(kFakeHash));
 }
 
 TEST_F(ExcluderChromeOSTest, ResetFlow) {
-  EXPECT_TRUE(excluder_->Exclude("abc"));
-  EXPECT_TRUE(excluder_->Exclude(kFakeHash));
-  EXPECT_TRUE(excluder_->IsExcluded("abc"));
-  EXPECT_TRUE(excluder_->IsExcluded(kFakeHash));
+  EXPECT_TRUE(excluder_.Exclude("abc"));
+  EXPECT_TRUE(excluder_.Exclude(kFakeHash));
+  EXPECT_TRUE(excluder_.IsExcluded("abc"));
+  EXPECT_TRUE(excluder_.IsExcluded(kFakeHash));
 
-  EXPECT_TRUE(excluder_->Reset());
-  EXPECT_FALSE(excluder_->IsExcluded("abc"));
-  EXPECT_FALSE(excluder_->IsExcluded(kFakeHash));
+  EXPECT_TRUE(excluder_.Reset());
+  EXPECT_FALSE(excluder_.IsExcluded("abc"));
+  EXPECT_FALSE(excluder_.IsExcluded(kFakeHash));
 }
 
 }  // namespace chromeos_update_engine
diff --git a/cros/fake_system_state.cc b/cros/fake_system_state.cc
index 9dfdc5b..7673b1d 100644
--- a/cros/fake_system_state.cc
+++ b/cros/fake_system_state.cc
@@ -21,15 +21,13 @@
 // Mock the SystemStateInterface so that we could lie that
 // OOBE is completed even when there's no such marker file, etc.
 FakeSystemState::FakeSystemState()
-    : mock_update_attempter_(this, nullptr),
-      mock_request_params_(this),
-      fake_update_manager_(&fake_clock_),
+    : mock_update_attempter_(nullptr),
       clock_(&fake_clock_),
       connection_manager_(&mock_connection_manager_),
       hardware_(&fake_hardware_),
       metrics_reporter_(&mock_metrics_reporter_),
-      prefs_(&mock_prefs_),
-      powerwash_safe_prefs_(&mock_powerwash_safe_prefs_),
+      prefs_(&fake_prefs_),
+      powerwash_safe_prefs_(&fake_powerwash_safe_prefs_),
       payload_state_(&mock_payload_state_),
       update_attempter_(&mock_update_attempter_),
       request_params_(&mock_request_params_),
@@ -37,7 +35,7 @@
       update_manager_(&fake_update_manager_),
       device_policy_(nullptr),
       fake_system_rebooted_(false) {
-  mock_payload_state_.Initialize(this);
+  mock_payload_state_.Initialize();
 }
 
 }  // namespace chromeos_update_engine
diff --git a/cros/fake_system_state.h b/cros/fake_system_state.h
index 2f92b7c..da36306 100644
--- a/cros/fake_system_state.h
+++ b/cros/fake_system_state.h
@@ -17,6 +17,8 @@
 #ifndef UPDATE_ENGINE_CROS_FAKE_SYSTEM_STATE_H_
 #define UPDATE_ENGINE_CROS_FAKE_SYSTEM_STATE_H_
 
+#include <memory>
+
 #include <base/logging.h>
 #include <gmock/gmock.h>
 #include <policy/mock_device_policy.h>
@@ -25,6 +27,7 @@
 #include "update_engine/common/fake_boot_control.h"
 #include "update_engine/common/fake_clock.h"
 #include "update_engine/common/fake_hardware.h"
+#include "update_engine/common/fake_prefs.h"
 #include "update_engine/common/mock_metrics_reporter.h"
 #include "update_engine/common/mock_prefs.h"
 #include "update_engine/common/system_state.h"
@@ -42,7 +45,15 @@
 // OOBE is completed even when there's no such marker file, etc.
 class FakeSystemState : public SystemState {
  public:
-  FakeSystemState();
+  static void CreateInstance() {
+    static std::unique_ptr<FakeSystemState> system_state;
+    system_state.reset(new FakeSystemState());
+    g_pointer_ = system_state.get();
+  }
+
+  static FakeSystemState* Get() {
+    return reinterpret_cast<FakeSystemState*>(g_pointer_);
+  }
 
   // Base class overrides. All getters return the current implementation of
   // various members, either the default (fake/mock) or the one set to override
@@ -196,6 +207,16 @@
     return &fake_hardware_;
   }
 
+  inline FakePrefs* fake_prefs() {
+    CHECK(prefs_ == &fake_prefs_);
+    return &fake_prefs_;
+  }
+
+  inline FakePrefs* fake_powerwash_safe_prefs() {
+    CHECK(powerwash_safe_prefs_ == &fake_powerwash_safe_prefs_);
+    return &fake_powerwash_safe_prefs_;
+  }
+
   inline testing::NiceMock<MockMetricsReporter>* mock_metrics_reporter() {
     CHECK(metrics_reporter_ == &mock_metrics_reporter_);
     return &mock_metrics_reporter_;
@@ -237,11 +258,18 @@
   }
 
  private:
+  // Don't allow for direct initialization of this class.
+  FakeSystemState();
+
   // Default mock/fake implementations (owned).
+  chromeos_update_manager::FakeUpdateManager fake_update_manager_;
   FakeBootControl fake_boot_control_;
   FakeClock fake_clock_;
-  testing::NiceMock<MockConnectionManager> mock_connection_manager_;
   FakeHardware fake_hardware_;
+  FakePrefs fake_prefs_;
+  FakePrefs fake_powerwash_safe_prefs_;
+
+  testing::NiceMock<MockConnectionManager> mock_connection_manager_;
   testing::NiceMock<MockMetricsReporter> mock_metrics_reporter_;
   testing::NiceMock<MockPrefs> mock_prefs_;
   testing::NiceMock<MockPrefs> mock_powerwash_safe_prefs_;
@@ -249,7 +277,6 @@
   testing::NiceMock<MockUpdateAttempter> mock_update_attempter_;
   testing::NiceMock<MockOmahaRequestParams> mock_request_params_;
   testing::NiceMock<MockP2PManager> mock_p2p_manager_;
-  chromeos_update_manager::FakeUpdateManager fake_update_manager_;
   testing::NiceMock<MockPowerManager> mock_power_manager_;
 
   // Pointers to objects that client code can override. They are initialized to
diff --git a/cros/hardware_chromeos.cc b/cros/hardware_chromeos.cc
index b9018ff..14f2497 100644
--- a/cros/hardware_chromeos.cc
+++ b/cros/hardware_chromeos.cc
@@ -253,7 +253,7 @@
 }
 
 bool HardwareChromeOS::CancelPowerwash() {
-  bool result = base::DeleteFile(base::FilePath(kPowerwashMarkerFile), false);
+  bool result = base::DeleteFile(base::FilePath(kPowerwashMarkerFile));
 
   if (result) {
     LOG(INFO) << "Successfully deleted the powerwash marker file : "
@@ -264,7 +264,7 @@
   }
 
   // Delete the rollback save marker file if it existed.
-  if (!base::DeleteFile(base::FilePath(kRollbackSaveMarkerFile), false)) {
+  if (!base::DeleteFile(base::FilePath(kRollbackSaveMarkerFile))) {
     PLOG(ERROR) << "Could not remove rollback save marker";
   }
 
diff --git a/cros/image_properties.h b/cros/image_properties.h
index 4957d12..1297547 100644
--- a/cros/image_properties.h
+++ b/cros/image_properties.h
@@ -25,8 +25,6 @@
 
 namespace chromeos_update_engine {
 
-class SystemState;
-
 // The read-only system properties of the running image.
 struct ImageProperties {
   // The product id of the image used for all channels, except canary.
@@ -77,16 +75,15 @@
 // Loads all the image properties from the running system. In case of error
 // loading any of these properties from the read-only system image a default
 // value may be returned instead.
-ImageProperties LoadImageProperties(SystemState* system_state);
+ImageProperties LoadImageProperties();
 
 // Loads the mutable image properties from the stateful partition if found or
 // the system image otherwise.
-MutableImageProperties LoadMutableImageProperties(SystemState* system_state);
+MutableImageProperties LoadMutableImageProperties();
 
 // Stores the mutable image properties in the stateful partition. Returns
 // whether the operation succeeded.
-bool StoreMutableImageProperties(SystemState* system_state,
-                                 const MutableImageProperties& properties);
+bool StoreMutableImageProperties(const MutableImageProperties& properties);
 
 // Logs the image properties.
 void LogImageProperties();
diff --git a/cros/image_properties_chromeos.cc b/cros/image_properties_chromeos.cc
index c22da7c..79155b5 100644
--- a/cros/image_properties_chromeos.cc
+++ b/cros/image_properties_chromeos.cc
@@ -86,7 +86,7 @@
 }
 }  // namespace test
 
-ImageProperties LoadImageProperties(SystemState* system_state) {
+ImageProperties LoadImageProperties() {
   ImageProperties result;
 
   brillo::KeyValueStore lsb_release;
@@ -97,7 +97,7 @@
   // In dev-mode and unofficial build we can override the image properties set
   // in the system image with the ones from the stateful partition, except the
   // channel of the current image.
-  HardwareInterface* const hardware = system_state->hardware();
+  HardwareInterface* const hardware = SystemState::Get()->hardware();
   if (!hardware->IsOfficialBuild() || !hardware->IsNormalBootMode())
     LoadLsbRelease(LsbReleaseSource::kStateful, &lsb_release);
 
@@ -124,7 +124,7 @@
   return result;
 }
 
-MutableImageProperties LoadMutableImageProperties(SystemState* system_state) {
+MutableImageProperties LoadMutableImageProperties() {
   MutableImageProperties result;
   brillo::KeyValueStore lsb_release;
   LoadLsbRelease(LsbReleaseSource::kSystem, &lsb_release);
@@ -137,8 +137,7 @@
   return result;
 }
 
-bool StoreMutableImageProperties(SystemState* system_state,
-                                 const MutableImageProperties& properties) {
+bool StoreMutableImageProperties(const MutableImageProperties& properties) {
   brillo::KeyValueStore lsb_release;
   LoadLsbRelease(LsbReleaseSource::kStateful, &lsb_release);
   lsb_release.SetString(kLsbReleaseUpdateChannelKey, properties.target_channel);
diff --git a/cros/image_properties_chromeos_unittest.cc b/cros/image_properties_chromeos_unittest.cc
index 4822995..497554e 100644
--- a/cros/image_properties_chromeos_unittest.cc
+++ b/cros/image_properties_chromeos_unittest.cc
@@ -40,16 +40,15 @@
     EXPECT_TRUE(base::CreateDirectory(base::FilePath(
         tempdir_.GetPath().value() + kStatefulPartition + "/etc")));
     test::SetImagePropertiesRootPrefix(tempdir_.GetPath().value().c_str());
+    FakeSystemState::CreateInstance();
     SetLockDown(false);
   }
 
   void SetLockDown(bool locked_down) {
-    fake_system_state_.fake_hardware()->SetIsOfficialBuild(locked_down);
-    fake_system_state_.fake_hardware()->SetIsNormalBootMode(locked_down);
+    FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(locked_down);
+    FakeSystemState::Get()->fake_hardware()->SetIsNormalBootMode(locked_down);
   }
 
-  FakeSystemState fake_system_state_;
-
   base::ScopedTempDir tempdir_;
 };
 
@@ -61,7 +60,7 @@
                       "CHROMEOS_RELEASE_VERSION=0.2.2.3\n"
                       "CHROMEOS_RELEASE_TRACK=dev-channel\n"
                       "CHROMEOS_AUSERVER=http://www.google.com"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("arm-generic", props.board);
   EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", props.product_id);
   EXPECT_EQ("0.2.2.3", props.version);
@@ -73,7 +72,7 @@
   ASSERT_TRUE(WriteFileString(
       tempdir_.GetPath().Append("etc/lsb-release").value(),
       "CHROMEOS_RELEASE_APPID={58c35cef-9d30-476e-9098-ce20377d535d}"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("{58c35cef-9d30-476e-9098-ce20377d535d}", props.product_id);
 }
 
@@ -82,12 +81,12 @@
       WriteFileString(tempdir_.GetPath().Append("etc/lsb-release").value(),
                       "CHROMEOS_RELEASE_FOO=CHROMEOS_RELEASE_VERSION=1.2.3.4\n"
                       "CHROMEOS_RELEASE_VERSION=0.2.2.3"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("0.2.2.3", props.version);
 }
 
 TEST_F(ImagePropertiesTest, MissingVersionTest) {
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("", props.version);
 }
 
@@ -103,12 +102,11 @@
       "CHROMEOS_RELEASE_BOARD=x86-generic\n"
       "CHROMEOS_RELEASE_TRACK=beta-channel\n"
       "CHROMEOS_AUSERVER=https://www.google.com"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("x86-generic", props.board);
   EXPECT_EQ("dev-channel", props.current_channel);
   EXPECT_EQ("https://www.google.com", props.omaha_url);
-  MutableImageProperties mutable_props =
-      LoadMutableImageProperties(&fake_system_state_);
+  MutableImageProperties mutable_props = LoadMutableImageProperties();
   EXPECT_EQ("beta-channel", mutable_props.target_channel);
 }
 
@@ -125,12 +123,11 @@
       "CHROMEOS_RELEASE_TRACK=stable-channel\n"
       "CHROMEOS_AUSERVER=http://www.google.com"));
   SetLockDown(true);
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("arm-generic", props.board);
   EXPECT_EQ("dev-channel", props.current_channel);
   EXPECT_EQ("https://www.google.com", props.omaha_url);
-  MutableImageProperties mutable_props =
-      LoadMutableImageProperties(&fake_system_state_);
+  MutableImageProperties mutable_props = LoadMutableImageProperties();
   EXPECT_EQ("stable-channel", mutable_props.target_channel);
 }
 
@@ -141,7 +138,7 @@
                       "CHROMEOS_BOARD_APPID=b\n"
                       "CHROMEOS_CANARY_APPID=c\n"
                       "CHROMEOS_RELEASE_TRACK=stable-channel\n"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("stable-channel", props.current_channel);
   EXPECT_EQ("b", props.product_id);
 }
@@ -153,7 +150,7 @@
                       "CHROMEOS_BOARD_APPID=b\n"
                       "CHROMEOS_CANARY_APPID=c\n"
                       "CHROMEOS_RELEASE_TRACK=canary-channel\n"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("canary-channel", props.current_channel);
   EXPECT_EQ("c", props.canary_product_id);
 }
@@ -164,7 +161,7 @@
                       "CHROMEOS_RELEASE_APPID=r\n"
                       "CHROMEOS_CANARY_APPID=c\n"
                       "CHROMEOS_RELEASE_TRACK=stable-channel\n"));
-  ImageProperties props = LoadImageProperties(&fake_system_state_);
+  ImageProperties props = LoadImageProperties();
   EXPECT_EQ("stable-channel", props.current_channel);
   EXPECT_EQ("r", props.product_id);
 }
diff --git a/cros/logging.cc b/cros/logging.cc
index e09166c..8b6c556 100644
--- a/cros/logging.cc
+++ b/cros/logging.cc
@@ -46,7 +46,7 @@
     base::ReplaceFile(
         base::FilePath(symlink_path), base::FilePath(log_path), nullptr);
   }
-  base::DeleteFile(base::FilePath(symlink_path), true);
+  base::DeletePathRecursively(base::FilePath(symlink_path));
   if (symlink(log_path.c_str(), symlink_path.c_str()) == -1) {
     PLOG(ERROR) << "Unable to create symlink " << symlink_path
                 << " pointing at " << log_path;
diff --git a/cros/metrics_reporter_omaha.cc b/cros/metrics_reporter_omaha.cc
index 2cc0de5..22c0aa9 100644
--- a/cros/metrics_reporter_omaha.cc
+++ b/cros/metrics_reporter_omaha.cc
@@ -22,7 +22,6 @@
 #include <base/strings/string_number_conversions.h>
 #include <metrics/metrics_library.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/common/constants.h"
 #include "update_engine/common/prefs_interface.h"
 #include "update_engine/common/system_state.h"
@@ -155,7 +154,6 @@
 }
 
 void MetricsReporterOmaha::ReportUpdateCheckMetrics(
-    SystemState* system_state,
     metrics::CheckResult result,
     metrics::CheckReaction reaction,
     metrics::DownloadErrorCode download_error_code) {
@@ -182,8 +180,7 @@
   }
 
   base::TimeDelta time_since_last;
-  if (WallclockDurationHelper(system_state,
-                              kPrefsMetricsCheckLastReportingTime,
+  if (WallclockDurationHelper(kPrefsMetricsCheckLastReportingTime,
                               &time_since_last)) {
     metric = metrics::kMetricCheckTimeSinceLastCheckMinutes;
     metrics_lib_->SendToUMA(metric,
@@ -195,8 +192,7 @@
 
   base::TimeDelta uptime_since_last;
   static int64_t uptime_since_last_storage = 0;
-  if (MonotonicDurationHelper(
-          system_state, &uptime_since_last_storage, &uptime_since_last)) {
+  if (MonotonicDurationHelper(&uptime_since_last_storage, &uptime_since_last)) {
     metric = metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes;
     metrics_lib_->SendToUMA(metric,
                             uptime_since_last.InMinutes(),
@@ -206,14 +202,14 @@
   }
 
   // First section of target version specified for the update.
-  if (system_state && system_state->request_params()) {
+  if (SystemState::Get()->request_params()) {
     string target_version =
-        system_state->request_params()->target_version_prefix();
+        SystemState::Get()->request_params()->target_version_prefix();
     value = utils::VersionPrefix(target_version);
     if (value != 0) {
       metric = metrics::kMetricCheckTargetVersion;
       metrics_lib_->SendSparseToUMA(metric, value);
-      if (system_state->request_params()->rollback_allowed()) {
+      if (SystemState::Get()->request_params()->rollback_allowed()) {
         metric = metrics::kMetricCheckRollbackTargetVersion;
         metrics_lib_->SendSparseToUMA(metric, value);
       }
@@ -233,7 +229,6 @@
 }
 
 void MetricsReporterOmaha::ReportUpdateAttemptMetrics(
-    SystemState* system_state,
     int attempt_number,
     PayloadType payload_type,
     base::TimeDelta duration,
@@ -284,8 +279,7 @@
   }
 
   base::TimeDelta time_since_last;
-  if (WallclockDurationHelper(system_state,
-                              kPrefsMetricsAttemptLastReportingTime,
+  if (WallclockDurationHelper(kPrefsMetricsAttemptLastReportingTime,
                               &time_since_last)) {
     metric = metrics::kMetricAttemptTimeSinceLastAttemptMinutes;
     metrics_lib_->SendToUMA(metric,
@@ -297,8 +291,7 @@
 
   static int64_t uptime_since_last_storage = 0;
   base::TimeDelta uptime_since_last;
-  if (MonotonicDurationHelper(
-          system_state, &uptime_since_last_storage, &uptime_since_last)) {
+  if (MonotonicDurationHelper(&uptime_since_last_storage, &uptime_since_last)) {
     metric = metrics::kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
     metrics_lib_->SendToUMA(metric,
                             uptime_since_last.InMinutes(),
@@ -557,13 +550,13 @@
 }
 
 bool MetricsReporterOmaha::WallclockDurationHelper(
-    SystemState* system_state,
     const std::string& state_variable_key,
     TimeDelta* out_duration) {
   bool ret = false;
-  Time now = system_state->clock()->GetWallclockTime();
+  Time now = SystemState::Get()->clock()->GetWallclockTime();
   int64_t stored_value;
-  if (system_state->prefs()->GetInt64(state_variable_key, &stored_value)) {
+  if (SystemState::Get()->prefs()->GetInt64(state_variable_key,
+                                            &stored_value)) {
     Time stored_time = Time::FromInternalValue(stored_value);
     if (stored_time > now) {
       LOG(ERROR) << "Stored time-stamp used for " << state_variable_key
@@ -574,19 +567,18 @@
     }
   }
 
-  if (!system_state->prefs()->SetInt64(state_variable_key,
-                                       now.ToInternalValue())) {
+  if (!SystemState::Get()->prefs()->SetInt64(state_variable_key,
+                                             now.ToInternalValue())) {
     LOG(ERROR) << "Error storing time-stamp in " << state_variable_key;
   }
 
   return ret;
 }
 
-bool MetricsReporterOmaha::MonotonicDurationHelper(SystemState* system_state,
-                                                   int64_t* storage,
+bool MetricsReporterOmaha::MonotonicDurationHelper(int64_t* storage,
                                                    TimeDelta* out_duration) {
   bool ret = false;
-  Time now = system_state->clock()->GetMonotonicTime();
+  Time now = SystemState::Get()->clock()->GetMonotonicTime();
   if (*storage != 0) {
     Time stored_time = Time::FromInternalValue(*storage);
     *out_duration = now - stored_time;
diff --git a/cros/metrics_reporter_omaha.h b/cros/metrics_reporter_omaha.h
index 5b3fdb1..b6ffcce 100644
--- a/cros/metrics_reporter_omaha.h
+++ b/cros/metrics_reporter_omaha.h
@@ -29,7 +29,6 @@
 #include "update_engine/common/error_code.h"
 #include "update_engine/common/metrics_constants.h"
 #include "update_engine/common/metrics_reporter_interface.h"
-#include "update_engine/common/system_state.h"
 
 namespace chromeos_update_engine {
 
@@ -117,13 +116,11 @@
   void ReportDailyMetrics(base::TimeDelta os_age) override;
 
   void ReportUpdateCheckMetrics(
-      SystemState* system_state,
       metrics::CheckResult result,
       metrics::CheckReaction reaction,
       metrics::DownloadErrorCode download_error_code) override;
 
-  void ReportUpdateAttemptMetrics(SystemState* system_state,
-                                  int attempt_number,
+  void ReportUpdateAttemptMetrics(int attempt_number,
                                   PayloadType payload_type,
                                   base::TimeDelta duration,
                                   base::TimeDelta duration_uptime,
@@ -181,8 +178,7 @@
   // If the function returns |true|, the duration (always non-negative)
   // is returned in |out_duration|. If the function returns |false|
   // something went wrong or there was no previous measurement.
-  bool WallclockDurationHelper(SystemState* system_state,
-                               const std::string& state_variable_key,
+  bool WallclockDurationHelper(const std::string& state_variable_key,
                                base::TimeDelta* out_duration);
 
   // This function returns the duration on the monotonic clock since the
@@ -194,9 +190,7 @@
   // If the function returns |true|, the duration (always non-negative)
   // is returned in |out_duration|. If the function returns |false|
   // something went wrong or there was no previous measurement.
-  bool MonotonicDurationHelper(SystemState* system_state,
-                               int64_t* storage,
-                               base::TimeDelta* out_duration);
+  bool MonotonicDurationHelper(int64_t* storage, base::TimeDelta* out_duration);
 
   std::unique_ptr<MetricsLibraryInterface> metrics_lib_;
 
diff --git a/cros/metrics_reporter_omaha_unittest.cc b/cros/metrics_reporter_omaha_unittest.cc
index a25472a..cdc44cd 100644
--- a/cros/metrics_reporter_omaha_unittest.cc
+++ b/cros/metrics_reporter_omaha_unittest.cc
@@ -25,7 +25,6 @@
 #include <metrics/metrics_library_mock.h>
 
 #include "update_engine/common/fake_clock.h"
-#include "update_engine/common/fake_prefs.h"
 #include "update_engine/cros/fake_system_state.h"
 
 using base::TimeDelta;
@@ -40,12 +39,16 @@
 
   // Reset the metrics_lib_ to a mock library.
   void SetUp() override {
+    FakeSystemState::CreateInstance();
+    fake_clock_ = FakeSystemState::Get()->fake_clock();
     mock_metrics_lib_ = new testing::NiceMock<MetricsLibraryMock>();
     reporter_.metrics_lib_.reset(mock_metrics_lib_);
   }
 
   testing::NiceMock<MetricsLibraryMock>* mock_metrics_lib_;
   MetricsReporterOmaha reporter_;
+
+  FakeClock* fake_clock_;
 };
 
 TEST_F(MetricsReporterOmahaTest, ReportDailyMetrics) {
@@ -58,15 +61,9 @@
 }
 
 TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetrics) {
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
-
   // We need to execute the report twice to test the time since last report.
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(1000000));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(1000000));
 
   metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable;
   metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored;
@@ -104,24 +101,20 @@
           metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes, 1, _, _, _))
       .Times(1);
 
-  reporter_.ReportUpdateCheckMetrics(
-      &fake_system_state, result, reaction, error_code);
+  reporter_.ReportUpdateCheckMetrics(result, reaction, error_code);
 
   // Advance the clock by 1 minute and report the same metrics again.
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(61000000));
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(61000000));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(61000000));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(61000000));
   // Allow rollback
-  reporter_.ReportUpdateCheckMetrics(
-      &fake_system_state, result, reaction, error_code);
+  reporter_.ReportUpdateCheckMetrics(result, reaction, error_code);
 }
 
 TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetricsPinned) {
-  FakeSystemState fake_system_state;
-
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.set_target_version_prefix("10575.");
   params.set_rollback_allowed(false);
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
   metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable;
   metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored;
@@ -138,17 +131,14 @@
               SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, _))
       .Times(0);
 
-  reporter_.ReportUpdateCheckMetrics(
-      &fake_system_state, result, reaction, error_code);
+  reporter_.ReportUpdateCheckMetrics(result, reaction, error_code);
 }
 
 TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetricsRollback) {
-  FakeSystemState fake_system_state;
-
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.set_target_version_prefix("10575.");
   params.set_rollback_allowed(true);
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
   metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable;
   metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored;
@@ -166,8 +156,7 @@
       SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, 10575))
       .Times(1);
 
-  reporter_.ReportUpdateCheckMetrics(
-      &fake_system_state, result, reaction, error_code);
+  reporter_.ReportUpdateCheckMetrics(result, reaction, error_code);
 }
 
 TEST_F(MetricsReporterOmahaTest,
@@ -183,14 +172,8 @@
 }
 
 TEST_F(MetricsReporterOmahaTest, ReportUpdateAttemptMetrics) {
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
-
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(1000000));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(1000000));
 
   int attempt_number = 1;
   PayloadType payload_type = kPayloadTypeFull;
@@ -252,8 +235,7 @@
           metrics::kMetricAttemptTimeSinceLastAttemptUptimeMinutes, 1, _, _, _))
       .Times(1);
 
-  reporter_.ReportUpdateAttemptMetrics(&fake_system_state,
-                                       attempt_number,
+  reporter_.ReportUpdateAttemptMetrics(attempt_number,
                                        payload_type,
                                        duration,
                                        duration_uptime,
@@ -262,10 +244,9 @@
                                        internal_error_code);
 
   // Advance the clock by 1 minute and report the same metrics again.
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(61000000));
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(61000000));
-  reporter_.ReportUpdateAttemptMetrics(&fake_system_state,
-                                       attempt_number,
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(61000000));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(61000000));
+  reporter_.ReportUpdateAttemptMetrics(attempt_number,
                                        payload_type,
                                        duration,
                                        duration_uptime,
@@ -539,113 +520,87 @@
 }
 
 TEST_F(MetricsReporterOmahaTest, WallclockDurationHelper) {
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
   base::TimeDelta duration;
   const std::string state_variable_key = "test-prefs";
-  FakePrefs fake_prefs;
-
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
 
   // Initialize wallclock to 1 sec.
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(1000000));
 
   // First time called so no previous measurement available.
-  EXPECT_FALSE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  EXPECT_FALSE(
+      reporter_.WallclockDurationHelper(state_variable_key, &duration));
 
   // Next time, we should get zero since the clock didn't advance.
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // We can also call it as many times as we want with it being
   // considered a failure.
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // Advance the clock one second, then we should get 1 sec on the
   // next call and 0 sec on the subsequent call.
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(2000000));
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(2000000));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 1);
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // Advance clock two seconds and we should get 2 sec and then 0 sec.
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(4000000));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 2);
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // There's a possibility that the wallclock can go backwards (NTP
   // adjustments, for example) so check that we properly handle this
   // case.
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(3000000));
-  EXPECT_FALSE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
-  fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
-  EXPECT_TRUE(reporter_.WallclockDurationHelper(
-      &fake_system_state, state_variable_key, &duration));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(3000000));
+  EXPECT_FALSE(
+      reporter_.WallclockDurationHelper(state_variable_key, &duration));
+  fake_clock_->SetWallclockTime(base::Time::FromInternalValue(4000000));
+  EXPECT_TRUE(reporter_.WallclockDurationHelper(state_variable_key, &duration));
   EXPECT_EQ(duration.InSeconds(), 1);
 }
 
 TEST_F(MetricsReporterOmahaTest, MonotonicDurationHelper) {
   int64_t storage = 0;
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
   base::TimeDelta duration;
 
-  fake_system_state.set_clock(&fake_clock);
-
   // Initialize monotonic clock to 1 sec.
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(1000000));
 
   // First time called so no previous measurement available.
-  EXPECT_FALSE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  EXPECT_FALSE(reporter_.MonotonicDurationHelper(&storage, &duration));
 
   // Next time, we should get zero since the clock didn't advance.
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // We can also call it as many times as we want with it being
   // considered a failure.
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // Advance the clock one second, then we should get 1 sec on the
   // next call and 0 sec on the subsequent call.
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(2000000));
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(2000000));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 1);
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 
   // Advance clock two seconds and we should get 2 sec and then 0 sec.
-  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(4000000));
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  fake_clock_->SetMonotonicTime(base::Time::FromInternalValue(4000000));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 2);
-  EXPECT_TRUE(reporter_.MonotonicDurationHelper(
-      &fake_system_state, &storage, &duration));
+  EXPECT_TRUE(reporter_.MonotonicDurationHelper(&storage, &duration));
   EXPECT_EQ(duration.InSeconds(), 0);
 }
 
diff --git a/cros/mock_omaha_request_params.h b/cros/mock_omaha_request_params.h
index 6072d22..1e21812 100644
--- a/cros/mock_omaha_request_params.h
+++ b/cros/mock_omaha_request_params.h
@@ -27,8 +27,7 @@
 
 class MockOmahaRequestParams : public OmahaRequestParams {
  public:
-  explicit MockOmahaRequestParams(SystemState* system_state)
-      : OmahaRequestParams(system_state) {
+  MockOmahaRequestParams() : OmahaRequestParams() {
     // Delegate all calls to the parent instance by default. This helps the
     // migration from tests using the real RequestParams when they should have
     // use a fake or mock.
diff --git a/cros/mock_payload_state.h b/cros/mock_payload_state.h
index 56094e6..211b96d 100644
--- a/cros/mock_payload_state.h
+++ b/cros/mock_payload_state.h
@@ -21,14 +21,13 @@
 
 #include <gmock/gmock.h>
 
-#include "update_engine/common/system_state.h"
 #include "update_engine/cros/payload_state_interface.h"
 
 namespace chromeos_update_engine {
 
 class MockPayloadState : public PayloadStateInterface {
  public:
-  bool Initialize(SystemState* system_state) { return true; }
+  bool Initialize() { return true; }
 
   // Significant methods.
   MOCK_METHOD1(SetResponse, void(const OmahaResponse& response));
diff --git a/cros/omaha_request_action.cc b/cros/omaha_request_action.cc
index 0916f9d..1e5c15f 100644
--- a/cros/omaha_request_action.cc
+++ b/cros/omaha_request_action.cc
@@ -48,6 +48,7 @@
 #include "update_engine/common/platform_constants.h"
 #include "update_engine/common/prefs.h"
 #include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/connection_manager_interface.h"
 #include "update_engine/cros/omaha_request_builder_xml.h"
@@ -98,6 +99,7 @@
 constexpr char kAttrElapsedDays[] = "elapsed_days";
 constexpr char kAttrElapsedSeconds[] = "elapsed_seconds";
 constexpr char kAttrEvent[] = "event";
+constexpr char kAttrFp[] = "fp";
 constexpr char kAttrHashSha256[] = "hash_sha256";
 // Deprecated: "hash"; Although we still need to pass it from the server for
 // backward compatibility.
@@ -111,45 +113,85 @@
 constexpr char kValPostInstall[] = "postinstall";
 constexpr char kValNoUpdate[] = "noupdate";
 
-// updatecheck attributes (without the underscore prefix).
+// updatecheck attributes.
 // Deprecated: "eol"
-constexpr char kAttrEolDate[] = "eol_date";
-constexpr char kAttrRollback[] = "rollback";
-constexpr char kAttrFirmwareVersion[] = "firmware_version";
-constexpr char kAttrKernelVersion[] = "kernel_version";
+constexpr char kAttrEolDate[] = "_eol_date";
+constexpr char kAttrRollback[] = "_rollback";
+constexpr char kAttrFirmwareVersion[] = "_firmware_version";
+constexpr char kAttrKernelVersion[] = "_kernel_version";
 
 // Struct used for holding data obtained when parsing the XML.
 struct OmahaParserData {
-  explicit OmahaParserData(XML_Parser _xml_parser) : xml_parser(_xml_parser) {}
+  OmahaParserData(XML_Parser _xml_parser, int _rollback_allowed_milestones)
+      : xml_parser(_xml_parser),
+        rollback_allowed_milestones(_rollback_allowed_milestones) {}
 
   // Pointer to the expat XML_Parser object.
   XML_Parser xml_parser;
 
+  // Some values that we need during parsing.
+  int rollback_allowed_milestones;
+
   // This is the state of the parser as it's processing the XML.
   bool failed = false;
   bool entity_decl = false;
   string current_path;
 
   // These are the values extracted from the XML.
-  string updatecheck_poll_interval;
-  map<string, string> updatecheck_attrs;
-  string daystart_elapsed_days;
-  string daystart_elapsed_seconds;
+  struct DayStart {
+    string elapsed_days;
+    string elapsed_seconds;
+  } daystart;
 
   struct App {
     string id;
-    vector<string> url_codebase;
-    string manifest_version;
-    map<string, string> action_postinstall_attrs;
-    string updatecheck_status;
     Optional<string> cohort;
     Optional<string> cohorthint;
     Optional<string> cohortname;
 
+    struct Url {
+      string codebase;
+    };
+    vector<Url> urls;
+
+    struct Manifest {
+      string version;
+    } manifest;
+
+    struct UpdateCheck {
+      string status;
+      string poll_interval;
+      string eol_date;
+      string rollback;
+      string firmware_version;
+      string kernel_version;
+      string past_firmware_version;
+      string past_kernel_version;
+    } updatecheck;
+
+    struct PostInstallAction {
+      vector<string> is_delta_payloads;
+      vector<string> metadata_signature_rsas;
+      vector<string> metadata_sizes;
+      string max_days_to_scatter;
+      string no_update;
+      string more_info_url;
+      string prompt;
+      string deadline;
+      string disable_p2p_for_downloading;
+      string disable_p2p_for_sharing;
+      string public_key_rsa;
+      string max_failure_count_per_url;
+      string disable_payload_backoff;
+      string powerwash_required;
+    };
+    Optional<PostInstallAction> postinstall_action;
+
     struct Package {
       string name;
       string size;
       string hash;
+      string fp;
     };
     vector<Package> packages;
   };
@@ -178,52 +220,75 @@
     }
   }
 
-  if (data->current_path == "/response/app") {
-    OmahaParserData::App app;
-    if (attrs.find(kAttrAppId) != attrs.end())
-      app.id = attrs[kAttrAppId];
+  if (data->current_path == "/response/daystart") {
+    data->daystart = {
+        .elapsed_days = attrs[kAttrElapsedDays],
+        .elapsed_seconds = attrs[kAttrElapsedSeconds],
+    };
+  } else if (data->current_path == "/response/app") {
+    data->apps.push_back({.id = attrs[kAttrAppId]});
     if (attrs.find(kAttrCohort) != attrs.end())
-      app.cohort = attrs[kAttrCohort];
+      data->apps.back().cohort = attrs[kAttrCohort];
     if (attrs.find(kAttrCohortHint) != attrs.end())
-      app.cohorthint = attrs[kAttrCohortHint];
+      data->apps.back().cohorthint = attrs[kAttrCohortHint];
     if (attrs.find(kAttrCohortName) != attrs.end())
-      app.cohortname = attrs[kAttrCohortName];
-    data->apps.push_back(std::move(app));
+      data->apps.back().cohortname = attrs[kAttrCohortName];
   } else if (data->current_path == "/response/app/updatecheck") {
-    if (!data->apps.empty())
-      data->apps.back().updatecheck_status = attrs[kAttrStatus];
-    if (data->updatecheck_poll_interval.empty())
-      data->updatecheck_poll_interval = attrs[kAttrPollInterval];
-    // Omaha sends arbitrary key-value pairs as extra attributes starting with
-    // an underscore.
-    for (const auto& attr : attrs) {
-      if (!attr.first.empty() && attr.first[0] == '_')
-        data->updatecheck_attrs[attr.first.substr(1)] = attr.second;
-    }
-  } else if (data->current_path == "/response/daystart") {
-    // Get the install-date.
-    data->daystart_elapsed_days = attrs[kAttrElapsedDays];
-    data->daystart_elapsed_seconds = attrs[kAttrElapsedSeconds];
+    data->apps.back().updatecheck = {
+        .status = attrs[kAttrStatus],
+        .poll_interval = attrs[kAttrPollInterval],
+        .eol_date = attrs[kAttrEolDate],
+        .rollback = attrs[kAttrRollback],
+        .firmware_version = attrs[kAttrFirmwareVersion],
+        .kernel_version = attrs[kAttrKernelVersion],
+        .past_firmware_version = attrs[base::StringPrintf(
+            "%s_%i", kAttrFirmwareVersion, data->rollback_allowed_milestones)],
+        .past_kernel_version = attrs[base::StringPrintf(
+            "%s_%i", kAttrKernelVersion, data->rollback_allowed_milestones)],
+    };
   } else if (data->current_path == "/response/app/updatecheck/urls/url") {
-    // Look at all <url> elements.
-    if (!data->apps.empty())
-      data->apps.back().url_codebase.push_back(attrs[kAttrCodeBase]);
+    data->apps.back().urls.push_back({.codebase = attrs[kAttrCodeBase]});
   } else if (data->current_path ==
              "/response/app/updatecheck/manifest/packages/package") {
-    // Look at all <package> elements.
-    if (!data->apps.empty())
-      data->apps.back().packages.push_back({.name = attrs[kAttrName],
-                                            .size = attrs[kAttrSize],
-                                            .hash = attrs[kAttrHashSha256]});
+    data->apps.back().packages.push_back({
+        .name = attrs[kAttrName],
+        .size = attrs[kAttrSize],
+        .hash = attrs[kAttrHashSha256],
+        .fp = attrs[kAttrFp],
+    });
   } else if (data->current_path == "/response/app/updatecheck/manifest") {
-    // Get the version.
-    if (!data->apps.empty())
-      data->apps.back().manifest_version = attrs[kAttrVersion];
+    data->apps.back().manifest.version = attrs[kAttrVersion];
   } else if (data->current_path ==
              "/response/app/updatecheck/manifest/actions/action") {
     // We only care about the postinstall action.
-    if (attrs[kAttrEvent] == kValPostInstall && !data->apps.empty()) {
-      data->apps.back().action_postinstall_attrs = std::move(attrs);
+    if (attrs[kAttrEvent] == kValPostInstall) {
+      OmahaParserData::App::PostInstallAction action = {
+          .is_delta_payloads = base::SplitString(attrs[kAttrIsDeltaPayload],
+                                                 ":",
+                                                 base::TRIM_WHITESPACE,
+                                                 base::SPLIT_WANT_ALL),
+          .metadata_signature_rsas =
+              base::SplitString(attrs[kAttrMetadataSignatureRsa],
+                                ":",
+                                base::TRIM_WHITESPACE,
+                                base::SPLIT_WANT_ALL),
+          .metadata_sizes = base::SplitString(attrs[kAttrMetadataSize],
+                                              ":",
+                                              base::TRIM_WHITESPACE,
+                                              base::SPLIT_WANT_ALL),
+          .max_days_to_scatter = attrs[kAttrMaxDaysToScatter],
+          .no_update = attrs[kAttrNoUpdate],
+          .more_info_url = attrs[kAttrMoreInfo],
+          .prompt = attrs[kAttrPrompt],
+          .deadline = attrs[kAttrDeadline],
+          .disable_p2p_for_downloading = attrs[kAttrDisableP2PForDownloading],
+          .disable_p2p_for_sharing = attrs[kAttrDisableP2PForSharing],
+          .public_key_rsa = attrs[kAttrPublicKeyRsa],
+          .max_failure_count_per_url = attrs[kAttrMaxFailureCountPerUrl],
+          .disable_payload_backoff = attrs[kAttrDisablePayloadBackoff],
+          .powerwash_required = attrs[kAttrPowerwash],
+      };
+      data->apps.back().postinstall_action = std::move(action);
     }
   }
 }
@@ -272,14 +337,11 @@
 }  // namespace
 
 OmahaRequestAction::OmahaRequestAction(
-    SystemState* system_state,
     OmahaEvent* event,
     std::unique_ptr<HttpFetcher> http_fetcher,
     bool ping_only,
     const string& session_id)
-    : system_state_(system_state),
-      params_(system_state->request_params()),
-      event_(event),
+    : event_(event),
       http_fetcher_(std::move(http_fetcher)),
       policy_provider_(std::make_unique<policy::PolicyProvider>()),
       ping_only_(ping_only),
@@ -295,7 +357,8 @@
 int OmahaRequestAction::CalculatePingDays(const string& key) {
   int days = kPingNeverPinged;
   int64_t last_ping = 0;
-  if (system_state_->prefs()->GetInt64(key, &last_ping) && last_ping >= 0) {
+  if (SystemState::Get()->prefs()->GetInt64(key, &last_ping) &&
+      last_ping >= 0) {
     days = (Time::Now() - Time::FromInternalValue(last_ping)).InDays();
     if (days < 0) {
       // If |days| is negative, then the system clock must have jumped
@@ -326,15 +389,15 @@
 bool OmahaRequestAction::ShouldPing() const {
   if (ping_active_days_ == kPingNeverPinged &&
       ping_roll_call_days_ == kPingNeverPinged) {
-    int powerwash_count = system_state_->hardware()->GetPowerwashCount();
+    int powerwash_count = SystemState::Get()->hardware()->GetPowerwashCount();
     if (powerwash_count > 0) {
       LOG(INFO) << "Not sending ping with a=-1 r=-1 to omaha because "
                 << "powerwash_count is " << powerwash_count;
       return false;
     }
-    if (system_state_->hardware()->GetFirstActiveOmahaPingSent()) {
+    if (SystemState::Get()->hardware()->GetFirstActiveOmahaPingSent()) {
       LOG(INFO) << "Not sending ping with a=-1 r=-1 to omaha because "
-                << "the first_active_omaha_ping_sent is true";
+                << "the first_active_omaha_ping_sent is true.";
       return false;
     }
     return true;
@@ -343,11 +406,8 @@
 }
 
 // static
-int OmahaRequestAction::GetInstallDate(SystemState* system_state) {
-  PrefsInterface* prefs = system_state->prefs();
-  if (prefs == nullptr)
-    return -1;
-
+int OmahaRequestAction::GetInstallDate() {
+  auto* prefs = SystemState::Get()->prefs();
   // If we have the value stored on disk, just return it.
   int64_t stored_value;
   if (prefs->GetInt64(kPrefsInstallDateDays, &stored_value)) {
@@ -380,8 +440,8 @@
   // inspecting the timestamp of when OOBE happened.
 
   Time time_of_oobe;
-  if (!system_state->hardware()->IsOOBEEnabled() ||
-      !system_state->hardware()->IsOOBEComplete(&time_of_oobe)) {
+  if (!SystemState::Get()->hardware()->IsOOBEEnabled() ||
+      !SystemState::Get()->hardware()->IsOOBEComplete(&time_of_oobe)) {
     LOG(INFO) << "Not generating Omaha InstallData as we have "
               << "no prefs file and OOBE is not complete or not enabled.";
     return -1;
@@ -396,21 +456,22 @@
   }
 
   // Persist this to disk, for future use.
-  if (!OmahaRequestAction::PersistInstallDate(
-          system_state, num_days, kProvisionedFromOOBEMarker))
+  if (!OmahaRequestAction::PersistInstallDate(num_days,
+                                              kProvisionedFromOOBEMarker))
     return -1;
 
   LOG(INFO) << "Set the Omaha InstallDate from OOBE time-stamp to " << num_days
-            << " days";
+            << " days.";
 
   return num_days;
 }
 
 void OmahaRequestAction::StorePingReply(
     const OmahaParserData& parser_data) const {
+  const auto* params = SystemState::Get()->request_params();
   for (const auto& app : parser_data.apps) {
-    auto it = params_->dlc_apps_params().find(app.id);
-    if (it == params_->dlc_apps_params().end())
+    auto it = params->dlc_apps_params().find(app.id);
+    if (it == params->dlc_apps_params().end())
       continue;
 
     const OmahaRequestParams::AppParams& dlc_params = it->second;
@@ -419,7 +480,7 @@
     if (!dlc_params.send_ping)
       continue;
 
-    PrefsInterface* prefs = system_state_->prefs();
+    auto* prefs = SystemState::Get()->prefs();
     // Reset the active metadata value to |kPingInactiveValue|.
     auto active_key =
         prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
@@ -429,7 +490,7 @@
 
     auto last_rollcall_key =
         prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingLastRollcall});
-    if (!prefs->SetString(last_rollcall_key, parser_data.daystart_elapsed_days))
+    if (!prefs->SetString(last_rollcall_key, parser_data.daystart.elapsed_days))
       LOG(ERROR) << "Failed to set the value of ping metadata '"
                  << last_rollcall_key << "'.";
 
@@ -438,7 +499,7 @@
       // the previous ping was an active one.
       auto last_active_key =
           prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingLastActive});
-      if (!prefs->SetString(last_active_key, parser_data.daystart_elapsed_days))
+      if (!prefs->SetString(last_active_key, parser_data.daystart.elapsed_days))
         LOG(ERROR) << "Failed to set the value of ping metadata '"
                    << last_active_key << "'.";
     }
@@ -454,20 +515,19 @@
   }
 
   OmahaRequestBuilderXml omaha_request(event_.get(),
-                                       params_,
                                        ping_only_,
                                        ShouldPing(),  // include_ping
                                        ping_active_days_,
                                        ping_roll_call_days_,
-                                       GetInstallDate(system_state_),
-                                       system_state_->prefs(),
+                                       GetInstallDate(),
                                        session_id_);
   string request_post = omaha_request.GetRequest();
 
   // Set X-Goog-Update headers.
+  const auto* params = SystemState::Get()->request_params();
   http_fetcher_->SetHeader(kXGoogleUpdateInteractivity,
-                           params_->interactive() ? "fg" : "bg");
-  http_fetcher_->SetHeader(kXGoogleUpdateAppId, params_->GetAppId());
+                           params->interactive() ? "fg" : "bg");
+  http_fetcher_->SetHeader(kXGoogleUpdateAppId, params->GetAppId());
   http_fetcher_->SetHeader(
       kXGoogleUpdateUpdater,
       base::StringPrintf(
@@ -475,9 +535,9 @@
 
   http_fetcher_->SetPostData(
       request_post.data(), request_post.size(), kHttpContentTypeTextXml);
-  LOG(INFO) << "Posting an Omaha request to " << params_->update_url();
+  LOG(INFO) << "Posting an Omaha request to " << params->update_url();
   LOG(INFO) << "Request: " << request_post;
-  http_fetcher_->BeginTransfer(params_->update_url());
+  http_fetcher_->BeginTransfer(params->update_url());
 }
 
 void OmahaRequestAction::TerminateProcessing() {
@@ -516,14 +576,15 @@
 
 // Update the last ping day preferences based on the server daystart
 // response. Returns true on success, false otherwise.
-bool UpdateLastPingDays(OmahaParserData* parser_data, PrefsInterface* prefs) {
+bool UpdateLastPingDays(OmahaParserData* parser_data) {
   int64_t elapsed_seconds = 0;
   TEST_AND_RETURN_FALSE(base::StringToInt64(
-      parser_data->daystart_elapsed_seconds, &elapsed_seconds));
+      parser_data->daystart.elapsed_seconds, &elapsed_seconds));
   TEST_AND_RETURN_FALSE(elapsed_seconds >= 0);
 
   // Remember the local time that matches the server's last midnight
   // time.
+  auto* prefs = SystemState::Get()->prefs();
   Time daystart = Time::Now() - TimeDelta::FromSeconds(elapsed_seconds);
   prefs->SetInt64(kPrefsLastActivePingDay, daystart.ToInternalValue());
   prefs->SetInt64(kPrefsLastRollCallPingDay, daystart.ToInternalValue());
@@ -537,8 +598,8 @@
                   OmahaResponse* output_object,
                   bool can_exclude,
                   ScopedActionCompleter* completer) {
-  if (app->updatecheck_status.empty() ||
-      app->updatecheck_status == kValNoUpdate) {
+  if (app->updatecheck.status.empty() ||
+      app->updatecheck.status == kValNoUpdate) {
     if (!app->packages.empty()) {
       LOG(ERROR) << "No update in this <app> but <package> is not empty.";
       completer->set_code(ErrorCode::kOmahaResponseInvalid);
@@ -547,81 +608,62 @@
     return true;
   }
   if (app->packages.empty()) {
-    LOG(ERROR) << "Omaha Response has no packages";
+    LOG(ERROR) << "Omaha Response has no packages.";
     completer->set_code(ErrorCode::kOmahaResponseInvalid);
     return false;
   }
-  if (app->url_codebase.empty()) {
-    LOG(ERROR) << "No Omaha Response URLs";
+  if (app->urls.empty()) {
+    LOG(ERROR) << "No Omaha Response URLs.";
     completer->set_code(ErrorCode::kOmahaResponseInvalid);
     return false;
   }
-  LOG(INFO) << "Found " << app->url_codebase.size() << " url(s)";
-  vector<string> metadata_sizes =
-      base::SplitString(app->action_postinstall_attrs[kAttrMetadataSize],
-                        ":",
-                        base::TRIM_WHITESPACE,
-                        base::SPLIT_WANT_ALL);
-  vector<string> metadata_signatures = base::SplitString(
-      app->action_postinstall_attrs[kAttrMetadataSignatureRsa],
-      ":",
-      base::TRIM_WHITESPACE,
-      base::SPLIT_WANT_ALL);
-  vector<string> is_delta_payloads =
-      base::SplitString(app->action_postinstall_attrs[kAttrIsDeltaPayload],
-                        ":",
-                        base::TRIM_WHITESPACE,
-                        base::SPLIT_WANT_ALL);
   for (size_t i = 0; i < app->packages.size(); i++) {
     const auto& package = app->packages[i];
     if (package.name.empty()) {
-      LOG(ERROR) << "Omaha Response has empty package name";
+      LOG(ERROR) << "Omaha Response has empty package name.";
       completer->set_code(ErrorCode::kOmahaResponseInvalid);
       return false;
     }
-    LOG(INFO) << "Found package " << package.name;
 
     OmahaResponse::Package out_package;
     out_package.app_id = app->id;
     out_package.can_exclude = can_exclude;
-    for (const string& codebase : app->url_codebase) {
-      if (codebase.empty()) {
-        LOG(ERROR) << "Omaha Response URL has empty codebase";
+    for (const auto& url : app->urls) {
+      if (url.codebase.empty()) {
+        LOG(ERROR) << "Omaha Response URL has empty codebase.";
         completer->set_code(ErrorCode::kOmahaResponseInvalid);
         return false;
       }
-      out_package.payload_urls.push_back(codebase + package.name);
+      out_package.payload_urls.push_back(url.codebase + package.name);
     }
-    // Parse the payload size.
+
     base::StringToUint64(package.size, &out_package.size);
     if (out_package.size <= 0) {
       LOG(ERROR) << "Omaha Response has invalid payload size: " << package.size;
       completer->set_code(ErrorCode::kOmahaResponseInvalid);
       return false;
     }
-    LOG(INFO) << "Payload size = " << out_package.size << " bytes";
 
-    if (i < metadata_sizes.size())
-      base::StringToUint64(metadata_sizes[i], &out_package.metadata_size);
-    LOG(INFO) << "Payload metadata size = " << out_package.metadata_size
-              << " bytes";
+    if (i < app->postinstall_action->metadata_sizes.size())
+      base::StringToUint64(app->postinstall_action->metadata_sizes[i],
+                           &out_package.metadata_size);
 
-    if (i < metadata_signatures.size())
-      out_package.metadata_signature = metadata_signatures[i];
-    LOG(INFO) << "Payload metadata signature = "
-              << out_package.metadata_signature;
+    if (i < app->postinstall_action->metadata_signature_rsas.size())
+      out_package.metadata_signature =
+          app->postinstall_action->metadata_signature_rsas[i];
 
     out_package.hash = package.hash;
     if (out_package.hash.empty()) {
-      LOG(ERROR) << "Omaha Response has empty hash_sha256 value";
+      LOG(ERROR) << "Omaha Response has empty hash_sha256 value.";
       completer->set_code(ErrorCode::kOmahaResponseInvalid);
       return false;
     }
-    LOG(INFO) << "Payload hash = " << out_package.hash;
 
-    if (i < is_delta_payloads.size())
-      out_package.is_delta = ParseBool(is_delta_payloads[i]);
-    LOG(INFO) << "Payload is delta = " << utils::ToString(out_package.is_delta);
+    out_package.fp = package.fp;
+
+    if (i < app->postinstall_action->is_delta_payloads.size())
+      out_package.is_delta =
+          ParseBool(app->postinstall_action->is_delta_payloads[i]);
 
     output_object->packages.push_back(std::move(out_package));
   }
@@ -671,36 +713,23 @@
 
 // Parses the 2 key version strings kernel_version and firmware_version. If the
 // field is not present, or cannot be parsed the values default to 0xffff.
-void ParseRollbackVersions(int allowed_milestones,
-                           OmahaParserData* parser_data,
+void ParseRollbackVersions(const OmahaParserData::App& platform_app,
+                           int allowed_milestones,
                            OmahaResponse* output_object) {
+  // Defaults to false if attribute is not present.
+  output_object->is_rollback = ParseBool(platform_app.updatecheck.rollback);
+
   utils::ParseRollbackKeyVersion(
-      parser_data->updatecheck_attrs[kAttrFirmwareVersion],
+      platform_app.updatecheck.firmware_version,
       &output_object->rollback_key_version.firmware_key,
       &output_object->rollback_key_version.firmware);
   utils::ParseRollbackKeyVersion(
-      parser_data->updatecheck_attrs[kAttrKernelVersion],
+      platform_app.updatecheck.kernel_version,
       &output_object->rollback_key_version.kernel_key,
       &output_object->rollback_key_version.kernel);
 
-  // Create the attribute name strings for milestone N - allowed_milestones.
-  const string firmware_max_rollforward_attr =
-      base::StringPrintf("%s_%i", kAttrFirmwareVersion, allowed_milestones);
-  const string kernel_max_rollforward_attr =
-      base::StringPrintf("%s_%i", kAttrKernelVersion, allowed_milestones);
-
-  const bool max_firmware_and_kernel_exist =
-      parser_data->updatecheck_attrs.count(firmware_max_rollforward_attr) > 0 &&
-      parser_data->updatecheck_attrs.count(kernel_max_rollforward_attr) > 0;
-
-  string firmware_version;
-  string kernel_version;
-  if (max_firmware_and_kernel_exist) {
-    firmware_version =
-        parser_data->updatecheck_attrs[firmware_max_rollforward_attr];
-    kernel_version =
-        parser_data->updatecheck_attrs[kernel_max_rollforward_attr];
-  }
+  string firmware_version = platform_app.updatecheck.past_firmware_version;
+  string kernel_version = platform_app.updatecheck.past_kernel_version;
 
   LOG(INFO) << "For milestone N-" << allowed_milestones
             << " firmware_key_version=" << firmware_version
@@ -715,6 +744,16 @@
   output_object->past_rollback_key_version = std::move(version);
 }
 
+void PersistEolInfo(const OmahaParserData::App& platform_app) {
+  // If EOL date attribute is not sent, don't delete the old persisted EOL
+  // date information.
+  if (!platform_app.updatecheck.eol_date.empty() &&
+      !SystemState::Get()->prefs()->SetString(
+          kPrefsOmahaEolDate, platform_app.updatecheck.eol_date)) {
+    LOG(ERROR) << "Setting EOL date failed.";
+  }
+}
+
 }  // namespace
 
 bool OmahaRequestAction::ParseResponse(OmahaParserData* parser_data,
@@ -724,68 +763,63 @@
     completer->set_code(ErrorCode::kOmahaResponseInvalid);
     return false;
   }
-  LOG(INFO) << "Found " << parser_data->apps.size() << " <app>.";
 
-  // chromium-os:37289: The PollInterval is not supported by Omaha server
-  // currently.  But still keeping this existing code in case we ever decide to
-  // slow down the request rate from the server-side. Note that the PollInterval
-  // is not persisted, so it has to be sent by the server on every response to
-  // guarantee that the scheduler uses this value (otherwise, if the device got
-  // rebooted after the last server-indicated value, it'll revert to the default
-  // value). Also kDefaultMaxUpdateChecks value for the scattering logic is
-  // based on the assumption that we perform an update check every hour so that
-  // the max value of 8 will roughly be equivalent to one work day. If we decide
-  // to use PollInterval permanently, we should update the
-  // max_update_checks_allowed to take PollInterval into account.  Note: The
-  // parsing for PollInterval happens even before parsing of the status because
-  // we may want to specify the PollInterval even when there's no update.
-  base::StringToInt(parser_data->updatecheck_poll_interval,
-                    &output_object->poll_interval);
+  // Locate the platform App since it's an important one that has specific
+  // information attached to it that may not be available from other Apps.
+  const auto* params = SystemState::Get()->request_params();
+  auto platform_app = std::find_if(parser_data->apps.begin(),
+                                   parser_data->apps.end(),
+                                   [&params](const OmahaParserData::App& app) {
+                                     return app.id == params->GetAppId();
+                                   });
+  if (platform_app == parser_data->apps.end()) {
+    LOG(WARNING) << "Platform App is missing.";
+  } else {
+    // chromium-os:37289: The PollInterval is not supported by Omaha server
+    // currently.  But still keeping this existing code in case we ever decide
+    // to slow down the request rate from the server-side. Note that the
+    // PollInterval is not persisted, so it has to be sent by the server on
+    // every response to guarantee that the scheduler uses this value
+    // (otherwise, if the device got rebooted after the last server-indicated
+    // value, it'll revert to the default value). Also kDefaultMaxUpdateChecks
+    // value for the scattering logic is based on the assumption that we perform
+    // an update check every hour so that the max value of 8 will roughly be
+    // equivalent to one work day. If we decide to use PollInterval permanently,
+    // we should update the max_update_checks_allowed to take PollInterval into
+    // account.  Note: The parsing for PollInterval happens even before parsing
+    // of the status because we may want to specify the PollInterval even when
+    // there's no update.
+    base::StringToInt(platform_app->updatecheck.poll_interval,
+                      &output_object->poll_interval);
+
+    PersistEolInfo(*platform_app);
+
+    // Parses the rollback versions of the current image. If the fields do not
+    // exist they default to 0xffff for the 4 key versions.
+    ParseRollbackVersions(
+        *platform_app, params->rollback_allowed_milestones(), output_object);
+  }
 
   // Check for the "elapsed_days" attribute in the "daystart"
   // element. This is the number of days since Jan 1 2007, 0:00
   // PST. If we don't have a persisted value of the Omaha InstallDate,
   // we'll use it to calculate it and then persist it.
-  if (ParseInstallDate(parser_data, output_object) &&
-      !HasInstallDate(system_state_)) {
+  if (ParseInstallDate(parser_data, output_object) && !HasInstallDate()) {
     // Since output_object->install_date_days is never negative, the
     // elapsed_days -> install-date calculation is reduced to simply
     // rounding down to the nearest number divisible by 7.
     int remainder = output_object->install_date_days % 7;
     int install_date_days_rounded =
         output_object->install_date_days - remainder;
-    if (PersistInstallDate(system_state_,
-                           install_date_days_rounded,
+    if (PersistInstallDate(install_date_days_rounded,
                            kProvisionedFromOmahaResponse)) {
       LOG(INFO) << "Set the Omaha InstallDate from Omaha Response to "
-                << install_date_days_rounded << " days";
+                << install_date_days_rounded << " days.";
     }
   }
 
   // We persist the cohorts sent by omaha even if the status is "noupdate".
-  for (const auto& app : parser_data->apps) {
-    if (app.id == params_->GetAppId()) {
-      if (app.cohort)
-        PersistCohortData(kPrefsOmahaCohort, app.cohort.value());
-      if (app.cohorthint)
-        PersistCohortData(kPrefsOmahaCohortHint, app.cohorthint.value());
-      if (app.cohortname)
-        PersistCohortData(kPrefsOmahaCohortName, app.cohortname.value());
-      break;
-    }
-  }
-
-  PersistEolInfo(parser_data->updatecheck_attrs);
-
-  // Rollback-related updatecheck attributes.
-  // Defaults to false if attribute is not present.
-  output_object->is_rollback =
-      ParseBool(parser_data->updatecheck_attrs[kAttrRollback]);
-
-  // Parses the rollback versions of the current image. If the fields do not
-  // exist they default to 0xffff for the 4 key versions.
-  ParseRollbackVersions(
-      params_->rollback_allowed_milestones(), parser_data, output_object);
+  PersistCohorts(*parser_data);
 
   if (!ParseStatus(parser_data, output_object, completer))
     return false;
@@ -800,7 +834,7 @@
     // non-critical package installations, let the errors propagate instead
     // of being handled inside update_engine as installations are a dlcservice
     // specific feature.
-    bool can_exclude = !params_->is_install() && params_->IsDlcAppId(app.id);
+    bool can_exclude = !params->is_install() && params->IsDlcAppId(app.id);
     if (!ParsePackage(&app, output_object, can_exclude, completer))
       return false;
   }
@@ -812,37 +846,34 @@
                                      OmahaResponse* output_object,
                                      ScopedActionCompleter* completer) {
   output_object->update_exists = false;
+  auto* params = SystemState::Get()->request_params();
   for (const auto& app : parser_data->apps) {
-    const string& status = app.updatecheck_status;
+    const string& status = app.updatecheck.status;
     if (status == kValNoUpdate) {
       // If the app is a DLC, allow status "noupdate" to support DLC
       // deprecations.
-      if (params_->IsDlcAppId(app.id)) {
-        LOG(INFO) << "No update for <app> " << app.id
+      if (params->IsDlcAppId(app.id)) {
+        LOG(INFO) << "No update for App " << app.id
                   << " but update continuing since a DLC.";
-        params_->SetDlcNoUpdate(app.id);
+        params->SetDlcNoUpdate(app.id);
         continue;
       }
       // Don't update if any app has status="noupdate".
-      LOG(INFO) << "No update for <app> " << app.id;
+      LOG(INFO) << "No update for App " << app.id;
       output_object->update_exists = false;
       break;
     } else if (status == "ok") {
-      auto const& attr_no_update =
-          app.action_postinstall_attrs.find(kAttrNoUpdate);
-      if (attr_no_update != app.action_postinstall_attrs.end() &&
-          attr_no_update->second == "true") {
+      if (ParseBool(app.postinstall_action->no_update)) {
         // noupdate="true" in postinstall attributes means it's an update to
         // self, only update if there's at least one app really have update.
-        LOG(INFO) << "Update to self for <app> " << app.id;
+        LOG(INFO) << "Update to self for App " << app.id;
       } else {
-        LOG(INFO) << "Update for <app> " << app.id;
         output_object->update_exists = true;
       }
-    } else if (status.empty() && params_->is_install() &&
-               params_->GetAppId() == app.id) {
+    } else if (status.empty() && params->is_install() &&
+               params->GetAppId() == app.id) {
       // Skips the platform app for install operation.
-      LOG(INFO) << "No payload (and ignore) for <app> " << app.id;
+      LOG(INFO) << "No payload (and ignore) for App " << app.id;
     } else {
       LOG(ERROR) << "Unknown Omaha response status: " << status;
       completer->set_code(ErrorCode::kOmahaResponseInvalid);
@@ -860,59 +891,58 @@
 bool OmahaRequestAction::ParseParams(OmahaParserData* parser_data,
                                      OmahaResponse* output_object,
                                      ScopedActionCompleter* completer) {
-  map<string, string> attrs;
-  for (auto& app : parser_data->apps) {
-    if (app.id == params_->GetAppId()) {
-      // this is the app (potentially the only app)
-      output_object->version = app.manifest_version;
-    } else if (params_->is_install() &&
-               app.manifest_version != params_->app_version()) {
-      LOG(WARNING) << "An app has a different version (" << app.manifest_version
-                   << ") that is different than platform app version ("
-                   << params_->app_version() << ")";
+  const auto* params = SystemState::Get()->request_params();
+  const OmahaParserData::App* main_app = nullptr;
+  for (const auto& app : parser_data->apps) {
+    if (app.id == params->GetAppId() && app.postinstall_action) {
+      main_app = &app;
+    } else if (params->is_install()) {
+      if (app.manifest.version != params->app_version()) {
+        LOG(WARNING) << "An app has a version: " << app.manifest.version
+                     << " that is different than platform app version: "
+                     << params->app_version();
+      }
     }
-    if (!app.action_postinstall_attrs.empty() && attrs.empty()) {
-      attrs = app.action_postinstall_attrs;
+    if (app.postinstall_action && main_app == nullptr) {
+      main_app = &app;
     }
   }
-  if (params_->is_install()) {
-    LOG(INFO) << "Use request version for Install operation.";
-    output_object->version = params_->app_version();
+
+  if (main_app == nullptr) {
+    LOG(ERROR) << "Omaha Response has no postinstall event action.";
+    completer->set_code(ErrorCode::kOmahaResponseInvalid);
+    return false;
   }
+
+  const OmahaParserData::App& app = *main_app;
+  // Get the optional properties one by one.
+  output_object->version = app.manifest.version;
+  output_object->more_info_url = app.postinstall_action->more_info_url;
+  output_object->prompt = ParseBool(app.postinstall_action->prompt);
+  output_object->deadline = app.postinstall_action->deadline;
+  output_object->max_days_to_scatter =
+      ParseInt(app.postinstall_action->max_days_to_scatter);
+  output_object->disable_p2p_for_downloading =
+      ParseBool(app.postinstall_action->disable_p2p_for_downloading);
+  output_object->disable_p2p_for_sharing =
+      ParseBool(app.postinstall_action->disable_p2p_for_sharing);
+  output_object->public_key_rsa = app.postinstall_action->public_key_rsa;
+
+  if (!base::StringToUint(app.postinstall_action->max_failure_count_per_url,
+                          &output_object->max_failure_count_per_url))
+    output_object->max_failure_count_per_url = kDefaultMaxFailureCountPerUrl;
+
+  output_object->disable_payload_backoff =
+      ParseBool(app.postinstall_action->disable_payload_backoff);
+  output_object->powerwash_required =
+      ParseBool(app.postinstall_action->powerwash_required);
+
   if (output_object->version.empty()) {
     LOG(ERROR) << "Omaha Response does not have version in manifest!";
     completer->set_code(ErrorCode::kOmahaResponseInvalid);
     return false;
   }
 
-  LOG(INFO) << "Received omaha response to update to version "
-            << output_object->version;
-
-  if (attrs.empty()) {
-    LOG(ERROR) << "Omaha Response has no postinstall event action";
-    completer->set_code(ErrorCode::kOmahaResponseInvalid);
-    return false;
-  }
-
-  // Get the optional properties one by one.
-  output_object->more_info_url = attrs[kAttrMoreInfo];
-  output_object->prompt = ParseBool(attrs[kAttrPrompt]);
-  output_object->deadline = attrs[kAttrDeadline];
-  output_object->max_days_to_scatter = ParseInt(attrs[kAttrMaxDaysToScatter]);
-  output_object->disable_p2p_for_downloading =
-      ParseBool(attrs[kAttrDisableP2PForDownloading]);
-  output_object->disable_p2p_for_sharing =
-      ParseBool(attrs[kAttrDisableP2PForSharing]);
-  output_object->public_key_rsa = attrs[kAttrPublicKeyRsa];
-
-  string max = attrs[kAttrMaxFailureCountPerUrl];
-  if (!base::StringToUint(max, &output_object->max_failure_count_per_url))
-    output_object->max_failure_count_per_url = kDefaultMaxFailureCountPerUrl;
-
-  output_object->disable_payload_backoff =
-      ParseBool(attrs[kAttrDisablePayloadBackoff]);
-  output_object->powerwash_required = ParseBool(attrs[kAttrPowerwash]);
-
   return true;
 }
 
@@ -925,7 +955,8 @@
   string current_response(response_buffer_.begin(), response_buffer_.end());
   LOG(INFO) << "Omaha request response: " << current_response;
 
-  PayloadStateInterface* const payload_state = system_state_->payload_state();
+  PayloadStateInterface* const payload_state =
+      SystemState::Get()->payload_state();
 
   // Set the max kernel key version based on whether rollback is allowed.
   SetMaxKernelKeyVersionForRollback();
@@ -941,8 +972,7 @@
   if (aux_error_code != ErrorCode::kSuccess) {
     metrics::DownloadErrorCode download_error_code =
         metrics_utils::GetDownloadErrorCode(aux_error_code);
-    system_state_->metrics_reporter()->ReportUpdateCheckMetrics(
-        system_state_,
+    SystemState::Get()->metrics_reporter()->ReportUpdateCheckMetrics(
         metrics::CheckResult::kUnset,
         metrics::CheckReaction::kUnset,
         download_error_code);
@@ -963,7 +993,9 @@
   }
 
   XML_Parser parser = XML_ParserCreate(nullptr);
-  OmahaParserData parser_data(parser);
+  OmahaParserData parser_data(
+      parser,
+      SystemState::Get()->request_params()->rollback_allowed_milestones());
   XML_SetUserData(parser, &parser_data);
   XML_SetElementHandler(parser, ParserHandlerStart, ParserHandlerEnd);
   XML_SetEntityDeclHandler(parser, ParserHandlerEntityDecl);
@@ -993,7 +1025,7 @@
   // Update the last ping day preferences based on the server daystart response
   // even if we didn't send a ping. Omaha always includes the daystart in the
   // response, but log the error if it didn't.
-  LOG_IF(ERROR, !UpdateLastPingDays(&parser_data, system_state_->prefs()))
+  LOG_IF(ERROR, !UpdateLastPingDays(&parser_data))
       << "Failed to update the last ping day preferences!";
 
   // Sets first_active_omaha_ping_sent to true (vpd in CrOS). We only do this if
@@ -1002,9 +1034,9 @@
   // need to check if a=-1 has been sent because older devices have already sent
   // their a=-1 in the past and we have to set first_active_omaha_ping_sent for
   // future checks.
-  if (!system_state_->hardware()->GetFirstActiveOmahaPingSent()) {
-    if (!system_state_->hardware()->SetFirstActiveOmahaPingSent()) {
-      system_state_->metrics_reporter()->ReportInternalErrorCode(
+  if (!SystemState::Get()->hardware()->GetFirstActiveOmahaPingSent()) {
+    if (!SystemState::Get()->hardware()->SetFirstActiveOmahaPingSent()) {
+      SystemState::Get()->metrics_reporter()->ReportInternalErrorCode(
           ErrorCode::kFirstActiveOmahaPingSentPersistenceError);
     }
   }
@@ -1023,8 +1055,8 @@
   if (!ParseResponse(&parser_data, &output_object, &completer))
     return;
   ProcessExclusions(&output_object,
-                    system_state_->request_params(),
-                    system_state_->update_attempter()->GetExcluder());
+                    SystemState::Get()->request_params(),
+                    SystemState::Get()->update_attempter()->GetExcluder());
   output_object.update_exists = true;
   SetOutputObject(output_object);
 
@@ -1088,7 +1120,7 @@
 void OmahaRequestAction::CompleteProcessing() {
   ScopedActionCompleter completer(processor_, this);
   OmahaResponse& output_object = const_cast<OmahaResponse&>(GetOutputObject());
-  PayloadStateInterface* payload_state = system_state_->payload_state();
+  PayloadStateInterface* payload_state = SystemState::Get()->payload_state();
 
   if (ShouldDeferDownload(&output_object)) {
     output_object.update_exists = false;
@@ -1100,7 +1132,7 @@
   if (payload_state->ShouldBackoffDownload()) {
     output_object.update_exists = false;
     LOG(INFO) << "Ignoring Omaha updates in order to backoff our retry "
-              << "attempts";
+              << "attempts.";
     completer.set_code(ErrorCode::kOmahaUpdateDeferredForBackoff);
     return;
   }
@@ -1110,11 +1142,11 @@
 void OmahaRequestAction::OnLookupPayloadViaP2PCompleted(const string& url) {
   LOG(INFO) << "Lookup complete, p2p-client returned URL '" << url << "'";
   if (!url.empty()) {
-    system_state_->payload_state()->SetP2PUrl(url);
+    SystemState::Get()->payload_state()->SetP2PUrl(url);
   } else {
     LOG(INFO) << "Forcibly disabling use of p2p for downloading "
               << "because no suitable peer could be found.";
-    system_state_->payload_state()->SetUsingP2PForDownloading(false);
+    SystemState::Get()->payload_state()->SetUsingP2PForDownloading(false);
   }
   CompleteProcessing();
 }
@@ -1138,18 +1170,17 @@
   int64_t manifest_signature_size = 0;
   int64_t next_data_offset = 0;
   int64_t next_data_length = 0;
-  if (system_state_ &&
-      system_state_->prefs()->GetInt64(kPrefsManifestMetadataSize,
-                                       &manifest_metadata_size) &&
+  if (SystemState::Get()->prefs()->GetInt64(kPrefsManifestMetadataSize,
+                                            &manifest_metadata_size) &&
       manifest_metadata_size != -1 &&
-      system_state_->prefs()->GetInt64(kPrefsManifestSignatureSize,
-                                       &manifest_signature_size) &&
+      SystemState::Get()->prefs()->GetInt64(kPrefsManifestSignatureSize,
+                                            &manifest_signature_size) &&
       manifest_signature_size != -1 &&
-      system_state_->prefs()->GetInt64(kPrefsUpdateStateNextDataOffset,
-                                       &next_data_offset) &&
+      SystemState::Get()->prefs()->GetInt64(kPrefsUpdateStateNextDataOffset,
+                                            &next_data_offset) &&
       next_data_offset != -1 &&
-      system_state_->prefs()->GetInt64(kPrefsUpdateStateNextDataLength,
-                                       &next_data_length)) {
+      SystemState::Get()->prefs()->GetInt64(kPrefsUpdateStateNextDataLength,
+                                            &next_data_length)) {
     minimum_size = manifest_metadata_size + manifest_signature_size +
                    next_data_offset + next_data_length;
   }
@@ -1160,10 +1191,10 @@
     return;
   string file_id =
       utils::CalculateP2PFileId(raw_hash, response.packages[0].size);
-  if (system_state_->p2p_manager()) {
+  if (SystemState::Get()->p2p_manager()) {
     LOG(INFO) << "Checking if payload is available via p2p, file_id=" << file_id
               << " minimum_size=" << minimum_size;
-    system_state_->p2p_manager()->LookupUrlForFile(
+    SystemState::Get()->p2p_manager()->LookupUrlForFile(
         file_id,
         minimum_size,
         TimeDelta::FromSeconds(kMaxP2PNetworkWaitTimeSeconds),
@@ -1173,7 +1204,8 @@
 }
 
 bool OmahaRequestAction::ShouldDeferDownload(OmahaResponse* output_object) {
-  if (params_->interactive()) {
+  const auto* params = SystemState::Get()->request_params();
+  if (params->interactive()) {
     LOG(INFO) << "Not deferring download because update is interactive.";
     return false;
   }
@@ -1182,7 +1214,8 @@
   // defer the download. This is because the download will always
   // happen from a peer on the LAN and we've been waiting in line for
   // our turn.
-  const PayloadStateInterface* payload_state = system_state_->payload_state();
+  const PayloadStateInterface* payload_state =
+      SystemState::Get()->payload_state();
   if (payload_state->GetUsingP2PForDownloading() &&
       !payload_state->GetP2PUrl().empty()) {
     LOG(INFO) << "Download not deferred because download "
@@ -1193,7 +1226,7 @@
   // We should defer the downloads only if we've first satisfied the
   // wall-clock-based-waiting period and then the update-check-based waiting
   // period, if required.
-  if (!params_->wall_clock_based_wait_enabled()) {
+  if (!params->wall_clock_based_wait_enabled()) {
     LOG(INFO) << "Wall-clock-based waiting period is not enabled,"
               << " so no deferring needed.";
     return false;
@@ -1234,23 +1267,24 @@
   Time update_first_seen_at = LoadOrPersistUpdateFirstSeenAtPref();
   if (update_first_seen_at == base::Time()) {
     LOG(INFO) << "Not scattering as UpdateFirstSeenAt value cannot be read or "
-                 "persisted";
+                 "persisted.";
     return kWallClockWaitDoneAndUpdateCheckWaitNotRequired;
   }
 
   TimeDelta elapsed_time =
-      system_state_->clock()->GetWallclockTime() - update_first_seen_at;
+      SystemState::Get()->clock()->GetWallclockTime() - update_first_seen_at;
   TimeDelta max_scatter_period =
       TimeDelta::FromDays(output_object->max_days_to_scatter);
   int64_t staging_wait_time_in_days = 0;
   // Use staging and its default max value if staging is on.
-  if (system_state_->prefs()->GetInt64(kPrefsWallClockStagingWaitPeriod,
-                                       &staging_wait_time_in_days) &&
+  if (SystemState::Get()->prefs()->GetInt64(kPrefsWallClockStagingWaitPeriod,
+                                            &staging_wait_time_in_days) &&
       staging_wait_time_in_days > 0)
     max_scatter_period = TimeDelta::FromDays(kMaxWaitTimeStagingInDays);
 
+  const auto* params = SystemState::Get()->request_params();
   LOG(INFO) << "Waiting Period = "
-            << utils::FormatSecs(params_->waiting_period().InSeconds())
+            << utils::FormatSecs(params->waiting_period().InSeconds())
             << ", Time Elapsed = "
             << utils::FormatSecs(elapsed_time.InSeconds())
             << ", MaxDaysToScatter = " << max_scatter_period.InDays();
@@ -1260,7 +1294,7 @@
     // previous FSI, which means this update will be applied mostly in OOBE
     // cases. For these cases, we shouldn't scatter so as to finish the OOBE
     // quickly.
-    LOG(INFO) << "Not scattering as deadline flag is set";
+    LOG(INFO) << "Not scattering as deadline flag is set.";
     return kWallClockWaitDoneAndUpdateCheckWaitNotRequired;
   }
 
@@ -1281,14 +1315,14 @@
 
   // This means we are required to participate in scattering.
   // See if our turn has arrived now.
-  TimeDelta remaining_wait_time = params_->waiting_period() - elapsed_time;
+  TimeDelta remaining_wait_time = params->waiting_period() - elapsed_time;
   if (remaining_wait_time.InSeconds() <= 0) {
     // Yes, it's our turn now.
     LOG(INFO) << "Successfully passed the wall-clock-based-wait.";
 
     // But we can't download until the update-check-count-based wait is also
     // satisfied, so mark it as required now if update checks are enabled.
-    return params_->update_check_count_wait_enabled()
+    return params->update_check_count_wait_enabled()
                ? kWallClockWaitDoneButUpdateCheckWaitRequired
                : kWallClockWaitDoneAndUpdateCheckWaitNotRequired;
   }
@@ -1303,10 +1337,11 @@
 
 bool OmahaRequestAction::IsUpdateCheckCountBasedWaitingSatisfied() {
   int64_t update_check_count_value;
+  const auto* params = SystemState::Get()->request_params();
 
-  if (system_state_->prefs()->Exists(kPrefsUpdateCheckCount)) {
-    if (!system_state_->prefs()->GetInt64(kPrefsUpdateCheckCount,
-                                          &update_check_count_value)) {
+  if (SystemState::Get()->prefs()->Exists(kPrefsUpdateCheckCount)) {
+    if (!SystemState::Get()->prefs()->GetInt64(kPrefsUpdateCheckCount,
+                                               &update_check_count_value)) {
       // We are unable to read the update check count from file for some reason.
       // So let's proceed anyway so as to not stall the update.
       LOG(ERROR) << "Unable to read update check count. "
@@ -1317,15 +1352,15 @@
     // This file does not exist. This means we haven't started our update
     // check count down yet, so this is the right time to start the count down.
     update_check_count_value =
-        base::RandInt(params_->min_update_checks_needed(),
-                      params_->max_update_checks_allowed());
+        base::RandInt(params->min_update_checks_needed(),
+                      params->max_update_checks_allowed());
 
     LOG(INFO) << "Randomly picked update check count value = "
               << update_check_count_value;
 
     // Write out the initial value of update_check_count_value.
-    if (!system_state_->prefs()->SetInt64(kPrefsUpdateCheckCount,
-                                          update_check_count_value)) {
+    if (!SystemState::Get()->prefs()->SetInt64(kPrefsUpdateCheckCount,
+                                               update_check_count_value)) {
       // We weren't able to write the update check count file for some reason.
       // So let's proceed anyway so as to not stall the update.
       LOG(ERROR) << "Unable to write update check count. "
@@ -1340,7 +1375,7 @@
   }
 
   if (update_check_count_value < 0 ||
-      update_check_count_value > params_->max_update_checks_allowed()) {
+      update_check_count_value > params->max_update_checks_allowed()) {
     // We err on the side of skipping scattering logic instead of stalling
     // a machine from receiving any updates in case of any unexpected state.
     LOG(ERROR) << "Invalid value for update check count detected. "
@@ -1359,7 +1394,7 @@
 bool OmahaRequestAction::ParseInstallDate(OmahaParserData* parser_data,
                                           OmahaResponse* output_object) {
   int64_t elapsed_days = 0;
-  if (!base::StringToInt64(parser_data->daystart_elapsed_days, &elapsed_days))
+  if (!base::StringToInt64(parser_data->daystart.elapsed_days, &elapsed_days))
     return false;
 
   if (elapsed_days < 0)
@@ -1370,59 +1405,74 @@
 }
 
 // static
-bool OmahaRequestAction::HasInstallDate(SystemState* system_state) {
-  PrefsInterface* prefs = system_state->prefs();
-  if (prefs == nullptr)
-    return false;
-
-  return prefs->Exists(kPrefsInstallDateDays);
+bool OmahaRequestAction::HasInstallDate() {
+  return SystemState::Get()->prefs()->Exists(kPrefsInstallDateDays);
 }
 
 // static
 bool OmahaRequestAction::PersistInstallDate(
-    SystemState* system_state,
     int install_date_days,
     InstallDateProvisioningSource source) {
   TEST_AND_RETURN_FALSE(install_date_days >= 0);
 
-  PrefsInterface* prefs = system_state->prefs();
-  if (prefs == nullptr)
-    return false;
-
+  auto* prefs = SystemState::Get()->prefs();
   if (!prefs->SetInt64(kPrefsInstallDateDays, install_date_days))
     return false;
 
-  system_state->metrics_reporter()->ReportInstallDateProvisioningSource(
+  SystemState::Get()->metrics_reporter()->ReportInstallDateProvisioningSource(
       static_cast<int>(source),  // Sample.
       kProvisionedMax);          // Maximum.
   return true;
 }
 
-bool OmahaRequestAction::PersistCohortData(const string& prefs_key,
-                                           const string& new_value) {
-  if (new_value.empty() && system_state_->prefs()->Exists(prefs_key)) {
-    LOG(INFO) << "Removing stored " << prefs_key << " value.";
-    return system_state_->prefs()->Delete(prefs_key);
-  } else if (!new_value.empty()) {
-    LOG(INFO) << "Storing new setting " << prefs_key << " as " << new_value;
-    return system_state_->prefs()->SetString(prefs_key, new_value);
+void OmahaRequestAction::PersistCohortData(const string& prefs_key,
+                                           const Optional<string>& new_value) {
+  if (!new_value)
+    return;
+  const string& value = new_value.value();
+  if (value.empty() && SystemState::Get()->prefs()->Exists(prefs_key)) {
+    if (!SystemState::Get()->prefs()->Delete(prefs_key))
+      LOG(ERROR) << "Failed to remove stored " << prefs_key << "value.";
+    else
+      LOG(INFO) << "Removed stored " << prefs_key << " value.";
+  } else if (!value.empty()) {
+    if (!SystemState::Get()->prefs()->SetString(prefs_key, value))
+      LOG(INFO) << "Failed to store new setting " << prefs_key << " as "
+                << value;
+    else
+      LOG(INFO) << "Stored cohort setting " << prefs_key << " as " << value;
   }
-  return true;
 }
 
-bool OmahaRequestAction::PersistEolInfo(const map<string, string>& attrs) {
-  // If EOL date attribute is not sent, don't delete the old persisted EOL
-  // date information.
-  auto eol_date_attr = attrs.find(kAttrEolDate);
-  if (eol_date_attr != attrs.end()) {
-    const auto& eol_date = eol_date_attr->second;
-    if (!system_state_->prefs()->SetString(kPrefsOmahaEolDate, eol_date)) {
-      LOG(ERROR) << "Setting EOL date failed.";
-      return false;
+void OmahaRequestAction::PersistCohorts(const OmahaParserData& parser_data) {
+  const auto* params = SystemState::Get()->request_params();
+  for (const auto& app : parser_data.apps) {
+    // For platform App ID.
+    if (app.id == params->GetAppId()) {
+      PersistCohortData(kPrefsOmahaCohort, app.cohort);
+      PersistCohortData(kPrefsOmahaCohortName, app.cohortname);
+      PersistCohortData(kPrefsOmahaCohortHint, app.cohorthint);
+    } else if (params->IsDlcAppId(app.id)) {
+      string dlc_id;
+      if (!params->GetDlcId(app.id, &dlc_id)) {
+        LOG(WARNING) << "Skip persisting cohorts for DLC App ID=" << app.id
+                     << " as it is not in the request params.";
+        continue;
+      }
+      auto* prefs = SystemState::Get()->prefs();
+      PersistCohortData(
+          prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsOmahaCohort}),
+          app.cohort);
+      PersistCohortData(
+          prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsOmahaCohortName}),
+          app.cohortname);
+      PersistCohortData(
+          prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsOmahaCohortHint}),
+          app.cohorthint);
+    } else {
+      LOG(WARNING) << "Skip persisting cohorts for unknown App ID=" << app.id;
     }
-    LOG(INFO) << "Set EOL date to " << eol_date;
   }
-  return true;
 }
 
 void OmahaRequestAction::ActionCompleted(ErrorCode code) {
@@ -1484,15 +1534,16 @@
       break;
   }
 
-  system_state_->metrics_reporter()->ReportUpdateCheckMetrics(
-      system_state_, result, reaction, download_error_code);
+  SystemState::Get()->metrics_reporter()->ReportUpdateCheckMetrics(
+      result, reaction, download_error_code);
 }
 
 bool OmahaRequestAction::ShouldIgnoreUpdate(const OmahaResponse& response,
                                             ErrorCode* error) const {
   // Note: policy decision to not update to a version we rolled back from.
   string rollback_version =
-      system_state_->payload_state()->GetRollbackVersion();
+      SystemState::Get()->payload_state()->GetRollbackVersion();
+  const auto* params = SystemState::Get()->request_params();
   if (!rollback_version.empty()) {
     LOG(INFO) << "Detected previous rollback from version " << rollback_version;
     if (rollback_version == response.version) {
@@ -1502,11 +1553,11 @@
     }
   }
 
-  if (system_state_->hardware()->IsOOBEEnabled() &&
-      !system_state_->hardware()->IsOOBEComplete(nullptr) &&
+  if (SystemState::Get()->hardware()->IsOOBEEnabled() &&
+      !SystemState::Get()->hardware()->IsOOBEComplete(nullptr) &&
       (response.deadline.empty() ||
-       system_state_->payload_state()->GetRollbackHappened()) &&
-      params_->app_version() != "ForcedUpdate") {
+       SystemState::Get()->payload_state()->GetRollbackHappened()) &&
+      params->app_version() != "ForcedUpdate") {
     LOG(INFO) << "Ignoring a non-critical Omaha update before OOBE completion.";
     *error = ErrorCode::kNonCriticalUpdateInOOBE;
     return true;
@@ -1537,16 +1588,8 @@
 
 bool OmahaRequestAction::IsUpdateAllowedOverCellularByPrefs(
     const OmahaResponse& response) const {
-  PrefsInterface* prefs = system_state_->prefs();
-
-  if (!prefs) {
-    LOG(INFO) << "Disabling updates over cellular as the preferences are "
-                 "not available.";
-    return false;
-  }
-
+  auto* prefs = SystemState::Get()->prefs();
   bool is_allowed;
-
   if (prefs->Exists(kPrefsUpdateOverCellularPermission) &&
       prefs->GetBoolean(kPrefsUpdateOverCellularPermission, &is_allowed) &&
       is_allowed) {
@@ -1594,7 +1637,7 @@
   ConnectionType type;
   ConnectionTethering tethering;
   ConnectionManagerInterface* connection_manager =
-      system_state_->connection_manager();
+      SystemState::Get()->connection_manager();
   if (!connection_manager->GetConnectionProperties(&type, &tethering)) {
     LOG(INFO) << "We could not determine our connection type. "
               << "Defaulting to allow updates.";
@@ -1657,7 +1700,8 @@
 
 void OmahaRequestAction::SetMaxKernelKeyVersionForRollback() const {
   int max_kernel_rollforward;
-  int min_kernel_version = system_state_->hardware()->GetMinKernelKeyVersion();
+  int min_kernel_version =
+      SystemState::Get()->hardware()->GetMinKernelKeyVersion();
   if (IsRollbackEnabled()) {
     // If rollback is enabled, set the max kernel key version to the current
     // kernel key version. This has the effect of freezing kernel key roll
@@ -1683,22 +1727,22 @@
   }
 
   bool max_rollforward_set =
-      system_state_->hardware()->SetMaxKernelKeyRollforward(
+      SystemState::Get()->hardware()->SetMaxKernelKeyRollforward(
           max_kernel_rollforward);
   if (!max_rollforward_set) {
     LOG(ERROR) << "Failed to set kernel_max_rollforward";
   }
   // Report metrics
-  system_state_->metrics_reporter()->ReportKeyVersionMetrics(
+  SystemState::Get()->metrics_reporter()->ReportKeyVersionMetrics(
       min_kernel_version, max_kernel_rollforward, max_rollforward_set);
 }
 
 base::Time OmahaRequestAction::LoadOrPersistUpdateFirstSeenAtPref() const {
   Time update_first_seen_at;
   int64_t update_first_seen_at_int;
-  if (system_state_->prefs()->Exists(kPrefsUpdateFirstSeenAt)) {
-    if (system_state_->prefs()->GetInt64(kPrefsUpdateFirstSeenAt,
-                                         &update_first_seen_at_int)) {
+  if (SystemState::Get()->prefs()->Exists(kPrefsUpdateFirstSeenAt)) {
+    if (SystemState::Get()->prefs()->GetInt64(kPrefsUpdateFirstSeenAt,
+                                              &update_first_seen_at_int)) {
       // Note: This timestamp could be that of ANY update we saw in the past
       // (not necessarily this particular update we're considering to apply)
       // but never got to apply because of some reason (e.g. stop AU policy,
@@ -1718,10 +1762,10 @@
       return base::Time();
     }
   } else {
-    update_first_seen_at = system_state_->clock()->GetWallclockTime();
+    update_first_seen_at = SystemState::Get()->clock()->GetWallclockTime();
     update_first_seen_at_int = update_first_seen_at.ToInternalValue();
-    if (system_state_->prefs()->SetInt64(kPrefsUpdateFirstSeenAt,
-                                         update_first_seen_at_int)) {
+    if (SystemState::Get()->prefs()->SetInt64(kPrefsUpdateFirstSeenAt,
+                                              update_first_seen_at_int)) {
       LOG(INFO) << "Persisted the new value for UpdateFirstSeenAt: "
                 << utils::ToString(update_first_seen_at);
     } else {
diff --git a/cros/omaha_request_action.h b/cros/omaha_request_action.h
index 1a3a912..4926c7d 100644
--- a/cros/omaha_request_action.h
+++ b/cros/omaha_request_action.h
@@ -28,12 +28,12 @@
 
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
+#include <base/optional.h>
 #include <brillo/secure_blob.h>
 #include <curl/curl.h>
 
 #include "update_engine/common/action.h"
 #include "update_engine/common/http_fetcher.h"
-#include "update_engine/common/system_state.h"
 #include "update_engine/cros/omaha_request_builder_xml.h"
 #include "update_engine/cros/omaha_response.h"
 
@@ -49,7 +49,6 @@
 class NoneType;
 class OmahaRequestAction;
 class OmahaRequestParams;
-class PrefsInterface;
 
 // This struct is declared in the .cc file.
 struct OmahaParserData;
@@ -101,8 +100,7 @@
   // OmahaRequestAction(..., new OmahaEvent(...), new WhateverHttpFetcher);
   // or
   // OmahaRequestAction(..., nullptr, new WhateverHttpFetcher);
-  OmahaRequestAction(SystemState* system_state,
-                     OmahaEvent* event,
+  OmahaRequestAction(OmahaEvent* event,
                      std::unique_ptr<HttpFetcher> http_fetcher,
                      bool ping_only,
                      const std::string& session_id);
@@ -156,7 +154,7 @@
   // Gets the install date, expressed as the number of PST8PDT
   // calendar weeks since January 1st 2007, times seven. Returns -1 if
   // unknown. See http://crbug.com/336838 for details about this value.
-  static int GetInstallDate(SystemState* system_state);
+  static int GetInstallDate();
 
   // Parses the Omaha Response in |doc| and sets the
   // |install_date_days| field of |output_object| to the value of the
@@ -167,25 +165,25 @@
 
   // Returns True if the kPrefsInstallDateDays state variable is set,
   // False otherwise.
-  static bool HasInstallDate(SystemState* system_state);
+  static bool HasInstallDate();
 
   // Writes |install_date_days| into the kPrefsInstallDateDays state
   // variable and emits an UMA stat for the |source| used. Returns
   // True if the value was written, False if an error occurred.
-  static bool PersistInstallDate(SystemState* system_state,
-                                 int install_date_days,
+  static bool PersistInstallDate(int install_date_days,
                                  InstallDateProvisioningSource source);
 
-  // Persist the new cohort* value received in the XML file in the |prefs_key|
-  // preference file. If the |new_value| is empty, the currently stored value
-  // will be deleted. Don't call this function with an empty |new_value| if the
-  // value was not set in the XML, since that would delete the stored value.
-  bool PersistCohortData(const std::string& prefs_key,
-                         const std::string& new_value);
+  // Persist the new cohort value received in the XML file in the |prefs_key|
+  // preference file. If the |new_value| is empty, do nothing. If the
+  // |new_value| stores and empty value, the currently stored value will be
+  // deleted. Don't call this function with an empty |new_value| if the value
+  // was not set in the XML, since that would delete the stored value.
+  void PersistCohortData(const std::string& prefs_key,
+                         const base::Optional<std::string>& new_value);
 
-  // Parses and persists the end-of-life date flag sent back in the updatecheck
-  // tag attributes. The flags will be validated and stored in the Prefs.
-  bool PersistEolInfo(const std::map<std::string, std::string>& attrs);
+  // Parses and persists the cohorts sent back in the updatecheck tag
+  // attributes.
+  void PersistCohorts(const OmahaParserData& parser_data);
 
   // If this is an update check request, initializes
   // |ping_active_days_| and |ping_roll_call_days_| to values that may
@@ -283,12 +281,6 @@
   // kPrefsUpdateFirstSeenAt pref and returns it as a base::Time object.
   base::Time LoadOrPersistUpdateFirstSeenAtPref() const;
 
-  // Global system context.
-  SystemState* system_state_;
-
-  // Contains state that is relevant in the processing of the Omaha request.
-  OmahaRequestParams* params_;
-
   // Pointer to the OmahaEvent info. This is an UpdateCheck request if null.
   std::unique_ptr<OmahaEvent> event_;
 
diff --git a/cros/omaha_request_action_fuzzer.cc b/cros/omaha_request_action_fuzzer.cc
index dd02467..995de8c 100644
--- a/cros/omaha_request_action_fuzzer.cc
+++ b/cros/omaha_request_action_fuzzer.cc
@@ -31,10 +31,9 @@
   brillo::FakeMessageLoop loop(nullptr);
   loop.SetAsCurrent();
 
-  chromeos_update_engine::FakeSystemState fake_system_state;
+  chromeos_update_engine::FakeSystemState::CreateInstance();
   auto omaha_request_action =
       std::make_unique<chromeos_update_engine::OmahaRequestAction>(
-          &fake_system_state,
           nullptr,
           std::make_unique<chromeos_update_engine::MockHttpFetcher>(
               data, size, nullptr),
diff --git a/cros/omaha_request_action_unittest.cc b/cros/omaha_request_action_unittest.cc
index c3842b8..01be1a8 100644
--- a/cros/omaha_request_action_unittest.cc
+++ b/cros/omaha_request_action_unittest.cc
@@ -135,7 +135,7 @@
   }
 
   string GetUpdateResponse() const {
-    chromeos_update_engine::OmahaRequestParams request_params{nullptr};
+    chromeos_update_engine::OmahaRequestParams request_params;
     request_params.set_app_id(app_id);
     return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
            "protocol=\"3.0\">"
@@ -158,10 +158,10 @@
            version +
            "\">"
            "<packages><package hash=\"not-used\" name=\"" +
-           filename + "\" size=\"" + base::NumberToString(size) +
-           "\" hash_sha256=\"" + hash + "\"/>" +
-           (multi_package ? "<package name=\"package2\" size=\"222\" "
-                            "hash_sha256=\"hash2\"/>"
+           filename + "\" size=\"" + base::NumberToString(size) + "\" fp=\"" +
+           fp + "\" hash_sha256=\"" + hash + "\"/>" +
+           (multi_package ? "<package name=\"package2\" size=\"222\" fp=\"" +
+                                fp2 + "\" hash_sha256=\"hash2\"/>"
                           : "") +
            "</packages>"
            "<actions><action event=\"postinstall\" MetadataSize=\"11" +
@@ -187,8 +187,9 @@
                       "><updatecheck status=\"ok\"><urls><url codebase=\"" +
                       codebase2 + "\"/></urls><manifest version=\"" + version2 +
                       "\"><packages>"
-                      "<package name=\"package3\" size=\"333\" "
-                      "hash_sha256=\"hash3\"/></packages>"
+                      "<package name=\"package3\" size=\"333\" fp=\"" +
+                      fp2 +
+                      "\" hash_sha256=\"hash3\"/></packages>"
                       "<actions><action event=\"postinstall\" " +
                       (multi_app_self_update
                            ? "noupdate=\"true\" IsDeltaPayload=\"true\" "
@@ -204,19 +205,33 @@
                 : "") +
            (dlc_app_update
                 ? "<app appid=\"" + request_params.GetDlcAppId(kDlcId1) +
-                      "\" status=\"ok\">"
+                      "\" " +
+                      (include_dlc_cohorts
+                           ? "cohort=\"" + dlc_cohort + "\" cohorthint=\"" +
+                                 dlc_cohorthint + "\" cohortname=\"" +
+                                 dlc_cohortname + "\" "
+                           : "") +
+                      "status=\"ok\">"
                       "<updatecheck status=\"ok\"><urls><url codebase=\"" +
                       codebase + "\"/><url codebase=\"" + codebase2 +
                       "\"/></urls><manifest version=\"" + version +
                       "\"><packages><package name=\"package3\" size=\"333\" "
-                      "hash_sha256=\"hash3\"/></packages><actions>"
-                      "<action event=\"install\" run=\".signed\"/>"
+                      "fp=\"" +
+                      fp2 +
+                      "\" hash_sha256=\"hash3\"/></packages>"
+                      "<actions><action event=\"install\" run=\".signed\"/>"
                       "<action event=\"postinstall\" MetadataSize=\"33\"/>"
                       "</actions></manifest></updatecheck></app>"
                 : "") +
            (dlc_app_no_update
                 ? "<app appid=\"" + request_params.GetDlcAppId(kDlcId2) +
-                      "\"><updatecheck status=\"noupdate\"/></app>"
+                      +"\" " +
+                      (include_dlc_cohorts
+                           ? "cohort=\"" + dlc_cohort + "\" cohorthint=\"" +
+                                 dlc_cohorthint + "\" cohortname=\"" +
+                                 dlc_cohortname + "\" "
+                           : "") +
+                      "><updatecheck status=\"noupdate\"/></app>"
                 : "") +
            "</response>";
   }
@@ -227,7 +242,6 @@
   string app_id = kTestAppId;
   string app_id2 = kTestAppId2;
   string app_id_skip_updatecheck = kTestAppIdSkipUpdatecheck;
-  string current_version = kCurrentVersion;
   string version = "1.2.3.4";
   string version2 = "2.3.4.5";
   string more_info_url = "http://more/info";
@@ -236,6 +250,8 @@
   string codebase2 = "http://code/base/2/";
   string filename = "file.signed";
   string hash = "4841534831323334";
+  string fp = "3.98ba213e";
+  string fp2 = "3.755aff78e";
   uint64_t size = 123;
   string deadline = "";
   string max_days_to_scatter = "7";
@@ -252,6 +268,11 @@
   string cohort = "";
   string cohorthint = "";
   string cohortname = "";
+  // Whether to include Omaha cohorts for DLC apps.
+  bool include_dlc_cohorts = false;
+  string dlc_cohort = "";
+  string dlc_cohorthint = "";
+  string dlc_cohortname = "";
 
   // Whether to include the CrOS <!ENTITY> in the XML response.
   bool include_entity = false;
@@ -357,6 +378,8 @@
 class OmahaRequestActionTest : public ::testing::Test {
  protected:
   void SetUp() override {
+    FakeSystemState::CreateInstance();
+
     request_params_.set_os_sp("service_pack");
     request_params_.set_os_board("x86-generic");
     request_params_.set_app_id(kTestAppId);
@@ -374,8 +397,8 @@
     request_params_.set_is_install(false);
     request_params_.set_dlc_apps_params({});
 
-    fake_system_state_.set_request_params(&request_params_);
-    fake_system_state_.set_prefs(&fake_prefs_);
+    FakeSystemState::Get()->set_request_params(&request_params_);
+    fake_prefs_ = FakeSystemState::Get()->fake_prefs();
 
     // Setting the default update check params. Lookup |TestUpdateCheck()|.
     tuc_params_ = {
@@ -391,12 +414,12 @@
         .expected_download_error_code = metrics::DownloadErrorCode::kUnset,
     };
 
-    ON_CALL(*fake_system_state_.mock_update_attempter(), GetExcluder())
+    ON_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetExcluder())
         .WillByDefault(Return(&mock_excluder_));
   }
 
   // This function uses the parameters in |tuc_params_| to do an update check.
-  // It will fill out |post_str| with the result data and |response| with
+  // It will fill out |post_str_| with the result data and |response| with
   // |OmahaResponse|. Returns true iff an output response was obtained from the
   // |OmahaRequestAction|. If |fail_http_response_code| is non-negative, the
   // transfer will fail with that code. |ping_only| is passed through to the
@@ -409,8 +432,8 @@
   // metric should not be reported.
   bool TestUpdateCheck();
 
-  // Tests events using |event| and |https_response|. It will fill up |post_str|
-  // with the result data.
+  // Tests events using |event| and |https_response|. It will fill up
+  // |post_str_| with the result data.
   void TestEvent(OmahaEvent* event, const string& http_response);
 
   // Runs and checks a ping test. |ping_only| indicates whether it should send
@@ -434,12 +457,11 @@
                const string& expected_p2p_url);
 
   StrictMock<MockExcluder> mock_excluder_;
-  FakeSystemState fake_system_state_;
   FakeUpdateResponse fake_update_response_;
   // Used by all tests.
-  OmahaRequestParams request_params_{&fake_system_state_};
+  OmahaRequestParams request_params_;
 
-  FakePrefs fake_prefs_;
+  FakePrefs* fake_prefs_;
 
   OmahaRequestActionTestProcessorDelegate delegate_;
 
@@ -447,9 +469,8 @@
 
   TestUpdateCheckParams tuc_params_;
 
-  // TODO(ahassani): Add trailing _ to these two variables.
-  OmahaResponse response;
-  string post_str;
+  OmahaResponse response_;
+  string post_str_;
 };
 
 class OmahaRequestActionDlcPingTest : public OmahaRequestActionTest {
@@ -482,6 +503,7 @@
   std::string last_active_key_;
   std::string last_rollcall_key_;
 };
+
 bool OmahaRequestActionTest::TestUpdateCheck() {
   brillo::FakeMessageLoop loop(nullptr);
   loop.SetAsCurrent();
@@ -492,13 +514,12 @@
   if (tuc_params_.fail_http_response_code >= 0) {
     fetcher->FailTransfer(tuc_params_.fail_http_response_code);
   }
-  // This ensures the tests didn't forget to update fake_system_state_ if they
-  // are not using the default request_params_.
-  EXPECT_EQ(&request_params_, fake_system_state_.request_params());
+  // This ensures the tests didn't forget to update |FakeSystemState| if they
+  // are not using the default |request_params_|.
+  EXPECT_EQ(&request_params_, FakeSystemState::Get()->request_params());
 
   auto omaha_request_action =
-      std::make_unique<OmahaRequestAction>(&fake_system_state_,
-                                           nullptr,
+      std::make_unique<OmahaRequestAction>(nullptr,
                                            std::move(fetcher),
                                            tuc_params_.ping_only,
                                            tuc_params_.session_id);
@@ -535,14 +556,13 @@
   processor.EnqueueAction(std::move(omaha_request_action));
   processor.EnqueueAction(std::move(collector_action));
 
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
-              ReportUpdateCheckMetrics(_, _, _, _))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
+              ReportUpdateCheckMetrics(_, _, _))
       .Times(AnyNumber());
 
   EXPECT_CALL(
-      *fake_system_state_.mock_metrics_reporter(),
-      ReportUpdateCheckMetrics(_,
-                               tuc_params_.expected_check_result,
+      *FakeSystemState::Get()->mock_metrics_reporter(),
+      ReportUpdateCheckMetrics(tuc_params_.expected_check_result,
                                tuc_params_.expected_check_reaction,
                                tuc_params_.expected_download_error_code))
       .Times(tuc_params_.ping_only ? 0 : 1);
@@ -553,8 +573,8 @@
   loop.Run();
   EXPECT_FALSE(loop.PendingTasks());
   if (delegate_.omaha_response_)
-    response = *delegate_.omaha_response_;
-  post_str = string(delegate_.post_data_.begin(), delegate_.post_data_.end());
+    response_ = *delegate_.omaha_response_;
+  post_str_ = string(delegate_.post_data_.begin(), delegate_.post_data_.end());
   return delegate_.omaha_response_ != nullptr;
 }
 
@@ -567,7 +587,6 @@
   loop.SetAsCurrent();
 
   auto action = std::make_unique<OmahaRequestAction>(
-      &fake_system_state_,
       event,
       std::make_unique<MockHttpFetcher>(
           http_response.data(), http_response.size(), nullptr),
@@ -583,7 +602,7 @@
   loop.Run();
   EXPECT_FALSE(loop.PendingTasks());
 
-  post_str = string(delegate_.post_data_.begin(), delegate_.post_data_.end());
+  post_str_ = string(delegate_.post_data_.begin(), delegate_.post_data_.end());
 }
 
 TEST_F(OmahaRequestActionTest, RejectEntities) {
@@ -594,7 +613,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, NoUpdateTest) {
@@ -603,7 +622,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, MultiAppNoUpdateTest) {
@@ -613,7 +632,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, MultiAppNoPartialUpdateTest) {
@@ -623,7 +642,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, NoSelfUpdateTest) {
@@ -635,33 +654,34 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 // Test that all the values in the response are parsed in a normal update
-// response.
+// response_.
 TEST_F(OmahaRequestActionTest, ValidUpdateTest) {
   fake_update_response_.deadline = "20101020";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(fake_update_response_.version, response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(fake_update_response_.version, response_.version);
   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
-            response.packages[0].payload_urls[0]);
-  EXPECT_EQ(fake_update_response_.more_info_url, response.more_info_url);
-  EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
-  EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
-  EXPECT_EQ(true, response.packages[0].is_delta);
-  EXPECT_EQ(fake_update_response_.prompt == "true", response.prompt);
-  EXPECT_EQ(fake_update_response_.deadline, response.deadline);
-  EXPECT_FALSE(response.powerwash_required);
+            response_.packages[0].payload_urls[0]);
+  EXPECT_EQ(fake_update_response_.more_info_url, response_.more_info_url);
+  EXPECT_EQ(fake_update_response_.hash, response_.packages[0].hash);
+  EXPECT_EQ(fake_update_response_.size, response_.packages[0].size);
+  EXPECT_EQ(fake_update_response_.fp, response_.packages[0].fp);
+  EXPECT_EQ(true, response_.packages[0].is_delta);
+  EXPECT_EQ(fake_update_response_.prompt == "true", response_.prompt);
+  EXPECT_EQ(fake_update_response_.deadline, response_.deadline);
+  EXPECT_FALSE(response_.powerwash_required);
   // Omaha cohort attributes are not set in the response, so they should not be
   // persisted.
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohort));
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohortHint));
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohortName));
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsOmahaCohort));
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsOmahaCohortHint));
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsOmahaCohortName));
 }
 
 TEST_F(OmahaRequestActionTest, MultiPackageUpdateTest) {
@@ -670,21 +690,23 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(fake_update_response_.version, response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(fake_update_response_.version, response_.version);
   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
-            response.packages[0].payload_urls[0]);
+            response_.packages[0].payload_urls[0]);
   EXPECT_EQ(fake_update_response_.codebase + "package2",
-            response.packages[1].payload_urls[0]);
-  EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
-  EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
-  EXPECT_EQ(true, response.packages[0].is_delta);
-  EXPECT_EQ(11u, response.packages[0].metadata_size);
-  ASSERT_EQ(2u, response.packages.size());
-  EXPECT_EQ(string("hash2"), response.packages[1].hash);
-  EXPECT_EQ(222u, response.packages[1].size);
-  EXPECT_EQ(22u, response.packages[1].metadata_size);
-  EXPECT_EQ(false, response.packages[1].is_delta);
+            response_.packages[1].payload_urls[0]);
+  EXPECT_EQ(fake_update_response_.hash, response_.packages[0].hash);
+  EXPECT_EQ(fake_update_response_.size, response_.packages[0].size);
+  EXPECT_EQ(fake_update_response_.fp, response_.packages[0].fp);
+  EXPECT_EQ(true, response_.packages[0].is_delta);
+  EXPECT_EQ(11u, response_.packages[0].metadata_size);
+  ASSERT_EQ(2u, response_.packages.size());
+  EXPECT_EQ(string("hash2"), response_.packages[1].hash);
+  EXPECT_EQ(222u, response_.packages[1].size);
+  EXPECT_EQ(fake_update_response_.fp2, response_.packages[1].fp);
+  EXPECT_EQ(22u, response_.packages[1].metadata_size);
+  EXPECT_EQ(false, response_.packages[1].is_delta);
 }
 
 TEST_F(OmahaRequestActionTest, MultiAppUpdateTest) {
@@ -693,21 +715,23 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(fake_update_response_.version, response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(fake_update_response_.version, response_.version);
   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
-            response.packages[0].payload_urls[0]);
+            response_.packages[0].payload_urls[0]);
   EXPECT_EQ(fake_update_response_.codebase2 + "package3",
-            response.packages[1].payload_urls[0]);
-  EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
-  EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
-  EXPECT_EQ(11u, response.packages[0].metadata_size);
-  EXPECT_EQ(true, response.packages[0].is_delta);
-  ASSERT_EQ(2u, response.packages.size());
-  EXPECT_EQ(string("hash3"), response.packages[1].hash);
-  EXPECT_EQ(333u, response.packages[1].size);
-  EXPECT_EQ(33u, response.packages[1].metadata_size);
-  EXPECT_EQ(false, response.packages[1].is_delta);
+            response_.packages[1].payload_urls[0]);
+  EXPECT_EQ(fake_update_response_.hash, response_.packages[0].hash);
+  EXPECT_EQ(fake_update_response_.size, response_.packages[0].size);
+  EXPECT_EQ(fake_update_response_.fp, response_.packages[0].fp);
+  EXPECT_EQ(11u, response_.packages[0].metadata_size);
+  EXPECT_EQ(true, response_.packages[0].is_delta);
+  ASSERT_EQ(2u, response_.packages.size());
+  EXPECT_EQ(string("hash3"), response_.packages[1].hash);
+  EXPECT_EQ(333u, response_.packages[1].size);
+  EXPECT_EQ(fake_update_response_.fp2, response_.packages[1].fp);
+  EXPECT_EQ(33u, response_.packages[1].metadata_size);
+  EXPECT_EQ(false, response_.packages[1].is_delta);
 }
 
 TEST_F(OmahaRequestActionTest, MultiAppPartialUpdateTest) {
@@ -717,18 +741,20 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(fake_update_response_.version, response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(fake_update_response_.version, response_.version);
   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
-            response.packages[0].payload_urls[0]);
-  EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
-  EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
-  EXPECT_EQ(11u, response.packages[0].metadata_size);
-  ASSERT_EQ(2u, response.packages.size());
-  EXPECT_EQ(string("hash3"), response.packages[1].hash);
-  EXPECT_EQ(333u, response.packages[1].size);
-  EXPECT_EQ(33u, response.packages[1].metadata_size);
-  EXPECT_EQ(true, response.packages[1].is_delta);
+            response_.packages[0].payload_urls[0]);
+  EXPECT_EQ(fake_update_response_.hash, response_.packages[0].hash);
+  EXPECT_EQ(fake_update_response_.size, response_.packages[0].size);
+  EXPECT_EQ(fake_update_response_.fp, response_.packages[0].fp);
+  EXPECT_EQ(11u, response_.packages[0].metadata_size);
+  ASSERT_EQ(2u, response_.packages.size());
+  EXPECT_EQ(string("hash3"), response_.packages[1].hash);
+  EXPECT_EQ(333u, response_.packages[1].size);
+  EXPECT_EQ(fake_update_response_.fp2, response_.packages[1].fp);
+  EXPECT_EQ(33u, response_.packages[1].metadata_size);
+  EXPECT_EQ(true, response_.packages[1].is_delta);
 }
 
 TEST_F(OmahaRequestActionTest, MultiAppMultiPackageUpdateTest) {
@@ -738,27 +764,30 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(fake_update_response_.version, response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(fake_update_response_.version, response_.version);
   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
-            response.packages[0].payload_urls[0]);
+            response_.packages[0].payload_urls[0]);
   EXPECT_EQ(fake_update_response_.codebase + "package2",
-            response.packages[1].payload_urls[0]);
+            response_.packages[1].payload_urls[0]);
   EXPECT_EQ(fake_update_response_.codebase2 + "package3",
-            response.packages[2].payload_urls[0]);
-  EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
-  EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
-  EXPECT_EQ(11u, response.packages[0].metadata_size);
-  EXPECT_EQ(true, response.packages[0].is_delta);
-  ASSERT_EQ(3u, response.packages.size());
-  EXPECT_EQ(string("hash2"), response.packages[1].hash);
-  EXPECT_EQ(222u, response.packages[1].size);
-  EXPECT_EQ(22u, response.packages[1].metadata_size);
-  EXPECT_EQ(false, response.packages[1].is_delta);
-  EXPECT_EQ(string("hash3"), response.packages[2].hash);
-  EXPECT_EQ(333u, response.packages[2].size);
-  EXPECT_EQ(33u, response.packages[2].metadata_size);
-  EXPECT_EQ(false, response.packages[2].is_delta);
+            response_.packages[2].payload_urls[0]);
+  EXPECT_EQ(fake_update_response_.hash, response_.packages[0].hash);
+  EXPECT_EQ(fake_update_response_.size, response_.packages[0].size);
+  EXPECT_EQ(fake_update_response_.fp, response_.packages[0].fp);
+  EXPECT_EQ(11u, response_.packages[0].metadata_size);
+  EXPECT_EQ(true, response_.packages[0].is_delta);
+  ASSERT_EQ(3u, response_.packages.size());
+  EXPECT_EQ(string("hash2"), response_.packages[1].hash);
+  EXPECT_EQ(222u, response_.packages[1].size);
+  EXPECT_EQ(fake_update_response_.fp2, response_.packages[1].fp);
+  EXPECT_EQ(22u, response_.packages[1].metadata_size);
+  EXPECT_EQ(false, response_.packages[1].is_delta);
+  EXPECT_EQ(string("hash3"), response_.packages[2].hash);
+  EXPECT_EQ(333u, response_.packages[2].size);
+  EXPECT_EQ(fake_update_response_.fp2, response_.packages[2].fp);
+  EXPECT_EQ(33u, response_.packages[2].metadata_size);
+  EXPECT_EQ(false, response_.packages[2].is_delta);
 }
 
 TEST_F(OmahaRequestActionTest, PowerwashTest) {
@@ -767,8 +796,8 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(response.powerwash_required);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(response_.powerwash_required);
 }
 
 TEST_F(OmahaRequestActionTest, ExtraHeadersSentInteractiveTest) {
@@ -781,7 +810,7 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ExtraHeadersSentNoInteractiveTest) {
@@ -794,14 +823,14 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByConnection) {
   // Set up a connection manager that doesn't allow a valid update over
   // the current ethernet connection.
   MockConnectionManager mock_cm;
-  fake_system_state_.set_connection_manager(&mock_cm);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
 
   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
       .WillRepeatedly(DoAll(SetArgPointee<0>(ConnectionType::kEthernet),
@@ -816,14 +845,14 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ValidUpdateOverCellularAllowedByDevicePolicy) {
   // This test tests that update over cellular is allowed as device policy
   // says yes.
   MockConnectionManager mock_cm;
-  fake_system_state_.set_connection_manager(&mock_cm);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
 
   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
       .WillRepeatedly(DoAll(SetArgPointee<0>(ConnectionType::kCellular),
@@ -838,14 +867,14 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ValidUpdateOverCellularBlockedByDevicePolicy) {
   // This test tests that update over cellular is blocked as device policy
   // says no.
   MockConnectionManager mock_cm;
-  fake_system_state_.set_connection_manager(&mock_cm);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
 
   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
       .WillRepeatedly(DoAll(SetArgPointee<0>(ConnectionType::kCellular),
@@ -862,7 +891,7 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -870,8 +899,8 @@
   // This test tests that, when device policy is not set, update over cellular
   // is allowed as permission for update over cellular is set to true.
   MockConnectionManager mock_cm;
-  fake_prefs_.SetBoolean(kPrefsUpdateOverCellularPermission, true);
-  fake_system_state_.set_connection_manager(&mock_cm);
+  fake_prefs_->SetBoolean(kPrefsUpdateOverCellularPermission, true);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
 
   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
       .WillRepeatedly(DoAll(SetArgPointee<0>(ConnectionType::kCellular),
@@ -886,7 +915,7 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -900,10 +929,10 @@
   // A size different from the size in omaha response.
   int64_t diff_size = 999;
 
-  fake_prefs_.SetString(kPrefsUpdateOverCellularTargetVersion, diff_version);
-  fake_prefs_.SetInt64(kPrefsUpdateOverCellularTargetSize, diff_size);
+  fake_prefs_->SetString(kPrefsUpdateOverCellularTargetVersion, diff_version);
+  fake_prefs_->SetInt64(kPrefsUpdateOverCellularTargetSize, diff_size);
   // This test tests cellular (3G) being the only connection type being allowed.
-  fake_system_state_.set_connection_manager(&mock_cm);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
 
   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
       .WillRepeatedly(DoAll(SetArgPointee<0>(ConnectionType::kCellular),
@@ -920,7 +949,7 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -934,9 +963,9 @@
   // A size same as the size in omaha response.
   int64_t new_size = fake_update_response_.size;
 
-  fake_prefs_.SetString(kPrefsUpdateOverCellularTargetVersion, new_version);
-  fake_prefs_.SetInt64(kPrefsUpdateOverCellularTargetSize, new_size);
-  fake_system_state_.set_connection_manager(&mock_cm);
+  fake_prefs_->SetString(kPrefsUpdateOverCellularTargetVersion, new_version);
+  fake_prefs_->SetInt64(kPrefsUpdateOverCellularTargetSize, new_size);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
 
   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
       .WillRepeatedly(DoAll(SetArgPointee<0>(ConnectionType::kCellular),
@@ -951,13 +980,13 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByRollback) {
   string rollback_version = "1234.0.0";
   MockPayloadState mock_payload_state;
-  fake_system_state_.set_payload_state(&mock_payload_state);
+  FakeSystemState::Get()->set_payload_state(&mock_payload_state);
   fake_update_response_.version = rollback_version;
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kOmahaUpdateIgnoredPerPolicy;
@@ -968,13 +997,13 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 // Verify that update checks called during OOBE will not try to download an
 // update if the response doesn't include the deadline field.
 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBE) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kNonCriticalUpdateInOOBE;
   tuc_params_.expected_check_result = metrics::CheckResult::kParsingError;
@@ -984,50 +1013,51 @@
   // OmahaRequestAction::ActionCompleted.
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 // Verify that the IsOOBEComplete() value is ignored when the OOBE flow is not
 // enabled.
 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBEDisabled) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
-  fake_system_state_.fake_hardware()->SetIsOOBEEnabled(false);
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEEnabled(false);
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 // Verify that update checks called during OOBE will still try to download an
 // update if the response includes the deadline field.
 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBEDeadlineSet) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
   fake_update_response_.deadline = "20101020";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 // Verify that update checks called during OOBE will not try to download an
 // update if a rollback happened, even when the response includes the deadline
 // field.
 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBERollback) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
   fake_update_response_.deadline = "20101020";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kNonCriticalUpdateInOOBE;
   tuc_params_.expected_check_result = metrics::CheckResult::kParsingError;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
-  EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetRollbackHappened())
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()),
+              GetRollbackHappened())
       .WillOnce(Return(true));
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 // Verify that non-critical updates are skipped by reporting the
@@ -1036,10 +1066,10 @@
 // kOmahaUpdateIgnoredOverCellular error in this case  might cause undesired UX
 // in OOBE (warning the user about an update that will be skipped).
 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesInOOBEOverCellular) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
 
   MockConnectionManager mock_cm;
-  fake_system_state_.set_connection_manager(&mock_cm);
+  FakeSystemState::Get()->set_connection_manager(&mock_cm);
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kNonCriticalUpdateInOOBE;
   tuc_params_.expected_check_result = metrics::CheckResult::kParsingError;
@@ -1054,21 +1084,21 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, WallClockBasedWaitAloneCausesScattering) {
   request_params_.set_wall_clock_based_wait_enabled(true);
   request_params_.set_update_check_count_wait_enabled(false);
   request_params_.set_waiting_period(TimeDelta::FromDays(2));
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kOmahaUpdateDeferredPerPolicy;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kDeferring;
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -1077,13 +1107,13 @@
   request_params_.set_update_check_count_wait_enabled(false);
   request_params_.set_waiting_period(TimeDelta::FromDays(2));
   request_params_.set_interactive(true);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   // Verify if we are interactive check we don't defer.
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, NoWallClockBasedWaitCausesNoScattering) {
@@ -1096,7 +1126,7 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ZeroMaxDaysToScatterCausesNoScattering) {
@@ -1110,7 +1140,7 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ZeroUpdateCheckCountCausesNoScattering) {
@@ -1119,15 +1149,15 @@
   request_params_.set_update_check_count_wait_enabled(true);
   request_params_.set_min_update_checks_needed(0);
   request_params_.set_max_update_checks_allowed(0);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
 
   int64_t count;
-  ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count));
+  ASSERT_TRUE(fake_prefs_->GetInt64(kPrefsUpdateCheckCount, &count));
   ASSERT_EQ(count, 0);
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, NonZeroUpdateCheckCountCausesScattering) {
@@ -1136,7 +1166,7 @@
   request_params_.set_update_check_count_wait_enabled(true);
   request_params_.set_min_update_checks_needed(1);
   request_params_.set_max_update_checks_allowed(8);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kOmahaUpdateDeferredPerPolicy;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kDeferring;
@@ -1144,9 +1174,9 @@
   ASSERT_FALSE(TestUpdateCheck());
 
   int64_t count;
-  ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count));
+  ASSERT_TRUE(fake_prefs_->GetInt64(kPrefsUpdateCheckCount, &count));
   ASSERT_GT(count, 0);
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -1157,13 +1187,13 @@
   request_params_.set_min_update_checks_needed(1);
   request_params_.set_max_update_checks_allowed(8);
   request_params_.set_interactive(true);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   // Verify if we are interactive check we don't defer.
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, ExistingUpdateCheckCountCausesScattering) {
@@ -1172,20 +1202,20 @@
   request_params_.set_update_check_count_wait_enabled(true);
   request_params_.set_min_update_checks_needed(1);
   request_params_.set_max_update_checks_allowed(8);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kOmahaUpdateDeferredPerPolicy;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kDeferring;
 
-  ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsUpdateCheckCount, 5));
+  ASSERT_TRUE(fake_prefs_->SetInt64(kPrefsUpdateCheckCount, 5));
   ASSERT_FALSE(TestUpdateCheck());
 
   int64_t count;
-  ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count));
+  ASSERT_TRUE(fake_prefs_->GetInt64(kPrefsUpdateCheckCount, &count));
   // |count| remains the same, as the decrementing happens in update_attempter
   // which this test doesn't exercise.
   ASSERT_EQ(count, 5);
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -1196,14 +1226,14 @@
   request_params_.set_min_update_checks_needed(1);
   request_params_.set_max_update_checks_allowed(8);
   request_params_.set_interactive(true);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
-  ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsUpdateCheckCount, 5));
+  ASSERT_TRUE(fake_prefs_->SetInt64(kPrefsUpdateCheckCount, 5));
 
   // Verify if we are interactive check we don't defer.
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, StagingTurnedOnCausesScattering) {
@@ -1212,9 +1242,9 @@
   request_params_.set_wall_clock_based_wait_enabled(true);
   request_params_.set_waiting_period(TimeDelta::FromDays(6));
   request_params_.set_update_check_count_wait_enabled(false);
-  fake_system_state_.fake_clock()->SetWallclockTime(Time::Now());
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(Time::Now());
 
-  ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsWallClockStagingWaitPeriod, 6));
+  ASSERT_TRUE(fake_prefs_->SetInt64(kPrefsWallClockStagingWaitPeriod, 6));
   // This should not prevent scattering due to staging.
   fake_update_response_.max_days_to_scatter = "0";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
@@ -1223,7 +1253,7 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 
   // Interactive updates should not be affected.
   request_params_.set_interactive(true);
@@ -1232,7 +1262,7 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, CohortsArePersisted) {
@@ -1240,55 +1270,120 @@
   fake_update_response_.cohort = "s/154454/8479665";
   fake_update_response_.cohorthint = "please-put-me-on-beta";
   fake_update_response_.cohortname = "stable";
+  request_params_.set_dlc_apps_params(
+      {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}}});
+  fake_update_response_.dlc_app_update = true;
+  fake_update_response_.include_dlc_cohorts = true;
+  fake_update_response_.dlc_cohort = "s/154454/8479665/dlc";
+  fake_update_response_.dlc_cohorthint = "please-put-me-on-beta-dlc";
+  fake_update_response_.dlc_cohortname = "stable-dlc";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
+  EXPECT_CALL(mock_excluder_, IsExcluded(_)).WillRepeatedly(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
   string value;
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohort, &value));
   EXPECT_EQ(fake_update_response_.cohort, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortHint, &value));
   EXPECT_EQ(fake_update_response_.cohorthint, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortName, &value));
   EXPECT_EQ(fake_update_response_.cohortname, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey({kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohort}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohort, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortHint}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohorthint, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortName}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohortname, value);
 }
 
 TEST_F(OmahaRequestActionTest, CohortsAreUpdated) {
-  EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohort, "old_value"));
-  EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohortHint, "old_hint"));
-  EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohortName, "old_name"));
+  EXPECT_TRUE(fake_prefs_->SetString(kPrefsOmahaCohort, "old_value"));
+  EXPECT_TRUE(fake_prefs_->SetString(kPrefsOmahaCohortHint, "old_hint"));
+  EXPECT_TRUE(fake_prefs_->SetString(kPrefsOmahaCohortName, "old_name"));
+  const string dlc_cohort_key =
+      fake_prefs_->CreateSubKey({kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohort});
+  const string dlc_cohort_hint_key = fake_prefs_->CreateSubKey(
+      {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortHint});
+  const string dlc_cohort_name_key = fake_prefs_->CreateSubKey(
+      {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortName});
+  request_params_.set_dlc_apps_params(
+      {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}}});
+  EXPECT_TRUE(fake_prefs_->SetString(dlc_cohort_key, "old_value_dlc"));
+  EXPECT_TRUE(fake_prefs_->SetString(dlc_cohort_hint_key, "old_hint_dlc"));
+  EXPECT_TRUE(fake_prefs_->SetString(dlc_cohort_name_key, "old_name_dlc"));
   fake_update_response_.include_cohorts = true;
   fake_update_response_.cohort = "s/154454/8479665";
   fake_update_response_.cohorthint = "please-put-me-on-beta";
   fake_update_response_.cohortname = "";
+  fake_update_response_.dlc_app_update = true;
+  fake_update_response_.include_dlc_cohorts = true;
+  fake_update_response_.dlc_cohort = "s/154454/8479665/dlc";
+  fake_update_response_.dlc_cohorthint = "please-put-me-on-beta-dlc";
+  fake_update_response_.dlc_cohortname = "";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
+  EXPECT_CALL(mock_excluder_, IsExcluded(_)).WillRepeatedly(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
   string value;
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohort, &value));
   EXPECT_EQ(fake_update_response_.cohort, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortHint, &value));
   EXPECT_EQ(fake_update_response_.cohorthint, value);
 
-  EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
+  EXPECT_FALSE(fake_prefs_->GetString(kPrefsOmahaCohortName, &value));
+
+  EXPECT_TRUE(fake_prefs_->GetString(dlc_cohort_key, &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohort, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(dlc_cohort_hint_key, &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohorthint, value);
+
+  EXPECT_FALSE(fake_prefs_->GetString(dlc_cohort_name_key, &value));
 }
 
 TEST_F(OmahaRequestActionTest, CohortsAreNotModifiedWhenMissing) {
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
-  EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohort, "old_value"));
+  EXPECT_TRUE(fake_prefs_->SetString(kPrefsOmahaCohort, "old_value"));
+  const string dlc_cohort_key =
+      fake_prefs_->CreateSubKey({kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohort});
+  EXPECT_TRUE(fake_prefs_->SetString(dlc_cohort_key, "old_value_dlc"));
   ASSERT_TRUE(TestUpdateCheck());
 
   string value;
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohort, &value));
   EXPECT_EQ("old_value", value);
 
-  EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
-  EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
+  EXPECT_FALSE(fake_prefs_->GetString(kPrefsOmahaCohortHint, &value));
+  EXPECT_FALSE(fake_prefs_->GetString(kPrefsOmahaCohortName, &value));
+
+  EXPECT_TRUE(fake_prefs_->GetString(dlc_cohort_key, &value));
+  EXPECT_EQ("old_value_dlc", value);
+
+  EXPECT_FALSE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortHint}),
+      &value));
+  EXPECT_FALSE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortName}),
+      &value));
 }
 
 TEST_F(OmahaRequestActionTest, CohortsArePersistedWhenNoUpdate) {
@@ -1303,13 +1398,13 @@
   ASSERT_TRUE(TestUpdateCheck());
 
   string value;
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohort, &value));
   EXPECT_EQ(fake_update_response_.cohort, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortHint, &value));
   EXPECT_EQ(fake_update_response_.cohorthint, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortName, &value));
   EXPECT_EQ(fake_update_response_.cohortname, value);
 }
 
@@ -1319,19 +1414,60 @@
   fake_update_response_.cohort = "s/154454/8479665";
   fake_update_response_.cohorthint = "please-put-me-on-beta";
   fake_update_response_.cohortname = "stable";
+  request_params_.set_dlc_apps_params(
+      {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}},
+       {request_params_.GetDlcAppId(kDlcId2), {.name = kDlcId2}}});
+  fake_update_response_.dlc_app_update = true;
+  fake_update_response_.dlc_app_no_update = true;
+  fake_update_response_.include_dlc_cohorts = true;
+  fake_update_response_.dlc_cohort = "s/154454/8479665/dlc";
+  fake_update_response_.dlc_cohorthint = "please-put-me-on-beta-dlc";
+  fake_update_response_.dlc_cohortname = "stable-dlc";
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
+  EXPECT_CALL(mock_excluder_, IsExcluded(_)).WillRepeatedly(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
   string value;
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohort, &value));
   EXPECT_EQ(fake_update_response_.cohort, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortHint, &value));
   EXPECT_EQ(fake_update_response_.cohorthint, value);
 
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsOmahaCohortName, &value));
   EXPECT_EQ(fake_update_response_.cohortname, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey({kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohort}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohort, value);
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey({kDlcPrefsSubDir, kDlcId2, kPrefsOmahaCohort}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohort, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortHint}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohorthint, value);
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId2, kPrefsOmahaCohortHint}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohorthint, value);
+
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId1, kPrefsOmahaCohortName}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohortname, value);
+  EXPECT_TRUE(fake_prefs_->GetString(
+      fake_prefs_->CreateSubKey(
+          {kDlcPrefsSubDir, kDlcId2, kPrefsOmahaCohortName}),
+      &value));
+  EXPECT_EQ(fake_update_response_.dlc_cohortname, value);
 }
 
 TEST_F(OmahaRequestActionTest, NoOutputPipeTest) {
@@ -1340,7 +1476,6 @@
   loop.SetAsCurrent();
 
   auto action = std::make_unique<OmahaRequestAction>(
-      &fake_system_state_,
       nullptr,
       std::make_unique<MockHttpFetcher>(
           http_response.data(), http_response.size(), nullptr),
@@ -1365,7 +1500,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, EmptyResponseTest) {
@@ -1374,7 +1509,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, MissingStatusTest) {
@@ -1389,7 +1524,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, InvalidStatusTest) {
@@ -1404,7 +1539,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, MissingNodesetTest) {
@@ -1419,7 +1554,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, MissingFieldTest) {
@@ -1434,7 +1569,7 @@
       "<urls><url codebase=\"http://missing/field/test/\"/></urls>"
       "<manifest version=\"10.2.3.4\">"
       "<packages><package hash=\"not-used\" name=\"f\" "
-      "size=\"587\" hash_sha256=\"lkq34j5345\"/></packages>"
+      "size=\"587\" fp=\"3.789\" hash_sha256=\"lkq34j5345\"/></packages>"
       "<actions><action event=\"postinstall\" "
       "Prompt=\"false\" "
       "IsDeltaPayload=\"false\" "
@@ -1443,15 +1578,16 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ("10.2.3.4", response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ("10.2.3.4", response_.version);
   EXPECT_EQ("http://missing/field/test/f",
-            response.packages[0].payload_urls[0]);
-  EXPECT_EQ("", response.more_info_url);
-  EXPECT_EQ("lkq34j5345", response.packages[0].hash);
-  EXPECT_EQ(587u, response.packages[0].size);
-  EXPECT_FALSE(response.prompt);
-  EXPECT_TRUE(response.deadline.empty());
+            response_.packages[0].payload_urls[0]);
+  EXPECT_EQ("", response_.more_info_url);
+  EXPECT_EQ("lkq34j5345", response_.packages[0].hash);
+  EXPECT_EQ(string("3.789"), response_.packages[0].fp);
+  EXPECT_EQ(587u, response_.packages[0].size);
+  EXPECT_FALSE(response_.prompt);
+  EXPECT_TRUE(response_.deadline.empty());
 }
 
 namespace {
@@ -1475,7 +1611,6 @@
 
   string http_response("doesn't matter");
   auto action = std::make_unique<OmahaRequestAction>(
-      &fake_system_state_,
       nullptr,
       std::make_unique<MockHttpFetcher>(
           http_response.data(), http_response.size(), nullptr),
@@ -1499,9 +1634,9 @@
   request_params_.set_target_channel("unittest_track&lt;");
   request_params_.set_lts_tag("unittest_hint&lt;");
   request_params_.set_hwid("<OEM MODEL>");
-  fake_prefs_.SetString(kPrefsOmahaCohort, "evil\nstring");
-  fake_prefs_.SetString(kPrefsOmahaCohortHint, "evil&string\\");
-  fake_prefs_.SetString(
+  fake_prefs_->SetString(kPrefsOmahaCohort, "evil\nstring");
+  fake_prefs_->SetString(kPrefsOmahaCohortHint, "evil&string\\");
+  fake_prefs_->SetString(
       kPrefsOmahaCohortName,
       base::JoinString(vector<string>(100, "My spoon is too big."), " "));
   tuc_params_.http_response = "invalid xml>";
@@ -1511,22 +1646,22 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_NE(string::npos, post_str.find("testtheservice_pack&gt;"));
-  EXPECT_EQ(string::npos, post_str.find("testtheservice_pack>"));
-  EXPECT_NE(string::npos, post_str.find("x86 generic&lt;id"));
-  EXPECT_EQ(string::npos, post_str.find("x86 generic<id"));
-  EXPECT_NE(string::npos, post_str.find("unittest_track&amp;lt;"));
-  EXPECT_EQ(string::npos, post_str.find("unittest_track&lt;"));
-  EXPECT_NE(string::npos, post_str.find("unittest_hint&amp;lt;"));
-  EXPECT_EQ(string::npos, post_str.find("unittest_hint&lt;"));
-  EXPECT_NE(string::npos, post_str.find("&lt;OEM MODEL&gt;"));
-  EXPECT_EQ(string::npos, post_str.find("<OEM MODEL>"));
-  EXPECT_NE(string::npos, post_str.find("cohort=\"evil\nstring\""));
-  EXPECT_EQ(string::npos, post_str.find("cohorthint=\"evil&string\\\""));
-  EXPECT_NE(string::npos, post_str.find("cohorthint=\"evil&amp;string\\\""));
+  EXPECT_NE(string::npos, post_str_.find("testtheservice_pack&gt;"));
+  EXPECT_EQ(string::npos, post_str_.find("testtheservice_pack>"));
+  EXPECT_NE(string::npos, post_str_.find("x86 generic&lt;id"));
+  EXPECT_EQ(string::npos, post_str_.find("x86 generic<id"));
+  EXPECT_NE(string::npos, post_str_.find("unittest_track&amp;lt;"));
+  EXPECT_EQ(string::npos, post_str_.find("unittest_track&lt;"));
+  EXPECT_NE(string::npos, post_str_.find("unittest_hint&amp;lt;"));
+  EXPECT_EQ(string::npos, post_str_.find("unittest_hint&lt;"));
+  EXPECT_NE(string::npos, post_str_.find("&lt;OEM MODEL&gt;"));
+  EXPECT_EQ(string::npos, post_str_.find("<OEM MODEL>"));
+  EXPECT_NE(string::npos, post_str_.find("cohort=\"evil\nstring\""));
+  EXPECT_EQ(string::npos, post_str_.find("cohorthint=\"evil&string\\\""));
+  EXPECT_NE(string::npos, post_str_.find("cohorthint=\"evil&amp;string\\\""));
   // Values from Prefs that are too big are removed from the XML instead of
   // encoded.
-  EXPECT_EQ(string::npos, post_str.find("cohortname="));
+  EXPECT_EQ(string::npos, post_str_.find("cohortname="));
 }
 
 TEST_F(OmahaRequestActionTest, XmlDecodeTest) {
@@ -1537,10 +1672,10 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_EQ("testthe<url", response.more_info_url);
+  EXPECT_EQ("testthe<url", response_.more_info_url);
   EXPECT_EQ("testthe&codebase/file.signed",
-            response.packages[0].payload_urls[0]);
-  EXPECT_EQ("<20110101", response.deadline);
+            response_.packages[0].payload_urls[0]);
+  EXPECT_EQ("<20110101", response_.deadline);
 }
 
 TEST_F(OmahaRequestActionTest, ParseIntTest) {
@@ -1549,12 +1684,12 @@
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
+  EXPECT_EQ(fake_update_response_.size, response_.packages[0].size);
 }
 
 TEST_F(OmahaRequestActionTest, FormatUpdateCheckOutputTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   tuc_params_.http_response = "invalid xml>";
   tuc_params_.expected_code = ErrorCode::kOmahaRequestXMLParseError;
   tuc_params_.expected_check_result = metrics::CheckResult::kParsingError;
@@ -1568,13 +1703,13 @@
   ASSERT_FALSE(TestUpdateCheck());
 
   EXPECT_NE(
-      post_str.find("        <ping active=\"1\" a=\"-1\" r=\"-1\"></ping>\n"
-                    "        <updatecheck></updatecheck>\n"),
+      post_str_.find("        <ping active=\"1\" a=\"-1\" r=\"-1\"></ping>\n"
+                     "        <updatecheck></updatecheck>\n"),
       string::npos);
-  EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""),
+  EXPECT_NE(post_str_.find("hardware_class=\"OEM MODEL 09235 7471\""),
             string::npos);
   // No <event> tag should be sent if we didn't reboot to an update.
-  EXPECT_EQ(post_str.find("<event"), string::npos);
+  EXPECT_EQ(post_str_.find("<event"), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
@@ -1585,9 +1720,9 @@
       "        <event eventtype=\"%d\" eventresult=\"%d\"></event>\n",
       OmahaEvent::kTypeUpdateDownloadStarted,
       OmahaEvent::kResultSuccess);
-  EXPECT_NE(post_str.find(expected_event), string::npos);
-  EXPECT_EQ(post_str.find("ping"), string::npos);
-  EXPECT_EQ(post_str.find("updatecheck"), string::npos);
+  EXPECT_NE(post_str_.find(expected_event), string::npos);
+  EXPECT_EQ(post_str_.find("ping"), string::npos);
+  EXPECT_EQ(post_str_.find("updatecheck"), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, FormatErrorEventOutputTest) {
@@ -1602,14 +1737,13 @@
       OmahaEvent::kTypeDownloadComplete,
       OmahaEvent::kResultError,
       static_cast<int>(ErrorCode::kError));
-  EXPECT_NE(post_str.find(expected_event), string::npos);
-  EXPECT_EQ(post_str.find("updatecheck"), string::npos);
+  EXPECT_NE(post_str_.find(expected_event), string::npos);
+  EXPECT_EQ(post_str_.find("updatecheck"), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, IsEventTest) {
   string http_response("doesn't matter");
   OmahaRequestAction update_check_action(
-      &fake_system_state_,
       nullptr,
       std::make_unique<MockHttpFetcher>(
           http_response.data(), http_response.size(), nullptr),
@@ -1618,7 +1752,6 @@
   EXPECT_FALSE(update_check_action.IsEvent());
 
   OmahaRequestAction event_action(
-      &fake_system_state_,
       new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
       std::make_unique<MockHttpFetcher>(
           http_response.data(), http_response.size(), nullptr),
@@ -1639,9 +1772,9 @@
     request_params_.set_delta_okay(delta_okay);
 
     ASSERT_FALSE(TestUpdateCheck());
-    EXPECT_NE(
-        post_str.find(base::StringPrintf(" delta_okay=\"%s\"", delta_okay_str)),
-        string::npos)
+    EXPECT_NE(post_str_.find(
+                  base::StringPrintf(" delta_okay=\"%s\"", delta_okay_str)),
+              string::npos)
         << "i = " << i;
   }
 }
@@ -1658,7 +1791,7 @@
     request_params_.set_interactive(interactive);
 
     ASSERT_FALSE(TestUpdateCheck());
-    EXPECT_NE(post_str.find(
+    EXPECT_NE(post_str_.find(
                   base::StringPrintf("installsource=\"%s\"", interactive_str)),
               string::npos)
         << "i = " << i;
@@ -1678,11 +1811,11 @@
 
     ASSERT_FALSE(TestUpdateCheck());
     if (target_version_set) {
-      EXPECT_NE(post_str.find("<updatecheck targetversionprefix=\"10032.\">"),
+      EXPECT_NE(post_str_.find("<updatecheck targetversionprefix=\"10032.\">"),
                 string::npos)
           << "i = " << i;
     } else {
-      EXPECT_EQ(post_str.find("targetversionprefix"), string::npos)
+      EXPECT_EQ(post_str_.find("targetversionprefix"), string::npos)
           << "i = " << i;
     }
   }
@@ -1703,10 +1836,11 @@
 
     ASSERT_FALSE(TestUpdateCheck());
     if (rollback_allowed && target_version_set) {
-      EXPECT_NE(post_str.find("rollback_allowed=\"true\""), string::npos)
+      EXPECT_NE(post_str_.find("rollback_allowed=\"true\""), string::npos)
           << "i = " << i;
     } else {
-      EXPECT_EQ(post_str.find("rollback_allowed"), string::npos) << "i = " << i;
+      EXPECT_EQ(post_str_.find("rollback_allowed"), string::npos)
+          << "i = " << i;
     }
   }
 }
@@ -1741,15 +1875,15 @@
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
   request_params_.set_autoupdate_token(autoupdate_token);
-  fake_prefs_.SetString(kPrefsOmahaCohortHint, omaha_cohort_hint);
+  fake_prefs_->SetString(kPrefsOmahaCohortHint, omaha_cohort_hint);
 
   ASSERT_TRUE(TestUpdateCheck());
 
   EXPECT_NE(string::npos,
-            post_str.find("cohorthint=\"" +
-                          string(xml_encoded_autoupdate_token) + "\""));
-  EXPECT_EQ(string::npos, post_str.find(autoupdate_token));
-  EXPECT_EQ(string::npos, post_str.find(omaha_cohort_hint));
+            post_str_.find("cohorthint=\"" +
+                           string(xml_encoded_autoupdate_token) + "\""));
+  EXPECT_EQ(string::npos, post_str_.find(autoupdate_token));
+  EXPECT_EQ(string::npos, post_str_.find(omaha_cohort_hint));
 }
 
 TEST_F(OmahaRequestActionTest, DeviceQuickFixBuildTokenIsNotSetTest) {
@@ -1761,14 +1895,14 @@
   tuc_params_.http_response = fake_update_response_.GetNoUpdateResponse();
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
-  fake_prefs_.SetString(kPrefsOmahaCohortHint, omaha_cohort_hint);
+  fake_prefs_->SetString(kPrefsOmahaCohortHint, omaha_cohort_hint);
 
   ASSERT_TRUE(TestUpdateCheck());
 
   EXPECT_NE(
       string::npos,
-      post_str.find("cohorthint=\"" + string(xml_encoded_cohort_hint) + "\""));
-  EXPECT_EQ(string::npos, post_str.find(omaha_cohort_hint));
+      post_str_.find("cohorthint=\"" + string(xml_encoded_cohort_hint) + "\""));
+  EXPECT_EQ(string::npos, post_str_.find(omaha_cohort_hint));
 }
 
 TEST_F(OmahaRequestActionTest, TargetChannelHintTest) {
@@ -1779,12 +1913,12 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_NE(string::npos, post_str.find("ltstag=\"hint&gt;\""));
+  EXPECT_NE(string::npos, post_str_.find("ltstag=\"hint&gt;\""));
 }
 
 void OmahaRequestActionTest::PingTest(bool ping_only) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
       .Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
@@ -1807,14 +1941,14 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_NE(post_str.find("<ping active=\"1\" a=\"6\" r=\"5\"></ping>"),
+  EXPECT_NE(post_str_.find("<ping active=\"1\" a=\"6\" r=\"5\"></ping>"),
             string::npos);
   if (ping_only) {
-    EXPECT_EQ(post_str.find("updatecheck"), string::npos);
-    EXPECT_EQ(post_str.find("previousversion"), string::npos);
+    EXPECT_EQ(post_str_.find("updatecheck"), string::npos);
+    EXPECT_EQ(post_str_.find("previousversion"), string::npos);
   } else {
-    EXPECT_NE(post_str.find("updatecheck"), string::npos);
-    EXPECT_NE(post_str.find("previousversion"), string::npos);
+    EXPECT_NE(post_str_.find("updatecheck"), string::npos);
+    EXPECT_NE(post_str_.find("previousversion"), string::npos);
   }
 }
 
@@ -1828,7 +1962,7 @@
 
 TEST_F(OmahaRequestActionTest, ActivePingTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
       .Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
@@ -1848,12 +1982,12 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_NE(post_str.find("<ping active=\"1\" a=\"3\"></ping>"), string::npos);
+  EXPECT_NE(post_str_.find("<ping active=\"1\" a=\"3\"></ping>"), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, RollCallPingTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
       .Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
@@ -1873,13 +2007,13 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_NE(post_str.find("<ping active=\"1\" r=\"4\"></ping>\n"),
+  EXPECT_NE(post_str_.find("<ping active=\"1\" r=\"4\"></ping>\n"),
             string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, NoPingTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
       .Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
@@ -1904,13 +2038,13 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_EQ(post_str.find("ping"), string::npos);
+  EXPECT_EQ(post_str_.find("ping"), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, IgnoreEmptyPingTest) {
   // This test ensures that we ignore empty ping only requests.
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   int64_t now = Time::Now().ToInternalValue();
   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
       .WillOnce(DoAll(SetArgPointee<1>(now), Return(true)));
@@ -1925,12 +2059,12 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(post_str.empty());
+  EXPECT_TRUE(post_str_.empty());
 }
 
 TEST_F(OmahaRequestActionTest, BackInTimePingTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
       .Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
@@ -1956,7 +2090,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_EQ(post_str.find("ping"), string::npos);
+  EXPECT_EQ(post_str_.find("ping"), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, LastPingDayUpdateTest) {
@@ -1969,7 +2103,7 @@
   int64_t midnight_slack =
       (Time::Now() - TimeDelta::FromSeconds(195)).ToInternalValue();
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(prefs,
@@ -1994,7 +2128,7 @@
 
 TEST_F(OmahaRequestActionTest, NoElapsedSecondsTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
@@ -2013,7 +2147,7 @@
 
 TEST_F(OmahaRequestActionTest, BadElapsedSecondsTest) {
   NiceMock<MockPrefs> prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
@@ -2038,8 +2172,8 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_EQ(post_str.find("machineid="), string::npos);
-  EXPECT_EQ(post_str.find("userid="), string::npos);
+  EXPECT_EQ(post_str_.find("machineid="), string::npos);
+  EXPECT_EQ(post_str_.find("userid="), string::npos);
 }
 
 TEST_F(OmahaRequestActionTest, NetworkFailureTest) {
@@ -2054,7 +2188,7 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, NetworkFailureBadHTTPCodeTest) {
@@ -2069,7 +2203,7 @@
       metrics::DownloadErrorCode::kHttpStatusOther;
 
   ASSERT_FALSE(TestUpdateCheck());
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, TestUpdateFirstSeenAtGetsPersistedFirstTime) {
@@ -2079,7 +2213,7 @@
 
   Time arbitrary_date;
   ASSERT_TRUE(Time::FromString("6/4/1989", &arbitrary_date));
-  fake_system_state_.fake_clock()->SetWallclockTime(arbitrary_date);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(arbitrary_date);
 
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   tuc_params_.expected_code = ErrorCode::kOmahaUpdateDeferredPerPolicy;
@@ -2088,9 +2222,9 @@
   ASSERT_FALSE(TestUpdateCheck());
 
   int64_t timestamp = 0;
-  ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt, &timestamp));
+  ASSERT_TRUE(fake_prefs_->GetInt64(kPrefsUpdateFirstSeenAt, &timestamp));
   EXPECT_EQ(arbitrary_date.ToInternalValue(), timestamp);
-  EXPECT_FALSE(response.update_exists);
+  EXPECT_FALSE(response_.update_exists);
 
   // Verify if we are interactive check we don't defer.
   request_params_.set_interactive(true);
@@ -2098,7 +2232,7 @@
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUpdating;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, TestUpdateFirstSeenAtGetsUsedIfAlreadyPresent) {
@@ -2110,17 +2244,17 @@
   ASSERT_TRUE(Time::FromString("1/1/2012", &t1));
   ASSERT_TRUE(Time::FromString("1/3/2012", &t2));
   ASSERT_TRUE(
-      fake_prefs_.SetInt64(kPrefsUpdateFirstSeenAt, t1.ToInternalValue()));
-  fake_system_state_.fake_clock()->SetWallclockTime(t2);
+      fake_prefs_->SetInt64(kPrefsUpdateFirstSeenAt, t1.ToInternalValue()));
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(t2);
 
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 
   // Make sure the timestamp t1 is unchanged showing that it was reused.
   int64_t timestamp = 0;
-  ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt, &timestamp));
+  ASSERT_TRUE(fake_prefs_->GetInt64(kPrefsUpdateFirstSeenAt, &timestamp));
   ASSERT_TRUE(timestamp == t1.ToInternalValue());
 }
 
@@ -2146,12 +2280,12 @@
 
   ASSERT_FALSE(TestUpdateCheck());
 
-  EXPECT_NE(
-      string::npos,
-      post_str.find("appid=\"{22222222-2222-2222-2222-222222222222}\" "
-                    "version=\"0.0.0.0\" from_version=\"1.2.3.4\" "
-                    "track=\"stable-channel\" from_track=\"canary-channel\" "));
-  EXPECT_EQ(string::npos, post_str.find("o.bundle"));
+  EXPECT_NE(string::npos,
+            post_str_.find(
+                "appid=\"{22222222-2222-2222-2222-222222222222}\" "
+                "version=\"0.0.0.0\" from_version=\"1.2.3.4\" "
+                "track=\"stable-channel\" from_track=\"canary-channel\" "));
+  EXPECT_EQ(string::npos, post_str_.find("o.bundle"));
 }
 
 TEST_F(OmahaRequestActionTest, TestChangingToLessStableChannel) {
@@ -2178,20 +2312,20 @@
 
   EXPECT_NE(
       string::npos,
-      post_str.find("appid=\"{11111111-1111-1111-1111-111111111111}\" "
-                    "version=\"5.6.7.8\" "
-                    "track=\"canary-channel\" from_track=\"stable-channel\""));
-  EXPECT_EQ(string::npos, post_str.find("from_version"));
-  EXPECT_NE(string::npos, post_str.find("o.bundle.version=\"1\""));
+      post_str_.find("appid=\"{11111111-1111-1111-1111-111111111111}\" "
+                     "version=\"5.6.7.8\" "
+                     "track=\"canary-channel\" from_track=\"stable-channel\""));
+  EXPECT_EQ(string::npos, post_str_.find("from_version"));
+  EXPECT_NE(string::npos, post_str_.find("o.bundle.version=\"1\""));
 }
 
 // Checks that the initial ping with a=-1 r=-1 is not send when the device
 // was powerwashed.
 TEST_F(OmahaRequestActionTest, PingWhenPowerwashed) {
-  fake_prefs_.SetString(kPrefsPreviousVersion, "");
+  fake_prefs_->SetString(kPrefsPreviousVersion, "");
 
   // Flag that the device was powerwashed in the past.
-  fake_system_state_.fake_hardware()->SetPowerwashCount(1);
+  FakeSystemState::Get()->fake_hardware()->SetPowerwashCount(1);
   tuc_params_.http_response = fake_update_response_.GetNoUpdateResponse();
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
@@ -2199,19 +2333,19 @@
   ASSERT_TRUE(TestUpdateCheck());
 
   // We shouldn't send a ping in this case since powerwash > 0.
-  EXPECT_EQ(string::npos, post_str.find("<ping"));
+  EXPECT_EQ(string::npos, post_str_.find("<ping"));
 }
 
 // Checks that the initial ping with a=-1 r=-1 is not send when the device
 // first_active_omaha_ping_sent is set.
 TEST_F(OmahaRequestActionTest, PingWhenFirstActiveOmahaPingIsSent) {
-  fake_prefs_.SetString(kPrefsPreviousVersion, "");
+  fake_prefs_->SetString(kPrefsPreviousVersion, "");
 
   // Flag that the device was not powerwashed in the past.
-  fake_system_state_.fake_hardware()->SetPowerwashCount(0);
+  FakeSystemState::Get()->fake_hardware()->SetPowerwashCount(0);
 
   // Flag that the device has sent first active ping in the past.
-  fake_system_state_.fake_hardware()->SetFirstActiveOmahaPingSent();
+  FakeSystemState::Get()->fake_hardware()->SetFirstActiveOmahaPingSent();
 
   tuc_params_.http_response = fake_update_response_.GetNoUpdateResponse();
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
@@ -2221,13 +2355,13 @@
 
   // We shouldn't send a ping in this case since
   // first_active_omaha_ping_sent=true
-  EXPECT_EQ(string::npos, post_str.find("<ping"));
+  EXPECT_EQ(string::npos, post_str_.find("<ping"));
 }
 
 // Checks that the event 54 is sent on a reboot to a new update.
 TEST_F(OmahaRequestActionTest, RebootAfterUpdateEvent) {
   // Flag that the device was updated in a previous boot.
-  fake_prefs_.SetString(kPrefsPreviousVersion, "1.2.3.4");
+  fake_prefs_->SetString(kPrefsPreviousVersion, "1.2.3.4");
 
   tuc_params_.http_response = fake_update_response_.GetNoUpdateResponse();
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
@@ -2238,15 +2372,15 @@
   // An event 54 is included and has the right version.
   EXPECT_NE(
       string::npos,
-      post_str.find(base::StringPrintf("<event eventtype=\"%d\"",
-                                       OmahaEvent::kTypeRebootedAfterUpdate)));
+      post_str_.find(base::StringPrintf("<event eventtype=\"%d\"",
+                                        OmahaEvent::kTypeRebootedAfterUpdate)));
   EXPECT_NE(string::npos,
-            post_str.find("previousversion=\"1.2.3.4\"></event>"));
+            post_str_.find("previousversion=\"1.2.3.4\"></event>"));
 
   // The previous version flag should have been removed.
-  EXPECT_TRUE(fake_prefs_.Exists(kPrefsPreviousVersion));
+  EXPECT_TRUE(fake_prefs_->Exists(kPrefsPreviousVersion));
   string prev_version;
-  EXPECT_TRUE(fake_prefs_.GetString(kPrefsPreviousVersion, &prev_version));
+  EXPECT_TRUE(fake_prefs_->GetString(kPrefsPreviousVersion, &prev_version));
   EXPECT_TRUE(prev_version.empty());
 }
 
@@ -2265,7 +2399,7 @@
   string actual_p2p_url;
 
   MockPayloadState mock_payload_state;
-  fake_system_state_.set_payload_state(&mock_payload_state);
+  FakeSystemState::Get()->set_payload_state(&mock_payload_state);
   EXPECT_CALL(mock_payload_state, P2PAttemptAllowed())
       .WillRepeatedly(Return(payload_state_allow_p2p_attempt));
   EXPECT_CALL(mock_payload_state, GetUsingP2PForDownloading())
@@ -2280,7 +2414,7 @@
       .WillRepeatedly(SaveArg<0>(&actual_p2p_url));
 
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetLookupUrlForFileResult(p2p_client_result_url);
 
   TimeDelta timeout = TimeDelta::FromSeconds(kMaxP2PNetworkWaitTimeSeconds);
@@ -2295,11 +2429,11 @@
   tuc_params_.expected_check_result = metrics::CheckResult::kUpdateAvailable;
 
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 
   EXPECT_EQ(omaha_disable_p2p_for_downloading,
-            response.disable_p2p_for_downloading);
-  EXPECT_EQ(omaha_disable_p2p_for_sharing, response.disable_p2p_for_sharing);
+            response_.disable_p2p_for_downloading);
+  EXPECT_EQ(omaha_disable_p2p_for_sharing, response_.disable_p2p_for_sharing);
 
   EXPECT_EQ(expected_allow_p2p_for_downloading,
             actual_allow_p2p_for_downloading);
@@ -2398,49 +2532,49 @@
   // deadline in the response is needed to force the update attempt to
   // occur; responses without a deadline seen during OOBE will normally
   // return ErrorCode::kNonCriticalUpdateInOOBE.
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
   fake_update_response_.deadline = "20101020";
 
   // Check that we parse elapsed_days in the Omaha Response correctly.
   // and that the kPrefsInstallDateDays value is written to.
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays));
-  EXPECT_TRUE(InstallDateParseHelper("42", &response));
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(42, response.install_date_days);
-  EXPECT_TRUE(fake_prefs_.Exists(kPrefsInstallDateDays));
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsInstallDateDays));
+  EXPECT_TRUE(InstallDateParseHelper("42", &response_));
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(42, response_.install_date_days);
+  EXPECT_TRUE(fake_prefs_->Exists(kPrefsInstallDateDays));
   int64_t prefs_days;
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsInstallDateDays, &prefs_days));
   EXPECT_EQ(prefs_days, 42);
 
   // If there already is a value set, we shouldn't do anything.
-  EXPECT_TRUE(InstallDateParseHelper("7", &response));
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(7, response.install_date_days);
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
+  EXPECT_TRUE(InstallDateParseHelper("7", &response_));
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(7, response_.install_date_days);
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsInstallDateDays, &prefs_days));
   EXPECT_EQ(prefs_days, 42);
 
   // Note that elapsed_days is not necessarily divisible by 7 so check
   // that we round down correctly when populating kPrefsInstallDateDays.
-  EXPECT_TRUE(fake_prefs_.Delete(kPrefsInstallDateDays));
-  EXPECT_TRUE(InstallDateParseHelper("23", &response));
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(23, response.install_date_days);
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
+  EXPECT_TRUE(fake_prefs_->Delete(kPrefsInstallDateDays));
+  EXPECT_TRUE(InstallDateParseHelper("23", &response_));
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(23, response_.install_date_days);
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsInstallDateDays, &prefs_days));
   EXPECT_EQ(prefs_days, 21);
 
   // Check that we correctly handle elapsed_days not being included in
-  // the Omaha Response.
-  EXPECT_TRUE(InstallDateParseHelper("", &response));
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(-1, response.install_date_days);
+  // the Omaha Response_.
+  EXPECT_TRUE(InstallDateParseHelper("", &response_));
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(-1, response_.install_date_days);
 }
 
 // If there is no prefs and OOBE is not complete, we should not
 // report anything to Omaha.
 TEST_F(OmahaRequestActionTest, GetInstallDateWhenNoPrefsNorOOBE) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
-  EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), -1);
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays));
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
+  EXPECT_EQ(OmahaRequestAction::GetInstallDate(), -1);
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsInstallDateDays));
 }
 
 // If OOBE is complete and happened on a valid date (e.g. after Jan
@@ -2449,21 +2583,21 @@
 // nothing.
 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedWithInvalidDate) {
   Time oobe_date = Time::FromTimeT(42);  // Dec 31, 1969 16:00:42 PST.
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date);
-  EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), -1);
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays));
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(oobe_date);
+  EXPECT_EQ(OmahaRequestAction::GetInstallDate(), -1);
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsInstallDateDays));
 }
 
 // Then check with a valid date. The date Jan 20, 2007 0:00 PST
 // should yield an InstallDate of 14.
 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedWithValidDate) {
   Time oobe_date = Time::FromTimeT(1169280000);  // Jan 20, 2007 0:00 PST.
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date);
-  EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 14);
-  EXPECT_TRUE(fake_prefs_.Exists(kPrefsInstallDateDays));
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(oobe_date);
+  EXPECT_EQ(OmahaRequestAction::GetInstallDate(), 14);
+  EXPECT_TRUE(fake_prefs_->Exists(kPrefsInstallDateDays));
 
   int64_t prefs_days;
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsInstallDateDays, &prefs_days));
   EXPECT_EQ(prefs_days, 14);
 }
 
@@ -2473,20 +2607,20 @@
 // there's a prefs file, we should still get 14.
 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedDateChanges) {
   // Set a valid date in the prefs first.
-  EXPECT_TRUE(fake_prefs_.SetInt64(kPrefsInstallDateDays, 14));
+  EXPECT_TRUE(fake_prefs_->SetInt64(kPrefsInstallDateDays, 14));
 
   Time oobe_date = Time::FromTimeT(1170144000);  // Jan 30, 2007 0:00 PST.
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date);
-  EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 14);
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(oobe_date);
+  EXPECT_EQ(OmahaRequestAction::GetInstallDate(), 14);
 
   int64_t prefs_days;
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsInstallDateDays, &prefs_days));
   EXPECT_EQ(prefs_days, 14);
 
   // If we delete the prefs file, we should get 28 days.
-  EXPECT_TRUE(fake_prefs_.Delete(kPrefsInstallDateDays));
-  EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 28);
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
+  EXPECT_TRUE(fake_prefs_->Delete(kPrefsInstallDateDays));
+  EXPECT_EQ(OmahaRequestAction::GetInstallDate(), 28);
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsInstallDateDays, &prefs_days));
   EXPECT_EQ(prefs_days, 28);
 }
 
@@ -2494,7 +2628,7 @@
 // device sets the max kernel key version to the current version.
 // ie. the same behavior as if rollback is enabled.
 TEST_F(OmahaRequestActionTest, NoPolicyEnterpriseDevicesSetMaxRollback) {
-  FakeHardware* fake_hw = fake_system_state_.fake_hardware();
+  FakeHardware* fake_hw = FakeSystemState::Get()->fake_hardware();
 
   // Setup and verify some initial default values for the kernel TPM
   // values that control verified boot and rollback.
@@ -2505,7 +2639,7 @@
   EXPECT_EQ(kRollforwardInfinity, fake_hw->GetMaxKernelKeyRollforward());
 
   EXPECT_CALL(
-      *fake_system_state_.mock_metrics_reporter(),
+      *FakeSystemState::Get()->mock_metrics_reporter(),
       ReportKeyVersionMetrics(min_kernel_version, min_kernel_version, true))
       .Times(1);
 
@@ -2515,7 +2649,7 @@
   tuc_params_.rollback_allowed_milestones = 3;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 
   // Verify kernel_max_rollforward was set to the current minimum
   // kernel key version. This has the effect of freezing roll
@@ -2530,7 +2664,7 @@
 // max kernel key version to the current version. ie. the same
 // behavior as if rollback is enabled.
 TEST_F(OmahaRequestActionTest, NoPolicyConsumerDevicesSetMaxRollback) {
-  FakeHardware* fake_hw = fake_system_state_.fake_hardware();
+  FakeHardware* fake_hw = FakeSystemState::Get()->fake_hardware();
 
   // Setup and verify some initial default values for the kernel TPM
   // values that control verified boot and rollback.
@@ -2541,7 +2675,7 @@
   EXPECT_EQ(kRollforwardInfinity, fake_hw->GetMaxKernelKeyRollforward());
 
   EXPECT_CALL(
-      *fake_system_state_.mock_metrics_reporter(),
+      *FakeSystemState::Get()->mock_metrics_reporter(),
       ReportKeyVersionMetrics(min_kernel_version, kRollforwardInfinity, true))
       .Times(1);
 
@@ -2551,7 +2685,7 @@
   tuc_params_.rollback_allowed_milestones = 3;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 
   // Verify that with rollback disabled that kernel_max_rollforward
   // was set to logical infinity. This is the expected behavior for
@@ -2564,7 +2698,7 @@
 // Verifies that a device with rollback enabled sets kernel_max_rollforward
 // in the TPM to prevent roll forward.
 TEST_F(OmahaRequestActionTest, RollbackEnabledDevicesSetMaxRollback) {
-  FakeHardware* fake_hw = fake_system_state_.fake_hardware();
+  FakeHardware* fake_hw = FakeSystemState::Get()->fake_hardware();
 
   // Setup and verify some initial default values for the kernel TPM
   // values that control verified boot and rollback.
@@ -2576,7 +2710,7 @@
   EXPECT_EQ(kRollforwardInfinity, fake_hw->GetMaxKernelKeyRollforward());
 
   EXPECT_CALL(
-      *fake_system_state_.mock_metrics_reporter(),
+      *FakeSystemState::Get()->mock_metrics_reporter(),
       ReportKeyVersionMetrics(min_kernel_version, min_kernel_version, true))
       .Times(1);
 
@@ -2587,7 +2721,7 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 
   // Verify that with rollback enabled that kernel_max_rollforward
   // was set to the current minimum kernel key version. This has
@@ -2601,7 +2735,7 @@
 // Verifies that a device with rollback disabled sets kernel_max_rollforward
 // in the TPM to logical infinity, to allow roll forward.
 TEST_F(OmahaRequestActionTest, RollbackDisabledDevicesSetMaxRollback) {
-  FakeHardware* fake_hw = fake_system_state_.fake_hardware();
+  FakeHardware* fake_hw = FakeSystemState::Get()->fake_hardware();
 
   // Setup and verify some initial default values for the kernel TPM
   // values that control verified boot and rollback.
@@ -2613,7 +2747,7 @@
   EXPECT_EQ(kRollforwardInfinity, fake_hw->GetMaxKernelKeyRollforward());
 
   EXPECT_CALL(
-      *fake_system_state_.mock_metrics_reporter(),
+      *FakeSystemState::Get()->mock_metrics_reporter(),
       ReportKeyVersionMetrics(min_kernel_version, kRollforwardInfinity, true))
       .Times(1);
 
@@ -2624,7 +2758,7 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 
   // Verify that with rollback disabled that kernel_max_rollforward
   // was set to logical infinity.
@@ -2641,8 +2775,8 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(response.is_rollback);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(response_.is_rollback);
 }
 
 TEST_F(OmahaRequestActionTest, RollbackResponseValidVersionsParsed) {
@@ -2656,12 +2790,12 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(response.is_rollback);
-  EXPECT_EQ(1, response.rollback_key_version.firmware_key);
-  EXPECT_EQ(2, response.rollback_key_version.firmware);
-  EXPECT_EQ(3, response.rollback_key_version.kernel_key);
-  EXPECT_EQ(4, response.rollback_key_version.kernel);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(response_.is_rollback);
+  EXPECT_EQ(1, response_.rollback_key_version.firmware_key);
+  EXPECT_EQ(2, response_.rollback_key_version.firmware);
+  EXPECT_EQ(3, response_.rollback_key_version.kernel_key);
+  EXPECT_EQ(4, response_.rollback_key_version.kernel);
 }
 
 TEST_F(OmahaRequestActionTest,
@@ -2669,17 +2803,17 @@
   FakeClock fake_clock;
   Time now = Time::Now();
   fake_clock.SetWallclockTime(now);
-  fake_system_state_.set_clock(&fake_clock);
+  FakeSystemState::Get()->set_clock(&fake_clock);
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(fake_prefs_.Exists(kPrefsUpdateFirstSeenAt));
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(fake_prefs_->Exists(kPrefsUpdateFirstSeenAt));
 
   int64_t stored_first_seen_at_time;
-  EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt,
-                                   &stored_first_seen_at_time));
+  EXPECT_TRUE(fake_prefs_->GetInt64(kPrefsUpdateFirstSeenAt,
+                                    &stored_first_seen_at_time));
   EXPECT_EQ(now.ToInternalValue(), stored_first_seen_at_time);
 }
 
@@ -2688,7 +2822,7 @@
   FakeClock fake_clock;
   Time now = Time::Now();
   fake_clock.SetWallclockTime(now);
-  fake_system_state_.set_clock(&fake_clock);
+  FakeSystemState::Get()->set_clock(&fake_clock);
 
   tuc_params_.http_response = fake_update_response_.GetNoUpdateResponse();
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
@@ -2696,8 +2830,8 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_FALSE(response.update_exists);
-  EXPECT_FALSE(fake_prefs_.Exists(kPrefsUpdateFirstSeenAt));
+  EXPECT_FALSE(response_.update_exists);
+  EXPECT_FALSE(fake_prefs_->Exists(kPrefsUpdateFirstSeenAt));
 }
 
 TEST_F(OmahaRequestActionTest, InstallTest) {
@@ -2710,20 +2844,20 @@
   ASSERT_TRUE(TestUpdateCheck());
 
   for (const auto& it : request_params_.dlc_apps_params()) {
-    EXPECT_NE(string::npos, post_str.find("appid=\"" + it.first + "\""));
+    EXPECT_NE(string::npos, post_str_.find("appid=\"" + it.first + "\""));
   }
   EXPECT_NE(string::npos,
-            post_str.find("appid=\"" + fake_update_response_.app_id + "\""));
+            post_str_.find("appid=\"" + fake_update_response_.app_id + "\""));
 
-  // Count number of updatecheck tag in response.
+  // Count number of updatecheck tag in response_.
   int updatecheck_count = 0;
   size_t pos = 0;
-  while ((pos = post_str.find("<updatecheck", pos)) != string::npos) {
+  while ((pos = post_str_.find("<updatecheck", pos)) != string::npos) {
     updatecheck_count++;
     pos++;
   }
   EXPECT_EQ(request_params_.dlc_apps_params().size(), updatecheck_count);
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, InstallMissingPlatformVersionTest) {
@@ -2738,8 +2872,8 @@
 
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_EQ(fake_update_response_.current_version, response.version);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_EQ(fake_update_response_.version, response_.version);
 }
 
 TEST_F(OmahaRequestActionTest, UpdateWithDlcTest) {
@@ -2750,10 +2884,10 @@
   EXPECT_CALL(mock_excluder_, IsExcluded(_)).WillRepeatedly(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_EQ(response.packages.size(), 2u);
+  EXPECT_EQ(response_.packages.size(), 2u);
   // Two candidate URLs.
-  EXPECT_EQ(response.packages[1].payload_urls.size(), 2u);
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_EQ(response_.packages[1].payload_urls.size(), 2u);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, UpdateWithPartiallyExcludedDlcTest) {
@@ -2767,10 +2901,10 @@
       .WillOnce(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_EQ(response.packages.size(), 2u);
+  EXPECT_EQ(response_.packages.size(), 2u);
   // One candidate URL.
-  EXPECT_EQ(response.packages[1].payload_urls.size(), 1u);
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_EQ(response_.packages[1].payload_urls.size(), 1u);
+  EXPECT_TRUE(response_.update_exists);
   EXPECT_TRUE(request_params_.dlc_apps_params().at(kDlcAppId).updated);
 }
 
@@ -2785,8 +2919,8 @@
       .WillOnce(Return(true));
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_EQ(response.packages.size(), 1u);
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_EQ(response_.packages.size(), 1u);
+  EXPECT_TRUE(response_.update_exists);
   EXPECT_FALSE(request_params_.dlc_apps_params().at(kDlcAppId).updated);
 }
 
@@ -2798,7 +2932,7 @@
   EXPECT_CALL(mock_excluder_, IsExcluded(_)).WillRepeatedly(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, UpdateWithDlcAndDeprecatedDlcTest) {
@@ -2811,7 +2945,7 @@
   EXPECT_CALL(mock_excluder_, IsExcluded(_)).WillRepeatedly(Return(false));
   ASSERT_TRUE(TestUpdateCheck());
 
-  EXPECT_TRUE(response.update_exists);
+  EXPECT_TRUE(response_.update_exists);
 }
 
 TEST_F(OmahaRequestActionTest, PastRollbackVersionsNoEntries) {
@@ -2825,16 +2959,16 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(response.is_rollback);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(response_.is_rollback);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.firmware_key);
+            response_.past_rollback_key_version.firmware_key);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.firmware);
+            response_.past_rollback_key_version.firmware);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.kernel_key);
+            response_.past_rollback_key_version.kernel_key);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.kernel);
+            response_.past_rollback_key_version.kernel);
 }
 
 TEST_F(OmahaRequestActionTest, PastRollbackVersionsValidEntries) {
@@ -2852,12 +2986,12 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(response.is_rollback);
-  EXPECT_EQ(16, response.past_rollback_key_version.firmware_key);
-  EXPECT_EQ(15, response.past_rollback_key_version.firmware);
-  EXPECT_EQ(14, response.past_rollback_key_version.kernel_key);
-  EXPECT_EQ(13, response.past_rollback_key_version.kernel);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(response_.is_rollback);
+  EXPECT_EQ(16, response_.past_rollback_key_version.firmware_key);
+  EXPECT_EQ(15, response_.past_rollback_key_version.firmware);
+  EXPECT_EQ(14, response_.past_rollback_key_version.kernel_key);
+  EXPECT_EQ(13, response_.past_rollback_key_version.kernel);
 }
 
 TEST_F(OmahaRequestActionTest, MismatchNumberOfVersions) {
@@ -2876,36 +3010,36 @@
   tuc_params_.is_policy_loaded = true;
 
   EXPECT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(response.update_exists);
-  EXPECT_TRUE(response.is_rollback);
+  EXPECT_TRUE(response_.update_exists);
+  EXPECT_TRUE(response_.is_rollback);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.firmware_key);
+            response_.past_rollback_key_version.firmware_key);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.firmware);
+            response_.past_rollback_key_version.firmware);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.kernel_key);
+            response_.past_rollback_key_version.kernel_key);
   EXPECT_EQ(std::numeric_limits<uint16_t>::max(),
-            response.past_rollback_key_version.kernel);
+            response_.past_rollback_key_version.kernel);
 }
 
 TEST_F(OmahaRequestActionTest, IncludeRequisitionTest) {
   request_params_.set_device_requisition("remora");
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_NE(string::npos, post_str.find("requisition=\"remora\""));
+  EXPECT_NE(string::npos, post_str_.find("requisition=\"remora\""));
 }
 
 TEST_F(OmahaRequestActionTest, NoIncludeRequisitionTest) {
   request_params_.set_device_requisition("");
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_EQ(string::npos, post_str.find("requisition"));
+  EXPECT_EQ(string::npos, post_str_.find("requisition"));
 }
 
 TEST_F(OmahaRequestActionTest, PersistEolDateTest) {
   tuc_params_.http_response =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
-      "protocol=\"3.0\"><app appid=\"foo\" status=\"ok\">"
+      "protocol=\"3.0\"><app appid=\"test-app-id\" status=\"ok\">"
       "<ping status=\"ok\"/><updatecheck status=\"noupdate\" "
       "_eol_date=\"200\" _foo=\"bar\"/></app></response>";
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
@@ -2914,35 +3048,35 @@
   ASSERT_TRUE(TestUpdateCheck());
 
   string eol_date;
-  EXPECT_TRUE(
-      fake_system_state_.prefs()->GetString(kPrefsOmahaEolDate, &eol_date));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->GetString(kPrefsOmahaEolDate,
+                                                         &eol_date));
   EXPECT_EQ("200", eol_date);
 }
 
 TEST_F(OmahaRequestActionTest, PersistEolMissingDateTest) {
   tuc_params_.http_response =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
-      "protocol=\"3.0\"><app appid=\"foo\" status=\"ok\">"
+      "protocol=\"3.0\"><app appid=\"test-app-id\" status=\"ok\">"
       "<ping status=\"ok\"/><updatecheck status=\"noupdate\" "
       "_foo=\"bar\"/></app></response>";
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
 
   const string kDate = "123";
-  fake_system_state_.prefs()->SetString(kPrefsOmahaEolDate, kDate);
+  FakeSystemState::Get()->prefs()->SetString(kPrefsOmahaEolDate, kDate);
 
   ASSERT_TRUE(TestUpdateCheck());
 
   string eol_date;
-  EXPECT_TRUE(
-      fake_system_state_.prefs()->GetString(kPrefsOmahaEolDate, &eol_date));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->GetString(kPrefsOmahaEolDate,
+                                                         &eol_date));
   EXPECT_EQ(kDate, eol_date);
 }
 
 TEST_F(OmahaRequestActionTest, PersistEolBadDateTest) {
   tuc_params_.http_response =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
-      "protocol=\"3.0\"><app appid=\"foo\" status=\"ok\">"
+      "protocol=\"3.0\"><app appid=\"test-app-id\" status=\"ok\">"
       "<ping status=\"ok\"/><updatecheck status=\"noupdate\" "
       "_eol_date=\"bad\" foo=\"bar\"/></app></response>";
   tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
@@ -2951,8 +3085,8 @@
   ASSERT_TRUE(TestUpdateCheck());
 
   string eol_date;
-  EXPECT_TRUE(
-      fake_system_state_.prefs()->GetString(kPrefsOmahaEolDate, &eol_date));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->GetString(kPrefsOmahaEolDate,
+                                                         &eol_date));
   EXPECT_EQ(kEolDateInvalid, StringToEolDate(eol_date));
 }
 
@@ -2965,14 +3099,14 @@
 
   int64_t temp_int;
   // If there was no ping, the metadata files shouldn't exist yet.
-  EXPECT_FALSE(fake_prefs_.GetInt64(active_key_, &temp_int));
-  EXPECT_FALSE(fake_prefs_.GetInt64(last_active_key_, &temp_int));
-  EXPECT_FALSE(fake_prefs_.GetInt64(last_rollcall_key_, &temp_int));
+  EXPECT_FALSE(fake_prefs_->GetInt64(active_key_, &temp_int));
+  EXPECT_FALSE(fake_prefs_->GetInt64(last_active_key_, &temp_int));
+  EXPECT_FALSE(fake_prefs_->GetInt64(last_rollcall_key_, &temp_int));
 }
 
 TEST_F(OmahaRequestActionDlcPingTest, StorePingReplyActiveTest) {
   // Create Active value
-  fake_prefs_.SetInt64(active_key_, 0);
+  fake_prefs_->SetInt64(active_key_, 0);
 
   OmahaRequestParams::AppParams app_param = {
       .active_counting_type = OmahaRequestParams::kDateBased,
@@ -2985,17 +3119,17 @@
   int64_t temp_int;
   string temp_str;
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(fake_prefs_.GetInt64(active_key_, &temp_int));
+  EXPECT_TRUE(fake_prefs_->GetInt64(active_key_, &temp_int));
   EXPECT_EQ(temp_int, kPingInactiveValue);
-  EXPECT_TRUE(fake_prefs_.GetString(last_active_key_, &temp_str));
+  EXPECT_TRUE(fake_prefs_->GetString(last_active_key_, &temp_str));
   EXPECT_EQ(temp_str, "4763");
-  EXPECT_TRUE(fake_prefs_.GetString(last_rollcall_key_, &temp_str));
+  EXPECT_TRUE(fake_prefs_->GetString(last_rollcall_key_, &temp_str));
   EXPECT_EQ(temp_str, "4763");
 }
 
 TEST_F(OmahaRequestActionDlcPingTest, StorePingReplyInactiveTest) {
   // Create Active value
-  fake_prefs_.SetInt64(active_key_, 0);
+  fake_prefs_->SetInt64(active_key_, 0);
 
   OmahaRequestParams::AppParams app_param = {
       .active_counting_type = OmahaRequestParams::kDateBased,
@@ -3006,16 +3140,16 @@
       {{request_params_.GetDlcAppId(dlc_id_), app_param}});
 
   // Set the previous active value to an older value than 4763.
-  fake_prefs_.SetString(last_active_key_, "555");
+  fake_prefs_->SetString(last_active_key_, "555");
 
   int64_t temp_int;
   ASSERT_TRUE(TestUpdateCheck());
-  EXPECT_TRUE(fake_prefs_.GetInt64(active_key_, &temp_int));
+  EXPECT_TRUE(fake_prefs_->GetInt64(active_key_, &temp_int));
   EXPECT_EQ(temp_int, kPingInactiveValue);
   string temp_str;
-  EXPECT_TRUE(fake_prefs_.GetString(last_active_key_, &temp_str));
+  EXPECT_TRUE(fake_prefs_->GetString(last_active_key_, &temp_str));
   EXPECT_EQ(temp_str, "555");
-  EXPECT_TRUE(fake_prefs_.GetString(last_rollcall_key_, &temp_str));
+  EXPECT_TRUE(fake_prefs_->GetString(last_rollcall_key_, &temp_str));
   EXPECT_EQ(temp_str, "4763");
 }
 
diff --git a/cros/omaha_request_builder_xml.cc b/cros/omaha_request_builder_xml.cc
index 43ee548..6cd9ab8 100644
--- a/cros/omaha_request_builder_xml.cc
+++ b/cros/omaha_request_builder_xml.cc
@@ -28,7 +28,7 @@
 #include <base/time/time.h>
 
 #include "update_engine/common/constants.h"
-#include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/omaha_request_params.h"
 
@@ -144,20 +144,21 @@
     }
     if (!ping_only_) {
       if (!app_data.skip_update) {
+        const auto* params = SystemState::Get()->request_params();
         app_body += "        <updatecheck";
-        if (!params_->target_version_prefix().empty()) {
+        if (!params->target_version_prefix().empty()) {
           app_body += base::StringPrintf(
               " targetversionprefix=\"%s\"",
-              XmlEncodeWithDefault(params_->target_version_prefix()).c_str());
+              XmlEncodeWithDefault(params->target_version_prefix()).c_str());
           // Rollback requires target_version_prefix set.
-          if (params_->rollback_allowed()) {
+          if (params->rollback_allowed()) {
             app_body += " rollback_allowed=\"true\"";
           }
         }
-        if (!params_->lts_tag().empty()) {
+        if (!params->lts_tag().empty()) {
           app_body += base::StringPrintf(
               " ltstag=\"%s\"",
-              XmlEncodeWithDefault(params_->lts_tag()).c_str());
+              XmlEncodeWithDefault(params->lts_tag()).c_str());
         }
         app_body += "></updatecheck>\n";
       }
@@ -170,8 +171,9 @@
       // for ping-only requests because they come before the client has
       // rebooted. The previous version event is also not sent if it was already
       // sent for this new version with a previous updatecheck.
+      auto* prefs = SystemState::Get()->prefs();
       string prev_version;
-      if (!prefs_->GetString(kPrefsPreviousVersion, &prev_version)) {
+      if (!prefs->GetString(kPrefsPreviousVersion, &prev_version)) {
         prev_version = kNoVersion;
       }
       // We only store a non-empty previous version value after a successful
@@ -184,7 +186,7 @@
             OmahaEvent::kTypeRebootedAfterUpdate,
             OmahaEvent::kResultSuccess,
             XmlEncodeWithDefault(prev_version, kNoVersion).c_str());
-        LOG_IF(WARNING, !prefs_->SetString(kPrefsPreviousVersion, ""))
+        LOG_IF(WARNING, !prefs->SetString(kPrefsPreviousVersion, ""))
             << "Unable to reset the previous version.";
       }
     }
@@ -215,9 +217,10 @@
   return app_body;
 }
 
-string OmahaRequestBuilderXml::GetCohortArg(const string arg_name,
-                                            const string prefs_key,
-                                            const string override_value) const {
+string OmahaRequestBuilderXml::GetCohortArg(
+    const string& arg_name,
+    const string& prefs_key,
+    const string& override_value) const {
   string cohort_value;
   if (!override_value.empty()) {
     // |override_value| take precedence over pref value.
@@ -225,9 +228,10 @@
   } else {
     // There's nothing wrong with not having a given cohort setting, so we check
     // existence first to avoid the warning log message.
-    if (!prefs_->Exists(prefs_key))
+    const auto* prefs = SystemState::Get()->prefs();
+    if (!prefs->Exists(prefs_key))
       return "";
-    if (!prefs_->GetString(prefs_key, &cohort_value) || cohort_value.empty())
+    if (!prefs->GetString(prefs_key, &cohort_value) || cohort_value.empty())
       return "";
   }
   // This is a validity check to avoid sending a huge XML file back to Ohama due
@@ -262,11 +266,12 @@
 string OmahaRequestBuilderXml::GetApp(const OmahaAppData& app_data) const {
   string app_body = GetAppBody(app_data);
   string app_versions;
+  const auto* params = SystemState::Get()->request_params();
 
   // If we are downgrading to a more stable channel and we are allowed to do
   // powerwash, then pass 0.0.0.0 as the version. This is needed to get the
   // highest-versioned payload on the destination channel.
-  if (params_->ShouldPowerwash()) {
+  if (params->ShouldPowerwash()) {
     LOG(INFO) << "Passing OS version as 0.0.0.0 as we are set to powerwash "
               << "on downgrading to the version in the more stable channel";
     app_versions = "version=\"" + string(kNoVersion) + "\" from_version=\"" +
@@ -276,16 +281,16 @@
                    XmlEncodeWithDefault(app_data.version, kNoVersion) + "\" ";
   }
 
-  string download_channel = params_->download_channel();
+  string download_channel = params->download_channel();
   string app_channels =
       "track=\"" + XmlEncodeWithDefault(download_channel) + "\" ";
-  if (params_->current_channel() != download_channel) {
+  if (params->current_channel() != download_channel) {
     app_channels += "from_track=\"" +
-                    XmlEncodeWithDefault(params_->current_channel()) + "\" ";
+                    XmlEncodeWithDefault(params->current_channel()) + "\" ";
   }
 
   string delta_okay_str =
-      params_->delta_okay() && !params_->is_install() ? "true" : "false";
+      params->delta_okay() && !params->is_install() ? "true" : "false";
 
   // If install_date_days is not set (e.g. its value is -1 ), don't
   // include the attribute.
@@ -296,30 +301,47 @@
   }
 
   string app_cohort_args;
-  app_cohort_args += GetCohortArg("cohort", kPrefsOmahaCohort);
-  app_cohort_args += GetCohortArg("cohortname", kPrefsOmahaCohortName);
+  string cohort_key = kPrefsOmahaCohort;
+  string cohortname_key = kPrefsOmahaCohortName;
+  string cohorthint_key = kPrefsOmahaCohortHint;
 
+  // Override the cohort keys for DLC App IDs.
+  const auto& dlc_apps_params = params->dlc_apps_params();
+  auto itr = dlc_apps_params.find(app_data.id);
+  if (itr != dlc_apps_params.end()) {
+    auto dlc_id = itr->second.name;
+    const auto* prefs = SystemState::Get()->prefs();
+    cohort_key =
+        prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsOmahaCohort});
+    cohortname_key =
+        prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsOmahaCohortName});
+    cohorthint_key =
+        prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsOmahaCohortHint});
+  }
+
+  app_cohort_args += GetCohortArg("cohort", cohort_key);
+  app_cohort_args += GetCohortArg("cohortname", cohortname_key);
   // Policy provided value overrides pref.
-  string autoupdate_token = params_->autoupdate_token();
-  app_cohort_args += GetCohortArg("cohorthint",
-                                  kPrefsOmahaCohortHint,
-                                  autoupdate_token /* override_value */);
+  app_cohort_args +=
+      GetCohortArg("cohorthint",
+                   cohorthint_key,
+                   params->autoupdate_token() /* override_value */);
 
   string fingerprint_arg;
-  if (!params_->os_build_fingerprint().empty()) {
+  if (!params->os_build_fingerprint().empty()) {
     fingerprint_arg = "fingerprint=\"" +
-                      XmlEncodeWithDefault(params_->os_build_fingerprint()) +
+                      XmlEncodeWithDefault(params->os_build_fingerprint()) +
                       "\" ";
   }
 
   string buildtype_arg;
-  if (!params_->os_build_type().empty()) {
+  if (!params->os_build_type().empty()) {
     buildtype_arg = "os_build_type=\"" +
-                    XmlEncodeWithDefault(params_->os_build_type()) + "\" ";
+                    XmlEncodeWithDefault(params->os_build_type()) + "\" ";
   }
 
   string product_components_args;
-  if (!params_->ShouldPowerwash() && !app_data.product_components.empty()) {
+  if (!params->ShouldPowerwash() && !app_data.product_components.empty()) {
     brillo::KeyValueStore store;
     if (store.LoadFromString(app_data.product_components)) {
       for (const string& key : store.GetKeys()) {
@@ -345,9 +367,9 @@
   }
 
   string requisition_arg;
-  if (!params_->device_requisition().empty()) {
+  if (!params->device_requisition().empty()) {
     requisition_arg = "requisition=\"" +
-                      XmlEncodeWithDefault(params_->device_requisition()) +
+                      XmlEncodeWithDefault(params->device_requisition()) +
                       "\" ";
   }
 
@@ -360,14 +382,14 @@
       product_components_args +
       fingerprint_arg +
       buildtype_arg +
-      "board=\"" + XmlEncodeWithDefault(params_->os_board()) + "\" " +
-      "hardware_class=\"" + XmlEncodeWithDefault(params_->hwid()) + "\" " +
+      "board=\"" + XmlEncodeWithDefault(params->os_board()) + "\" " +
+      "hardware_class=\"" + XmlEncodeWithDefault(params->hwid()) + "\" " +
       "delta_okay=\"" + delta_okay_str + "\" " +
       install_date_in_days_str +
 
       // DLC excluded for installs and updates.
       (app_data.is_dlc ? "" :
-      "lang=\"" + XmlEncodeWithDefault(params_->app_lang(), "en-US") + "\" " +
+      "lang=\"" + XmlEncodeWithDefault(params->app_lang(), "en-US") + "\" " +
       requisition_arg) +
 
       ">\n" +
@@ -378,18 +400,20 @@
 }
 
 string OmahaRequestBuilderXml::GetOs() const {
+  const auto* params = SystemState::Get()->request_params();
   string os_xml =
       "    <os "
       "version=\"" +
-      XmlEncodeWithDefault(params_->os_version()) + "\" " + "platform=\"" +
-      XmlEncodeWithDefault(params_->os_platform()) + "\" " + "sp=\"" +
-      XmlEncodeWithDefault(params_->os_sp()) +
+      XmlEncodeWithDefault(params->os_version()) + "\" " + "platform=\"" +
+      XmlEncodeWithDefault(params->os_platform()) + "\" " + "sp=\"" +
+      XmlEncodeWithDefault(params->os_sp()) +
       "\">"
       "</os>\n";
   return os_xml;
 }
 
 string OmahaRequestBuilderXml::GetRequest() const {
+  const auto* params = SystemState::Get()->request_params();
   string os_xml = GetOs();
   string app_xml = GetApps();
 
@@ -402,7 +426,7 @@
       session_id_.c_str(),
       constants::kOmahaUpdaterID,
       kOmahaUpdaterVersion,
-      params_->interactive() ? "ondemandupdate" : "scheduler",
+      params->interactive() ? "ondemandupdate" : "scheduler",
       os_xml.c_str(),
       app_xml.c_str());
 
@@ -410,22 +434,23 @@
 }
 
 string OmahaRequestBuilderXml::GetApps() const {
+  const auto* params = SystemState::Get()->request_params();
   string app_xml = "";
   OmahaAppData product_app = {
-      .id = params_->GetAppId(),
-      .version = params_->app_version(),
-      .product_components = params_->product_components(),
+      .id = params->GetAppId(),
+      .version = params->app_version(),
+      .product_components = params->product_components(),
       // Skips updatecheck for platform app in case of an install operation.
-      .skip_update = params_->is_install(),
+      .skip_update = params->is_install(),
       .is_dlc = false,
 
       .app_params = {.active_counting_type = OmahaRequestParams::kDayBased,
                      .send_ping = include_ping_}};
   app_xml += GetApp(product_app);
-  for (const auto& it : params_->dlc_apps_params()) {
+  for (const auto& it : params->dlc_apps_params()) {
     OmahaAppData dlc_app_data = {
         .id = it.first,
-        .version = params_->is_install() ? kNoVersion : params_->app_version(),
+        .version = params->is_install() ? kNoVersion : params->app_version(),
         .skip_update = false,
         .is_dlc = true,
         .app_params = it.second};
diff --git a/cros/omaha_request_builder_xml.h b/cros/omaha_request_builder_xml.h
index 4f860dd..7c246f7 100644
--- a/cros/omaha_request_builder_xml.h
+++ b/cros/omaha_request_builder_xml.h
@@ -33,7 +33,6 @@
 
 #include "update_engine/common/action.h"
 #include "update_engine/common/http_fetcher.h"
-#include "update_engine/common/system_state.h"
 #include "update_engine/cros/omaha_request_params.h"
 #include "update_engine/cros/omaha_response.h"
 
@@ -122,22 +121,18 @@
 class OmahaRequestBuilderXml : OmahaRequestBuilder {
  public:
   OmahaRequestBuilderXml(const OmahaEvent* event,
-                         OmahaRequestParams* params,
                          bool ping_only,
                          bool include_ping,
                          int ping_active_days,
                          int ping_roll_call_days,
                          int install_date_in_days,
-                         PrefsInterface* prefs,
                          const std::string& session_id)
       : event_(event),
-        params_(params),
         ping_only_(ping_only),
         include_ping_(include_ping),
         ping_active_days_(ping_active_days),
         ping_roll_call_days_(ping_roll_call_days),
         install_date_in_days_(install_date_in_days),
-        prefs_(prefs),
         session_id_(session_id) {}
 
   ~OmahaRequestBuilderXml() override = default;
@@ -168,9 +163,9 @@
   // Returns the cohort* argument to include in the <app> tag for the passed
   // |arg_name| and |prefs_key|, if any. The return value is suitable to
   // concatenate to the list of arguments and includes a space at the end.
-  std::string GetCohortArg(const std::string arg_name,
-                           const std::string prefs_key,
-                           const std::string override_value = "") const;
+  std::string GetCohortArg(const std::string& arg_name,
+                           const std::string& prefs_key,
+                           const std::string& override_value = "") const;
 
   // Returns an XML ping element if any of the elapsed days need to be
   // sent, or an empty string otherwise.
@@ -182,13 +177,11 @@
       const OmahaRequestParams::AppParams& app_params) const;
 
   const OmahaEvent* event_;
-  OmahaRequestParams* params_;
   bool ping_only_;
   bool include_ping_;
   int ping_active_days_;
   int ping_roll_call_days_;
   int install_date_in_days_;
-  PrefsInterface* prefs_;
   std::string session_id_;
 
   DISALLOW_COPY_AND_ASSIGN(OmahaRequestBuilderXml);
diff --git a/cros/omaha_request_builder_xml_unittest.cc b/cros/omaha_request_builder_xml_unittest.cc
index 11d808b..76a7241 100644
--- a/cros/omaha_request_builder_xml_unittest.cc
+++ b/cros/omaha_request_builder_xml_unittest.cc
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include <base/guid.h>
+#include <base/strings/stringprintf.h>
 #include <gtest/gtest.h>
 
 #include "update_engine/cros/fake_system_state.h"
@@ -28,6 +29,10 @@
 using std::pair;
 using std::string;
 using std::vector;
+using testing::_;
+using testing::DoAll;
+using testing::Return;
+using testing::SetArgPointee;
 
 namespace chromeos_update_engine {
 
@@ -55,11 +60,15 @@
 
 class OmahaRequestBuilderXmlTest : public ::testing::Test {
  protected:
-  void SetUp() override {}
+  void SetUp() override {
+    FakeSystemState::CreateInstance();
+    FakeSystemState::Get()->set_request_params(&params_);
+  }
   void TearDown() override {}
 
-  FakeSystemState fake_system_state_;
   static constexpr size_t kGuidSize = 36;
+
+  OmahaRequestParams params_;
 };
 
 TEST_F(OmahaRequestBuilderXmlTest, XmlEncodeTest) {
@@ -88,16 +97,13 @@
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, PlatformGetAppTest) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_device_requisition("device requisition");
+  params_.set_device_requisition("device requisition");
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
   OmahaAppData dlc_app_data = {.id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
                                .version = "",
@@ -112,16 +118,13 @@
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, DlcGetAppTest) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_device_requisition("device requisition");
+  params_.set_device_requisition("device requisition");
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
   OmahaAppData dlc_app_data = {
       .id = "_dlc_id", .version = "", .skip_update = false, .is_dlc = true};
@@ -134,20 +137,17 @@
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlRequestIdTest) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
+  const string request_xml = omaha_request.GetRequest();
   const string key = "requestid";
   const string request_id =
-      FindAttributeKeyValueInXml(kRequestXml, key, kGuidSize);
+      FindAttributeKeyValueInXml(request_xml, key, kGuidSize);
   // A valid |request_id| is either a GUID version 4 or empty string.
   if (!request_id.empty())
     EXPECT_TRUE(base::IsValidGUID(request_id));
@@ -155,20 +155,17 @@
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlSessionIdTest) {
   const string gen_session_id = base::GenerateGUID();
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        gen_session_id};
-  const string kRequestXml = omaha_request.GetRequest();
+  const string request_xml = omaha_request.GetRequest();
   const string key = "sessionid";
   const string session_id =
-      FindAttributeKeyValueInXml(kRequestXml, key, kGuidSize);
+      FindAttributeKeyValueInXml(request_xml, key, kGuidSize);
   // A valid |session_id| is either a GUID version 4 or empty string.
   if (!session_id.empty()) {
     EXPECT_TRUE(base::IsValidGUID(session_id));
@@ -177,123 +174,107 @@
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlPlatformUpdateTest) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
-  EXPECT_EQ(1, CountSubstringInString(kRequestXml, "<updatecheck"))
-      << kRequestXml;
+  const string request_xml = omaha_request.GetRequest();
+  EXPECT_EQ(1, CountSubstringInString(request_xml, "<updatecheck"))
+      << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlPlatformUpdateWithDlcsTest) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_dlc_apps_params(
-      {{omaha_request_params.GetDlcAppId("dlc_no_0"), {.name = "dlc_no_0"}},
-       {omaha_request_params.GetDlcAppId("dlc_no_1"), {.name = "dlc_no_1"}}});
+  params_.set_dlc_apps_params(
+      {{params_.GetDlcAppId("dlc_no_0"), {.name = "dlc_no_0"}},
+       {params_.GetDlcAppId("dlc_no_1"), {.name = "dlc_no_1"}}});
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
-  EXPECT_EQ(3, CountSubstringInString(kRequestXml, "<updatecheck"))
-      << kRequestXml;
+  const string request_xml = omaha_request.GetRequest();
+  EXPECT_EQ(3, CountSubstringInString(request_xml, "<updatecheck"))
+      << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcInstallationTest) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
   const std::map<std::string, OmahaRequestParams::AppParams> dlcs = {
-      {omaha_request_params.GetDlcAppId("dlc_no_0"), {.name = "dlc_no_0"}},
-      {omaha_request_params.GetDlcAppId("dlc_no_1"), {.name = "dlc_no_1"}}};
-  omaha_request_params.set_dlc_apps_params(dlcs);
-  omaha_request_params.set_is_install(true);
+      {params_.GetDlcAppId("dlc_no_0"), {.name = "dlc_no_0"}},
+      {params_.GetDlcAppId("dlc_no_1"), {.name = "dlc_no_1"}}};
+  params_.set_dlc_apps_params(dlcs);
+  params_.set_is_install(true);
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
-  EXPECT_EQ(2, CountSubstringInString(kRequestXml, "<updatecheck"))
-      << kRequestXml;
+  const string request_xml = omaha_request.GetRequest();
+  EXPECT_EQ(2, CountSubstringInString(request_xml, "<updatecheck"))
+      << request_xml;
 
-  auto FindAppId = [kRequestXml](size_t pos) -> size_t {
-    return kRequestXml.find("<app appid", pos);
+  auto FindAppId = [request_xml](size_t pos) -> size_t {
+    return request_xml.find("<app appid", pos);
   };
   // Skip over the Platform AppID, which is always first.
   size_t pos = FindAppId(0);
   for (auto&& _ : dlcs) {
     (void)_;
-    EXPECT_NE(string::npos, (pos = FindAppId(pos + 1))) << kRequestXml;
+    EXPECT_NE(string::npos, (pos = FindAppId(pos + 1))) << request_xml;
     const string dlc_app_id_version = FindAttributeKeyValueInXml(
-        kRequestXml.substr(pos), "version", string(kNoVersion).size());
+        request_xml.substr(pos), "version", string(kNoVersion).size());
     EXPECT_EQ(kNoVersion, dlc_app_id_version);
 
     const string false_str = "false";
     const string dlc_app_id_delta_okay = FindAttributeKeyValueInXml(
-        kRequestXml.substr(pos), "delta_okay", false_str.length());
+        request_xml.substr(pos), "delta_okay", false_str.length());
     EXPECT_EQ(false_str, dlc_app_id_delta_okay);
   }
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcNoPing) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_dlc_apps_params(
-      {{omaha_request_params.GetDlcAppId("dlc_no_0"), {.name = "dlc_no_0"}}});
+  params_.set_dlc_apps_params(
+      {{params_.GetDlcAppId("dlc_no_0"), {.name = "dlc_no_0"}}});
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
-  EXPECT_EQ(0, CountSubstringInString(kRequestXml, "<ping")) << kRequestXml;
+  const string request_xml = omaha_request.GetRequest();
+  EXPECT_EQ(0, CountSubstringInString(request_xml, "<ping")) << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcPingRollCallNoActive) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_dlc_apps_params(
-      {{omaha_request_params.GetDlcAppId("dlc_no_0"),
+  params_.set_dlc_apps_params(
+      {{params_.GetDlcAppId("dlc_no_0"),
         {.active_counting_type = OmahaRequestParams::kDateBased,
          .name = "dlc_no_0",
          .ping_date_last_active = 25,
          .ping_date_last_rollcall = 36,
          .send_ping = true}}});
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
-  EXPECT_EQ(1, CountSubstringInString(kRequestXml, "<ping rd=\"36\""))
-      << kRequestXml;
+  const string request_xml = omaha_request.GetRequest();
+  EXPECT_EQ(1, CountSubstringInString(request_xml, "<ping rd=\"36\""))
+      << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcPingRollCallAndActive) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_dlc_apps_params(
-      {{omaha_request_params.GetDlcAppId("dlc_no_0"),
+  params_.set_dlc_apps_params(
+      {{params_.GetDlcAppId("dlc_no_0"),
         {.active_counting_type = OmahaRequestParams::kDateBased,
          .name = "dlc_no_0",
          .ping_active = 1,
@@ -301,101 +282,140 @@
          .ping_date_last_rollcall = 36,
          .send_ping = true}}});
   OmahaRequestBuilderXml omaha_request{nullptr,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
+  const string request_xml = omaha_request.GetRequest();
   EXPECT_EQ(1,
-            CountSubstringInString(kRequestXml,
+            CountSubstringInString(request_xml,
                                    "<ping active=\"1\" ad=\"25\" rd=\"36\""))
-      << kRequestXml;
+      << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlUpdateCompleteEvent) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
   OmahaEvent event(OmahaEvent::kTypeUpdateComplete);
   OmahaRequestBuilderXml omaha_request{&event,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
-  LOG(INFO) << kRequestXml;
+  const string request_xml = omaha_request.GetRequest();
+  LOG(INFO) << request_xml;
   EXPECT_EQ(
       1,
       CountSubstringInString(
-          kRequestXml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
-      << kRequestXml;
+          request_xml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
+      << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest,
        GetRequestXmlUpdateCompleteEventSomeDlcsExcluded) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_dlc_apps_params({
-      {omaha_request_params.GetDlcAppId("dlc_1"), {.updated = true}},
-      {omaha_request_params.GetDlcAppId("dlc_2"), {.updated = false}},
+  params_.set_dlc_apps_params({
+      {params_.GetDlcAppId("dlc_1"), {.updated = true}},
+      {params_.GetDlcAppId("dlc_2"), {.updated = false}},
   });
   OmahaEvent event(OmahaEvent::kTypeUpdateComplete);
   OmahaRequestBuilderXml omaha_request{&event,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
+  const string request_xml = omaha_request.GetRequest();
   EXPECT_EQ(
       2,
       CountSubstringInString(
-          kRequestXml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
-      << kRequestXml;
+          request_xml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
+      << request_xml;
   EXPECT_EQ(
       1,
       CountSubstringInString(
-          kRequestXml,
+          request_xml,
           "<event eventtype=\"3\" eventresult=\"0\" errorcode=\"62\"></event>"))
-      << kRequestXml;
+      << request_xml;
 }
 
 TEST_F(OmahaRequestBuilderXmlTest,
        GetRequestXmlUpdateCompleteEventAllDlcsExcluded) {
-  OmahaRequestParams omaha_request_params{&fake_system_state_};
-  omaha_request_params.set_dlc_apps_params({
-      {omaha_request_params.GetDlcAppId("dlc_1"), {.updated = false}},
-      {omaha_request_params.GetDlcAppId("dlc_2"), {.updated = false}},
+  params_.set_dlc_apps_params({
+      {params_.GetDlcAppId("dlc_1"), {.updated = false}},
+      {params_.GetDlcAppId("dlc_2"), {.updated = false}},
   });
   OmahaEvent event(OmahaEvent::kTypeUpdateComplete);
   OmahaRequestBuilderXml omaha_request{&event,
-                                       &omaha_request_params,
                                        false,
                                        false,
                                        0,
                                        0,
                                        0,
-                                       fake_system_state_.prefs(),
                                        ""};
-  const string kRequestXml = omaha_request.GetRequest();
+  const string request_xml = omaha_request.GetRequest();
   EXPECT_EQ(
       1,
       CountSubstringInString(
-          kRequestXml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
-      << kRequestXml;
+          request_xml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
+      << request_xml;
   EXPECT_EQ(
       2,
       CountSubstringInString(
-          kRequestXml,
+          request_xml,
           "<event eventtype=\"3\" eventresult=\"0\" errorcode=\"62\"></event>"))
-      << kRequestXml;
+      << request_xml;
 }
+
+TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcCohortMissingCheck) {
+  constexpr char kDlcId[] = "test-dlc-id";
+  params_.set_dlc_apps_params(
+      {{params_.GetDlcAppId(kDlcId), {.name = kDlcId}}});
+  OmahaEvent event(OmahaEvent::kTypeUpdateDownloadStarted);
+  OmahaRequestBuilderXml omaha_request{&event, false, false, 0, 0, 0, ""};
+  const string request_xml = omaha_request.GetRequest();
+
+  // Check that no cohorts are in the request.
+  EXPECT_EQ(0, CountSubstringInString(request_xml, "cohort=")) << request_xml;
+  EXPECT_EQ(0, CountSubstringInString(request_xml, "cohortname="))
+      << request_xml;
+  EXPECT_EQ(0, CountSubstringInString(request_xml, "cohorthint="))
+      << request_xml;
+}
+
+TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcCohortCheck) {
+  const string kDlcId = "test-dlc-id";
+  params_.set_dlc_apps_params(
+      {{params_.GetDlcAppId(kDlcId), {.name = kDlcId}}});
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
+  OmahaEvent event(OmahaEvent::kTypeUpdateDownloadStarted);
+  OmahaRequestBuilderXml omaha_request{&event, false, false, 0, 0, 0, ""};
+  // DLC App ID Expectations.
+  const string dlc_cohort_key = PrefsInterface::CreateSubKey(
+      {kDlcPrefsSubDir, kDlcId, kPrefsOmahaCohort});
+  const string kDlcCohortVal = "test-cohort";
+  EXPECT_TRUE(fake_prefs->SetString(dlc_cohort_key, kDlcCohortVal));
+  const string dlc_cohort_name_key = PrefsInterface::CreateSubKey(
+      {kDlcPrefsSubDir, kDlcId, kPrefsOmahaCohortName});
+  const string kDlcCohortNameVal = "test-cohortname";
+  EXPECT_TRUE(fake_prefs->SetString(dlc_cohort_name_key, kDlcCohortNameVal));
+  const string dlc_cohort_hint_key = PrefsInterface::CreateSubKey(
+      {kDlcPrefsSubDir, kDlcId, kPrefsOmahaCohortHint});
+  const string kDlcCohortHintVal = "test-cohortval";
+  EXPECT_TRUE(fake_prefs->SetString(dlc_cohort_hint_key, kDlcCohortHintVal));
+  const string request_xml = omaha_request.GetRequest();
+
+  EXPECT_EQ(1,
+            CountSubstringInString(
+                request_xml,
+                base::StringPrintf(
+                    "cohort=\"%s\" cohortname=\"%s\" cohorthint=\"%s\"",
+                    kDlcCohortVal.c_str(),
+                    kDlcCohortNameVal.c_str(),
+                    kDlcCohortHintVal.c_str())))
+      << request_xml;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/cros/omaha_request_params.cc b/cros/omaha_request_params.cc
index c814e00..adcfc75 100644
--- a/cros/omaha_request_params.cc
+++ b/cros/omaha_request_params.cc
@@ -65,8 +65,8 @@
                               const string& update_url,
                               const UpdateCheckParams& params) {
   LOG(INFO) << "Initializing parameters for this update attempt";
-  image_props_ = LoadImageProperties(system_state_);
-  mutable_image_props_ = LoadMutableImageProperties(system_state_);
+  image_props_ = LoadImageProperties();
+  mutable_image_props_ = LoadMutableImageProperties();
 
   // Validation check the channel names.
   if (!IsValidChannel(image_props_.current_channel))
@@ -84,8 +84,8 @@
 
   os_sp_ = image_props_.version + "_" + GetMachineType();
   app_lang_ = "en-US";
-  hwid_ = system_state_->hardware()->GetHardwareClass();
-  device_requisition_ = system_state_->hardware()->GetDeviceRequisition();
+  hwid_ = SystemState::Get()->hardware()->GetHardwareClass();
+  device_requisition_ = SystemState::Get()->hardware()->GetDeviceRequisition();
 
   if (image_props_.current_channel == mutable_image_props_.target_channel) {
     // deltas are only okay if the /.nodelta file does not exist.  if we don't
@@ -122,6 +122,8 @@
 
   lts_tag_ = params.lts_tag;
 
+  autoupdate_token_ = params.quick_fix_build_token;
+
   rollback_allowed_ = params.rollback_allowed;
 
   // Set whether saving data over rollback is requested.
@@ -177,7 +179,7 @@
   new_props.target_channel = new_target_channel;
   new_props.is_powerwash_allowed = is_powerwash_allowed;
 
-  if (!StoreMutableImageProperties(system_state_, new_props)) {
+  if (!StoreMutableImageProperties(new_props)) {
     if (error_message)
       *error_message = "Error storing the new channel value.";
     return false;
@@ -274,6 +276,14 @@
   return dlc_apps_params().find(app_id) != dlc_apps_params().end();
 }
 
+bool OmahaRequestParams::GetDlcId(const string& app_id, string* dlc_id) const {
+  auto itr = dlc_apps_params_.find(app_id);
+  if (itr == dlc_apps_params_.end())
+    return false;
+  *dlc_id = itr->second.name;
+  return true;
+}
+
 void OmahaRequestParams::SetDlcNoUpdate(const string& app_id) {
   auto itr = dlc_apps_params_.find(app_id);
   if (itr == dlc_apps_params_.end())
diff --git a/cros/omaha_request_params.h b/cros/omaha_request_params.h
index 26ea1c9..fd4c2e2 100644
--- a/cros/omaha_request_params.h
+++ b/cros/omaha_request_params.h
@@ -37,8 +37,6 @@
 
 namespace chromeos_update_engine {
 
-class SystemState;
-
 // This class encapsulates the data Omaha gets for the request, along with
 // essential state needed for the processing of the request/response.  The
 // strings in this struct should not be XML escaped.
@@ -47,9 +45,8 @@
 // reflect its lifetime more appropriately.
 class OmahaRequestParams {
  public:
-  explicit OmahaRequestParams(SystemState* system_state)
-      : system_state_(system_state),
-        os_platform_(constants::kOmahaPlatformName),
+  OmahaRequestParams()
+      : os_platform_(constants::kOmahaPlatformName),
         os_version_(kOsVersion),
         delta_okay_(true),
         interactive_(false),
@@ -228,6 +225,10 @@
   // request parameters.
   virtual bool IsDlcAppId(const std::string& app_id) const;
 
+  // Returns the DLC App ID if the given App ID is a DLC that is currently part
+  // of the request parameters.
+  virtual bool GetDlcId(const std::string& app_id, std::string* dlc_id) const;
+
   // If the App ID is a DLC App ID will set to no update.
   void SetDlcNoUpdate(const std::string& app_id);
 
@@ -323,9 +324,6 @@
   // Gets the machine type (e.g. "i686").
   std::string GetMachineType() const;
 
-  // Global system context.
-  SystemState* system_state_;
-
   // The system image properties.
   ImageProperties image_props_;
   MutableImageProperties mutable_image_props_;
diff --git a/cros/omaha_request_params_unittest.cc b/cros/omaha_request_params_unittest.cc
index 71f3d4c..2d67ec0 100644
--- a/cros/omaha_request_params_unittest.cc
+++ b/cros/omaha_request_params_unittest.cc
@@ -25,7 +25,6 @@
 #include <gtest/gtest.h>
 
 #include "update_engine/common/constants.h"
-#include "update_engine/common/fake_prefs.h"
 #include "update_engine/common/platform_constants.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
@@ -38,26 +37,23 @@
 
 class OmahaRequestParamsTest : public ::testing::Test {
  public:
-  OmahaRequestParamsTest() : params_(&fake_system_state_) {}
+  OmahaRequestParamsTest() : params_() {}
 
  protected:
   void SetUp() override {
     // Create a uniquely named test directory.
     ASSERT_TRUE(tempdir_.CreateUniqueTempDir());
     params_.set_root(tempdir_.GetPath().value());
+    FakeSystemState::CreateInstance();
     SetLockDown(false);
-    fake_system_state_.set_prefs(&fake_prefs_);
   }
 
   void SetLockDown(bool locked_down) {
-    fake_system_state_.fake_hardware()->SetIsOfficialBuild(locked_down);
-    fake_system_state_.fake_hardware()->SetIsNormalBootMode(locked_down);
+    FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(locked_down);
+    FakeSystemState::Get()->fake_hardware()->SetIsNormalBootMode(locked_down);
   }
 
-  FakeSystemState fake_system_state_;
-  OmahaRequestParams params_{&fake_system_state_};
-  FakePrefs fake_prefs_;
-
+  OmahaRequestParams params_;
   base::ScopedTempDir tempdir_;
 };
 
@@ -110,7 +106,7 @@
 
 TEST_F(OmahaRequestParamsTest, SetTargetChannelTest) {
   {
-    OmahaRequestParams params(&fake_system_state_);
+    OmahaRequestParams params;
     params.set_root(tempdir_.GetPath().value());
     EXPECT_TRUE(params.Init("", "", {}));
     EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
@@ -124,7 +120,7 @@
 
 TEST_F(OmahaRequestParamsTest, SetIsPowerwashAllowedTest) {
   {
-    OmahaRequestParams params(&fake_system_state_);
+    OmahaRequestParams params;
     params.set_root(tempdir_.GetPath().value());
     EXPECT_TRUE(params.Init("", "", {}));
     EXPECT_TRUE(params.SetTargetChannel("canary-channel", true, nullptr));
@@ -138,7 +134,7 @@
 
 TEST_F(OmahaRequestParamsTest, SetTargetChannelInvalidTest) {
   {
-    OmahaRequestParams params(&fake_system_state_);
+    OmahaRequestParams params;
     params.set_root(tempdir_.GetPath().value());
     SetLockDown(true);
     EXPECT_TRUE(params.Init("", "", {}));
@@ -261,4 +257,38 @@
   EXPECT_TRUE(params_.Init("", "", {}));
   EXPECT_EQ("fake_requisition", params_.device_requisition());
 }
+
+TEST_F(OmahaRequestParamsTest, GetMissingDlcId) {
+  EXPECT_TRUE(params_.Init("", "", {}));
+
+  string dlc_id;
+  EXPECT_FALSE(params_.GetDlcId("some-dlc-app-id", &dlc_id));
+}
+
+TEST_F(OmahaRequestParamsTest, GetDlcId) {
+  EXPECT_TRUE(params_.Init("", "", {}));
+  const string kExpectedDlcId = "test-dlc";
+  const string dlc_app_id = params_.GetDlcAppId(kExpectedDlcId);
+  params_.set_dlc_apps_params({{dlc_app_id, {.name = kExpectedDlcId}}});
+
+  string dlc_id;
+  EXPECT_TRUE(params_.GetDlcId(dlc_app_id, &dlc_id));
+  EXPECT_EQ(kExpectedDlcId, dlc_id);
+}
+
+TEST_F(OmahaRequestParamsTest, GetDlcAppId) {
+  EXPECT_TRUE(params_.Init("", "", {}));
+  const string kAppId = "test-app-id";
+  params_.set_app_id(kAppId);
+  const string kDlcId = "test-dlc";
+  const string expected_dlc_app_id = kAppId + "_" + kDlcId;
+
+  EXPECT_EQ(expected_dlc_app_id, params_.GetDlcAppId(kDlcId));
+}
+
+TEST_F(OmahaRequestParamsTest, AutoUpdateTokenTest) {
+  EXPECT_TRUE(params_.Init("", "", {.quick_fix_build_token = "foo-token"}));
+  EXPECT_EQ("foo-token", params_.autoupdate_token());
+}
+
 }  // namespace chromeos_update_engine
diff --git a/cros/omaha_response.h b/cros/omaha_response.h
index 43783d6..3b07745 100644
--- a/cros/omaha_response.h
+++ b/cros/omaha_response.h
@@ -55,6 +55,8 @@
     bool can_exclude = false;
     // The App ID associated with the package.
     std::string app_id;
+    // The unique fingerprint value associated with the package.
+    std::string fp;
   };
   std::vector<Package> packages;
 
diff --git a/cros/omaha_response_handler_action.cc b/cros/omaha_response_handler_action.cc
index b6c223f..04cae3e 100644
--- a/cros/omaha_response_handler_action.cc
+++ b/cros/omaha_response_handler_action.cc
@@ -27,6 +27,7 @@
 #include "update_engine/common/constants.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/connection_manager_interface.h"
 #include "update_engine/cros/omaha_request_params.h"
@@ -43,10 +44,8 @@
 
 namespace chromeos_update_engine {
 
-OmahaResponseHandlerAction::OmahaResponseHandlerAction(
-    SystemState* system_state)
-    : system_state_(system_state),
-      deadline_file_(constants::kOmahaResponseDeadlineFile) {}
+OmahaResponseHandlerAction::OmahaResponseHandlerAction()
+    : deadline_file_(constants::kOmahaResponseDeadlineFile) {}
 
 void OmahaResponseHandlerAction::PerformAction() {
   CHECK(HasInputObject());
@@ -60,7 +59,7 @@
 
   // All decisions as to which URL should be used have already been done. So,
   // make the current URL as the download URL.
-  string current_url = system_state_->payload_state()->GetCurrentUrl();
+  string current_url = SystemState::Get()->payload_state()->GetCurrentUrl();
   if (current_url.empty()) {
     // This shouldn't happen as we should always supply the HTTPS backup URL.
     // Handling this anyway, just in case.
@@ -76,8 +75,9 @@
   install_plan_.download_url = current_url;
   install_plan_.version = response.version;
 
-  OmahaRequestParams* const params = system_state_->request_params();
-  PayloadStateInterface* const payload_state = system_state_->payload_state();
+  OmahaRequestParams* const params = SystemState::Get()->request_params();
+  PayloadStateInterface* const payload_state =
+      SystemState::Get()->payload_state();
 
   // If we're using p2p to download and there is a local peer, use it.
   if (payload_state->GetUsingP2PForDownloading() &&
@@ -106,31 +106,36 @@
          .metadata_signature = package.metadata_signature,
          .hash = raw_hash,
          .type = package.is_delta ? InstallPayloadType::kDelta
-                                  : InstallPayloadType::kFull});
+                                  : InstallPayloadType::kFull,
+         .fp = package.fp,
+         .app_id = package.app_id});
     update_check_response_hash += package.hash + ":";
   }
   install_plan_.public_key_rsa = response.public_key_rsa;
   install_plan_.hash_checks_mandatory = AreHashChecksMandatory(response);
   install_plan_.is_resume = DeltaPerformer::CanResumeUpdate(
-      system_state_->prefs(), update_check_response_hash);
+      SystemState::Get()->prefs(), update_check_response_hash);
   if (install_plan_.is_resume) {
     payload_state->UpdateResumed();
   } else {
     payload_state->UpdateRestarted();
     LOG_IF(WARNING,
-           !DeltaPerformer::ResetUpdateProgress(system_state_->prefs(), false))
+           !DeltaPerformer::ResetUpdateProgress(SystemState::Get()->prefs(),
+                                                false))
         << "Unable to reset the update progress.";
     LOG_IF(WARNING,
-           !system_state_->prefs()->SetString(kPrefsUpdateCheckResponseHash,
-                                              update_check_response_hash))
+           !SystemState::Get()->prefs()->SetString(
+               kPrefsUpdateCheckResponseHash, update_check_response_hash))
         << "Unable to save the update check response hash.";
   }
 
   if (params->is_install()) {
-    install_plan_.target_slot = system_state_->boot_control()->GetCurrentSlot();
+    install_plan_.target_slot =
+        SystemState::Get()->boot_control()->GetCurrentSlot();
     install_plan_.source_slot = BootControlInterface::kInvalidSlot;
   } else {
-    install_plan_.source_slot = system_state_->boot_control()->GetCurrentSlot();
+    install_plan_.source_slot =
+        SystemState::Get()->boot_control()->GetCurrentSlot();
     install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0;
   }
 
@@ -140,8 +145,8 @@
   // downloaded from.
   string current_channel_key =
       kPrefsChannelOnSlotPrefix + std::to_string(install_plan_.target_slot);
-  system_state_->prefs()->SetString(current_channel_key,
-                                    params->download_channel());
+  SystemState::Get()->prefs()->SetString(current_channel_key,
+                                         params->download_channel());
 
   // Checking whether device is able to boot up the returned rollback image.
   if (response.is_rollback) {
@@ -153,9 +158,9 @@
 
     // Calculate the values on the version values on current device.
     auto min_kernel_key_version = static_cast<uint32_t>(
-        system_state_->hardware()->GetMinKernelKeyVersion());
+        SystemState::Get()->hardware()->GetMinKernelKeyVersion());
     auto min_firmware_key_version = static_cast<uint32_t>(
-        system_state_->hardware()->GetMinFirmwareKeyVersion());
+        SystemState::Get()->hardware()->GetMinFirmwareKeyVersion());
 
     uint32_t kernel_key_version =
         static_cast<uint32_t>(response.rollback_key_version.kernel_key) << 16 |
@@ -208,15 +213,14 @@
       install_plan_.powerwash_required = true;
       // Always try to preserve enrollment and wifi data for enrolled devices.
       install_plan_.rollback_data_save_requested =
-          system_state_ && system_state_->device_policy() &&
-          system_state_->device_policy()->IsEnterpriseEnrolled();
+          SystemState::Get()->device_policy() &&
+          SystemState::Get()->device_policy()->IsEnterpriseEnrolled();
     }
   }
 
   TEST_AND_RETURN(HasOutputPipe());
   if (HasOutputPipe())
     SetOutputObject(install_plan_);
-  LOG(INFO) << "Using this install plan:";
   install_plan_.Dump();
 
   // Send the deadline data (if any) to Chrome through a file. This is a pretty
@@ -242,7 +246,7 @@
 
   // Check the generated install-plan with the Policy to confirm that
   // it can be applied at this time (or at all).
-  UpdateManager* const update_manager = system_state_->update_manager();
+  UpdateManager* const update_manager = SystemState::Get()->update_manager();
   CHECK(update_manager);
   auto ec = ErrorCode::kSuccess;
   update_manager->PolicyRequest(
@@ -283,7 +287,7 @@
                 << " max_firmware_rollforward=" << max_firmware_rollforward
                 << " rollback_allowed_milestones="
                 << params->rollback_allowed_milestones();
-      system_state_->hardware()->SetMaxKernelKeyRollforward(
+      SystemState::Get()->hardware()->SetMaxKernelKeyRollforward(
           max_kernel_rollforward);
       // TODO(crbug/783998): Set max firmware rollforward when implemented.
     }
@@ -292,7 +296,8 @@
               << " to infinity";
     // When rollback is not allowed, explicitly set the max roll forward to
     // infinity.
-    system_state_->hardware()->SetMaxKernelKeyRollforward(kRollforwardInfinity);
+    SystemState::Get()->hardware()->SetMaxKernelKeyRollforward(
+        kRollforwardInfinity);
     // TODO(crbug/783998): Set max firmware rollforward when implemented.
   }
 }
@@ -312,8 +317,8 @@
   //      devmode/debugd checks pass, in which case the hash is waived.
   //  * Dev/test image:
   //    - Any URL is allowed through with no hash checking.
-  if (!system_state_->request_params()->IsUpdateUrlOfficial() ||
-      !system_state_->hardware()->IsOfficialBuild()) {
+  if (!SystemState::Get()->request_params()->IsUpdateUrlOfficial() ||
+      !SystemState::Get()->hardware()->IsOfficialBuild()) {
     // Still do a hash check if a public key is included.
     if (!response.public_key_rsa.empty()) {
       // The autoupdate_CatchBadSignatures test checks for this string
diff --git a/cros/omaha_response_handler_action.h b/cros/omaha_response_handler_action.h
index f3b821e..9842c94 100644
--- a/cros/omaha_response_handler_action.h
+++ b/cros/omaha_response_handler_action.h
@@ -22,7 +22,6 @@
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include "update_engine/common/action.h"
-#include "update_engine/common/system_state.h"
 #include "update_engine/cros/omaha_request_action.h"
 #include "update_engine/payload_consumer/install_plan.h"
 
@@ -42,7 +41,7 @@
 
 class OmahaResponseHandlerAction : public Action<OmahaResponseHandlerAction> {
  public:
-  explicit OmahaResponseHandlerAction(SystemState* system_state);
+  OmahaResponseHandlerAction();
 
   typedef ActionTraits<OmahaResponseHandlerAction>::InputObjectType
       InputObjectType;
@@ -65,9 +64,6 @@
   // of the system and the contents of the Omaha response. False otherwise.
   bool AreHashChecksMandatory(const OmahaResponse& response);
 
-  // Global system context.
-  SystemState* system_state_;
-
   // The install plan, if we have an update.
   InstallPlan install_plan_;
 
diff --git a/cros/omaha_response_handler_action_unittest.cc b/cros/omaha_response_handler_action_unittest.cc
index 8da3205..c9b46b1 100644
--- a/cros/omaha_response_handler_action_unittest.cc
+++ b/cros/omaha_response_handler_action_unittest.cc
@@ -80,7 +80,11 @@
 class OmahaResponseHandlerActionTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    FakeBootControl* fake_boot_control = fake_system_state_.fake_boot_control();
+    FakeSystemState::CreateInstance();
+    // Enable MockPrefs;
+    FakeSystemState::Get()->set_prefs(nullptr);
+    FakeBootControl* fake_boot_control =
+        FakeSystemState::Get()->fake_boot_control();
     fake_boot_control->SetPartitionDevice(kPartitionNameKernel, 0, "/dev/sdz2");
     fake_boot_control->SetPartitionDevice(kPartitionNameRoot, 0, "/dev/sdz3");
     fake_boot_control->SetPartitionDevice(kPartitionNameKernel, 1, "/dev/sdz4");
@@ -100,7 +104,6 @@
   // it in non-success cases.
   ErrorCode action_result_code_;
 
-  FakeSystemState fake_system_state_;
   // "Hash+"
   const brillo::Blob expected_hash_ = {0x48, 0x61, 0x73, 0x68, 0x2b};
 };
@@ -117,6 +120,9 @@
     "-the_update_a.b.c.d_DELTA_.tgz";
 const char* const kBadVersion = "don't update me";
 const char* const kPayloadHashHex = "486173682b";
+const char* const kPayloadFp1 = "1.755aff78ec73dfc7f590893ac";
+const char* const kPayloadFp2 = "1.98ba213e0ccec0d0e8cdc74a5";
+const char* const kPayloadAppId = "test_app_id";
 }  // namespace
 
 bool OmahaResponseHandlerActionTest::DoTest(const OmahaResponse& in,
@@ -133,25 +139,25 @@
     string expected_hash;
     for (const auto& package : in.packages)
       expected_hash += package.hash + ":";
-    EXPECT_CALL(*(fake_system_state_.mock_prefs()),
+    EXPECT_CALL(*(FakeSystemState::Get()->mock_prefs()),
                 SetString(kPrefsUpdateCheckResponseHash, expected_hash))
         .WillOnce(Return(true));
 
     int slot =
-        fake_system_state_.request_params()->is_install()
-            ? fake_system_state_.fake_boot_control()->GetCurrentSlot()
-            : 1 - fake_system_state_.fake_boot_control()->GetCurrentSlot();
+        FakeSystemState::Get()->request_params()->is_install()
+            ? FakeSystemState::Get()->fake_boot_control()->GetCurrentSlot()
+            : 1 - FakeSystemState::Get()->fake_boot_control()->GetCurrentSlot();
     string key = kPrefsChannelOnSlotPrefix + std::to_string(slot);
-    EXPECT_CALL(*(fake_system_state_.mock_prefs()), SetString(key, testing::_))
+    EXPECT_CALL(*(FakeSystemState::Get()->mock_prefs()),
+                SetString(key, testing::_))
         .WillOnce(Return(true));
   }
 
   string current_url = in.packages.size() ? in.packages[0].payload_urls[0] : "";
-  EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetCurrentUrl())
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()), GetCurrentUrl())
       .WillRepeatedly(Return(current_url));
 
-  auto response_handler_action =
-      std::make_unique<OmahaResponseHandlerAction>(&fake_system_state_);
+  auto response_handler_action = std::make_unique<OmahaResponseHandlerAction>();
   if (!test_deadline_file.empty())
     response_handler_action->deadline_file_ = test_deadline_file;
 
@@ -185,7 +191,9 @@
     in.packages.push_back(
         {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
          .size = 12,
-         .hash = kPayloadHashHex});
+         .hash = kPayloadHashHex,
+         .app_id = kPayloadAppId,
+         .fp = kPayloadFp1});
     in.more_info_url = "http://more/info";
     in.prompt = false;
     in.deadline = "20101020";
@@ -193,6 +201,8 @@
     EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
     EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
     EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+    EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+    EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
     EXPECT_EQ(1U, install_plan.target_slot);
     string deadline;
     EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
@@ -211,15 +221,19 @@
     in.packages.push_back(
         {.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
          .size = 12,
-         .hash = kPayloadHashHex});
+         .hash = kPayloadHashHex,
+         .app_id = kPayloadAppId,
+         .fp = kPayloadFp1});
     in.more_info_url = "http://more/info";
     in.prompt = true;
     InstallPlan install_plan;
     // Set the other slot as current.
-    fake_system_state_.fake_boot_control()->SetCurrentSlot(1);
+    FakeSystemState::Get()->fake_boot_control()->SetCurrentSlot(1);
     EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
     EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
     EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+    EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+    EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
     EXPECT_EQ(0U, install_plan.target_slot);
     string deadline;
     EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline) &&
@@ -230,21 +244,26 @@
     OmahaResponse in;
     in.update_exists = true;
     in.version = "a.b.c.d";
-    in.packages.push_back(
-        {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
+    in.packages.push_back({.payload_urls = {kLongName},
+                           .size = 12,
+                           .hash = kPayloadHashHex,
+                           .app_id = kPayloadAppId,
+                           .fp = kPayloadFp1});
     in.more_info_url = "http://more/info";
     in.prompt = true;
     in.deadline = "some-deadline";
     InstallPlan install_plan;
-    fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
+    FakeSystemState::Get()->fake_boot_control()->SetCurrentSlot(0);
     // Because rollback happened, the deadline shouldn't be written into the
     // file.
-    EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
+    EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()),
                 GetRollbackHappened())
         .WillOnce(Return(true));
     EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
     EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
     EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+    EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+    EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
     EXPECT_EQ(1U, install_plan.target_slot);
     string deadline;
     EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
@@ -255,19 +274,24 @@
     OmahaResponse in;
     in.update_exists = true;
     in.version = "a.b.c.d";
-    in.packages.push_back(
-        {.payload_urls = {kLongName}, .size = 12, .hash = kPayloadHashHex});
+    in.packages.push_back({.payload_urls = {kLongName},
+                           .size = 12,
+                           .hash = kPayloadHashHex,
+                           .app_id = kPayloadAppId,
+                           .fp = kPayloadFp1});
     in.more_info_url = "http://more/info";
     in.prompt = true;
     in.deadline = "some-deadline";
     InstallPlan install_plan;
-    fake_system_state_.fake_boot_control()->SetCurrentSlot(0);
-    EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
+    FakeSystemState::Get()->fake_boot_control()->SetCurrentSlot(0);
+    EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()),
                 GetRollbackHappened())
         .WillOnce(Return(false));
     EXPECT_TRUE(DoTest(in, test_deadline_file.path(), &install_plan));
     EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
     EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+    EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+    EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
     EXPECT_EQ(1U, install_plan.target_slot);
     string deadline;
     EXPECT_TRUE(utils::ReadFile(test_deadline_file.path(), &deadline));
@@ -294,10 +318,10 @@
       {.payload_urls = {kLongName}, .size = 2, .hash = kPayloadHashHex});
   in.more_info_url = "http://more/info";
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_is_install(true);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(install_plan.source_slot, UINT_MAX);
@@ -309,10 +333,14 @@
   in.version = "a.b.c.d";
   in.packages.push_back({.payload_urls = {"http://package/1"},
                          .size = 1,
-                         .hash = kPayloadHashHex});
+                         .hash = kPayloadHashHex,
+                         .app_id = kPayloadAppId,
+                         .fp = kPayloadFp1});
   in.packages.push_back({.payload_urls = {"http://package/2"},
                          .size = 2,
-                         .hash = kPayloadHashHex});
+                         .hash = kPayloadHashHex,
+                         .app_id = kPayloadAppId,
+                         .fp = kPayloadFp2});
   in.more_info_url = "http://more/info";
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
@@ -322,6 +350,10 @@
   EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
   EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[1].app_id, install_plan.payloads[1].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
+  EXPECT_EQ(in.packages[1].fp, install_plan.payloads[1].fp);
   EXPECT_EQ(in.version, install_plan.version);
 }
 
@@ -332,16 +364,20 @@
   in.packages.push_back(
       {.payload_urls = {"http://test.should/need/hash.checks.signed"},
        .size = 12,
-       .hash = kPayloadHashHex});
+       .hash = kPayloadHashHex,
+       .app_id = kPayloadAppId,
+       .fp = kPayloadFp1});
   in.more_info_url = "http://more/info";
   // Hash checks are always skipped for non-official update URLs.
-  EXPECT_CALL(*(fake_system_state_.mock_request_params()),
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
               IsUpdateUrlOfficial())
       .WillRepeatedly(Return(true));
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_TRUE(install_plan.hash_checks_mandatory);
   EXPECT_EQ(in.version, install_plan.version);
 }
@@ -353,15 +389,19 @@
   in.packages.push_back(
       {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
        .size = 12,
-       .hash = kPayloadHashHex});
+       .hash = kPayloadHashHex,
+       .app_id = kPayloadAppId,
+       .fp = kPayloadFp1});
   in.more_info_url = "http://more/info";
-  EXPECT_CALL(*(fake_system_state_.mock_request_params()),
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
               IsUpdateUrlOfficial())
       .WillRepeatedly(Return(false));
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_FALSE(install_plan.hash_checks_mandatory);
   EXPECT_EQ(in.version, install_plan.version);
 }
@@ -375,16 +415,20 @@
   in.packages.push_back(
       {.payload_urls = {"http://url.normally/needs/hash.checks.signed"},
        .size = 12,
-       .hash = kPayloadHashHex});
+       .hash = kPayloadHashHex,
+       .app_id = kPayloadAppId,
+       .fp = kPayloadFp1});
   in.more_info_url = "http://more/info";
-  EXPECT_CALL(*(fake_system_state_.mock_request_params()),
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
               IsUpdateUrlOfficial())
       .WillRepeatedly(Return(true));
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_FALSE(install_plan.hash_checks_mandatory);
   EXPECT_EQ(in.version, install_plan.version);
 }
@@ -396,15 +440,19 @@
   in.packages.push_back(
       {.payload_urls = {"https://test.should/need/hash.checks.signed"},
        .size = 12,
-       .hash = kPayloadHashHex});
+       .hash = kPayloadHashHex,
+       .app_id = kPayloadAppId,
+       .fp = kPayloadFp1});
   in.more_info_url = "http://more/info";
-  EXPECT_CALL(*(fake_system_state_.mock_request_params()),
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
               IsUpdateUrlOfficial())
       .WillRepeatedly(Return(true));
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_TRUE(install_plan.hash_checks_mandatory);
   EXPECT_EQ(in.version, install_plan.version);
 }
@@ -417,15 +465,19 @@
       {.payload_urls = {"http://test.should.still/need/hash.checks",
                         "https://test.should.still/need/hash.checks"},
        .size = 12,
-       .hash = kPayloadHashHex});
+       .hash = kPayloadHashHex,
+       .app_id = kPayloadAppId,
+       .fp = kPayloadFp1});
   in.more_info_url = "http://more/info";
-  EXPECT_CALL(*(fake_system_state_.mock_request_params()),
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_request_params()),
               IsUpdateUrlOfficial())
       .WillRepeatedly(Return(true));
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_TRUE(install_plan.hash_checks_mandatory);
   EXPECT_EQ(in.version, install_plan.version);
 }
@@ -444,20 +496,15 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("canary-channel");
-  // The ImageProperties in Android uses prefs to store MutableImageProperties.
-#ifdef __ANDROID__
-  EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, true))
-      .WillOnce(Return(true));
-#endif  // __ANDROID__
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
   params.UpdateDownloadChannel();
   params.set_app_version("2.0.0.0");
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_TRUE(install_plan.powerwash_required);
@@ -477,21 +524,15 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("canary-channel");
-  // The |ImageProperties| in Android uses prefs to store
-  // |MutableImageProperties|.
-#ifdef __ANDROID__
-  EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, true))
-      .WillOnce(Return(true));
-#endif  // __ANDROID__
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", false, nullptr));
   params.UpdateDownloadChannel();
   params.set_app_version("2.0.0.0");
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.powerwash_required);
@@ -511,21 +552,15 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("beta-channel");
-  // The |ImageProperties| in Android uses prefs to store
-  // |MutableImageProperties|.
-#ifdef __ANDROID__
-  EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, true))
-      .WillOnce(Return(true));
-#endif  // __ANDROID__
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
   params.UpdateDownloadChannel();
   params.set_app_version("12345.48.0.0");
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.powerwash_required);
@@ -545,15 +580,15 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("beta-channel");
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
   params.UpdateDownloadChannel();
   params.set_app_version("12345.0.0.0");
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.powerwash_required);
@@ -576,8 +611,8 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("beta-channel");
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
@@ -587,9 +622,9 @@
   testing::NiceMock<policy::MockDevicePolicy> mock_device_policy;
   EXPECT_CALL(mock_device_policy, IsEnterpriseEnrolled())
       .WillOnce(Return(true));
-  fake_system_state_.set_device_policy(&mock_device_policy);
+  FakeSystemState::Get()->set_device_policy(&mock_device_policy);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_TRUE(install_plan.rollback_data_save_requested);
@@ -610,8 +645,8 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("beta-channel");
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
@@ -621,9 +656,9 @@
   testing::NiceMock<policy::MockDevicePolicy> mock_device_policy;
   EXPECT_CALL(mock_device_policy, IsEnterpriseEnrolled())
       .WillOnce(Return(false));
-  fake_system_state_.set_device_policy(&mock_device_policy);
+  FakeSystemState::Get()->set_device_policy(&mock_device_policy);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.rollback_data_save_requested);
@@ -643,15 +678,15 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("beta-channel");
   EXPECT_TRUE(params.SetTargetChannel("stable-channel", false, nullptr));
   params.UpdateDownloadChannel();
   params.set_app_version("12347.48.0.0");
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.rollback_data_save_requested);
@@ -671,20 +706,15 @@
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
 
-  OmahaRequestParams params(&fake_system_state_);
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  OmahaRequestParams params;
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   params.set_root(tempdir.GetPath().value());
   params.set_current_channel("stable-channel");
-  // The ImageProperties in Android uses prefs to store MutableImageProperties.
-#ifdef __ANDROID__
-  EXPECT_CALL(*fake_system_state_.mock_prefs(), SetBoolean(_, false))
-      .WillOnce(Return(true));
-#endif  // __ANDROID__
   EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
   params.UpdateDownloadChannel();
   params.set_app_version("1.0.0.0");
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.powerwash_required);
@@ -697,29 +727,33 @@
   in.packages.push_back(
       {.payload_urls = {"https://would.not/cause/hash/checks"},
        .size = 12,
-       .hash = kPayloadHashHex});
+       .hash = kPayloadHashHex,
+       .app_id = kPayloadAppId,
+       .fp = kPayloadFp1});
   in.more_info_url = "http://more/info";
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   // We're using a real OmahaRequestParams object here so we can't mock
   // IsUpdateUrlOfficial(), but setting the update URL to the AutoUpdate test
   // server will cause IsUpdateUrlOfficial() to return true.
   params.set_update_url(constants::kOmahaDefaultAUTestURL);
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
               SetUsingP2PForDownloading(true));
 
   string p2p_url = "http://9.8.7.6/p2p";
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(), GetP2PUrl())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(), GetP2PUrl())
       .WillRepeatedly(Return(p2p_url));
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
               GetUsingP2PForDownloading())
       .WillRepeatedly(Return(true));
 
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_EQ(p2p_url, install_plan.download_url);
   EXPECT_TRUE(install_plan.hash_checks_mandatory);
 }
@@ -746,17 +780,18 @@
 
   in.past_rollback_key_version = m4;
 
-  fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
-  fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
+  FakeSystemState::Get()->fake_hardware()->SetMinKernelKeyVersion(0x00010002);
+  FakeSystemState::Get()->fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
 
-  fake_system_state_.fake_hardware()->SetMaxKernelKeyRollforward(0xaaaaaaaa);
+  FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
+      0xaaaaaaaa);
   // TODO(crbug/783998): Add support for firmware when implemented.
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_rollback_allowed(true);
   params.set_rollback_allowed_milestones(4);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_TRUE(install_plan.is_rollback);
@@ -766,8 +801,9 @@
   const uint32_t expected_max_kernel_rollforward =
       static_cast<uint32_t>(m4.kernel_key) << 16 |
       static_cast<uint32_t>(m4.kernel);
-  EXPECT_EQ(expected_max_kernel_rollforward,
-            fake_system_state_.fake_hardware()->GetMaxKernelKeyRollforward());
+  EXPECT_EQ(
+      expected_max_kernel_rollforward,
+      FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
   // TODO(crbug/783998): Add support for firmware when implemented.
 }
 
@@ -790,23 +826,24 @@
   m4.kernel = 13;
   in.past_rollback_key_version = m4;
 
-  fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
-  fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
+  FakeSystemState::Get()->fake_hardware()->SetMinKernelKeyVersion(0x00010002);
+  FakeSystemState::Get()->fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
   const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
-  fake_system_state_.fake_hardware()->SetMaxKernelKeyRollforward(
+  FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
       current_kernel_max_rollforward);
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_rollback_allowed(true);
   params.set_rollback_allowed_milestones(4);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_FALSE(DoTest(in, "", &install_plan));
 
   // Max rollforward is not changed in error cases.
-  EXPECT_EQ(current_kernel_max_rollforward,
-            fake_system_state_.fake_hardware()->GetMaxKernelKeyRollforward());
+  EXPECT_EQ(
+      current_kernel_max_rollforward,
+      FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
   // TODO(crbug/783998): Add support for firmware when implemented.
 }
 
@@ -824,14 +861,14 @@
   in.rollback_key_version.firmware_key = 3;
   in.rollback_key_version.firmware = 3;  // This is lower than the minimum.
 
-  fake_system_state_.fake_hardware()->SetMinKernelKeyVersion(0x00010002);
-  fake_system_state_.fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
+  FakeSystemState::Get()->fake_hardware()->SetMinKernelKeyVersion(0x00010002);
+  FakeSystemState::Get()->fake_hardware()->SetMinFirmwareKeyVersion(0x00030004);
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_rollback_allowed(true);
   params.set_rollback_allowed_milestones(4);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_FALSE(DoTest(in, "", &install_plan));
 }
@@ -845,21 +882,22 @@
   in.is_rollback = false;
 
   const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
-  fake_system_state_.fake_hardware()->SetMaxKernelKeyRollforward(
+  FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
       current_kernel_max_rollforward);
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_rollback_allowed(true);
   params.set_rollback_allowed_milestones(4);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
   EXPECT_FALSE(install_plan.is_rollback);
 
   // Max rollforward is not changed for non-rollback cases.
-  EXPECT_EQ(current_kernel_max_rollforward,
-            fake_system_state_.fake_hardware()->GetMaxKernelKeyRollforward());
+  EXPECT_EQ(
+      current_kernel_max_rollforward,
+      FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
   // TODO(crbug/783998): Add support for firmware when implemented.
 }
 
@@ -871,21 +909,22 @@
                          .hash = kPayloadHashHex});
   in.is_rollback = true;
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_rollback_allowed(false);
   params.set_rollback_allowed_milestones(4);
 
   const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
-  fake_system_state_.fake_hardware()->SetMaxKernelKeyRollforward(
+  FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
       current_kernel_max_rollforward);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_FALSE(DoTest(in, "", &install_plan));
 
   // This case generates an error so, do not update max rollforward.
-  EXPECT_EQ(current_kernel_max_rollforward,
-            fake_system_state_.fake_hardware()->GetMaxKernelKeyRollforward());
+  EXPECT_EQ(
+      current_kernel_max_rollforward,
+      FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
   // TODO(crbug/783998): Add support for firmware when implemented.
 }
 
@@ -897,21 +936,22 @@
                          .hash = kPayloadHashHex});
   in.is_rollback = false;
 
-  OmahaRequestParams params(&fake_system_state_);
+  OmahaRequestParams params;
   params.set_rollback_allowed(true);
   params.set_rollback_allowed_milestones(0);
 
   const uint32_t current_kernel_max_rollforward = 0xaaaaaaaa;
-  fake_system_state_.fake_hardware()->SetMaxKernelKeyRollforward(
+  FakeSystemState::Get()->fake_hardware()->SetMaxKernelKeyRollforward(
       current_kernel_max_rollforward);
 
-  fake_system_state_.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
 
   // When allowed_milestones is 0, this is set to infinity.
-  EXPECT_EQ(kRollforwardInfinity,
-            fake_system_state_.fake_hardware()->GetMaxKernelKeyRollforward());
+  EXPECT_EQ(
+      kRollforwardInfinity,
+      FakeSystemState::Get()->fake_hardware()->GetMaxKernelKeyRollforward());
   // TODO(crbug/783998): Add support for firmware when implemented.
 }
 
@@ -921,10 +961,14 @@
   in.version = "a.b.c.d";
   in.packages.push_back({.payload_urls = {"http://package/1"},
                          .size = 1,
-                         .hash = kPayloadHashHex});
+                         .hash = kPayloadHashHex,
+                         .app_id = kPayloadAppId,
+                         .fp = kPayloadFp1});
   in.packages.push_back({.payload_urls = {"http://package/2"},
                          .size = 2,
-                         .hash = kPayloadHashHex});
+                         .hash = kPayloadHashHex,
+                         .app_id = kPayloadAppId,
+                         .fp = kPayloadFp2});
   in.more_info_url = "http://more/info";
   InstallPlan install_plan;
   EXPECT_TRUE(DoTest(in, "", &install_plan));
@@ -934,6 +978,10 @@
   EXPECT_EQ(in.packages[1].size, install_plan.payloads[1].size);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
   EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[1].app_id, install_plan.payloads[1].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
+  EXPECT_EQ(in.packages[1].fp, install_plan.payloads[1].fp);
   EXPECT_EQ(in.version, install_plan.version);
 }
 
@@ -943,12 +991,13 @@
   in.version = "a.b.c.d";
   in.packages.push_back({.payload_urls = {"http://foo/the_update_a.b.c.d.tgz"},
                          .size = 12,
-                         .hash = kPayloadHashHex});
+                         .hash = kPayloadHashHex,
+                         .app_id = kPayloadAppId,
+                         .fp = kPayloadFp1});
   // Setup the UpdateManager to disallow the update.
-  FakeClock fake_clock;
-  MockPolicy* mock_policy = new MockPolicy(&fake_clock);
+  MockPolicy* mock_policy = new MockPolicy();
   FakeUpdateManager* fake_update_manager =
-      fake_system_state_.fake_update_manager();
+      FakeSystemState::Get()->fake_update_manager();
   fake_update_manager->set_policy(mock_policy);
   EXPECT_CALL(*mock_policy, UpdateCanBeApplied(_, _, _, _, _))
       .WillOnce(
@@ -964,6 +1013,8 @@
   install_plan = *delegate_.response_handler_action_install_plan_;
   EXPECT_EQ(in.packages[0].payload_urls[0], install_plan.download_url);
   EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
+  EXPECT_EQ(in.packages[0].app_id, install_plan.payloads[0].app_id);
+  EXPECT_EQ(in.packages[0].fp, install_plan.payloads[0].fp);
   EXPECT_EQ(1U, install_plan.target_slot);
   EXPECT_EQ(in.version, install_plan.version);
 }
diff --git a/cros/p2p_manager.cc b/cros/p2p_manager.cc
index dc12b35..19e2600 100644
--- a/cros/p2p_manager.cc
+++ b/cros/p2p_manager.cc
@@ -51,6 +51,7 @@
 #include <base/strings/stringprintf.h>
 
 #include "update_engine/common/subprocess.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/update_manager/policy.h"
 #include "update_engine/update_manager/update_manager.h"
@@ -115,7 +116,6 @@
 class P2PManagerImpl : public P2PManager {
  public:
   P2PManagerImpl(Configuration* configuration,
-                 ClockInterface* clock,
                  UpdateManager* update_manager,
                  const string& file_extension,
                  const int num_files_to_keep,
@@ -170,9 +170,6 @@
   // Configuration object.
   unique_ptr<Configuration> configuration_;
 
-  // Object for telling the time.
-  ClockInterface* clock_;
-
   // A pointer to the global Update Manager.
   UpdateManager* update_manager_;
 
@@ -211,13 +208,11 @@
 const char P2PManagerImpl::kTmpExtension[] = ".tmp";
 
 P2PManagerImpl::P2PManagerImpl(Configuration* configuration,
-                               ClockInterface* clock,
                                UpdateManager* update_manager,
                                const string& file_extension,
                                const int num_files_to_keep,
                                const TimeDelta& max_file_age)
-    : clock_(clock),
-      update_manager_(update_manager),
+    : update_manager_(update_manager),
       file_extension_(file_extension),
       num_files_to_keep_(num_files_to_keep),
       max_file_age_(max_file_age) {
@@ -344,8 +339,9 @@
     // If instructed to keep only files younger than a given age
     // (|max_file_age_| != 0), delete files satisfying this criteria
     // right now. Otherwise add it to a list we'll consider for later.
-    if (clock_ != nullptr && max_file_age_ != TimeDelta() &&
-        clock_->GetWallclockTime() - time > max_file_age_) {
+    if (max_file_age_ != TimeDelta() &&
+        SystemState::Get()->clock()->GetWallclockTime() - time >
+            max_file_age_) {
       if (!DeleteP2PFile(name, "file too old"))
         deletion_failed = true;
     } else {
@@ -722,13 +718,11 @@
 }
 
 P2PManager* P2PManager::Construct(Configuration* configuration,
-                                  ClockInterface* clock,
                                   UpdateManager* update_manager,
                                   const string& file_extension,
                                   const int num_files_to_keep,
                                   const TimeDelta& max_file_age) {
   return new P2PManagerImpl(configuration,
-                            clock,
                             update_manager,
                             file_extension,
                             num_files_to_keep,
diff --git a/cros/p2p_manager.h b/cros/p2p_manager.h
index bd359fa..bef7806 100644
--- a/cros/p2p_manager.h
+++ b/cros/p2p_manager.h
@@ -27,7 +27,6 @@
 #include <policy/device_policy.h>
 #include <policy/libpolicy.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/common/prefs_interface.h"
 #include "update_engine/update_manager/update_manager.h"
 
@@ -174,7 +173,6 @@
   // performing housekeeping (pass zero to allow files of any age).
   static P2PManager* Construct(
       Configuration* configuration,
-      ClockInterface* clock,
       chromeos_update_manager::UpdateManager* update_manager,
       const std::string& file_extension,
       const int num_files_to_keep,
diff --git a/cros/p2p_manager_unittest.cc b/cros/p2p_manager_unittest.cc
index 8b6d741..17c4886 100644
--- a/cros/p2p_manager_unittest.cc
+++ b/cros/p2p_manager_unittest.cc
@@ -46,12 +46,12 @@
 #include <policy/libpolicy.h>
 #include <policy/mock_device_policy.h>
 
-#include "update_engine/common/fake_clock.h"
 #include "update_engine/common/prefs.h"
 #include "update_engine/common/subprocess.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/fake_p2p_manager_configuration.h"
+#include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/fake_update_manager.h"
 #include "update_engine/update_manager/mock_policy.h"
 
@@ -72,12 +72,13 @@
 // done.
 class P2PManagerTest : public testing::Test {
  protected:
-  P2PManagerTest() : fake_um_(&fake_clock_) {}
-  ~P2PManagerTest() override {}
+  P2PManagerTest() = default;
+  ~P2PManagerTest() override = default;
 
   // Derived from testing::Test.
   void SetUp() override {
     loop_.SetAsCurrent();
+    FakeSystemState::CreateInstance();
     async_signal_handler_.Init();
     subprocess_.Init(&async_signal_handler_);
     test_conf_ = new FakeP2PManagerConfiguration();
@@ -85,12 +86,11 @@
     // Allocate and install a mock policy implementation in the fake Update
     // Manager.  Note that the FakeUpdateManager takes ownership of the policy
     // object.
-    mock_policy_ = new chromeos_update_manager::MockPolicy(&fake_clock_);
+    mock_policy_ = new chromeos_update_manager::MockPolicy();
     fake_um_.set_policy(mock_policy_);
 
     // Construct the P2P manager under test.
     manager_.reset(P2PManager::Construct(test_conf_,
-                                         &fake_clock_,
                                          &fake_um_,
                                          "cros_au",
                                          3,
@@ -110,7 +110,6 @@
   // The P2PManager::Configuration instance used for testing.
   FakeP2PManagerConfiguration* test_conf_;
 
-  FakeClock fake_clock_;
   chromeos_update_manager::MockPolicy* mock_policy_ = nullptr;
   chromeos_update_manager::FakeUpdateManager fake_um_;
 
@@ -149,7 +148,6 @@
   // will be freed.
   test_conf_ = new FakeP2PManagerConfiguration();
   manager_.reset(P2PManager::Construct(test_conf_,
-                                       &fake_clock_,
                                        &fake_um_,
                                        "cros_au",
                                        3,
@@ -207,14 +205,14 @@
 
   // Set the clock just so files with a timestamp before |cutoff_time|
   // will be deleted at housekeeping.
-  fake_clock_.SetWallclockTime(cutoff_time + age_limit);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(cutoff_time +
+                                                         age_limit);
 
   // Specifically pass 0 for |num_files_to_keep| to allow any number of files.
   // Note that we need to reallocate the test_conf_ member, whose currently
   // aliased object will be freed.
   test_conf_ = new FakeP2PManagerConfiguration();
   manager_.reset(P2PManager::Construct(test_conf_,
-                                       &fake_clock_,
                                        &fake_um_,
                                        "cros_au",
                                        0 /* num_files_to_keep */,
@@ -360,7 +358,7 @@
 
 // Check that sharing a *new* file works.
 TEST_F(P2PManagerTest, ShareFile) {
-  const int kP2PTestFileSize = 1000 * 1000;  // 1 MB
+  const int kP2PTestFileSize = 1000 * 8;  // 8 KB
 
   EXPECT_TRUE(manager_->FileShare("foo", kP2PTestFileSize));
   EXPECT_EQ(manager_->FileGetPath("foo"),
@@ -379,7 +377,7 @@
 
 // Check that making a shared file visible, does what is expected.
 TEST_F(P2PManagerTest, MakeFileVisible) {
-  const int kP2PTestFileSize = 1000 * 1000;  // 1 MB
+  const int kP2PTestFileSize = 1000 * 8;  // 8 KB
 
   // First, check that it's not visible.
   manager_->FileShare("foo", kP2PTestFileSize);
diff --git a/cros/payload_state.cc b/cros/payload_state.cc
index d2e6851..d417ef5 100644
--- a/cros/payload_state.cc
+++ b/cros/payload_state.cc
@@ -78,11 +78,10 @@
     total_bytes_downloaded_[i] = current_bytes_downloaded_[i] = 0;
 }
 
-bool PayloadState::Initialize(SystemState* system_state) {
-  system_state_ = system_state;
-  prefs_ = system_state_->prefs();
-  powerwash_safe_prefs_ = system_state_->powerwash_safe_prefs();
-  excluder_ = system_state_->update_attempter()->GetExcluder();
+bool PayloadState::Initialize() {
+  prefs_ = SystemState::Get()->prefs();
+  powerwash_safe_prefs_ = SystemState::Get()->powerwash_safe_prefs();
+  excluder_ = SystemState::Get()->update_attempter()->GetExcluder();
   LoadResponseSignature();
   LoadPayloadAttemptNumber();
   LoadFullPayloadAttemptNumber();
@@ -197,7 +196,7 @@
 
   attempt_type_ = attempt_type;
 
-  ClockInterface* clock = system_state_->clock();
+  const auto* clock = SystemState::Get()->clock();
   attempt_start_time_boot_ = clock->GetBootTime();
   attempt_start_time_monotonic_ = clock->GetMonotonicTime();
   attempt_num_bytes_downloaded_ = 0;
@@ -206,7 +205,7 @@
   ConnectionType network_connection_type;
   ConnectionTethering tethering;
   ConnectionManagerInterface* connection_manager =
-      system_state_->connection_manager();
+      SystemState::Get()->connection_manager();
   if (!connection_manager->GetConnectionProperties(&network_connection_type,
                                                    &tethering)) {
     LOG(ERROR) << "Failed to determine connection type.";
@@ -236,7 +235,7 @@
 void PayloadState::UpdateSucceeded() {
   // Send the relevant metrics that are tracked in this class to UMA.
   CalculateUpdateDurationUptime();
-  SetUpdateTimestampEnd(system_state_->clock()->GetWallclockTime());
+  SetUpdateTimestampEnd(SystemState::Get()->clock()->GetWallclockTime());
 
   switch (attempt_type_) {
     case AttemptType::kUpdate:
@@ -246,7 +245,7 @@
       break;
 
     case AttemptType::kRollback:
-      system_state_->metrics_reporter()->ReportRollbackMetrics(
+      SystemState::Get()->metrics_reporter()->ReportRollbackMetrics(
           metrics::RollbackResult::kSuccess);
       break;
   }
@@ -256,7 +255,7 @@
   SetNumResponsesSeen(0);
   SetPayloadIndex(0);
 
-  metrics_utils::SetSystemUpdatedMarker(system_state_->clock(), prefs_);
+  metrics_utils::SetSystemUpdatedMarker(SystemState::Get()->clock(), prefs_);
 }
 
 void PayloadState::UpdateFailed(ErrorCode error) {
@@ -279,7 +278,7 @@
       break;
 
     case AttemptType::kRollback:
-      system_state_->metrics_reporter()->ReportRollbackMetrics(
+      SystemState::Get()->metrics_reporter()->ReportRollbackMetrics(
           metrics::RollbackResult::kFailed);
       break;
   }
@@ -409,7 +408,7 @@
               << "will happen from local peer (via p2p).";
     return false;
   }
-  if (system_state_->request_params()->interactive()) {
+  if (SystemState::Get()->request_params()->interactive()) {
     LOG(INFO) << "Payload backoff disabled for interactive update checks.";
     return false;
   }
@@ -425,7 +424,7 @@
     }
   }
 
-  if (!system_state_->hardware()->IsOfficialBuild() &&
+  if (!SystemState::Get()->hardware()->IsOfficialBuild() &&
       !prefs_->Exists(kPrefsNoIgnoreBackoff)) {
     // Backoffs are needed only for official builds. We do not want any delays
     // or update failures due to backoffs during testing or development. Unless
@@ -454,7 +453,7 @@
 }
 
 void PayloadState::Rollback() {
-  SetRollbackVersion(system_state_->request_params()->app_version());
+  SetRollbackVersion(SystemState::Get()->request_params()->app_version());
   AttemptStarted(AttemptType::kRollback);
 }
 
@@ -612,7 +611,7 @@
       return kPayloadTypeDelta;
     }
   }
-  OmahaRequestParams* params = system_state_->request_params();
+  OmahaRequestParams* params = SystemState::Get()->request_params();
   if (params->delta_okay()) {
     return kPayloadTypeFull;
   }
@@ -629,7 +628,7 @@
 
   int64_t payload_bytes_downloaded = attempt_num_bytes_downloaded_;
 
-  ClockInterface* clock = system_state_->clock();
+  const auto* clock = SystemState::Get()->clock();
   TimeDelta duration = clock->GetBootTime() - attempt_start_time_boot_;
   TimeDelta duration_uptime =
       clock->GetMonotonicTime() - attempt_start_time_monotonic_;
@@ -680,8 +679,7 @@
       break;
   }
 
-  system_state_->metrics_reporter()->ReportUpdateAttemptMetrics(
-      system_state_,
+  SystemState::Get()->metrics_reporter()->ReportUpdateAttemptMetrics(
       attempt_number,
       payload_type,
       duration,
@@ -690,7 +688,7 @@
       attempt_result,
       internal_error_code);
 
-  system_state_->metrics_reporter()->ReportUpdateAttemptDownloadMetrics(
+  SystemState::Get()->metrics_reporter()->ReportUpdateAttemptDownloadMetrics(
       payload_bytes_downloaded,
       payload_download_speed_bps,
       download_source,
@@ -720,7 +718,8 @@
   if (!attempt_in_progress)
     return;
 
-  system_state_->metrics_reporter()
+  SystemState::Get()
+      ->metrics_reporter()
       ->ReportAbnormallyTerminatedUpdateAttemptMetrics();
 
   ClearPersistedAttemptMetrics();
@@ -784,7 +783,7 @@
 
   int updates_abandoned_count = num_responses_seen_ - 1;
 
-  system_state_->metrics_reporter()->ReportSuccessfulUpdateMetrics(
+  SystemState::Get()->metrics_reporter()->ReportSuccessfulUpdateMetrics(
       attempt_count,
       updates_abandoned_count,
       payload_type,
@@ -800,7 +799,7 @@
 void PayloadState::UpdateNumReboots() {
   // We only update the reboot count when the system has been detected to have
   // been rebooted.
-  if (!system_state_->system_rebooted()) {
+  if (!SystemState::Get()->system_rebooted()) {
     return;
   }
 
@@ -820,7 +819,7 @@
   SetUrlFailureCount(0);
   SetUrlSwitchCount(0);
   UpdateBackoffExpiryTime();  // This will reset the backoff expiry time.
-  SetUpdateTimestampStart(system_state_->clock()->GetWallclockTime());
+  SetUpdateTimestampStart(SystemState::Get()->clock()->GetWallclockTime());
   SetUpdateTimestampEnd(Time());  // Set to null time
   SetUpdateDurationUptime(TimeDelta::FromSeconds(0));
   ResetDownloadSourcesOnNewUpdate();
@@ -832,7 +831,6 @@
 }
 
 void PayloadState::ResetRollbackVersion() {
-  CHECK(powerwash_safe_prefs_);
   rollback_version_ = "";
   powerwash_safe_prefs_->Delete(kPrefsRollbackVersion);
 }
@@ -881,7 +879,6 @@
 }
 
 void PayloadState::LoadResponseSignature() {
-  CHECK(prefs_);
   string stored_value;
   if (prefs_->Exists(kPrefsCurrentResponseSignature) &&
       prefs_->GetString(kPrefsCurrentResponseSignature, &stored_value)) {
@@ -890,7 +887,6 @@
 }
 
 void PayloadState::SetResponseSignature(const string& response_signature) {
-  CHECK(prefs_);
   response_signature_ = response_signature;
   LOG(INFO) << "Current Response Signature = \n" << response_signature_;
   prefs_->SetString(kPrefsCurrentResponseSignature, response_signature_);
@@ -913,7 +909,6 @@
 
 void PayloadState::SetFullPayloadAttemptNumber(
     int full_payload_attempt_number) {
-  CHECK(prefs_);
   full_payload_attempt_number_ = full_payload_attempt_number;
   LOG(INFO) << "Full Payload Attempt Number = " << full_payload_attempt_number_;
   prefs_->SetInt64(kPrefsFullPayloadAttemptNumber,
@@ -921,7 +916,6 @@
 }
 
 void PayloadState::SetPayloadIndex(size_t payload_index) {
-  CHECK(prefs_);
   payload_index_ = payload_index;
   LOG(INFO) << "Payload Index = " << payload_index_;
   prefs_->SetInt64(kPrefsUpdateStatePayloadIndex, payload_index_);
@@ -942,7 +936,6 @@
 }
 
 void PayloadState::SetUrlIndex(uint32_t url_index) {
-  CHECK(prefs_);
   url_index_ = url_index;
   LOG(INFO) << "Current URL Index = " << url_index_;
   prefs_->SetInt64(kPrefsCurrentUrlIndex, url_index_);
@@ -958,7 +951,6 @@
 }
 
 void PayloadState::SetScatteringWaitPeriod(TimeDelta wait_period) {
-  CHECK(prefs_);
   scattering_wait_period_ = wait_period;
   LOG(INFO) << "Scattering Wait Period (seconds) = "
             << scattering_wait_period_.InSeconds();
@@ -976,7 +968,6 @@
 }
 
 void PayloadState::SetStagingWaitPeriod(TimeDelta wait_period) {
-  CHECK(prefs_);
   staging_wait_period_ = wait_period;
   LOG(INFO) << "Staging Wait Period (days) =" << staging_wait_period_.InDays();
   if (staging_wait_period_.InSeconds() > 0) {
@@ -992,7 +983,6 @@
 }
 
 void PayloadState::SetUrlSwitchCount(uint32_t url_switch_count) {
-  CHECK(prefs_);
   url_switch_count_ = url_switch_count;
   LOG(INFO) << "URL Switch Count = " << url_switch_count_;
   prefs_->SetInt64(kPrefsUrlSwitchCount, url_switch_count_);
@@ -1003,7 +993,6 @@
 }
 
 void PayloadState::SetUrlFailureCount(uint32_t url_failure_count) {
-  CHECK(prefs_);
   url_failure_count_ = url_failure_count;
   LOG(INFO) << "Current URL (Url" << GetUrlIndex()
             << ")'s Failure Count = " << url_failure_count_;
@@ -1011,7 +1000,6 @@
 }
 
 void PayloadState::LoadBackoffExpiryTime() {
-  CHECK(prefs_);
   int64_t stored_value;
   if (!prefs_->Exists(kPrefsBackoffExpiryTime))
     return;
@@ -1030,7 +1018,6 @@
 }
 
 void PayloadState::SetBackoffExpiryTime(const Time& new_time) {
-  CHECK(prefs_);
   backoff_expiry_time_ = new_time;
   LOG(INFO) << "Backoff Expiry Time = "
             << utils::ToString(backoff_expiry_time_);
@@ -1040,7 +1027,7 @@
 
 TimeDelta PayloadState::GetUpdateDuration() {
   Time end_time = update_timestamp_end_.is_null()
-                      ? system_state_->clock()->GetWallclockTime()
+                      ? SystemState::Get()->clock()->GetWallclockTime()
                       : update_timestamp_end_;
   return end_time - update_timestamp_start_;
 }
@@ -1048,10 +1035,7 @@
 void PayloadState::LoadUpdateTimestampStart() {
   int64_t stored_value;
   Time stored_time;
-
-  CHECK(prefs_);
-
-  Time now = system_state_->clock()->GetWallclockTime();
+  Time now = SystemState::Get()->clock()->GetWallclockTime();
 
   if (!prefs_->Exists(kPrefsUpdateTimestampStart)) {
     // The preference missing is not unexpected - in that case, just
@@ -1099,8 +1083,6 @@
   int64_t stored_value;
   TimeDelta stored_delta;
 
-  CHECK(prefs_);
-
   if (!prefs_->Exists(kPrefsUpdateDurationUptime)) {
     // The preference missing is not unexpected - in that case, just
     // we'll use zero as the delta
@@ -1131,14 +1113,12 @@
 }
 
 void PayloadState::LoadRollbackHappened() {
-  CHECK(powerwash_safe_prefs_);
   bool rollback_happened = false;
   powerwash_safe_prefs_->GetBoolean(kPrefsRollbackHappened, &rollback_happened);
   SetRollbackHappened(rollback_happened);
 }
 
 void PayloadState::SetRollbackHappened(bool rollback_happened) {
-  CHECK(powerwash_safe_prefs_);
   LOG(INFO) << "Setting rollback-happened to " << rollback_happened << ".";
   rollback_happened_ = rollback_happened;
   if (rollback_happened) {
@@ -1150,7 +1130,6 @@
 }
 
 void PayloadState::LoadRollbackVersion() {
-  CHECK(powerwash_safe_prefs_);
   string rollback_version;
   if (powerwash_safe_prefs_->GetString(kPrefsRollbackVersion,
                                        &rollback_version)) {
@@ -1159,7 +1138,6 @@
 }
 
 void PayloadState::SetRollbackVersion(const string& rollback_version) {
-  CHECK(powerwash_safe_prefs_);
   LOG(INFO) << "Excluding version " << rollback_version;
   rollback_version_ = rollback_version;
   powerwash_safe_prefs_->SetString(kPrefsRollbackVersion, rollback_version);
@@ -1168,7 +1146,6 @@
 void PayloadState::SetUpdateDurationUptimeExtended(const TimeDelta& value,
                                                    const Time& timestamp,
                                                    bool use_logging) {
-  CHECK(prefs_);
   update_duration_uptime_ = value;
   update_duration_uptime_timestamp_ = timestamp;
   prefs_->SetInt64(kPrefsUpdateDurationUptime,
@@ -1180,12 +1157,12 @@
 }
 
 void PayloadState::SetUpdateDurationUptime(const TimeDelta& value) {
-  Time now = system_state_->clock()->GetMonotonicTime();
+  Time now = SystemState::Get()->clock()->GetMonotonicTime();
   SetUpdateDurationUptimeExtended(value, now, true);
 }
 
 void PayloadState::CalculateUpdateDurationUptime() {
-  Time now = system_state_->clock()->GetMonotonicTime();
+  Time now = SystemState::Get()->clock()->GetMonotonicTime();
   TimeDelta uptime_since_last_update = now - update_duration_uptime_timestamp_;
 
   if (uptime_since_last_update > TimeDelta::FromSeconds(kUptimeResolution)) {
@@ -1207,8 +1184,6 @@
 void PayloadState::SetCurrentBytesDownloaded(DownloadSource source,
                                              uint64_t current_bytes_downloaded,
                                              bool log) {
-  CHECK(prefs_);
-
   if (source >= kNumDownloadSources)
     return;
 
@@ -1230,8 +1205,6 @@
 void PayloadState::SetTotalBytesDownloaded(DownloadSource source,
                                            uint64_t total_bytes_downloaded,
                                            bool log) {
-  CHECK(prefs_);
-
   if (source >= kNumDownloadSources)
     return;
 
@@ -1250,7 +1223,6 @@
 }
 
 void PayloadState::SetNumResponsesSeen(int num_responses_seen) {
-  CHECK(prefs_);
   num_responses_seen_ = num_responses_seen;
   LOG(INFO) << "Num Responses Seen = " << num_responses_seen_;
   prefs_->SetInt64(kPrefsNumResponsesSeen, num_responses_seen_);
@@ -1259,8 +1231,8 @@
 void PayloadState::ComputeCandidateUrls() {
   bool http_url_ok = true;
 
-  if (system_state_->hardware()->IsOfficialBuild()) {
-    const policy::DevicePolicy* policy = system_state_->device_policy();
+  if (SystemState::Get()->hardware()->IsOfficialBuild()) {
+    const policy::DevicePolicy* policy = SystemState::Get()->device_policy();
     if (policy && policy->GetHttpDownloadsEnabled(&http_url_ok) && !http_url_ok)
       LOG(INFO) << "Downloads via HTTP Url are not enabled by device policy";
   } else {
@@ -1293,12 +1265,14 @@
 
   // Avoid the UpdateEngineStarted actions if this is not the first time we
   // run the update engine since reboot.
-  if (!system_state_->system_rebooted())
+  if (!SystemState::Get()->system_rebooted())
     return;
 
   // Report time_to_reboot if we booted into a new update.
   metrics_utils::LoadAndReportTimeToReboot(
-      system_state_->metrics_reporter(), prefs_, system_state_->clock());
+      SystemState::Get()->metrics_reporter(),
+      prefs_,
+      SystemState::Get()->clock());
   prefs_->Delete(kPrefsSystemUpdatedMarker);
 
   // Check if it is needed to send metrics about a failed reboot into a new
@@ -1323,7 +1297,8 @@
     // since we successfully booted the new update in that case. If the boot
     // failed, we will read this value from the same version, so it will always
     // be compatible.
-    if (installed_from == system_state_->boot_control()->GetCurrentSlot()) {
+    if (installed_from ==
+        SystemState::Get()->boot_control()->GetCurrentSlot()) {
       // A reboot was pending, but the chromebook is again in the same
       // BootDevice where the update was installed from.
       int64_t target_attempt;
@@ -1334,7 +1309,7 @@
       }
 
       // Report the UMA metric of the current boot failure.
-      system_state_->metrics_reporter()->ReportFailedUpdateCount(
+      SystemState::Get()->metrics_reporter()->ReportFailedUpdateCount(
           target_attempt);
     } else {
       prefs_->Delete(kPrefsTargetVersionAttempt);
@@ -1365,7 +1340,7 @@
   prefs_->SetInt64(kPrefsTargetVersionAttempt, target_attempt + 1);
 
   prefs_->SetInt64(kPrefsTargetVersionInstalledFrom,
-                   system_state_->boot_control()->GetCurrentSlot());
+                   SystemState::Get()->boot_control()->GetCurrentSlot());
 }
 
 void PayloadState::ResetUpdateStatus() {
@@ -1387,7 +1362,6 @@
 void PayloadState::SetP2PNumAttempts(int value) {
   p2p_num_attempts_ = value;
   LOG(INFO) << "p2p Num Attempts = " << p2p_num_attempts_;
-  CHECK(prefs_);
   prefs_->SetInt64(kPrefsP2PNumAttempts, value);
 }
 
@@ -1403,7 +1377,6 @@
   p2p_first_attempt_timestamp_ = time;
   LOG(INFO) << "p2p First Attempt Timestamp = "
             << utils::ToString(p2p_first_attempt_timestamp_);
-  CHECK(prefs_);
   int64_t stored_value = time.ToInternalValue();
   prefs_->SetInt64(kPrefsP2PFirstAttemptTimestamp, stored_value);
 }
@@ -1416,10 +1389,10 @@
 }
 
 void PayloadState::P2PNewAttempt() {
-  CHECK(prefs_);
   // Set timestamp, if it hasn't been set already
   if (p2p_first_attempt_timestamp_.is_null()) {
-    SetP2PFirstAttemptTimestamp(system_state_->clock()->GetWallclockTime());
+    SetP2PFirstAttemptTimestamp(
+        SystemState::Get()->clock()->GetWallclockTime());
   }
   // Increase number of attempts
   SetP2PNumAttempts(GetP2PNumAttempts() + 1);
@@ -1434,7 +1407,7 @@
   }
 
   if (!p2p_first_attempt_timestamp_.is_null()) {
-    Time now = system_state_->clock()->GetWallclockTime();
+    Time now = SystemState::Get()->clock()->GetWallclockTime();
     TimeDelta time_spent_attempting_p2p = now - p2p_first_attempt_timestamp_;
     if (time_spent_attempting_p2p.InSeconds() < 0) {
       LOG(ERROR) << "Time spent attempting p2p is negative"
diff --git a/cros/payload_state.h b/cros/payload_state.h
index 0827273..db54865 100644
--- a/cros/payload_state.h
+++ b/cros/payload_state.h
@@ -48,7 +48,7 @@
   // It performs the initial loading of all persisted state into memory and
   // dumps the initial state for debugging purposes.  Note: the other methods
   // should be called only after calling Initialize on this object.
-  bool Initialize(SystemState* system_state);
+  bool Initialize();
 
   // Implementation of PayloadStateInterface methods.
   void SetResponse(const OmahaResponse& response) override;
@@ -429,9 +429,6 @@
   // Get the total size of all payloads.
   int64_t GetPayloadSize();
 
-  // The global state of the system.
-  SystemState* system_state_;
-
   // Interface object with which we read/write persisted state. This must
   // be set by calling the Initialize method before calling any other method.
   PrefsInterface* prefs_;
@@ -486,10 +483,9 @@
   size_t payload_index_ = 0;
 
   // The index of the current URL.  This type is different from the one in the
-  // accessor methods because PrefsInterface supports only int64_t but we want
+  // accessor methods because |PrefsInterface| supports only int64_t but we want
   // to provide a stronger abstraction of uint32_t.  Each update to this value
-  // is persisted so we resume from the same value in case of a process
-  // restart.
+  // is persisted so we resume from the same value in case of a process restart.
   size_t url_index_;
 
   // The count of failures encountered in the current attempt to download using
diff --git a/cros/payload_state_unittest.cc b/cros/payload_state_unittest.cc
index b48cff4..5478fca 100644
--- a/cros/payload_state_unittest.cc
+++ b/cros/payload_state_unittest.cc
@@ -24,9 +24,7 @@
 
 #include "update_engine/common/constants.h"
 #include "update_engine/common/excluder_interface.h"
-#include "update_engine/common/fake_clock.h"
 #include "update_engine/common/fake_hardware.h"
-#include "update_engine/common/fake_prefs.h"
 #include "update_engine/common/metrics_reporter_interface.h"
 #include "update_engine/common/mock_excluder.h"
 #include "update_engine/common/mock_prefs.h"
@@ -106,12 +104,18 @@
   EXPECT_EQ(expected_response_sign, stored_response_sign);
 }
 
-class PayloadStateTest : public ::testing::Test {};
+class PayloadStateTest : public ::testing::Test {
+ public:
+  void SetUp() { FakeSystemState::CreateInstance(); }
 
-TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
+  // TODO(b/171829801): Replace all the |MockPrefs| in this file with
+  // |FakePrefs| so we don't have to catch every single unimportant mock call.
+};
+
+TEST_F(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
   OmahaResponse response;
-  FakeSystemState fake_system_state;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
       .Times(AtLeast(1));
@@ -133,7 +137,7 @@
       .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
   PayloadState payload_state;
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   payload_state.SetResponse(response);
   string stored_response_sign = payload_state.GetResponseSignature();
   string expected_response_sign =
@@ -146,15 +150,15 @@
   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
 }
 
-TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
+TEST_F(PayloadStateTest, SetResponseWorksWithSingleUrl) {
   OmahaResponse response;
   response.packages.push_back({.payload_urls = {"https://single.url.test"},
                                .size = 123456789,
                                .metadata_size = 58123,
                                .metadata_signature = "msign",
                                .hash = "hash"});
-  FakeSystemState fake_system_state;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
       .Times(AtLeast(1));
@@ -176,7 +180,7 @@
       .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
   PayloadState payload_state;
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   payload_state.SetResponse(response);
   string stored_response_sign = payload_state.GetResponseSignature();
   string expected_response_sign =
@@ -197,7 +201,7 @@
   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
 }
 
-TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
+TEST_F(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
   OmahaResponse response;
   response.packages.push_back({.payload_urls = {"http://multiple.url.test",
                                                 "https://multiple.url.test"},
@@ -205,8 +209,8 @@
                                .metadata_size = 558123,
                                .metadata_signature = "metasign",
                                .hash = "rhash"});
-  FakeSystemState fake_system_state;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
       .Times(AtLeast(1));
@@ -225,7 +229,7 @@
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
 
   PayloadState payload_state;
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   payload_state.SetResponse(response);
   string stored_response_sign = payload_state.GetResponseSignature();
   string expected_response_sign =
@@ -247,10 +251,10 @@
   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
 }
 
-TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
+TEST_F(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
   OmahaResponse response;
-  FakeSystemState fake_system_state;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
   PayloadState payload_state;
 
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
@@ -277,7 +281,7 @@
   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
       .Times(AtLeast(4));
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   // This does a SetResponse which causes all the states to be set to 0 for
   // the first time.
@@ -302,12 +306,11 @@
   EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
 }
 
-TEST(PayloadStateTest, NewResponseResetsPayloadState) {
+TEST_F(PayloadStateTest, NewResponseResetsPayloadState) {
   OmahaResponse response;
-  FakeSystemState fake_system_state;
   PayloadState payload_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Set the first response.
   SetupPayloadStateWith2Urls(
@@ -349,12 +352,12 @@
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
 }
 
-TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
+TEST_F(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   int progress_bytes = 100;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
 
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
@@ -400,7 +403,7 @@
       .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   SetupPayloadStateWith2Urls(
       "Hash5873", true, false, &payload_state, &response);
@@ -495,11 +498,12 @@
   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
 }
 
-TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
+TEST_F(PayloadStateTest,
+       PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
 
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
@@ -518,7 +522,7 @@
   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
       .Times(AtLeast(1));
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
@@ -534,11 +538,12 @@
   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
 }
 
-TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
+TEST_F(PayloadStateTest,
+       PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
 
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
   EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
@@ -556,7 +561,7 @@
   EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
       .Times(AtLeast(1));
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   SetupPayloadStateWith2Urls("Hash8593", true, true, &payload_state, &response);
 
@@ -571,12 +576,11 @@
   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
 }
 
-TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
+TEST_F(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash4427", true, false, &payload_state, &response);
 
@@ -592,27 +596,26 @@
   EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
 
   // Now, simulate a corrupted url index on persisted store which gets
-  // loaded when update_engine restarts. Using a different prefs object
-  // so as to not bother accounting for the uninteresting calls above.
-  FakeSystemState fake_system_state2;
-  NiceMock<MockPrefs>* prefs2 = fake_system_state2.mock_prefs();
-  EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*prefs2, GetInt64(_, _)).Times(AtLeast(1));
-  EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
+  // loaded when update_engine restarts.
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
+  EXPECT_CALL(*prefs, Exists(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*prefs, GetInt64(_, _)).Times(AtLeast(1));
+  EXPECT_CALL(*prefs, GetInt64(kPrefsPayloadAttemptNumber, _))
       .Times(AtLeast(1));
-  EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
+  EXPECT_CALL(*prefs, GetInt64(kPrefsFullPayloadAttemptNumber, _))
       .Times(AtLeast(1));
-  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
+  EXPECT_CALL(*prefs, GetInt64(kPrefsCurrentUrlIndex, _))
       .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(true)));
-  EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
+  EXPECT_CALL(*prefs, GetInt64(kPrefsCurrentUrlFailureCount, _))
       .Times(AtLeast(1));
-  EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _)).Times(AtLeast(1));
+  EXPECT_CALL(*prefs, GetInt64(kPrefsUrlSwitchCount, _)).Times(AtLeast(1));
 
   // Note: This will be a different payload object, but the response should
   // have the same hash as before so as to not trivially reset because the
   // response was different. We want to specifically test that even if the
   // response is same, we should reset the state if we find it corrupted.
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state2));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash4427", true, false, &payload_state, &response);
 
@@ -625,15 +628,14 @@
   EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
 }
 
-TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
+TEST_F(PayloadStateTest, NoBackoffInteractiveChecks) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.Init("", "", {.interactive = true});
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash6437", true, false, &payload_state, &response);
 
@@ -648,15 +650,14 @@
   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
 }
 
-TEST(PayloadStateTest, NoBackoffForP2PUpdates) {
+TEST_F(PayloadStateTest, NoBackoffForP2PUpdates) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.Init("", "", {});
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash6437", true, false, &payload_state, &response);
 
@@ -679,12 +680,11 @@
   EXPECT_TRUE(payload_state.ShouldBackoffDownload());
 }
 
-TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
+TEST_F(PayloadStateTest, NoBackoffForDeltaPayloads) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
 
   // Simulate a successful download and see that we're ready to download
@@ -723,12 +723,11 @@
             backoff_expiry_time.ToInternalValue());
 }
 
-TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
+TEST_F(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8939", true, false, &payload_state, &response);
 
@@ -744,13 +743,12 @@
   CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
 }
 
-TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
+TEST_F(PayloadStateTest, BackoffLogicCanBeDisabled) {
   OmahaResponse response;
   response.disable_payload_backoff = true;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8939", true, false, &payload_state, &response);
 
@@ -771,15 +769,14 @@
   EXPECT_FALSE(payload_state.ShouldBackoffDownload());
 }
 
-TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
+TEST_F(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
   OmahaResponse response;
   response.disable_payload_backoff = true;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   uint64_t https_total = 0;
   uint64_t http_total = 0;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash3286", true, false, &payload_state, &response);
   EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
@@ -862,7 +859,7 @@
   EXPECT_EQ(p2p_total,
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportSuccessfulUpdateMetrics(
                   1, _, kPayloadTypeFull, _, _, 314, _, _, _, 3));
 
@@ -880,12 +877,11 @@
   EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
 }
 
-TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
+TEST_F(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash3286", true, false, &payload_state, &response);
 
@@ -903,7 +899,7 @@
   int64_t total_bytes[kNumDownloadSources] = {};
   total_bytes[kDownloadSourceHttpServer] = num_bytes;
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportSuccessfulUpdateMetrics(
                   _,
                   _,
@@ -920,12 +916,11 @@
   payload_state.UpdateSucceeded();
 }
 
-TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
+TEST_F(PayloadStateTest, RestartingUpdateResetsMetrics) {
   OmahaResponse response;
-  FakeSystemState fake_system_state;
   PayloadState payload_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Set the first response.
   SetupPayloadStateWith2Urls(
@@ -950,25 +945,24 @@
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
 }
 
-TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
-  FakeSystemState fake_system_state;
-  PayloadState payload_state;
-
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+TEST_F(PayloadStateTest, NumRebootsIncrementsCorrectly) {
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
   EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AtLeast(0));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  PayloadState payload_state;
+  EXPECT_TRUE(payload_state.Initialize());
 
   payload_state.UpdateRestarted();
   EXPECT_EQ(0U, payload_state.GetNumReboots());
 
-  fake_system_state.set_system_rebooted(true);
+  FakeSystemState::Get()->set_system_rebooted(true);
   payload_state.UpdateResumed();
   // Num reboots should be incremented because system rebooted detected.
   EXPECT_EQ(1U, payload_state.GetNumReboots());
 
-  fake_system_state.set_system_rebooted(false);
+  FakeSystemState::Get()->set_system_rebooted(false);
   payload_state.UpdateResumed();
   // Num reboots should now be 1 as reboot was not detected.
   EXPECT_EQ(1U, payload_state.GetNumReboots());
@@ -978,13 +972,12 @@
   EXPECT_EQ(0U, payload_state.GetNumReboots());
 }
 
-TEST(PayloadStateTest, RollbackHappened) {
-  FakeSystemState fake_system_state;
+TEST_F(PayloadStateTest, RollbackHappened) {
+  FakeSystemState::Get()->set_powerwash_safe_prefs(nullptr);
+  auto* mock_powerwash_safe_prefs =
+      FakeSystemState::Get()->mock_powerwash_safe_prefs();
   PayloadState payload_state;
-
-  NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
-      fake_system_state.mock_powerwash_safe_prefs();
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Verify pre-conditions are good.
   EXPECT_FALSE(payload_state.GetRollbackHappened());
@@ -1009,20 +1002,19 @@
   EXPECT_TRUE(payload_state.GetRollbackHappened());
 }
 
-TEST(PayloadStateTest, RollbackVersion) {
-  FakeSystemState fake_system_state;
-  PayloadState payload_state;
-
-  NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
-      fake_system_state.mock_powerwash_safe_prefs();
+TEST_F(PayloadStateTest, RollbackVersion) {
+  FakeSystemState::Get()->set_powerwash_safe_prefs(nullptr);
+  auto* mock_powerwash_safe_prefs =
+      FakeSystemState::Get()->mock_powerwash_safe_prefs();
 
   // Mock out the os version and make sure it's excluded correctly.
   string rollback_version = "2345.0.0";
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.Init(rollback_version, "", {});
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  PayloadState payload_state;
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Verify pre-conditions are good.
   EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
@@ -1045,37 +1037,33 @@
 
   // Check that we report only UpdateEngine.Rollback.* metrics in
   // UpdateSucceeded().
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportRollbackMetrics(metrics::RollbackResult::kSuccess))
       .Times(1);
 
   payload_state.UpdateSucceeded();
 }
 
-TEST(PayloadStateTest, DurationsAreCorrect) {
+TEST_F(PayloadStateTest, DurationsAreCorrect) {
   OmahaResponse response;
   response.packages.resize(1);
-  PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
 
   // Set the clock to a well-known time - 1 second on the wall-clock
   // and 2 seconds on the monotonic clock
-  fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
-  fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
+  auto* fake_clock = FakeSystemState::Get()->fake_clock();
+  fake_clock->SetWallclockTime(Time::FromInternalValue(1000000));
+  fake_clock->SetMonotonicTime(Time::FromInternalValue(2000000));
 
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  PayloadState payload_state;
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Check that durations are correct for a successful update where
   // time has advanced 7 seconds on the wall clock and 4 seconds on
   // the monotonic clock.
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
-  fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
-  fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
+  fake_clock->SetWallclockTime(Time::FromInternalValue(8000000));
+  fake_clock->SetMonotonicTime(Time::FromInternalValue(6000000));
   payload_state.UpdateSucceeded();
   EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
   EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
@@ -1088,8 +1076,8 @@
 
   // Advance time a bit (10 secs), simulate download progress and
   // check that durations are updated.
-  fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
-  fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
+  fake_clock->SetWallclockTime(Time::FromInternalValue(18000000));
+  fake_clock->SetMonotonicTime(Time::FromInternalValue(16000000));
   payload_state.DownloadProgress(10);
   EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
   EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
@@ -1097,9 +1085,9 @@
   // Now simulate a reboot by resetting monotonic time (to 5000) and
   // creating a new PayloadState object and check that we load the
   // durations correctly (e.g. they are the same as before).
-  fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
+  fake_clock->SetMonotonicTime(Time::FromInternalValue(5000));
   PayloadState payload_state2;
-  EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state2.Initialize());
   payload_state2.SetResponse(response);
   EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
   EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
@@ -1107,65 +1095,62 @@
 
   // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
   // and check that the durations are increased accordingly.
-  fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
-  fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
+  fake_clock->SetWallclockTime(Time::FromInternalValue(25000000));
+  fake_clock->SetMonotonicTime(Time::FromInternalValue(6005000));
   payload_state2.UpdateSucceeded();
   EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
   EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
             16000000);
 }
 
-TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
+TEST_F(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
   OmahaResponse response;
-  PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
 
   // Set the clock to a well-known time (t = 30 seconds).
-  fake_clock.SetMonotonicTime(
+  auto* fake_clock = FakeSystemState::Get()->fake_clock();
+  fake_clock->SetMonotonicTime(
       Time::FromInternalValue(30 * Time::kMicrosecondsPerSecond));
 
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  PayloadState payload_state;
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Make the update succeed.
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
   payload_state.UpdateSucceeded();
 
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
   // Check that the marker was written.
-  EXPECT_TRUE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
+  EXPECT_TRUE(fake_prefs->Exists(kPrefsSystemUpdatedMarker));
 
   // Now simulate a reboot and set the wallclock time to a later point
   // (t = 500 seconds). We do this by using a new PayloadState object
   // and checking that it emits the right UMA metric with the right
   // value.
-  fake_clock.SetMonotonicTime(
+  fake_clock->SetMonotonicTime(
       Time::FromInternalValue(500 * Time::kMicrosecondsPerSecond));
   PayloadState payload_state2;
-  EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state2.Initialize());
 
   // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportTimeToReboot(7));
-  fake_system_state.set_system_rebooted(true);
+  FakeSystemState::Get()->set_system_rebooted(true);
 
   payload_state2.UpdateEngineStarted();
 
   // Check that the marker was nuked.
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsSystemUpdatedMarker));
 }
 
-TEST(PayloadStateTest, RestartAfterCrash) {
+TEST_F(PayloadStateTest, RestartAfterCrash) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   testing::StrictMock<MockMetricsReporter> mock_metrics_reporter;
-  fake_system_state.set_metrics_reporter(&mock_metrics_reporter);
-  NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
+  FakeSystemState::Get()->set_metrics_reporter(&mock_metrics_reporter);
+  FakeSystemState::Get()->set_prefs(nullptr);
+  auto* prefs = FakeSystemState::Get()->mock_prefs();
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Only the |kPrefsAttemptInProgress| state variable should be read.
   EXPECT_CALL(*prefs, Exists(_)).Times(0);
@@ -1178,83 +1163,75 @@
   EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
 
   // Simulate an update_engine restart without a reboot.
-  fake_system_state.set_system_rebooted(false);
+  FakeSystemState::Get()->set_system_rebooted(false);
 
   payload_state.UpdateEngineStarted();
 }
 
-TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
+TEST_F(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
   // If there's no marker at startup, ensure we don't report a metric.
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_TRUE(payload_state.Initialize());
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportAbnormallyTerminatedUpdateAttemptMetrics())
       .Times(0);
   payload_state.UpdateEngineStarted();
 }
 
-TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
-  PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakePrefs fake_prefs;
-
+TEST_F(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
   // If we have a marker at startup, ensure it's reported and the
   // marker is then cleared.
-  fake_system_state.set_prefs(&fake_prefs);
-  fake_prefs.SetBoolean(kPrefsAttemptInProgress, true);
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
+  fake_prefs->SetBoolean(kPrefsAttemptInProgress, true);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  PayloadState payload_state;
+  EXPECT_TRUE(payload_state.Initialize());
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportAbnormallyTerminatedUpdateAttemptMetrics())
       .Times(1);
   payload_state.UpdateEngineStarted();
 
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsAttemptInProgress));
 }
 
-TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
-  PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakePrefs fake_prefs;
-
+TEST_F(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
   // Make sure the marker is written and cleared during an attempt and
   // also that we DO NOT emit the metric (since the attempt didn't end
   // abnormally).
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  PayloadState payload_state;
+  EXPECT_TRUE(payload_state.Initialize());
   OmahaResponse response;
   response.packages.resize(1);
   payload_state.SetResponse(response);
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportAbnormallyTerminatedUpdateAttemptMetrics())
       .Times(0);
 
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
   // Attempt not in progress, should be clear.
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsAttemptInProgress));
 
   payload_state.UpdateRestarted();
 
   // Attempt not in progress, should be set.
-  EXPECT_TRUE(fake_prefs.Exists(kPrefsAttemptInProgress));
+  EXPECT_TRUE(fake_prefs->Exists(kPrefsAttemptInProgress));
 
   payload_state.UpdateSucceeded();
 
   // Attempt not in progress, should be clear.
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsAttemptInProgress));
 }
 
-TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
+TEST_F(PayloadStateTest, CandidateUrlsComputedCorrectly) {
   OmahaResponse response;
-  FakeSystemState fake_system_state;
   PayloadState payload_state;
 
   policy::MockDevicePolicy disable_http_policy;
-  fake_system_state.set_device_policy(&disable_http_policy);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  FakeSystemState::Get()->set_device_policy(&disable_http_policy);
+  EXPECT_TRUE(payload_state.Initialize());
 
   // Test with no device policy. Should default to allowing http.
   EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
@@ -1297,7 +1274,7 @@
   // Now, pretend that the HTTP policy is turned on. We want to make sure
   // the new policy is honored.
   policy::MockDevicePolicy enable_http_policy;
-  fake_system_state.set_device_policy(&enable_http_policy);
+  FakeSystemState::Get()->set_device_policy(&enable_http_policy);
   EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
       .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
 
@@ -1320,93 +1297,86 @@
   EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
 }
 
-TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
+TEST_F(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
 
   // Simulate a successful download and update.
   payload_state.DownloadComplete();
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportSuccessfulUpdateMetrics(
                   _, _, kPayloadTypeDelta, _, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 
   // Mock the request to a request where the delta was disabled but Omaha sends
   // a delta anyway and test again.
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.set_delta_okay(false);
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
 
   payload_state.DownloadComplete();
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportSuccessfulUpdateMetrics(
                   _, _, kPayloadTypeDelta, _, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 }
 
-TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
+TEST_F(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
   // Mock the request to a request where the delta was disabled.
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.set_delta_okay(false);
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash6437", true, false, &payload_state, &response);
 
   // Simulate a successful download and update.
   payload_state.DownloadComplete();
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportSuccessfulUpdateMetrics(
                   _, _, kPayloadTypeForcedFull, _, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 }
 
-TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
+TEST_F(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash6437", true, false, &payload_state, &response);
 
   // Mock the request to a request where the delta is enabled, although the
   // result is full.
-  OmahaRequestParams params(&fake_system_state);
+  OmahaRequestParams params;
   params.set_delta_okay(true);
-  fake_system_state.set_request_params(&params);
+  FakeSystemState::Get()->set_request_params(&params);
 
   // Simulate a successful download and update.
   payload_state.DownloadComplete();
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportSuccessfulUpdateMetrics(
                   _, _, kPayloadTypeFull, _, _, _, _, _, _, _));
   payload_state.UpdateSucceeded();
 }
 
-TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
-  FakeSystemState fake_system_state;
+TEST_F(PayloadStateTest, RebootAfterUpdateFailedMetric) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakePrefs fake_prefs;
-  fake_system_state.set_prefs(&fake_prefs);
-
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash3141", true, false, &payload_state, &response);
 
@@ -1416,40 +1386,40 @@
   payload_state.ExpectRebootInNewVersion("Version:12345678");
 
   // Reboot into the same environment to get an UMA metric with a value of 1.
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportFailedUpdateCount(1));
   payload_state.ReportFailedBootIfNeeded();
-  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
+  Mock::VerifyAndClearExpectations(
+      FakeSystemState::Get()->mock_metrics_reporter());
 
   // Simulate a second update and reboot into the same environment, this should
   // send a value of 2.
   payload_state.ExpectRebootInNewVersion("Version:12345678");
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportFailedUpdateCount(2));
   payload_state.ReportFailedBootIfNeeded();
-  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
+  Mock::VerifyAndClearExpectations(
+      FakeSystemState::Get()->mock_metrics_reporter());
 
   // Simulate a third failed reboot to new version, but this time for a
   // different payload. This should send a value of 1 this time.
   payload_state.ExpectRebootInNewVersion("Version:3141592");
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportFailedUpdateCount(1));
   payload_state.ReportFailedBootIfNeeded();
-  Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
+  Mock::VerifyAndClearExpectations(
+      FakeSystemState::Get()->mock_metrics_reporter());
 }
 
-TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
-  FakeSystemState fake_system_state;
+TEST_F(PayloadStateTest, RebootAfterUpdateSucceed) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakePrefs fake_prefs;
-  fake_system_state.set_prefs(&fake_prefs);
-
-  FakeBootControl* fake_boot_control = fake_system_state.fake_boot_control();
+  FakeBootControl* fake_boot_control =
+      FakeSystemState::Get()->fake_boot_control();
   fake_boot_control->SetCurrentSlot(0);
 
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash3141", true, false, &payload_state, &response);
 
@@ -1461,7 +1431,7 @@
   // Change the BootDevice to a different one, no metric should be sent.
   fake_boot_control->SetCurrentSlot(1);
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportFailedUpdateCount(_))
       .Times(0);
   payload_state.ReportFailedBootIfNeeded();
@@ -1472,14 +1442,10 @@
   payload_state.ReportFailedBootIfNeeded();
 }
 
-TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
-  FakeSystemState fake_system_state;
+TEST_F(PayloadStateTest, RebootAfterCanceledUpdate) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakePrefs fake_prefs;
-
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash3141", true, false, &payload_state, &response);
 
@@ -1488,7 +1454,7 @@
   payload_state.UpdateSucceeded();
   payload_state.ExpectRebootInNewVersion("Version:12345678");
 
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportFailedUpdateCount(_))
       .Times(0);
 
@@ -1499,15 +1465,11 @@
   payload_state.ReportFailedBootIfNeeded();
 }
 
-TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
-  FakeSystemState fake_system_state;
+TEST_F(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
   PayloadState payload_state;
-  FakePrefs fake_prefs;
+  EXPECT_TRUE(payload_state.Initialize());
 
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
-
-  EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportFailedUpdateCount(_))
       .Times(0);
 
@@ -1515,14 +1477,10 @@
   payload_state.ReportFailedBootIfNeeded();
 }
 
-TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
+TEST_F(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakePrefs fake_prefs;
-  fake_system_state.set_prefs(&fake_prefs);
-
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
 
@@ -1536,22 +1494,17 @@
   EXPECT_FALSE(payload_state.P2PAttemptAllowed());
 }
 
-TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
+TEST_F(PayloadStateTest, DisallowP2PAfterDeadline) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
-
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
 
   // Set the clock to 1 second.
   Time epoch = Time::FromInternalValue(1000000);
-  fake_clock.SetWallclockTime(epoch);
+  auto* fake_clock = FakeSystemState::Get()->fake_clock();
+  fake_clock->SetWallclockTime(epoch);
 
   // Do an attempt - this will set the timestamp.
   payload_state.P2PNewAttempt();
@@ -1563,7 +1516,7 @@
   EXPECT_TRUE(payload_state.P2PAttemptAllowed());
 
   // Set clock to half the deadline - this should work.
-  fake_clock.SetWallclockTime(
+  fake_clock->SetWallclockTime(
       epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
   EXPECT_TRUE(payload_state.P2PAttemptAllowed());
 
@@ -1572,24 +1525,20 @@
   EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
 
   // Set clock to _just_ before the deadline - this should work.
-  fake_clock.SetWallclockTime(
+  fake_clock->SetWallclockTime(
       epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
   EXPECT_TRUE(payload_state.P2PAttemptAllowed());
 
   // Set clock to _just_ after the deadline - this should not work.
-  fake_clock.SetWallclockTime(
+  fake_clock->SetWallclockTime(
       epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
   EXPECT_FALSE(payload_state.P2PAttemptAllowed());
 }
 
-TEST(PayloadStateTest, P2PStateVarsInitialValue) {
+TEST_F(PayloadStateTest, P2PStateVarsInitialValue) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakePrefs fake_prefs;
-
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
 
@@ -1598,21 +1547,16 @@
   EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
 }
 
-TEST(PayloadStateTest, P2PStateVarsArePersisted) {
+TEST_F(PayloadStateTest, P2PStateVarsArePersisted) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
 
   // Set the clock to something known.
   Time time = Time::FromInternalValue(12345);
-  fake_clock.SetWallclockTime(time);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(time);
 
   // New p2p attempt - as a side-effect this will update the p2p state vars.
   payload_state.P2PNewAttempt();
@@ -1622,27 +1566,21 @@
   // Now create a new PayloadState and check that it loads the state
   // vars correctly.
   PayloadState payload_state2;
-  EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state2.Initialize());
   EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
   EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
 }
 
-TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
+TEST_F(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
   OmahaResponse response;
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
-  fake_system_state.set_clock(&fake_clock);
-  fake_system_state.set_prefs(&fake_prefs);
-
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
   SetupPayloadStateWith2Urls(
       "Hash8593", true, false, &payload_state, &response);
 
   // Set the clock to something known.
   Time time = Time::FromInternalValue(12345);
-  fake_clock.SetWallclockTime(time);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(time);
 
   // New p2p attempt - as a side-effect this will update the p2p state vars.
   payload_state.P2PNewAttempt();
@@ -1659,13 +1597,12 @@
   EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
 }
 
-TEST(PayloadStateTest, NextPayloadResetsUrlIndex) {
+TEST_F(PayloadStateTest, NextPayloadResetsUrlIndex) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   StrictMock<MockExcluder> mock_excluder;
-  EXPECT_CALL(*fake_system_state.mock_update_attempter(), GetExcluder())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetExcluder())
       .WillOnce(Return(&mock_excluder));
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   OmahaResponse response;
   response.packages.push_back(
@@ -1689,13 +1626,12 @@
   EXPECT_EQ(payload_state.GetCurrentUrl(), "http://test1b");
 }
 
-TEST(PayloadStateTest, ExcludeNoopForNonExcludables) {
+TEST_F(PayloadStateTest, ExcludeNoopForNonExcludables) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   StrictMock<MockExcluder> mock_excluder;
-  EXPECT_CALL(*fake_system_state.mock_update_attempter(), GetExcluder())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetExcluder())
       .WillOnce(Return(&mock_excluder));
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   OmahaResponse response;
   response.packages.push_back(
@@ -1711,13 +1647,12 @@
   payload_state.ExcludeCurrentPayload();
 }
 
-TEST(PayloadStateTest, ExcludeOnlyCanExcludables) {
+TEST_F(PayloadStateTest, ExcludeOnlyCanExcludables) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   StrictMock<MockExcluder> mock_excluder;
-  EXPECT_CALL(*fake_system_state.mock_update_attempter(), GetExcluder())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetExcluder())
       .WillOnce(Return(&mock_excluder));
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   OmahaResponse response;
   response.packages.push_back(
@@ -1734,13 +1669,12 @@
   payload_state.ExcludeCurrentPayload();
 }
 
-TEST(PayloadStateTest, IncrementFailureExclusionTest) {
+TEST_F(PayloadStateTest, IncrementFailureExclusionTest) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   StrictMock<MockExcluder> mock_excluder;
-  EXPECT_CALL(*fake_system_state.mock_update_attempter(), GetExcluder())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetExcluder())
       .WillOnce(Return(&mock_excluder));
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   OmahaResponse response;
   // Critical package.
@@ -1778,13 +1712,12 @@
   payload_state.IncrementFailureCount();
 }
 
-TEST(PayloadStateTest, HaltExclusionPostPayloadExhaustion) {
+TEST_F(PayloadStateTest, HaltExclusionPostPayloadExhaustion) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
   StrictMock<MockExcluder> mock_excluder;
-  EXPECT_CALL(*fake_system_state.mock_update_attempter(), GetExcluder())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetExcluder())
       .WillOnce(Return(&mock_excluder));
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   OmahaResponse response;
   // Non-critical package.
@@ -1809,10 +1742,9 @@
   payload_state.ExcludeCurrentPayload();
 }
 
-TEST(PayloadStateTest, NonInfinitePayloadIndexIncrement) {
+TEST_F(PayloadStateTest, NonInfinitePayloadIndexIncrement) {
   PayloadState payload_state;
-  FakeSystemState fake_system_state;
-  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+  EXPECT_TRUE(payload_state.Initialize());
 
   payload_state.SetResponse({});
 
diff --git a/cros/real_system_state.cc b/cros/real_system_state.cc
index 4f57246..5f89b27 100644
--- a/cros/real_system_state.cc
+++ b/cros/real_system_state.cc
@@ -25,9 +25,7 @@
 #include <base/location.h>
 #include <base/time/time.h>
 #include <brillo/message_loops/message_loop.h>
-#if USE_CHROME_KIOSK_APP
 #include <chromeos/dbus/service_constants.h>
-#endif  // USE_CHROME_KIOSK_APP
 
 #include "update_engine/common/boot_control.h"
 #include "update_engine/common/boot_control_stub.h"
@@ -39,20 +37,10 @@
 #if USE_DBUS
 #include "update_engine/cros/dbus_connection.h"
 #endif  // USE_DBUS
-#include "update_engine/update_boot_flags_action.h"
 #include "update_engine/update_manager/state_factory.h"
 
-using brillo::MessageLoop;
-
 namespace chromeos_update_engine {
 
-RealSystemState::~RealSystemState() {
-  // Prevent any DBus communication from UpdateAttempter when shutting down the
-  // daemon.
-  if (update_attempter_)
-    update_attempter_->ClearObservers();
-}
-
 bool RealSystemState::Initialize() {
   boot_control_ = boot_control::CreateBootControl();
   if (!boot_control_) {
@@ -67,15 +55,13 @@
     return false;
   }
 
-#if USE_CHROME_KIOSK_APP
   kiosk_app_proxy_.reset(new org::chromium::KioskAppServiceInterfaceProxy(
       DBusConnection::Get()->GetDBus(), chromeos::kKioskAppServiceName));
-#endif  // USE_CHROME_KIOSK_APP
 
   LOG_IF(INFO, !hardware_->IsNormalBootMode()) << "Booted in dev mode.";
   LOG_IF(INFO, !hardware_->IsOfficialBuild()) << "Booted non-official build.";
 
-  connection_manager_ = connection_manager::CreateConnectionManager(this);
+  connection_manager_ = connection_manager::CreateConnectionManager();
   if (!connection_manager_) {
     LOG(ERROR) << "Error initializing the ConnectionManagerInterface.";
     return false;
@@ -147,8 +133,7 @@
       new CertificateChecker(prefs_.get(), &openssl_wrapper_));
   certificate_checker_->Init();
 
-  update_attempter_.reset(
-      new UpdateAttempter(this, certificate_checker_.get()));
+  update_attempter_.reset(new UpdateAttempter(certificate_checker_.get()));
 
   // Initialize the UpdateAttempter before the UpdateManager.
   update_attempter_->Init();
@@ -156,19 +141,13 @@
   // Initialize the Update Manager using the default state factory.
   chromeos_update_manager::State* um_state =
       chromeos_update_manager::DefaultStateFactory(&policy_provider_,
-#if USE_CHROME_KIOSK_APP
-                                                   kiosk_app_proxy_.get(),
-#else
-                                                   nullptr,
-#endif  // USE_CHROME_KIOSK_APP
-                                                   this);
+                                                   kiosk_app_proxy_.get());
 
   if (!um_state) {
     LOG(ERROR) << "Failed to initialize the Update Manager.";
     return false;
   }
   update_manager_.reset(new chromeos_update_manager::UpdateManager(
-      &clock_,
       base::TimeDelta::FromSeconds(5),
       base::TimeDelta::FromHours(12),
       um_state));
@@ -176,13 +155,12 @@
   // The P2P Manager depends on the Update Manager for its initialization.
   p2p_manager_.reset(
       P2PManager::Construct(nullptr,
-                            &clock_,
                             update_manager_.get(),
                             "cros_au",
                             kMaxP2PFilesToKeep,
                             base::TimeDelta::FromDays(kMaxP2PFileAgeDays)));
 
-  if (!payload_state_.Initialize(this)) {
+  if (!payload_state_.Initialize()) {
     LOG(ERROR) << "Failed to initialize the payload state object.";
     return false;
   }
@@ -201,43 +179,4 @@
   return true;
 }
 
-bool RealSystemState::StartUpdater() {
-  // Initiate update checks.
-  update_attempter_->ScheduleUpdates();
-
-  auto update_boot_flags_action =
-      std::make_unique<UpdateBootFlagsAction>(boot_control_.get());
-  processor_.EnqueueAction(std::move(update_boot_flags_action));
-  // Update boot flags after 45 seconds.
-  MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&ActionProcessor::StartProcessing,
-                 base::Unretained(&processor_)),
-      base::TimeDelta::FromSeconds(45));
-
-  // Broadcast the update engine status on startup to ensure consistent system
-  // state on crashes.
-  MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&UpdateAttempter::BroadcastStatus,
-                 base::Unretained(update_attempter_.get())));
-
-  // Run the UpdateEngineStarted() method on |update_attempter|.
-  MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&UpdateAttempter::UpdateEngineStarted,
-                 base::Unretained(update_attempter_.get())));
-  return true;
-}
-
-void RealSystemState::AddObserver(ServiceObserverInterface* observer) {
-  CHECK(update_attempter_.get());
-  update_attempter_->AddObserver(observer);
-}
-
-void RealSystemState::RemoveObserver(ServiceObserverInterface* observer) {
-  CHECK(update_attempter_.get());
-  update_attempter_->RemoveObserver(observer);
-}
-
 }  // namespace chromeos_update_engine
diff --git a/cros/real_system_state.h b/cros/real_system_state.h
index 798fca0..81a5e0e 100644
--- a/cros/real_system_state.h
+++ b/cros/real_system_state.h
@@ -23,10 +23,7 @@
 #include <set>
 
 #include <policy/device_policy.h>
-
-#if USE_CHROME_KIOSK_APP
 #include <kiosk-app/dbus-proxies.h>
-#endif  // USE_CHROME_KIOSK_APP
 
 #include "update_engine/certificate_checker.h"
 #include "update_engine/common/boot_control_interface.h"
@@ -48,95 +45,79 @@
 
 // A real implementation of the SystemStateInterface which is
 // used by the actual product code.
-class RealSystemState : public SystemState, public DaemonStateInterface {
+class RealSystemState : public SystemState {
  public:
   // Constructs all system objects that do not require separate initialization;
   // see Initialize() below for the remaining ones.
   RealSystemState() = default;
-  ~RealSystemState() override;
+  ~RealSystemState() = default;
 
+  static void SetInstance(RealSystemState* system_state) {
+    CHECK(g_pointer_ == nullptr) << "SystemState has been previously set.";
+    g_pointer_ = system_state;
+    LOG_IF(FATAL, !system_state->Initialize())
+        << "Failed to initialize system state.";
+  }
+
+  // SystemState overrides.
+  void set_device_policy(const policy::DevicePolicy* device_policy) override {
+    device_policy_ = device_policy;
+  }
+
+  const policy::DevicePolicy* device_policy() override {
+    return device_policy_;
+  }
+
+  BootControlInterface* boot_control() override { return boot_control_.get(); }
+
+  ClockInterface* clock() override { return &clock_; }
+
+  ConnectionManagerInterface* connection_manager() override {
+    return connection_manager_.get();
+  }
+
+  HardwareInterface* hardware() override { return hardware_.get(); }
+
+  MetricsReporterInterface* metrics_reporter() override {
+    return &metrics_reporter_;
+  }
+
+  PrefsInterface* prefs() override { return prefs_.get(); }
+
+  PrefsInterface* powerwash_safe_prefs() override {
+    return powerwash_safe_prefs_.get();
+  }
+
+  PayloadStateInterface* payload_state() override { return &payload_state_; }
+
+  UpdateAttempter* update_attempter() override {
+    return update_attempter_.get();
+  }
+
+  OmahaRequestParams* request_params() override { return &request_params_; }
+
+  P2PManager* p2p_manager() override { return p2p_manager_.get(); }
+
+  chromeos_update_manager::UpdateManager* update_manager() override {
+    return update_manager_.get();
+  }
+
+  PowerManagerInterface* power_manager() override {
+    return power_manager_.get();
+  }
+
+  bool system_rebooted() override { return system_rebooted_; }
+
+  DlcServiceInterface* dlcservice() override { return dlcservice_.get(); }
+
+ private:
   // Initializes and sets systems objects that require an initialization
   // separately from construction. Returns |true| on success.
   bool Initialize();
 
-  // DaemonStateInterface overrides.
-  // Start the periodic update attempts. Must be called at the beginning of the
-  // program to start the periodic update check process.
-  bool StartUpdater() override;
-
-  void AddObserver(ServiceObserverInterface* observer) override;
-  void RemoveObserver(ServiceObserverInterface* observer) override;
-  const std::set<ServiceObserverInterface*>& service_observers() override {
-    CHECK(update_attempter_.get());
-    return update_attempter_->service_observers();
-  }
-
-  // SystemState overrides.
-  inline void set_device_policy(
-      const policy::DevicePolicy* device_policy) override {
-    device_policy_ = device_policy;
-  }
-
-  inline const policy::DevicePolicy* device_policy() override {
-    return device_policy_;
-  }
-
-  inline BootControlInterface* boot_control() override {
-    return boot_control_.get();
-  }
-
-  inline ClockInterface* clock() override { return &clock_; }
-
-  inline ConnectionManagerInterface* connection_manager() override {
-    return connection_manager_.get();
-  }
-
-  inline HardwareInterface* hardware() override { return hardware_.get(); }
-
-  inline MetricsReporterInterface* metrics_reporter() override {
-    return &metrics_reporter_;
-  }
-
-  inline PrefsInterface* prefs() override { return prefs_.get(); }
-
-  inline PrefsInterface* powerwash_safe_prefs() override {
-    return powerwash_safe_prefs_.get();
-  }
-
-  inline PayloadStateInterface* payload_state() override {
-    return &payload_state_;
-  }
-
-  inline UpdateAttempter* update_attempter() override {
-    return update_attempter_.get();
-  }
-
-  inline OmahaRequestParams* request_params() override {
-    return &request_params_;
-  }
-
-  inline P2PManager* p2p_manager() override { return p2p_manager_.get(); }
-
-  inline chromeos_update_manager::UpdateManager* update_manager() override {
-    return update_manager_.get();
-  }
-
-  inline PowerManagerInterface* power_manager() override {
-    return power_manager_.get();
-  }
-
-  inline bool system_rebooted() override { return system_rebooted_; }
-
-  inline DlcServiceInterface* dlcservice() override {
-    return dlcservice_.get();
-  }
-
- private:
   // Real DBus proxies using the DBus connection.
-#if USE_CHROME_KIOSK_APP
   std::unique_ptr<org::chromium::KioskAppServiceInterfaceProxy>
       kiosk_app_proxy_;
-#endif  // USE_CHROME_KIOSK_APP
 
   // Interface for the power manager.
   std::unique_ptr<PowerManagerInterface> power_manager_;
@@ -181,7 +162,7 @@
   std::unique_ptr<UpdateAttempter> update_attempter_;
 
   // Common parameters for all Omaha requests.
-  OmahaRequestParams request_params_{this};
+  OmahaRequestParams request_params_;
 
   std::unique_ptr<P2PManager> p2p_manager_;
 
@@ -193,8 +174,6 @@
   // rebooted. Important for tracking whether you are running instance of the
   // update engine on first boot or due to a crash/restart.
   bool system_rebooted_{false};
-
-  ActionProcessor processor_;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/cros/update_attempter.cc b/cros/update_attempter.cc
index e8cb291..2fa6a80 100644
--- a/cros/update_attempter.cc
+++ b/cros/update_attempter.cc
@@ -44,7 +44,6 @@
 
 #include "update_engine/certificate_checker.h"
 #include "update_engine/common/boot_control_interface.h"
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/common/constants.h"
 #include "update_engine/common/dlcservice_interface.h"
 #include "update_engine/common/download_action.h"
@@ -126,14 +125,16 @@
   return code;
 }
 
-UpdateAttempter::UpdateAttempter(SystemState* system_state,
-                                 CertificateChecker* cert_checker)
+UpdateAttempter::UpdateAttempter(CertificateChecker* cert_checker)
     : processor_(new ActionProcessor()),
-      system_state_(system_state),
       cert_checker_(cert_checker),
       is_install_(false) {}
 
 UpdateAttempter::~UpdateAttempter() {
+  // Prevent any DBus communication from UpdateAttempter when shutting down the
+  // daemon.
+  ClearObservers();
+
   // CertificateChecker might not be initialized in unittests.
   if (cert_checker_)
     cert_checker_->SetObserver(nullptr);
@@ -146,18 +147,20 @@
   // Pulling from the SystemState can only be done after construction, since
   // this is an aggregate of various objects (such as the UpdateAttempter),
   // which requires them all to be constructed prior to it being used.
-  prefs_ = system_state_->prefs();
-  omaha_request_params_ = system_state_->request_params();
+  prefs_ = SystemState::Get()->prefs();
+  omaha_request_params_ = SystemState::Get()->request_params();
 
   if (cert_checker_)
     cert_checker_->SetObserver(this);
 
   // In case of update_engine restart without a reboot we need to restore the
   // reboot needed state.
-  if (GetBootTimeAtUpdate(nullptr))
+  if (GetBootTimeAtUpdate(nullptr)) {
     status_ = UpdateStatus::UPDATED_NEED_REBOOT;
-  else
+  } else {
     status_ = UpdateStatus::IDLE;
+    prefs_->Delete(kPrefsLastFp, {kDlcPrefsSubDir});
+  }
 }
 
 bool UpdateAttempter::ScheduleUpdates() {
@@ -165,7 +168,7 @@
     return false;
 
   chromeos_update_manager::UpdateManager* const update_manager =
-      system_state_->update_manager();
+      SystemState::Get()->update_manager();
   CHECK(update_manager);
   Callback<void(EvalStatus, const UpdateCheckParams&)> callback =
       Bind(&UpdateAttempter::OnUpdateScheduled, base::Unretained(this));
@@ -177,18 +180,45 @@
   return true;
 }
 
+bool UpdateAttempter::StartUpdater() {
+  // Initiate update checks.
+  ScheduleUpdates();
+
+  auto update_boot_flags_action = std::make_unique<UpdateBootFlagsAction>(
+      SystemState::Get()->boot_control());
+  aux_processor_.EnqueueAction(std::move(update_boot_flags_action));
+  // Update boot flags after 45 seconds.
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&ActionProcessor::StartProcessing,
+                 base::Unretained(&aux_processor_)),
+      base::TimeDelta::FromSeconds(45));
+
+  // Broadcast the update engine status on startup to ensure consistent system
+  // state on crashes.
+  MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&UpdateAttempter::BroadcastStatus, base::Unretained(this)));
+
+  MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&UpdateAttempter::UpdateEngineStarted,
+                 base::Unretained(this)));
+  return true;
+}
+
 void UpdateAttempter::CertificateChecked(ServerToCheck server_to_check,
                                          CertificateCheckResult result) {
-  system_state_->metrics_reporter()->ReportCertificateCheckMetrics(
+  SystemState::Get()->metrics_reporter()->ReportCertificateCheckMetrics(
       server_to_check, result);
 }
 
 bool UpdateAttempter::CheckAndReportDailyMetrics() {
   int64_t stored_value;
-  Time now = system_state_->clock()->GetWallclockTime();
-  if (system_state_->prefs()->Exists(kPrefsDailyMetricsLastReportedAt) &&
-      system_state_->prefs()->GetInt64(kPrefsDailyMetricsLastReportedAt,
-                                       &stored_value)) {
+  Time now = SystemState::Get()->clock()->GetWallclockTime();
+  if (SystemState::Get()->prefs()->Exists(kPrefsDailyMetricsLastReportedAt) &&
+      SystemState::Get()->prefs()->GetInt64(kPrefsDailyMetricsLastReportedAt,
+                                            &stored_value)) {
     Time last_reported_at = Time::FromInternalValue(stored_value);
     TimeDelta time_reported_since = now - last_reported_at;
     if (time_reported_since.InSeconds() < 0) {
@@ -211,8 +241,8 @@
   }
 
   LOG(INFO) << "Reporting daily metrics.";
-  system_state_->prefs()->SetInt64(kPrefsDailyMetricsLastReportedAt,
-                                   now.ToInternalValue());
+  SystemState::Get()->prefs()->SetInt64(kPrefsDailyMetricsLastReportedAt,
+                                        now.ToInternalValue());
 
   ReportOSAge();
 
@@ -221,10 +251,6 @@
 
 void UpdateAttempter::ReportOSAge() {
   struct stat sb;
-
-  if (system_state_ == nullptr)
-    return;
-
   if (stat("/etc/lsb-release", &sb) != 0) {
     PLOG(ERROR) << "Error getting file status for /etc/lsb-release "
                 << "(Note: this may happen in some unit tests)";
@@ -232,7 +258,7 @@
   }
 
   Time lsb_release_timestamp = Time::FromTimeSpec(sb.st_ctim);
-  Time now = system_state_->clock()->GetWallclockTime();
+  Time now = SystemState::Get()->clock()->GetWallclockTime();
   TimeDelta age = now - lsb_release_timestamp;
   if (age.InSeconds() < 0) {
     LOG(ERROR) << "The OS age (" << utils::FormatTimeDelta(age)
@@ -241,7 +267,7 @@
     return;
   }
 
-  system_state_->metrics_reporter()->ReportDailyMetrics(age);
+  SystemState::Get()->metrics_reporter()->ReportDailyMetrics(age);
 }
 
 void UpdateAttempter::Update(const UpdateCheckParams& params) {
@@ -260,8 +286,7 @@
     // not performing an update check because of this.
     LOG(INFO) << "Not updating b/c we already updated and we're waiting for "
               << "reboot, we'll ping Omaha instead";
-    system_state_->metrics_reporter()->ReportUpdateCheckMetrics(
-        system_state_,
+    SystemState::Get()->metrics_reporter()->ReportUpdateCheckMetrics(
         metrics::CheckResult::kRebootPending,
         metrics::CheckReaction::kUnset,
         metrics::DownloadErrorCode::kUnset);
@@ -304,8 +329,8 @@
   else
     LOG(INFO) << "No device policies/settings present.";
 
-  system_state_->set_device_policy(device_policy);
-  system_state_->p2p_manager()->SetDevicePolicy(device_policy);
+  SystemState::Get()->set_device_policy(device_policy);
+  SystemState::Get()->p2p_manager()->SetDevicePolicy(device_policy);
 }
 
 void UpdateAttempter::CalculateP2PParams(bool interactive) {
@@ -318,31 +343,31 @@
   // (Why would a developer want to opt in? If they are working on the
   // update_engine or p2p codebases so they can actually test their code.)
 
-  if (system_state_ != nullptr) {
-    if (!system_state_->p2p_manager()->IsP2PEnabled()) {
-      LOG(INFO) << "p2p is not enabled - disallowing p2p for both"
-                << " downloading and sharing.";
+  if (!SystemState::Get()->p2p_manager()->IsP2PEnabled()) {
+    LOG(INFO) << "p2p is not enabled - disallowing p2p for both"
+              << " downloading and sharing.";
+  } else {
+    // Allow p2p for sharing, even in interactive checks.
+    use_p2p_for_sharing = true;
+    if (!interactive) {
+      LOG(INFO) << "Non-interactive check - allowing p2p for downloading";
+      use_p2p_for_downloading = true;
     } else {
-      // Allow p2p for sharing, even in interactive checks.
-      use_p2p_for_sharing = true;
-      if (!interactive) {
-        LOG(INFO) << "Non-interactive check - allowing p2p for downloading";
-        use_p2p_for_downloading = true;
-      } else {
-        LOG(INFO) << "Forcibly disabling use of p2p for downloading "
-                  << "since this update attempt is interactive.";
-      }
+      LOG(INFO) << "Forcibly disabling use of p2p for downloading "
+                << "since this update attempt is interactive.";
     }
   }
 
-  PayloadStateInterface* const payload_state = system_state_->payload_state();
+  PayloadStateInterface* const payload_state =
+      SystemState::Get()->payload_state();
   payload_state->SetUsingP2PForDownloading(use_p2p_for_downloading);
   payload_state->SetUsingP2PForSharing(use_p2p_for_sharing);
 }
 
 bool UpdateAttempter::CalculateUpdateParams(const UpdateCheckParams& params) {
   http_response_code_ = 0;
-  PayloadStateInterface* const payload_state = system_state_->payload_state();
+  PayloadStateInterface* const payload_state =
+      SystemState::Get()->payload_state();
 
   // Refresh the policy before computing all the update parameters.
   RefreshDevicePolicy();
@@ -383,15 +408,6 @@
   // |omaha_request_params_| shall be made below this line.
   CalculateDlcParams();
 
-  // Set Quick Fix Build token if policy is set and the device is enterprise
-  // enrolled.
-  string token;
-  if (system_state_ && system_state_->device_policy()) {
-    if (!system_state_->device_policy()->GetDeviceQuickFixBuildToken(&token))
-      token.clear();
-  }
-  omaha_request_params_->set_autoupdate_token(token);
-
   LOG(INFO) << "target_version_prefix = "
             << omaha_request_params_->target_version_prefix()
             << ", rollback_allowed = "
@@ -437,7 +453,8 @@
   // Take a copy of the old scatter value before we update it, as
   // we need to update the waiting period if this value changes.
   TimeDelta old_scatter_factor = scatter_factor_;
-  const policy::DevicePolicy* device_policy = system_state_->device_policy();
+  const policy::DevicePolicy* device_policy =
+      SystemState::Get()->device_policy();
   if (device_policy) {
     int64_t new_scatter_factor_in_secs = 0;
     device_policy->GetScatterFactorInSeconds(&new_scatter_factor_in_secs);
@@ -451,8 +468,8 @@
     LOG(INFO) << "Scattering disabled since scatter factor is set to 0";
   } else if (interactive) {
     LOG(INFO) << "Scattering disabled as this is an interactive update check";
-  } else if (system_state_->hardware()->IsOOBEEnabled() &&
-             !system_state_->hardware()->IsOOBEComplete(nullptr)) {
+  } else if (SystemState::Get()->hardware()->IsOOBEEnabled() &&
+             !SystemState::Get()->hardware()->IsOOBEComplete(nullptr)) {
     LOG(INFO) << "Scattering disabled since OOBE is enabled but not complete "
                  "yet";
   } else {
@@ -554,19 +571,19 @@
   // 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.
-  system_state_->payload_state()->SetScatteringWaitPeriod(
+  SystemState::Get()->payload_state()->SetScatteringWaitPeriod(
       omaha_request_params_->waiting_period());
 }
 
 void UpdateAttempter::CalculateStagingParams(bool interactive) {
-  bool oobe_complete = system_state_->hardware()->IsOOBEEnabled() &&
-                       system_state_->hardware()->IsOOBEComplete(nullptr);
-  auto device_policy = system_state_->device_policy();
+  bool oobe_complete = SystemState::Get()->hardware()->IsOOBEEnabled() &&
+                       SystemState::Get()->hardware()->IsOOBEComplete(nullptr);
+  auto device_policy = SystemState::Get()->device_policy();
   StagingCase staging_case = StagingCase::kOff;
   if (device_policy && !interactive && oobe_complete) {
     staging_wait_time_ = omaha_request_params_->waiting_period();
     staging_case = CalculateStagingCase(
-        device_policy, prefs_, &staging_wait_time_, &staging_schedule_);
+        device_policy, &staging_wait_time_, &staging_schedule_);
   }
   switch (staging_case) {
     case StagingCase::kOff:
@@ -601,11 +618,10 @@
 
 bool UpdateAttempter::ResetDlcPrefs(const string& dlc_id) {
   vector<string> failures;
-  PrefsInterface* prefs = system_state_->prefs();
   for (auto& sub_key :
        {kPrefsPingActive, kPrefsPingLastActive, kPrefsPingLastRollcall}) {
-    auto key = prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, sub_key});
-    if (!prefs->Delete(key))
+    auto key = prefs_->CreateSubKey({kDlcPrefsSubDir, dlc_id, sub_key});
+    if (!prefs_->Delete(key))
       failures.emplace_back(sub_key);
   }
   if (failures.size() != 0)
@@ -615,6 +631,20 @@
   return failures.size() == 0;
 }
 
+void UpdateAttempter::SetPref(const string& pref_key,
+                              const string& pref_value,
+                              const string& payload_id) {
+  string dlc_id;
+  if (!omaha_request_params_->GetDlcId(payload_id, &dlc_id)) {
+    // Not a DLC ID, set fingerprint in perf for platform ID.
+    prefs_->SetString(pref_key, pref_value);
+  } else {
+    // Set fingerprint in pref for DLC ID.
+    auto key = prefs_->CreateSubKey({kDlcPrefsSubDir, dlc_id, pref_key});
+    prefs_->SetString(key, pref_value);
+  }
+}
+
 bool UpdateAttempter::SetDlcActiveValue(bool is_active, const string& dlc_id) {
   if (dlc_id.empty()) {
     LOG(ERROR) << "Empty DLC ID passed.";
@@ -622,11 +652,10 @@
   }
   LOG(INFO) << "Set DLC (" << dlc_id << ") to "
             << (is_active ? "Active" : "Inactive");
-  PrefsInterface* prefs = system_state_->prefs();
   if (is_active) {
     auto ping_active_key =
-        prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
-    if (!prefs->SetInt64(ping_active_key, kPingActiveValue)) {
+        prefs_->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
+    if (!prefs_->SetInt64(ping_active_key, kPingActiveValue)) {
       LOG(ERROR) << "Failed to set the value of ping metadata '"
                  << kPrefsPingActive << "'.";
       return false;
@@ -641,11 +670,11 @@
   // The first time a ping is sent, the metadata files containing the values
   // sent back by the server still don't exist. A value of -1 is used to
   // indicate this.
-  if (!system_state_->prefs()->Exists(metadata_key))
+  if (!SystemState::Get()->prefs()->Exists(metadata_key))
     return kPingNeverPinged;
 
   int64_t value;
-  if (system_state_->prefs()->GetInt64(metadata_key, &value))
+  if (SystemState::Get()->prefs()->GetInt64(metadata_key, &value))
     return value;
 
   // Return -2 when the file exists and there is a problem reading from it, or
@@ -657,11 +686,10 @@
   // Set the |dlc_ids_| only for an update. This is required to get the
   // currently installed DLC(s).
   if (!is_install_ &&
-      !system_state_->dlcservice()->GetDlcsToUpdate(&dlc_ids_)) {
+      !SystemState::Get()->dlcservice()->GetDlcsToUpdate(&dlc_ids_)) {
     LOG(INFO) << "Failed to retrieve DLC module IDs from dlcservice. Check the "
                  "state of dlcservice, will not update DLC modules.";
   }
-  PrefsInterface* prefs = system_state_->prefs();
   map<string, OmahaRequestParams::AppParams> dlc_apps_params;
   for (const auto& dlc_id : dlc_ids_) {
     OmahaRequestParams::AppParams dlc_params{
@@ -681,16 +709,16 @@
       // install or might not really be active yet.
       dlc_params.ping_active = kPingActiveValue;
       auto ping_active_key =
-          prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
-      if (!prefs->GetInt64(ping_active_key, &dlc_params.ping_active) ||
+          prefs_->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
+      if (!prefs_->GetInt64(ping_active_key, &dlc_params.ping_active) ||
           dlc_params.ping_active != kPingActiveValue) {
         dlc_params.ping_active = kPingInactiveValue;
       }
       auto ping_last_active_key =
-          prefs->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingLastActive});
+          prefs_->CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingLastActive});
       dlc_params.ping_date_last_active = GetPingMetadata(ping_last_active_key);
 
-      auto ping_last_rollcall_key = prefs->CreateSubKey(
+      auto ping_last_rollcall_key = prefs_->CreateSubKey(
           {kDlcPrefsSubDir, dlc_id, kPrefsPingLastRollcall});
       dlc_params.ping_date_last_rollcall =
           GetPingMetadata(ping_last_rollcall_key);
@@ -713,64 +741,55 @@
 
   // Actions:
   auto update_check_fetcher = std::make_unique<LibcurlHttpFetcher>(
-      GetProxyResolver(), system_state_->hardware());
+      GetProxyResolver(), SystemState::Get()->hardware());
   update_check_fetcher->set_server_to_check(ServerToCheck::kUpdate);
   // Try harder to connect to the network, esp when not interactive.
   // See comment in libcurl_http_fetcher.cc.
   update_check_fetcher->set_no_network_max_retries(interactive ? 1 : 3);
   update_check_fetcher->set_is_update_check(true);
-  auto update_check_action =
-      std::make_unique<OmahaRequestAction>(system_state_,
-                                           nullptr,
-                                           std::move(update_check_fetcher),
-                                           false,
-                                           session_id_);
-  auto response_handler_action =
-      std::make_unique<OmahaResponseHandlerAction>(system_state_);
-  auto update_boot_flags_action =
-      std::make_unique<UpdateBootFlagsAction>(system_state_->boot_control());
+  auto update_check_action = std::make_unique<OmahaRequestAction>(
+      nullptr, std::move(update_check_fetcher), false, session_id_);
+  auto response_handler_action = std::make_unique<OmahaResponseHandlerAction>();
+  auto update_boot_flags_action = std::make_unique<UpdateBootFlagsAction>(
+      SystemState::Get()->boot_control());
   auto download_started_action = std::make_unique<OmahaRequestAction>(
-      system_state_,
       new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
       std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
-                                           system_state_->hardware()),
+                                           SystemState::Get()->hardware()),
       false,
       session_id_);
 
-  LibcurlHttpFetcher* download_fetcher =
-      new LibcurlHttpFetcher(GetProxyResolver(), system_state_->hardware());
+  LibcurlHttpFetcher* download_fetcher = new LibcurlHttpFetcher(
+      GetProxyResolver(), SystemState::Get()->hardware());
   download_fetcher->set_server_to_check(ServerToCheck::kDownload);
   if (interactive)
     download_fetcher->set_max_retry_count(kDownloadMaxRetryCountInteractive);
   download_fetcher->SetHeader(kXGoogleUpdateSessionId, session_id_);
   auto download_action =
       std::make_unique<DownloadAction>(prefs_,
-                                       system_state_->boot_control(),
-                                       system_state_->hardware(),
-                                       system_state_,
+                                       SystemState::Get()->boot_control(),
+                                       SystemState::Get()->hardware(),
                                        download_fetcher,  // passes ownership
                                        interactive);
   download_action->set_delegate(this);
 
   auto download_finished_action = std::make_unique<OmahaRequestAction>(
-      system_state_,
       new OmahaEvent(OmahaEvent::kTypeUpdateDownloadFinished),
       std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
-                                           system_state_->hardware()),
+                                           SystemState::Get()->hardware()),
       false,
       session_id_);
   auto filesystem_verifier_action = std::make_unique<FilesystemVerifierAction>(
-      system_state_->boot_control()->GetDynamicPartitionControl());
+      SystemState::Get()->boot_control()->GetDynamicPartitionControl());
   auto update_complete_action = std::make_unique<OmahaRequestAction>(
-      system_state_,
       new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
       std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
-                                           system_state_->hardware()),
+                                           SystemState::Get()->hardware()),
       false,
       session_id_);
 
   auto postinstall_runner_action = std::make_unique<PostinstallRunnerAction>(
-      system_state_->boot_control(), system_state_->hardware());
+      SystemState::Get()->boot_control(), SystemState::Get()->hardware());
   postinstall_runner_action->set_delegate(this);
 
   // Bond them together. We have to use the leaf-types when calling
@@ -804,7 +823,8 @@
     // Enterprise-enrolled devices have an empty owner in their device policy.
     string owner;
     RefreshDevicePolicy();
-    const policy::DevicePolicy* device_policy = system_state_->device_policy();
+    const policy::DevicePolicy* device_policy =
+        SystemState::Get()->device_policy();
     if (device_policy && (!device_policy->GetOwner(&owner) || owner.empty())) {
       LOG(ERROR) << "Enterprise device detected. "
                  << "Cannot perform a powerwash for enterprise devices.";
@@ -823,26 +843,26 @@
   LOG(INFO) << "Setting rollback options.";
   install_plan_.reset(new InstallPlan());
   install_plan_->target_slot = GetRollbackSlot();
-  install_plan_->source_slot = system_state_->boot_control()->GetCurrentSlot();
+  install_plan_->source_slot =
+      SystemState::Get()->boot_control()->GetCurrentSlot();
 
-  TEST_AND_RETURN_FALSE(
-      install_plan_->LoadPartitionsFromSlots(system_state_->boot_control()));
+  TEST_AND_RETURN_FALSE(install_plan_->LoadPartitionsFromSlots(
+      SystemState::Get()->boot_control()));
   install_plan_->powerwash_required = powerwash;
 
-  LOG(INFO) << "Using this install plan:";
   install_plan_->Dump();
 
   auto install_plan_action =
       std::make_unique<InstallPlanAction>(*install_plan_);
   auto postinstall_runner_action = std::make_unique<PostinstallRunnerAction>(
-      system_state_->boot_control(), system_state_->hardware());
+      SystemState::Get()->boot_control(), SystemState::Get()->hardware());
   postinstall_runner_action->set_delegate(this);
   BondActions(install_plan_action.get(), postinstall_runner_action.get());
   processor_->EnqueueAction(std::move(install_plan_action));
   processor_->EnqueueAction(std::move(postinstall_runner_action));
 
   // Update the payload state for Rollback.
-  system_state_->payload_state()->Rollback();
+  SystemState::Get()->payload_state()->Rollback();
 
   SetStatusAndNotify(UpdateStatus::ATTEMPTING_ROLLBACK);
 
@@ -859,9 +879,10 @@
 
 BootControlInterface::Slot UpdateAttempter::GetRollbackSlot() const {
   LOG(INFO) << "UpdateAttempter::GetRollbackSlot";
-  const unsigned int num_slots = system_state_->boot_control()->GetNumSlots();
+  const unsigned int num_slots =
+      SystemState::Get()->boot_control()->GetNumSlots();
   const BootControlInterface::Slot current_slot =
-      system_state_->boot_control()->GetCurrentSlot();
+      SystemState::Get()->boot_control()->GetCurrentSlot();
 
   LOG(INFO) << "  Installed slots: " << num_slots;
   LOG(INFO) << "  Booted from slot: "
@@ -875,7 +896,7 @@
   vector<BootControlInterface::Slot> bootable_slots;
   for (BootControlInterface::Slot slot = 0; slot < num_slots; slot++) {
     if (slot != current_slot &&
-        system_state_->boot_control()->IsSlotBootable(slot)) {
+        SystemState::Get()->boot_control()->IsSlotBootable(slot)) {
       LOG(INFO) << "Found bootable slot "
                 << BootControlInterface::SlotName(slot);
       return slot;
@@ -981,15 +1002,7 @@
 }
 
 bool UpdateAttempter::RebootIfNeeded() {
-#ifdef __ANDROID__
-  if (status_ != UpdateStatus::UPDATED_NEED_REBOOT) {
-    LOG(INFO) << "Reboot requested, but status is "
-              << UpdateStatusToString(status_) << ", so not rebooting.";
-    return false;
-  }
-#endif  // __ANDROID__
-
-  if (system_state_->power_manager()->RequestReboot())
+  if (SystemState::Get()->power_manager()->RequestReboot())
     return true;
 
   return RebootDirectly();
@@ -1001,7 +1014,7 @@
     return;
   prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id);
 
-  int64_t value = system_state_->clock()->GetBootTime().ToInternalValue();
+  int64_t value = SystemState::Get()->clock()->GetBootTime().ToInternalValue();
   prefs_->SetInt64(kPrefsUpdateCompletedBootTime, value);
 }
 
@@ -1061,19 +1074,19 @@
 }
 
 void UpdateAttempter::UpdateLastCheckedTime() {
-  last_checked_time_ = system_state_->clock()->GetWallclockTime().ToTimeT();
+  last_checked_time_ =
+      SystemState::Get()->clock()->GetWallclockTime().ToTimeT();
 }
 
 void UpdateAttempter::UpdateRollbackHappened() {
-  DCHECK(system_state_);
-  DCHECK(system_state_->payload_state());
+  DCHECK(SystemState::Get()->payload_state());
   DCHECK(policy_provider_);
-  if (system_state_->payload_state()->GetRollbackHappened() &&
+  if (SystemState::Get()->payload_state()->GetRollbackHappened() &&
       (policy_provider_->device_policy_is_loaded() ||
        policy_provider_->IsConsumerDevice())) {
     // Rollback happened, but we already went through OOBE and policy is
     // present or it's a consumer device.
-    system_state_->payload_state()->SetRollbackHappened(false);
+    SystemState::Get()->payload_state()->SetRollbackHappened(false);
   }
 }
 
@@ -1116,7 +1129,7 @@
                     omaha_request_params_->app_version());
   DeltaPerformer::ResetUpdateProgress(prefs_, false);
 
-  system_state_->payload_state()->UpdateSucceeded();
+  SystemState::Get()->payload_state()->UpdateSucceeded();
 
   // Since we're done with scattering fully at this point, this is the
   // safest point delete the state files, as we're sure that the status is
@@ -1128,8 +1141,8 @@
   // after reboot so that the same device is not favored or punished in any
   // way.
   prefs_->Delete(kPrefsUpdateCheckCount);
-  system_state_->payload_state()->SetScatteringWaitPeriod(TimeDelta());
-  system_state_->payload_state()->SetStagingWaitPeriod(TimeDelta());
+  SystemState::Get()->payload_state()->SetScatteringWaitPeriod(TimeDelta());
+  SystemState::Get()->payload_state()->SetStagingWaitPeriod(TimeDelta());
   prefs_->Delete(kPrefsUpdateFirstSeenAt);
 
   // Note: below this comment should only be on |ErrorCode::kSuccess|.
@@ -1150,7 +1163,8 @@
 
 void UpdateAttempter::ProcessingDoneInstall(const ActionProcessor* processor,
                                             ErrorCode code) {
-  if (!system_state_->dlcservice()->InstallCompleted(GetSuccessfulDlcIds()))
+  if (!SystemState::Get()->dlcservice()->InstallCompleted(
+          GetSuccessfulDlcIds()))
     LOG(WARNING) << "dlcservice didn't successfully handle install completion.";
   SetStatusAndNotify(UpdateStatus::IDLE);
   ScheduleUpdates();
@@ -1161,7 +1175,7 @@
                                            ErrorCode code) {
   WriteUpdateCompletedMarker();
 
-  if (!system_state_->dlcservice()->UpdateCompleted(GetSuccessfulDlcIds()))
+  if (!SystemState::Get()->dlcservice()->UpdateCompleted(GetSuccessfulDlcIds()))
     LOG(WARNING) << "dlcservice didn't successfully handle update completion.";
   SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
   ScheduleUpdates();
@@ -1175,24 +1189,27 @@
     for (const auto& payload : install_plan_->payloads) {
       target_version_uid += brillo::data_encoding::Base64Encode(payload.hash) +
                             ":" + payload.metadata_signature + ":";
+      // Set fingerprint value for updates only.
+      if (!is_install_)
+        SetPref(kPrefsLastFp, payload.fp, payload.app_id);
     }
 
     // If we just downloaded a rollback image, we should preserve this fact
     // over the following powerwash.
     if (install_plan_->is_rollback) {
-      system_state_->payload_state()->SetRollbackHappened(true);
-      system_state_->metrics_reporter()->ReportEnterpriseRollbackMetrics(
+      SystemState::Get()->payload_state()->SetRollbackHappened(true);
+      SystemState::Get()->metrics_reporter()->ReportEnterpriseRollbackMetrics(
           /*success=*/true, install_plan_->version);
     }
 
     // Expect to reboot into the new version to send the proper metric during
     // next boot.
-    system_state_->payload_state()->ExpectRebootInNewVersion(
+    SystemState::Get()->payload_state()->ExpectRebootInNewVersion(
         target_version_uid);
   } else {
     // If we just finished a rollback, then we expect to have no Omaha
     // response. Otherwise, it's an error.
-    if (system_state_->payload_state()->GetRollbackVersion().empty()) {
+    if (SystemState::Get()->payload_state()->GetRollbackVersion().empty()) {
       LOG(ERROR) << "Can't send metrics because there was no Omaha response";
     }
   }
@@ -1340,7 +1357,7 @@
                                     uint64_t total) {
   // The PayloadState keeps track of how many bytes were actually downloaded
   // from a given URL for the URL skipping logic.
-  system_state_->payload_state()->DownloadProgress(bytes_progressed);
+  SystemState::Get()->payload_state()->DownloadProgress(bytes_progressed);
 
   double progress = 0;
   if (total)
@@ -1354,7 +1371,7 @@
 }
 
 void UpdateAttempter::DownloadComplete() {
-  system_state_->payload_state()->DownloadComplete();
+  SystemState::Get()->payload_state()->DownloadComplete();
 }
 
 void UpdateAttempter::ProgressUpdate(double progress) {
@@ -1396,9 +1413,10 @@
       // UpdateStatus::UPDATED_NEED_REBOOT state.
       ret_value = prefs_->Delete(kPrefsUpdateCompletedOnBootId) && ret_value;
       ret_value = prefs_->Delete(kPrefsUpdateCompletedBootTime) && ret_value;
+      ret_value = prefs_->Delete(kPrefsLastFp, {kDlcPrefsSubDir}) && ret_value;
 
       // Update the boot flags so the current slot has higher priority.
-      BootControlInterface* boot_control = system_state_->boot_control();
+      BootControlInterface* boot_control = SystemState::Get()->boot_control();
       if (!boot_control->SetActiveBootSlot(boot_control->GetCurrentSlot()))
         ret_value = false;
 
@@ -1409,7 +1427,7 @@
         ret_value = false;
 
       // Notify the PayloadState that the successful payload was canceled.
-      system_state_->payload_state()->ResetUpdateStatus();
+      SystemState::Get()->payload_state()->ResetUpdateStatus();
 
       // The previous version is used to report back to omaha after reboot that
       // we actually rebooted into the new version from this "prev-version". We
@@ -1439,8 +1457,9 @@
   out_status->is_install = is_install_;
 
   string str_eol_date;
-  if (system_state_->prefs()->Exists(kPrefsOmahaEolDate) &&
-      !system_state_->prefs()->GetString(kPrefsOmahaEolDate, &str_eol_date))
+  if (SystemState::Get()->prefs()->Exists(kPrefsOmahaEolDate) &&
+      !SystemState::Get()->prefs()->GetString(kPrefsOmahaEolDate,
+                                              &str_eol_date))
     LOG(ERROR) << "Failed to retrieve kPrefsOmahaEolDate pref.";
   out_status->eol_date = StringToEolDate(str_eol_date);
 
@@ -1467,13 +1486,13 @@
 uint32_t UpdateAttempter::GetErrorCodeFlags() {
   uint32_t flags = 0;
 
-  if (!system_state_->hardware()->IsNormalBootMode())
+  if (!SystemState::Get()->hardware()->IsNormalBootMode())
     flags |= static_cast<uint32_t>(ErrorCode::kDevModeFlag);
 
   if (install_plan_ && install_plan_->is_resume)
     flags |= static_cast<uint32_t>(ErrorCode::kResumedFlag);
 
-  if (!system_state_->hardware()->IsOfficialBuild())
+  if (!SystemState::Get()->hardware()->IsOfficialBuild())
     flags |= static_cast<uint32_t>(ErrorCode::kTestImageFlag);
 
   if (!omaha_request_params_->IsUpdateUrlOfficial()) {
@@ -1486,7 +1505,7 @@
 bool UpdateAttempter::ShouldCancel(ErrorCode* cancel_reason) {
   // Check if the channel we're attempting to update to is the same as the
   // target channel currently chosen by the user.
-  OmahaRequestParams* params = system_state_->request_params();
+  OmahaRequestParams* params = SystemState::Get()->request_params();
   if (params->download_channel() != params->target_channel()) {
     LOG(ERROR) << "Aborting download as target channel: "
                << params->target_channel()
@@ -1544,21 +1563,20 @@
     return false;
 
   LOG(ERROR) << "Update failed.";
-  system_state_->payload_state()->UpdateFailed(error_event_->error_code);
+  SystemState::Get()->payload_state()->UpdateFailed(error_event_->error_code);
 
   // Send metrics if it was a rollback.
   if (install_plan_ && install_plan_->is_rollback) {
-    system_state_->metrics_reporter()->ReportEnterpriseRollbackMetrics(
+    SystemState::Get()->metrics_reporter()->ReportEnterpriseRollbackMetrics(
         /*success=*/false, install_plan_->version);
   }
 
   // Send it to Omaha.
   LOG(INFO) << "Reporting the error event";
   auto error_event_action = std::make_unique<OmahaRequestAction>(
-      system_state_,
       error_event_.release(),  // Pass ownership.
       std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
-                                           system_state_->hardware()),
+                                           SystemState::Get()->hardware()),
       false,
       session_id_);
   processor_->EnqueueAction(std::move(error_event_action));
@@ -1601,10 +1619,9 @@
     ResetInteractivityFlags();
 
     auto ping_action = std::make_unique<OmahaRequestAction>(
-        system_state_,
         nullptr,
         std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
-                                             system_state_->hardware()),
+                                             SystemState::Get()->hardware()),
         true,
         "" /* session_id */);
     processor_->set_delegate(nullptr);
@@ -1687,9 +1704,9 @@
   // in case we rebooted because of a crash of the old version, so we
   // can do a proper crash report with correct information.
   // This must be done before calling
-  // system_state_->payload_state()->UpdateEngineStarted() since it will
+  // SystemState::Get()->payload_state()->UpdateEngineStarted() since it will
   // delete SystemUpdated marker file.
-  if (system_state_->system_rebooted() &&
+  if (SystemState::Get()->system_rebooted() &&
       prefs_->Exists(kPrefsSystemUpdatedMarker)) {
     if (!prefs_->GetString(kPrefsPreviousVersion, &prev_version_)) {
       // If we fail to get the version string, make sure it stays empty.
@@ -1697,20 +1714,38 @@
     }
   }
 
-  system_state_->payload_state()->UpdateEngineStarted();
+  MoveToPrefs({kPrefsLastRollCallPingDay, kPrefsLastActivePingDay});
+
+  SystemState::Get()->payload_state()->UpdateEngineStarted();
   StartP2PAtStartup();
 
-  excluder_ = CreateExcluder(system_state_->prefs());
+  excluder_ = CreateExcluder();
+}
+
+void UpdateAttempter::MoveToPrefs(const vector<string>& keys) {
+  auto* powerwash_safe_prefs = SystemState::Get()->powerwash_safe_prefs();
+  for (const auto& key : keys) {
+    // Do not overwrite existing pref key with powerwash prefs.
+    if (!prefs_->Exists(key) && powerwash_safe_prefs->Exists(key)) {
+      string value;
+      if (!powerwash_safe_prefs->GetString(key, &value) ||
+          !prefs_->SetString(key, value)) {
+        PLOG(ERROR) << "Unable to add powerwash safe key " << key
+                    << " to prefs. Powerwash safe key will be deleted.";
+      }
+    }
+    // Delete keys regardless of operation success to preserve privacy.
+    powerwash_safe_prefs->Delete(key);
+  }
 }
 
 bool UpdateAttempter::StartP2PAtStartup() {
-  if (system_state_ == nullptr ||
-      !system_state_->p2p_manager()->IsP2PEnabled()) {
+  if (!SystemState::Get()->p2p_manager()->IsP2PEnabled()) {
     LOG(INFO) << "Not starting p2p at startup since it's not enabled.";
     return false;
   }
 
-  if (system_state_->p2p_manager()->CountSharedFiles() < 1) {
+  if (SystemState::Get()->p2p_manager()->CountSharedFiles() < 1) {
     LOG(INFO) << "Not starting p2p at startup since our application "
               << "is not sharing any files.";
     return false;
@@ -1720,22 +1755,19 @@
 }
 
 bool UpdateAttempter::StartP2PAndPerformHousekeeping() {
-  if (system_state_ == nullptr)
-    return false;
-
-  if (!system_state_->p2p_manager()->IsP2PEnabled()) {
+  if (!SystemState::Get()->p2p_manager()->IsP2PEnabled()) {
     LOG(INFO) << "Not starting p2p since it's not enabled.";
     return false;
   }
 
   LOG(INFO) << "Ensuring that p2p is running.";
-  if (!system_state_->p2p_manager()->EnsureP2PRunning()) {
+  if (!SystemState::Get()->p2p_manager()->EnsureP2PRunning()) {
     LOG(ERROR) << "Error starting p2p.";
     return false;
   }
 
   LOG(INFO) << "Performing p2p housekeeping.";
-  if (!system_state_->p2p_manager()->PerformHousekeeping()) {
+  if (!SystemState::Get()->p2p_manager()->PerformHousekeeping()) {
     LOG(ERROR) << "Error performing housekeeping for p2p.";
     return false;
   }
@@ -1782,12 +1814,12 @@
   //  * The debugd dev features are accessible (i.e. in devmode with no owner).
   // This protects users running a base image, while still allowing a specific
   // window (gated by the debug dev features) where `cros flash` is usable.
-  if (!system_state_->hardware()->IsOfficialBuild()) {
+  if (!SystemState::Get()->hardware()->IsOfficialBuild()) {
     LOG(INFO) << "Non-official build; allowing any update source.";
     return true;
   }
 
-  if (system_state_->hardware()->AreDevFeaturesEnabled()) {
+  if (SystemState::Get()->hardware()->AreDevFeaturesEnabled()) {
     LOG(INFO) << "Developer features enabled; allowing custom update sources.";
     return true;
   }
@@ -1798,20 +1830,22 @@
 }
 
 void UpdateAttempter::ReportTimeToUpdateAppliedMetric() {
-  const policy::DevicePolicy* device_policy = system_state_->device_policy();
+  const policy::DevicePolicy* device_policy =
+      SystemState::Get()->device_policy();
   if (device_policy && device_policy->IsEnterpriseEnrolled()) {
     vector<policy::DevicePolicy::WeeklyTimeInterval> parsed_intervals;
     bool has_time_restrictions =
         device_policy->GetDisallowedTimeIntervals(&parsed_intervals);
 
     int64_t update_first_seen_at_int;
-    if (system_state_->prefs()->Exists(kPrefsUpdateFirstSeenAt)) {
-      if (system_state_->prefs()->GetInt64(kPrefsUpdateFirstSeenAt,
-                                           &update_first_seen_at_int)) {
+    if (SystemState::Get()->prefs()->Exists(kPrefsUpdateFirstSeenAt)) {
+      if (SystemState::Get()->prefs()->GetInt64(kPrefsUpdateFirstSeenAt,
+                                                &update_first_seen_at_int)) {
         TimeDelta update_delay =
-            system_state_->clock()->GetWallclockTime() -
+            SystemState::Get()->clock()->GetWallclockTime() -
             Time::FromInternalValue(update_first_seen_at_int);
-        system_state_->metrics_reporter()
+        SystemState::Get()
+            ->metrics_reporter()
             ->ReportEnterpriseUpdateSeenToDownloadDays(has_time_restrictions,
                                                        update_delay.InDays());
       }
diff --git a/cros/update_attempter.h b/cros/update_attempter.h
index 0f4c952..6010484 100644
--- a/cros/update_attempter.h
+++ b/cros/update_attempter.h
@@ -34,14 +34,13 @@
 #include "update_engine/client_library/include/update_engine/update_status.h"
 #include "update_engine/common/action_processor.h"
 #include "update_engine/common/cpu_limiter.h"
+#include "update_engine/common/daemon_state_interface.h"
 #include "update_engine/common/download_action.h"
 #include "update_engine/common/excluder_interface.h"
 #include "update_engine/common/proxy_resolver.h"
 #include "update_engine/common/service_observer_interface.h"
 #include "update_engine/common/system_state.h"
-#if USE_CHROME_NETWORK_PROXY
 #include "update_engine/cros/chrome_browser_proxy_resolver.h"
-#endif  // USE_CHROME_NETWORK_PROXY
 #include "update_engine/cros/omaha_request_builder_xml.h"
 #include "update_engine/cros/omaha_request_params.h"
 #include "update_engine/cros/omaha_response_handler_action.h"
@@ -59,13 +58,14 @@
 class UpdateAttempter : public ActionProcessorDelegate,
                         public DownloadActionDelegate,
                         public CertificateChecker::Observer,
-                        public PostinstallRunnerAction::DelegateInterface {
+                        public PostinstallRunnerAction::DelegateInterface,
+                        public DaemonStateInterface {
  public:
   using UpdateStatus = update_engine::UpdateStatus;
   using UpdateAttemptFlags = update_engine::UpdateAttemptFlags;
   static const int kMaxDeltaUpdateFailures;
 
-  UpdateAttempter(SystemState* system_state, CertificateChecker* cert_checker);
+  explicit UpdateAttempter(CertificateChecker* cert_checker);
   ~UpdateAttempter() override;
 
   // Further initialization to be done post construction.
@@ -219,15 +219,15 @@
   // 'cros flash' to function properly).
   bool IsAnyUpdateSourceAllowed() const;
 
-  // Add and remove a service observer.
-  void AddObserver(ServiceObserverInterface* observer) {
+  // |DaemonStateInterface| overrides.
+  bool StartUpdater() override;
+  void AddObserver(ServiceObserverInterface* observer) override {
     service_observers_.insert(observer);
   }
-  void RemoveObserver(ServiceObserverInterface* observer) {
+  void RemoveObserver(ServiceObserverInterface* observer) override {
     service_observers_.erase(observer);
   }
-
-  const std::set<ServiceObserverInterface*>& service_observers() {
+  const std::set<ServiceObserverInterface*>& service_observers() override {
     return service_observers_;
   }
 
@@ -289,6 +289,8 @@
   FRIEND_TEST(UpdateAttempterTest, UpdateDeferredByPolicyTest);
   FRIEND_TEST(UpdateAttempterTest, UpdateIsNotRunningWhenUpdateAvailable);
   FRIEND_TEST(UpdateAttempterTest, GetSuccessfulDlcIds);
+  FRIEND_TEST(UpdateAttempterTest, QuickFixTokenWhenDeviceIsEnterpriseEnrolled);
+  FRIEND_TEST(UpdateAttempterTest, MoveToPrefs);
 
   // Returns the special flags to be added to ErrorCode values based on the
   // parameters used in the current update attempt.
@@ -339,10 +341,8 @@
   void MarkDeltaUpdateFailure();
 
   ProxyResolver* GetProxyResolver() {
-#if USE_CHROME_NETWORK_PROXY
     if (obeying_proxies_)
       return &chrome_proxy_resolver_;
-#endif  // USE_CHROME_NETWORK_PROXY
     return &direct_proxy_resolver_;
   }
 
@@ -362,7 +362,7 @@
   // Calculates all the scattering related parameters (such as waiting period,
   // which type of scattering is enabled, etc.) and also updates/deletes
   // the corresponding prefs file used in scattering. Should be called
-  // only after the device policy has been loaded and set in the system_state_.
+  // only after the device policy has been loaded and set in the system state.
   void CalculateScatteringParams(bool interactive);
 
   // Sets a random value for the waiting period to wait for before downloading
@@ -388,6 +388,10 @@
   // on the |omaha_request_params_| object.
   void CalculateP2PParams(bool interactive);
 
+  // For each key, reads value from powerwash safe prefs and adds it to prefs
+  // if key doesnt already exist. Then deletes the powerwash safe keys.
+  void MoveToPrefs(const std::vector<std::string>& keys);
+
   // Starts P2P if it's enabled and there are files to actually share.
   // Called only at program startup. Returns true only if p2p was
   // started and housekeeping was performed.
@@ -431,6 +435,11 @@
   // Resets all the DLC prefs.
   bool ResetDlcPrefs(const std::string& dlc_id);
 
+  // Sets given pref key for DLC and platform.
+  void SetPref(const std::string& pref_key,
+               const std::string& pref_value,
+               const std::string& payload_id);
+
   // Get the integer values from the DLC metadata for |kPrefsPingLastActive|
   // or |kPrefsPingLastRollcall|.
   // The value is equal to -2 when the value cannot be read or is not numeric.
@@ -453,15 +462,11 @@
 
   // Our two proxy resolvers
   DirectProxyResolver direct_proxy_resolver_;
-#if USE_CHROME_NETWORK_PROXY
   ChromeBrowserProxyResolver chrome_proxy_resolver_;
-#endif  // USE_CHROME_NETWORK_PROXY
 
   std::unique_ptr<ActionProcessor> processor_;
 
-  // External state of the system outside the update_engine process
-  // carved out separately to mock out easily in unit tests.
-  SystemState* system_state_;
+  ActionProcessor aux_processor_;
 
   // Pointer to the certificate checker instance to use.
   CertificateChecker* cert_checker_;
@@ -473,7 +478,7 @@
   std::unique_ptr<InstallPlan> install_plan_;
 
   // Pointer to the preferences store interface. This is just a cached
-  // copy of system_state->prefs() because it's used in many methods and
+  // copy of SystemState::Get()->prefs() because it's used in many methods and
   // is convenient this way.
   PrefsInterface* prefs_ = nullptr;
 
diff --git a/cros/update_attempter_unittest.cc b/cros/update_attempter_unittest.cc
index f3211a0..a11e00c 100644
--- a/cros/update_attempter_unittest.cc
+++ b/cros/update_attempter_unittest.cc
@@ -37,12 +37,9 @@
 
 #include "update_engine/common/constants.h"
 #include "update_engine/common/dlcservice_interface.h"
-#include "update_engine/common/fake_clock.h"
-#include "update_engine/common/fake_prefs.h"
 #include "update_engine/common/mock_action.h"
 #include "update_engine/common/mock_action_processor.h"
 #include "update_engine/common/mock_http_fetcher.h"
-#include "update_engine/common/mock_prefs.h"
 #include "update_engine/common/mock_service_observer.h"
 #include "update_engine/common/platform_constants.h"
 #include "update_engine/common/prefs.h"
@@ -169,8 +166,7 @@
 // methods.
 class UpdateAttempterUnderTest : public UpdateAttempter {
  public:
-  explicit UpdateAttempterUnderTest(SystemState* system_state)
-      : UpdateAttempter(system_state, nullptr) {}
+  UpdateAttempterUnderTest() : UpdateAttempter(nullptr) {}
 
   void Update(const UpdateCheckParams& params) override {
     update_called_ = true;
@@ -223,27 +219,25 @@
 
 class UpdateAttempterTest : public ::testing::Test {
  protected:
-  UpdateAttempterTest()
-      : certificate_checker_(fake_system_state_.mock_prefs(),
-                             &openssl_wrapper_) {
+  void SetUp() override {
     // Override system state members.
-    fake_system_state_.set_connection_manager(&mock_connection_manager);
-    fake_system_state_.set_update_attempter(&attempter_);
-    fake_system_state_.set_dlcservice(&mock_dlcservice_);
-    fake_system_state_.set_update_manager(&mock_update_manager_);
+    FakeSystemState::CreateInstance();
+    FakeSystemState::Get()->set_connection_manager(&mock_connection_manager);
+    FakeSystemState::Get()->set_update_attempter(&attempter_);
+    FakeSystemState::Get()->set_dlcservice(&mock_dlcservice_);
+    FakeSystemState::Get()->set_update_manager(&mock_update_manager_);
     loop_.SetAsCurrent();
 
-    certificate_checker_.Init();
+    prefs_ = FakeSystemState::Get()->fake_prefs();
+    certificate_checker_.reset(
+        new CertificateChecker(prefs_, &openssl_wrapper_));
+    certificate_checker_->Init();
 
     attempter_.set_forced_update_pending_callback(
         new base::Callback<void(bool, bool)>(base::Bind([](bool, bool) {})));
     // Finish initializing the attempter.
     attempter_.Init();
-  }
 
-  void SetUp() override {
-    EXPECT_NE(nullptr, attempter_.system_state_);
-    EXPECT_NE(nullptr, attempter_.system_state_->update_manager());
     EXPECT_EQ(0, attempter_.http_response_code_);
     EXPECT_EQ(UpdateStatus::IDLE, attempter_.status_);
     EXPECT_EQ(0.0, attempter_.download_progress_);
@@ -252,21 +246,20 @@
     EXPECT_EQ(0ULL, attempter_.new_payload_size_);
     processor_ = new NiceMock<MockActionProcessor>();
     attempter_.processor_.reset(processor_);  // Transfers ownership.
-    prefs_ = fake_system_state_.mock_prefs();
 
     // Setup store/load semantics of P2P properties via the mock |PayloadState|.
     actual_using_p2p_for_downloading_ = false;
-    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+    EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
                 SetUsingP2PForDownloading(_))
         .WillRepeatedly(SaveArg<0>(&actual_using_p2p_for_downloading_));
-    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+    EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
                 GetUsingP2PForDownloading())
         .WillRepeatedly(ReturnPointee(&actual_using_p2p_for_downloading_));
     actual_using_p2p_for_sharing_ = false;
-    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+    EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
                 SetUsingP2PForSharing(_))
         .WillRepeatedly(SaveArg<0>(&actual_using_p2p_for_sharing_));
-    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+    EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
                 GetUsingP2PForDownloading())
         .WillRepeatedly(ReturnPointee(&actual_using_p2p_for_sharing_));
   }
@@ -292,12 +285,11 @@
   void SessionIdTestEnforceEmptyStrPingOmaha();
   void SessionIdTestConsistencyInUpdateFlow();
   void SessionIdTestInDownloadAction();
-  void UpdateToQuickFixBuildStart(bool set_token);
   void ResetRollbackHappenedStart(bool is_consumer,
                                   bool is_policy_available,
                                   bool expected_reset);
   // Staging related callbacks.
-  void SetUpStagingTest(const StagingSchedule& schedule, FakePrefs* prefs);
+  void SetUpStagingTest(const StagingSchedule& schedule);
   void CheckStagingOff();
   void StagingSetsPrefsAndTurnsOffScatteringStart();
   void StagingOffIfInteractiveStart();
@@ -320,18 +312,17 @@
   base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO};
   brillo::BaseMessageLoop loop_{base_loop_.task_runner()};
 
-  FakeSystemState fake_system_state_;
-  UpdateAttempterUnderTest attempter_{&fake_system_state_};
+  UpdateAttempterUnderTest attempter_;
   OpenSSLWrapper openssl_wrapper_;
-  CertificateChecker certificate_checker_;
+  std::unique_ptr<CertificateChecker> certificate_checker_;
   MockDlcService mock_dlcservice_;
   MockUpdateManager mock_update_manager_;
 
   NiceMock<MockActionProcessor>* processor_;
-  NiceMock<MockPrefs>*
-      prefs_;  // Shortcut to |fake_system_state_->mock_prefs()|.
   NiceMock<MockConnectionManager> mock_connection_manager;
 
+  FakePrefs* prefs_;
+
   // |CheckForUpdate()| test params.
   CheckForUpdateTestParams cfu_params_;
 
@@ -348,9 +339,9 @@
 void UpdateAttempterTest::TestCheckForUpdate() {
   // Setup
   attempter_.status_ = cfu_params_.status;
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(
       cfu_params_.is_official_build);
-  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(
+  FakeSystemState::Get()->fake_hardware()->SetAreDevFeaturesEnabled(
       cfu_params_.are_dev_features_enabled);
 
   // Invocation
@@ -508,11 +499,10 @@
   DownloadAction action(prefs_,
                         nullptr,
                         nullptr,
-                        nullptr,
                         fetcher.release(),
                         false /* interactive */);
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _)).Times(0);
   attempter_.ActionCompleted(nullptr, &action, ErrorCode::kSuccess);
+  EXPECT_FALSE(prefs_->Exists(kPrefsDeltaUpdateFailures));
   EXPECT_EQ(UpdateStatus::FINALIZING, attempter_.status());
   EXPECT_EQ(0.0, attempter_.download_progress_);
   ASSERT_EQ(nullptr, attempter_.error_event_.get());
@@ -522,8 +512,6 @@
   MockAction action;
   EXPECT_CALL(action, Type()).WillRepeatedly(Return("MockAction"));
   attempter_.status_ = UpdateStatus::DOWNLOADING;
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
-      .WillOnce(Return(false));
   attempter_.ActionCompleted(nullptr, &action, ErrorCode::kError);
   ASSERT_NE(nullptr, attempter_.error_event_.get());
 }
@@ -610,15 +598,14 @@
 TEST_F(UpdateAttempterTest, ActionCompletedOmahaRequestTest) {
   unique_ptr<MockHttpFetcher> fetcher(new MockHttpFetcher("", 0, nullptr));
   fetcher->FailTransfer(500);  // Sets the HTTP response code.
-  OmahaRequestAction action(
-      &fake_system_state_, nullptr, std::move(fetcher), false, "");
+  OmahaRequestAction action(nullptr, std::move(fetcher), false, "");
   ObjectCollectorAction<OmahaResponse> collector_action;
   BondActions(&action, &collector_action);
   OmahaResponse response;
   response.poll_interval = 234;
   action.SetOutputObject(response);
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _)).Times(0);
   attempter_.ActionCompleted(nullptr, &action, ErrorCode::kSuccess);
+  EXPECT_FALSE(prefs_->Exists(kPrefsDeltaUpdateFailures));
   EXPECT_EQ(500, attempter_.http_response_code());
   EXPECT_EQ(UpdateStatus::IDLE, attempter_.status());
   EXPECT_EQ(234U, attempter_.server_dictated_poll_interval_);
@@ -626,11 +613,10 @@
 }
 
 TEST_F(UpdateAttempterTest, ConstructWithUpdatedMarkerTest) {
-  FakePrefs fake_prefs;
   string boot_id;
   EXPECT_TRUE(utils::GetBootId(&boot_id));
-  fake_prefs.SetString(kPrefsUpdateCompletedOnBootId, boot_id);
-  fake_system_state_.set_prefs(&fake_prefs);
+  FakeSystemState::Get()->fake_prefs()->SetString(kPrefsUpdateCompletedOnBootId,
+                                                  boot_id);
   attempter_.Init();
   EXPECT_EQ(UpdateStatus::UPDATED_NEED_REBOOT, attempter_.status());
 }
@@ -639,12 +625,10 @@
   EXPECT_EQ(ErrorCode::kSuccess,
             GetErrorCodeForAction(nullptr, ErrorCode::kSuccess));
 
-  FakeSystemState fake_system_state;
-  OmahaRequestAction omaha_request_action(
-      &fake_system_state, nullptr, nullptr, false, "");
+  OmahaRequestAction omaha_request_action(nullptr, nullptr, false, "");
   EXPECT_EQ(ErrorCode::kOmahaRequestError,
             GetErrorCodeForAction(&omaha_request_action, ErrorCode::kError));
-  OmahaResponseHandlerAction omaha_response_handler_action(&fake_system_state_);
+  OmahaResponseHandlerAction omaha_response_handler_action;
   EXPECT_EQ(
       ErrorCode::kOmahaResponseHandlerError,
       GetErrorCodeForAction(&omaha_response_handler_action, ErrorCode::kError));
@@ -654,7 +638,8 @@
       ErrorCode::kFilesystemVerifierError,
       GetErrorCodeForAction(&filesystem_verifier_action, ErrorCode::kError));
   PostinstallRunnerAction postinstall_runner_action(
-      fake_system_state.fake_boot_control(), fake_system_state.fake_hardware());
+      FakeSystemState::Get()->fake_boot_control(),
+      FakeSystemState::Get()->fake_hardware());
   EXPECT_EQ(
       ErrorCode::kPostinstallRunnerError,
       GetErrorCodeForAction(&postinstall_runner_action, ErrorCode::kError));
@@ -666,59 +651,54 @@
 
 TEST_F(UpdateAttempterTest, DisableDeltaUpdateIfNeededTest) {
   attempter_.omaha_request_params_->set_delta_okay(true);
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
-      .WillOnce(Return(false));
   attempter_.DisableDeltaUpdateIfNeeded();
   EXPECT_TRUE(attempter_.omaha_request_params_->delta_okay());
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
-      .WillOnce(
-          DoAll(SetArgPointee<1>(UpdateAttempter::kMaxDeltaUpdateFailures - 1),
-                Return(true)));
+  prefs_->SetInt64(kPrefsDeltaUpdateFailures,
+                   UpdateAttempter::kMaxDeltaUpdateFailures - 1);
   attempter_.DisableDeltaUpdateIfNeeded();
   EXPECT_TRUE(attempter_.omaha_request_params_->delta_okay());
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
-      .WillOnce(
-          DoAll(SetArgPointee<1>(UpdateAttempter::kMaxDeltaUpdateFailures),
-                Return(true)));
+  prefs_->SetInt64(kPrefsDeltaUpdateFailures,
+                   UpdateAttempter::kMaxDeltaUpdateFailures);
   attempter_.DisableDeltaUpdateIfNeeded();
   EXPECT_FALSE(attempter_.omaha_request_params_->delta_okay());
-  EXPECT_CALL(*prefs_, GetInt64(_, _)).Times(0);
   attempter_.DisableDeltaUpdateIfNeeded();
   EXPECT_FALSE(attempter_.omaha_request_params_->delta_okay());
 }
 
 TEST_F(UpdateAttempterTest, MarkDeltaUpdateFailureTest) {
-  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
-      .WillOnce(Return(false))
-      .WillOnce(DoAll(SetArgPointee<1>(-1), Return(true)))
-      .WillOnce(DoAll(SetArgPointee<1>(1), Return(true)))
-      .WillOnce(
-          DoAll(SetArgPointee<1>(UpdateAttempter::kMaxDeltaUpdateFailures),
-                Return(true)));
-  EXPECT_CALL(*prefs_, SetInt64(Ne(kPrefsDeltaUpdateFailures), _))
-      .WillRepeatedly(Return(true));
-  EXPECT_CALL(*prefs_, SetInt64(kPrefsDeltaUpdateFailures, 1)).Times(2);
-  EXPECT_CALL(*prefs_, SetInt64(kPrefsDeltaUpdateFailures, 2));
-  EXPECT_CALL(*prefs_,
-              SetInt64(kPrefsDeltaUpdateFailures,
-                       UpdateAttempter::kMaxDeltaUpdateFailures + 1));
-  for (int i = 0; i < 4; i++)
-    attempter_.MarkDeltaUpdateFailure();
+  attempter_.MarkDeltaUpdateFailure();
+
+  EXPECT_TRUE(prefs_->SetInt64(kPrefsDeltaUpdateFailures, -1));
+  attempter_.MarkDeltaUpdateFailure();
+  int64_t value = 0;
+  EXPECT_TRUE(prefs_->GetInt64(kPrefsDeltaUpdateFailures, &value));
+  EXPECT_EQ(value, 1);
+
+  attempter_.MarkDeltaUpdateFailure();
+  EXPECT_TRUE(prefs_->GetInt64(kPrefsDeltaUpdateFailures, &value));
+  EXPECT_EQ(value, 2);
+
+  EXPECT_TRUE(prefs_->SetInt64(kPrefsDeltaUpdateFailures,
+                               UpdateAttempter::kMaxDeltaUpdateFailures));
+  attempter_.MarkDeltaUpdateFailure();
+  EXPECT_TRUE(prefs_->GetInt64(kPrefsDeltaUpdateFailures, &value));
+  EXPECT_EQ(value, UpdateAttempter::kMaxDeltaUpdateFailures + 1);
 }
 
 TEST_F(UpdateAttempterTest, ScheduleErrorEventActionNoEventTest) {
   EXPECT_CALL(*processor_, EnqueueAction(_)).Times(0);
   EXPECT_CALL(*processor_, StartProcessing()).Times(0);
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(), UpdateFailed(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(), UpdateFailed(_))
       .Times(0);
   OmahaResponse response;
   string url1 = "http://url1";
   response.packages.push_back({.payload_urls = {url1, "https://url"}});
-  EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetCurrentUrl())
+  EXPECT_CALL(*(FakeSystemState::Get()->mock_payload_state()), GetCurrentUrl())
       .WillRepeatedly(Return(url1));
-  fake_system_state_.mock_payload_state()->SetResponse(response);
+  FakeSystemState::Get()->mock_payload_state()->SetResponse(response);
   attempter_.ScheduleErrorEventAction();
-  EXPECT_EQ(url1, fake_system_state_.mock_payload_state()->GetCurrentUrl());
+  EXPECT_EQ(url1,
+            FakeSystemState::Get()->mock_payload_state()->GetCurrentUrl());
 }
 
 TEST_F(UpdateAttempterTest, ScheduleErrorEventActionTest) {
@@ -727,7 +707,7 @@
                   &AbstractAction::Type, OmahaRequestAction::StaticType()))));
   EXPECT_CALL(*processor_, StartProcessing());
   ErrorCode err = ErrorCode::kError;
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(), UpdateFailed(err));
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(), UpdateFailed(err));
   attempter_.error_event_.reset(new OmahaEvent(
       OmahaEvent::kTypeUpdateComplete, OmahaEvent::kResultError, err));
   attempter_.ScheduleErrorEventAction();
@@ -799,7 +779,7 @@
   // Create a device policy so that we can change settings.
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
   EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
   if (enterprise_rollback) {
     // We return an empty owner as this is an enterprise.
     EXPECT_CALL(*device_policy, GetOwner(_))
@@ -818,8 +798,8 @@
     BootControlInterface::Slot rollback_slot = 1;
     LOG(INFO) << "Test Mark Bootable: "
               << BootControlInterface::SlotName(rollback_slot);
-    fake_system_state_.fake_boot_control()->SetSlotBootable(rollback_slot,
-                                                            true);
+    FakeSystemState::Get()->fake_boot_control()->SetSlotBootable(rollback_slot,
+                                                                 true);
   }
 
   bool is_rollback_allowed = false;
@@ -944,7 +924,7 @@
 
 TEST_F(UpdateAttempterTest, P2PNotStartedAtStartupWhenNotEnabled) {
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetP2PEnabled(false);
   EXPECT_CALL(mock_p2p_manager, EnsureP2PRunning()).Times(0);
   attempter_.UpdateEngineStarted();
@@ -952,7 +932,7 @@
 
 TEST_F(UpdateAttempterTest, P2PNotStartedAtStartupWhenEnabledButNotSharing) {
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetP2PEnabled(true);
   EXPECT_CALL(mock_p2p_manager, EnsureP2PRunning()).Times(0);
   attempter_.UpdateEngineStarted();
@@ -960,7 +940,7 @@
 
 TEST_F(UpdateAttempterTest, P2PStartedAtStartupWhenEnabledAndSharing) {
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetP2PEnabled(true);
   mock_p2p_manager.fake().SetCountSharedFilesResult(1);
   EXPECT_CALL(mock_p2p_manager, EnsureP2PRunning());
@@ -978,7 +958,7 @@
   // If P2P is not enabled, check that we do not attempt housekeeping
   // and do not convey that P2P is to be used.
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetP2PEnabled(false);
   EXPECT_CALL(mock_p2p_manager, PerformHousekeeping()).Times(0);
   attempter_.Update({});
@@ -998,7 +978,7 @@
   // If P2P is enabled, but starting it fails ensure we don't do
   // any housekeeping and do not convey that P2P should be used.
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetP2PEnabled(true);
   mock_p2p_manager.fake().SetEnsureP2PRunningResult(false);
   mock_p2p_manager.fake().SetPerformHousekeepingResult(false);
@@ -1021,7 +1001,7 @@
   // If P2P is enabled, starting it works but housekeeping fails, ensure
   // we do not convey P2P is to be used.
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   mock_p2p_manager.fake().SetP2PEnabled(true);
   mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
   mock_p2p_manager.fake().SetPerformHousekeepingResult(false);
@@ -1041,7 +1021,7 @@
 
 void UpdateAttempterTest::P2PEnabledStart() {
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   // If P2P is enabled and starting it works, check that we performed
   // housekeeping and that we convey P2P should be used.
   mock_p2p_manager.fake().SetP2PEnabled(true);
@@ -1063,7 +1043,7 @@
 
 void UpdateAttempterTest::P2PEnabledInteractiveStart() {
   MockP2PManager mock_p2p_manager;
-  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
+  FakeSystemState::Get()->set_p2p_manager(&mock_p2p_manager);
   // For an interactive check, if P2P is enabled and starting it
   // works, check that we performed housekeeping and that we convey
   // P2P should be used for sharing but NOT for downloading.
@@ -1092,7 +1072,7 @@
 
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
   EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
 
   EXPECT_CALL(*device_policy, GetScatterFactorInSeconds(_))
       .WillRepeatedly(
@@ -1119,18 +1099,16 @@
   // Tests that the scatter_factor_in_seconds value is properly fetched
   // from the device policy and is decremented if value > 0.
   int64_t initial_value = 5;
-  FakePrefs fake_prefs;
-  attempter_.prefs_ = &fake_prefs;
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
 
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
-
-  EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));
+  EXPECT_TRUE(fake_prefs->SetInt64(kPrefsUpdateCheckCount, initial_value));
 
   int64_t scatter_factor_in_seconds = 10;
 
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
   EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
 
   EXPECT_CALL(*device_policy, GetScatterFactorInSeconds(_))
       .WillRepeatedly(
@@ -1143,10 +1121,10 @@
   EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());
 
   // Make sure the file still exists.
-  EXPECT_TRUE(fake_prefs.Exists(kPrefsUpdateCheckCount));
+  EXPECT_TRUE(fake_prefs->Exists(kPrefsUpdateCheckCount));
 
   int64_t new_value;
-  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &new_value));
+  EXPECT_TRUE(fake_prefs->GetInt64(kPrefsUpdateCheckCount, &new_value));
   EXPECT_EQ(initial_value - 1, new_value);
 
   EXPECT_TRUE(
@@ -1154,10 +1132,10 @@
 
   // However, if the count is already 0, it's not decremented. Test that.
   initial_value = 0;
-  EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));
+  EXPECT_TRUE(fake_prefs->SetInt64(kPrefsUpdateCheckCount, initial_value));
   attempter_.Update({});
-  EXPECT_TRUE(fake_prefs.Exists(kPrefsUpdateCheckCount));
-  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &new_value));
+  EXPECT_TRUE(fake_prefs->Exists(kPrefsUpdateCheckCount));
+  EXPECT_TRUE(fake_prefs->GetInt64(kPrefsUpdateCheckCount, &new_value));
   EXPECT_EQ(initial_value, new_value);
 
   ScheduleQuitMainLoop();
@@ -1176,15 +1154,12 @@
   // Tests that no scattering logic is enabled if the update check
   // is manually done (as opposed to a scheduled update check)
   int64_t initial_value = 8;
-  FakePrefs fake_prefs;
-  attempter_.prefs_ = &fake_prefs;
-
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
-  fake_system_state_.set_prefs(&fake_prefs);
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
 
   EXPECT_TRUE(
-      fake_prefs.SetInt64(kPrefsWallClockScatteringWaitPeriod, initial_value));
-  EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));
+      fake_prefs->SetInt64(kPrefsWallClockScatteringWaitPeriod, initial_value));
+  EXPECT_TRUE(fake_prefs->SetInt64(kPrefsUpdateCheckCount, initial_value));
 
   // make sure scatter_factor is non-zero as scattering is disabled
   // otherwise.
@@ -1192,7 +1167,7 @@
 
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
   EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
 
   EXPECT_CALL(*device_policy, GetScatterFactorInSeconds(_))
       .WillRepeatedly(
@@ -1209,29 +1184,25 @@
   // checks and all artifacts are removed.
   EXPECT_FALSE(
       attempter_.omaha_request_params_->wall_clock_based_wait_enabled());
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsWallClockScatteringWaitPeriod));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsWallClockScatteringWaitPeriod));
   EXPECT_EQ(0, attempter_.omaha_request_params_->waiting_period().InSeconds());
   EXPECT_FALSE(
       attempter_.omaha_request_params_->update_check_count_wait_enabled());
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsUpdateCheckCount));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsUpdateCheckCount));
 
   ScheduleQuitMainLoop();
 }
 
-void UpdateAttempterTest::SetUpStagingTest(const StagingSchedule& schedule,
-                                           FakePrefs* prefs) {
-  attempter_.prefs_ = prefs;
-  fake_system_state_.set_prefs(prefs);
-
+void UpdateAttempterTest::SetUpStagingTest(const StagingSchedule& schedule) {
   int64_t initial_value = 8;
   EXPECT_TRUE(
-      prefs->SetInt64(kPrefsWallClockScatteringWaitPeriod, initial_value));
-  EXPECT_TRUE(prefs->SetInt64(kPrefsUpdateCheckCount, initial_value));
+      prefs_->SetInt64(kPrefsWallClockScatteringWaitPeriod, initial_value));
+  EXPECT_TRUE(prefs_->SetInt64(kPrefsUpdateCheckCount, initial_value));
   attempter_.scatter_factor_ = TimeDelta::FromSeconds(20);
 
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
   EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
   EXPECT_CALL(*device_policy, GetDeviceUpdateStagingSchedule(_))
       .WillRepeatedly(DoAll(SetArgPointee<0>(schedule), Return(true)));
 
@@ -1250,17 +1221,17 @@
 
 void UpdateAttempterTest::StagingSetsPrefsAndTurnsOffScatteringStart() {
   // Tests that staging sets its prefs properly and turns off scattering.
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
-  FakePrefs fake_prefs;
-  SetUpStagingTest(kValidStagingSchedule, &fake_prefs);
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
+  SetUpStagingTest(kValidStagingSchedule);
 
   attempter_.Update({});
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
   // Check that prefs have the correct values.
   int64_t update_count;
-  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &update_count));
+  EXPECT_TRUE(fake_prefs->GetInt64(kPrefsUpdateCheckCount, &update_count));
   int64_t waiting_time_days;
-  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsWallClockStagingWaitPeriod,
-                                  &waiting_time_days));
+  EXPECT_TRUE(fake_prefs->GetInt64(kPrefsWallClockStagingWaitPeriod,
+                                   &waiting_time_days));
   EXPECT_GT(waiting_time_days, 0);
   // Update count should have been decremented.
   EXPECT_EQ(7, update_count);
@@ -1276,16 +1247,16 @@
   EXPECT_EQ(kValidStagingSchedule, attempter_.staging_schedule_);
   // Check that scattering is turned off
   EXPECT_EQ(0, attempter_.scatter_factor_.InSeconds());
-  EXPECT_FALSE(fake_prefs.Exists(kPrefsWallClockScatteringWaitPeriod));
+  EXPECT_FALSE(fake_prefs->Exists(kPrefsWallClockScatteringWaitPeriod));
 
   ScheduleQuitMainLoop();
 }
 
 void UpdateAttempterTest::CheckStagingOff() {
   // Check that all prefs were removed.
-  EXPECT_FALSE(attempter_.prefs_->Exists(kPrefsUpdateCheckCount));
-  EXPECT_FALSE(attempter_.prefs_->Exists(kPrefsWallClockScatteringWaitPeriod));
-  EXPECT_FALSE(attempter_.prefs_->Exists(kPrefsWallClockStagingWaitPeriod));
+  EXPECT_FALSE(prefs_->Exists(kPrefsUpdateCheckCount));
+  EXPECT_FALSE(prefs_->Exists(kPrefsWallClockScatteringWaitPeriod));
+  EXPECT_FALSE(prefs_->Exists(kPrefsWallClockStagingWaitPeriod));
   // Check that the Omaha parameters have the correct value.
   EXPECT_EQ(0, attempter_.omaha_request_params_->waiting_period().InDays());
   EXPECT_EQ(attempter_.omaha_request_params_->waiting_period(),
@@ -1307,9 +1278,8 @@
 
 void UpdateAttempterTest::StagingOffIfInteractiveStart() {
   // Tests that staging is turned off when an interactive update is requested.
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
-  FakePrefs fake_prefs;
-  SetUpStagingTest(kValidStagingSchedule, &fake_prefs);
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
+  SetUpStagingTest(kValidStagingSchedule);
 
   attempter_.Update({.interactive = true});
   CheckStagingOff();
@@ -1326,10 +1296,9 @@
 
 void UpdateAttempterTest::StagingOffIfOobeStart() {
   // Tests that staging is turned off if OOBE hasn't been completed.
-  fake_system_state_.fake_hardware()->SetIsOOBEEnabled(true);
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
-  FakePrefs fake_prefs;
-  SetUpStagingTest(kValidStagingSchedule, &fake_prefs);
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEEnabled(true);
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
+  SetUpStagingTest(kValidStagingSchedule);
 
   attempter_.Update({.interactive = true});
   CheckStagingOff();
@@ -1339,14 +1308,9 @@
 
 // Checks that we only report daily metrics at most every 24 hours.
 TEST_F(UpdateAttempterTest, ReportDailyMetrics) {
-  FakeClock fake_clock;
-  FakePrefs fake_prefs;
-
-  fake_system_state_.set_clock(&fake_clock);
-  fake_system_state_.set_prefs(&fake_prefs);
-
+  auto* fake_clock = FakeSystemState::Get()->fake_clock();
   Time epoch = Time::FromInternalValue(0);
-  fake_clock.SetWallclockTime(epoch);
+  fake_clock->SetWallclockTime(epoch);
 
   // If there is no kPrefsDailyMetricsLastReportedAt state variable,
   // we should report.
@@ -1355,32 +1319,32 @@
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
   // We should not report if only 10 hours has passed.
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(10));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(10));
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
   // We should not report if only 24 hours - 1 sec has passed.
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(24) -
-                              TimeDelta::FromSeconds(1));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(24) -
+                               TimeDelta::FromSeconds(1));
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
   // We should report if 24 hours has passed.
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(24));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(24));
   EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
 
   // But then we should not report again..
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
   // .. until another 24 hours has passed
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(47));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(47));
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(48));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(48));
   EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
   // .. and another 24 hours
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(71));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(71));
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(72));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(72));
   EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
@@ -1388,25 +1352,21 @@
   // negative, we report. This is in order to reset the timestamp and
   // avoid an edge condition whereby a distant point in the future is
   // in the state variable resulting in us never ever reporting again.
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(71));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(71));
   EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 
   // In this case we should not update until the clock reads 71 + 24 = 95.
   // Check that.
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(94));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(94));
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
-  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(95));
+  fake_clock->SetWallclockTime(epoch + TimeDelta::FromHours(95));
   EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
   EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
 }
 
 TEST_F(UpdateAttempterTest, BootTimeInUpdateMarkerFile) {
-  FakeClock fake_clock;
-  fake_clock.SetBootTime(Time::FromTimeT(42));
-  fake_system_state_.set_clock(&fake_clock);
-  FakePrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
+  FakeSystemState::Get()->fake_clock()->SetBootTime(Time::FromTimeT(42));
   attempter_.Init();
 
   Time boot_time;
@@ -1419,19 +1379,19 @@
 }
 
 TEST_F(UpdateAttempterTest, AnyUpdateSourceAllowedUnofficial) {
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(false);
   EXPECT_TRUE(attempter_.IsAnyUpdateSourceAllowed());
 }
 
 TEST_F(UpdateAttempterTest, AnyUpdateSourceAllowedOfficialDevmode) {
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
-  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(true);
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
+  FakeSystemState::Get()->fake_hardware()->SetAreDevFeaturesEnabled(true);
   EXPECT_TRUE(attempter_.IsAnyUpdateSourceAllowed());
 }
 
 TEST_F(UpdateAttempterTest, AnyUpdateSourceDisallowedOfficialNormal) {
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
-  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(false);
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
+  FakeSystemState::Get()->fake_hardware()->SetAreDevFeaturesEnabled(false);
   EXPECT_FALSE(attempter_.IsAnyUpdateSourceAllowed());
 }
 
@@ -1623,8 +1583,8 @@
 }
 
 TEST_F(UpdateAttempterTest, CheckForInstallTest) {
-  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
-  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(false);
+  FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(true);
+  FakeSystemState::Get()->fake_hardware()->SetAreDevFeaturesEnabled(false);
   attempter_.CheckForInstall({}, "autest");
   EXPECT_EQ(constants::kOmahaDefaultAUTestURL, attempter_.forced_omaha_url());
 
@@ -1662,19 +1622,21 @@
   UpdateCheckParams params;
   attempter_.CalculateUpdateParams({.target_version_prefix = "1234"});
   EXPECT_EQ("1234",
-            fake_system_state_.request_params()->target_version_prefix());
+            FakeSystemState::Get()->request_params()->target_version_prefix());
 
   attempter_.CalculateUpdateParams({});
-  EXPECT_TRUE(
-      fake_system_state_.request_params()->target_version_prefix().empty());
+  EXPECT_TRUE(FakeSystemState::Get()
+                  ->request_params()
+                  ->target_version_prefix()
+                  .empty());
 }
 
 TEST_F(UpdateAttempterTest, TargetChannelHintSetAndReset) {
   attempter_.CalculateUpdateParams({.lts_tag = "hint"});
-  EXPECT_EQ("hint", fake_system_state_.request_params()->lts_tag());
+  EXPECT_EQ("hint", FakeSystemState::Get()->request_params()->lts_tag());
 
   attempter_.CalculateUpdateParams({});
-  EXPECT_TRUE(fake_system_state_.request_params()->lts_tag().empty());
+  EXPECT_TRUE(FakeSystemState::Get()->request_params()->lts_tag().empty());
 }
 
 TEST_F(UpdateAttempterTest, RollbackAllowedSetAndReset) {
@@ -1683,44 +1645,47 @@
       .rollback_allowed = true,
       .rollback_allowed_milestones = 4,
   });
-  EXPECT_TRUE(fake_system_state_.request_params()->rollback_allowed());
-  EXPECT_EQ(4,
-            fake_system_state_.request_params()->rollback_allowed_milestones());
+  EXPECT_TRUE(FakeSystemState::Get()->request_params()->rollback_allowed());
+  EXPECT_EQ(
+      4,
+      FakeSystemState::Get()->request_params()->rollback_allowed_milestones());
 
   attempter_.CalculateUpdateParams({
       .target_version_prefix = "1234",
       .rollback_allowed_milestones = 4,
   });
-  EXPECT_FALSE(fake_system_state_.request_params()->rollback_allowed());
-  EXPECT_EQ(4,
-            fake_system_state_.request_params()->rollback_allowed_milestones());
+  EXPECT_FALSE(FakeSystemState::Get()->request_params()->rollback_allowed());
+  EXPECT_EQ(
+      4,
+      FakeSystemState::Get()->request_params()->rollback_allowed_milestones());
 }
 
 TEST_F(UpdateAttempterTest, ChannelDowngradeNoRollback) {
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
-  fake_system_state_.request_params()->set_root(tempdir.GetPath().value());
+  FakeSystemState::Get()->request_params()->set_root(tempdir.GetPath().value());
   attempter_.CalculateUpdateParams({
       .target_channel = "stable-channel",
   });
-  EXPECT_FALSE(fake_system_state_.request_params()->is_powerwash_allowed());
+  EXPECT_FALSE(
+      FakeSystemState::Get()->request_params()->is_powerwash_allowed());
 }
 
 TEST_F(UpdateAttempterTest, ChannelDowngradeRollback) {
   base::ScopedTempDir tempdir;
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
-  fake_system_state_.request_params()->set_root(tempdir.GetPath().value());
+  FakeSystemState::Get()->request_params()->set_root(tempdir.GetPath().value());
   attempter_.CalculateUpdateParams({
       .rollback_on_channel_downgrade = true,
       .target_channel = "stable-channel",
   });
-  EXPECT_TRUE(fake_system_state_.request_params()->is_powerwash_allowed());
+  EXPECT_TRUE(FakeSystemState::Get()->request_params()->is_powerwash_allowed());
 }
 
 TEST_F(UpdateAttempterTest, UpdateDeferredByPolicyTest) {
   // Construct an OmahaResponseHandlerAction that has processed an InstallPlan,
   // but the update is being deferred by the Policy.
-  OmahaResponseHandlerAction response_action(&fake_system_state_);
+  OmahaResponseHandlerAction response_action;
   response_action.install_plan_.version = "a.b.c.d";
   response_action.install_plan_.payloads.push_back(
       {.size = 1234ULL, .type = InstallPayloadType::kFull});
@@ -1781,14 +1746,14 @@
   UpdateCheckParams params = {.updates_enabled = true,
                               .rollback_allowed = false};
   attempter_.OnUpdateScheduled(EvalStatus::kSucceeded, params);
-  EXPECT_FALSE(fake_system_state_.request_params()->rollback_allowed());
+  EXPECT_FALSE(FakeSystemState::Get()->request_params()->rollback_allowed());
 }
 
 TEST_F(UpdateAttempterTest, RollbackAllowed) {
   UpdateCheckParams params = {.updates_enabled = true,
                               .rollback_allowed = true};
   attempter_.OnUpdateScheduled(EvalStatus::kSucceeded, params);
-  EXPECT_TRUE(fake_system_state_.request_params()->rollback_allowed());
+  EXPECT_TRUE(FakeSystemState::Get()->request_params()->rollback_allowed());
 }
 
 TEST_F(UpdateAttempterTest, InteractiveUpdateUsesPassedRestrictions) {
@@ -1815,7 +1780,8 @@
 void UpdateAttempterTest::ResetRollbackHappenedStart(bool is_consumer,
                                                      bool is_policy_loaded,
                                                      bool expected_reset) {
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(), GetRollbackHappened())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
+              GetRollbackHappened())
       .WillRepeatedly(Return(true));
   auto mock_policy_provider =
       std::make_unique<NiceMock<policy::MockPolicyProvider>>();
@@ -1826,7 +1792,7 @@
   const policy::MockDevicePolicy device_policy;
   EXPECT_CALL(*mock_policy_provider, GetDevicePolicy())
       .WillRepeatedly(ReturnRef(device_policy));
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
               SetRollbackHappened(false))
       .Times(expected_reset ? 1 : 0);
   attempter_.policy_provider_ = std::move(mock_policy_provider);
@@ -1868,7 +1834,7 @@
   attempter_.install_plan_.reset(new InstallPlan);
   attempter_.install_plan_->is_rollback = true;
 
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
               SetRollbackHappened(true))
       .Times(1);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -1878,7 +1844,7 @@
   attempter_.install_plan_.reset(new InstallPlan);
   attempter_.install_plan_->is_rollback = false;
 
-  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
               SetRollbackHappened(true))
       .Times(0);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -1889,7 +1855,7 @@
   attempter_.install_plan_->is_rollback = true;
   attempter_.install_plan_->version = kRollbackVersion;
 
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseRollbackMetrics(true, kRollbackVersion))
       .Times(1);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -1900,7 +1866,7 @@
   attempter_.install_plan_->is_rollback = false;
   attempter_.install_plan_->version = kRollbackVersion;
 
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseRollbackMetrics(_, _))
       .Times(0);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -1911,7 +1877,7 @@
   attempter_.install_plan_->is_rollback = true;
   attempter_.install_plan_->version = kRollbackVersion;
 
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseRollbackMetrics(false, kRollbackVersion))
       .Times(1);
   MockAction action;
@@ -1924,7 +1890,7 @@
   attempter_.install_plan_->is_rollback = false;
   attempter_.install_plan_->version = kRollbackVersion;
 
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseRollbackMetrics(_, _))
       .Times(0);
   MockAction action;
@@ -1933,7 +1899,7 @@
 }
 
 TEST_F(UpdateAttempterTest, TimeToUpdateAppliedMetricFailure) {
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseUpdateSeenToDownloadDays(_, _))
       .Times(0);
   attempter_.ProcessingDone(nullptr, ErrorCode::kOmahaUpdateDeferredPerPolicy);
@@ -1941,12 +1907,12 @@
 
 TEST_F(UpdateAttempterTest, TimeToUpdateAppliedOnNonEnterprise) {
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
   // Make device policy return that this is not enterprise enrolled
   EXPECT_CALL(*device_policy, IsEnterpriseEnrolled()).WillOnce(Return(false));
 
   // Ensure that the metric is not recorded.
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseUpdateSeenToDownloadDays(_, _))
       .Times(0);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -1956,27 +1922,22 @@
        TimeToUpdateAppliedWithTimeRestrictionMetricSuccess) {
   constexpr int kDaysToUpdate = 15;
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
   // Make device policy return that this is enterprise enrolled
   EXPECT_CALL(*device_policy, IsEnterpriseEnrolled()).WillOnce(Return(true));
   // Pretend that there's a time restriction policy in place
   EXPECT_CALL(*device_policy, GetDisallowedTimeIntervals(_))
       .WillOnce(Return(true));
 
-  FakePrefs fake_prefs;
   Time update_first_seen_at = Time::Now();
-  fake_prefs.SetInt64(kPrefsUpdateFirstSeenAt,
-                      update_first_seen_at.ToInternalValue());
+  FakeSystemState::Get()->fake_prefs()->SetInt64(
+      kPrefsUpdateFirstSeenAt, update_first_seen_at.ToInternalValue());
 
-  FakeClock fake_clock;
   Time update_finished_at =
       update_first_seen_at + TimeDelta::FromDays(kDaysToUpdate);
-  fake_clock.SetWallclockTime(update_finished_at);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(update_finished_at);
 
-  fake_system_state_.set_clock(&fake_clock);
-  fake_system_state_.set_prefs(&fake_prefs);
-
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseUpdateSeenToDownloadDays(true, kDaysToUpdate))
       .Times(1);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -1986,27 +1947,22 @@
        TimeToUpdateAppliedWithoutTimeRestrictionMetricSuccess) {
   constexpr int kDaysToUpdate = 15;
   auto device_policy = std::make_unique<policy::MockDevicePolicy>();
-  fake_system_state_.set_device_policy(device_policy.get());
+  FakeSystemState::Get()->set_device_policy(device_policy.get());
   // Make device policy return that this is enterprise enrolled
   EXPECT_CALL(*device_policy, IsEnterpriseEnrolled()).WillOnce(Return(true));
   // Pretend that there's no time restriction policy in place
   EXPECT_CALL(*device_policy, GetDisallowedTimeIntervals(_))
       .WillOnce(Return(false));
 
-  FakePrefs fake_prefs;
   Time update_first_seen_at = Time::Now();
-  fake_prefs.SetInt64(kPrefsUpdateFirstSeenAt,
-                      update_first_seen_at.ToInternalValue());
+  FakeSystemState::Get()->fake_prefs()->SetInt64(
+      kPrefsUpdateFirstSeenAt, update_first_seen_at.ToInternalValue());
 
-  FakeClock fake_clock;
   Time update_finished_at =
       update_first_seen_at + TimeDelta::FromDays(kDaysToUpdate);
-  fake_clock.SetWallclockTime(update_finished_at);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(update_finished_at);
 
-  fake_system_state_.set_clock(&fake_clock);
-  fake_system_state_.set_prefs(&fake_prefs);
-
-  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_metrics_reporter(),
               ReportEnterpriseUpdateSeenToDownloadDays(false, kDaysToUpdate))
       .Times(1);
   attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
@@ -2155,43 +2111,14 @@
   TestProcessingDone();
 }
 
-void UpdateAttempterTest::UpdateToQuickFixBuildStart(bool set_token) {
-  // Tests that checks if |device_quick_fix_build_token| arrives when
-  // policy is set and the device is enterprise enrolled based on |set_token|.
-  string token = set_token ? "some_token" : "";
-  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
-  fake_system_state_.set_device_policy(device_policy.get());
-  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
+TEST_F(UpdateAttempterTest, QuickFixTokenWhenDeviceIsEnterpriseEnrolled) {
+  attempter_.CalculateUpdateParams({.quick_fix_build_token = "token"});
+  EXPECT_EQ("token",
+            FakeSystemState::Get()->request_params()->autoupdate_token());
 
-  if (set_token)
-    EXPECT_CALL(*device_policy, GetDeviceQuickFixBuildToken(_))
-        .WillOnce(DoAll(SetArgPointee<0>(token), Return(true)));
-  else
-    EXPECT_CALL(*device_policy, GetDeviceQuickFixBuildToken(_))
-        .WillOnce(Return(false));
-  attempter_.policy_provider_.reset(
-      new policy::PolicyProvider(std::move(device_policy)));
-  attempter_.Update({});
-
-  EXPECT_EQ(token, attempter_.omaha_request_params_->autoupdate_token());
-  ScheduleQuitMainLoop();
-}
-
-TEST_F(UpdateAttempterTest,
-       QuickFixTokenWhenDeviceIsEnterpriseEnrolledAndPolicyIsSet) {
-  loop_.PostTask(FROM_HERE,
-                 base::Bind(&UpdateAttempterTest::UpdateToQuickFixBuildStart,
-                            base::Unretained(this),
-                            /*set_token=*/true));
-  loop_.Run();
-}
-
-TEST_F(UpdateAttempterTest, EmptyQuickFixToken) {
-  loop_.PostTask(FROM_HERE,
-                 base::Bind(&UpdateAttempterTest::UpdateToQuickFixBuildStart,
-                            base::Unretained(this),
-                            /*set_token=*/false));
-  loop_.Run();
+  attempter_.CalculateUpdateParams({});
+  EXPECT_TRUE(
+      FakeSystemState::Get()->request_params()->autoupdate_token().empty());
 }
 
 TEST_F(UpdateAttempterTest, ScheduleUpdateSpamHandlerTest) {
@@ -2329,11 +2256,7 @@
 
 TEST_F(UpdateAttempterTest, FutureEolTest) {
   EolDate eol_date = std::numeric_limits<int64_t>::max();
-  EXPECT_CALL(*prefs_, Exists(kPrefsOmahaEolDate)).WillOnce(Return(true));
-  EXPECT_CALL(*prefs_, GetString(kPrefsOmahaEolDate, _))
-      .WillOnce(
-          DoAll(SetArgPointee<1>(EolDateToString(eol_date)), Return(true)));
-
+  EXPECT_TRUE(prefs_->SetString(kPrefsOmahaEolDate, EolDateToString(eol_date)));
   UpdateEngineStatus status;
   attempter_.GetStatus(&status);
   EXPECT_EQ(eol_date, status.eol_date);
@@ -2341,29 +2264,13 @@
 
 TEST_F(UpdateAttempterTest, PastEolTest) {
   EolDate eol_date = 1;
-  EXPECT_CALL(*prefs_, Exists(kPrefsOmahaEolDate)).WillOnce(Return(true));
-  EXPECT_CALL(*prefs_, GetString(kPrefsOmahaEolDate, _))
-      .WillOnce(
-          DoAll(SetArgPointee<1>(EolDateToString(eol_date)), Return(true)));
-
+  EXPECT_TRUE(prefs_->SetString(kPrefsOmahaEolDate, EolDateToString(eol_date)));
   UpdateEngineStatus status;
   attempter_.GetStatus(&status);
   EXPECT_EQ(eol_date, status.eol_date);
 }
 
-TEST_F(UpdateAttempterTest, FailedEolTest) {
-  EXPECT_CALL(*prefs_, Exists(kPrefsOmahaEolDate)).WillOnce(Return(true));
-  EXPECT_CALL(*prefs_, GetString(kPrefsOmahaEolDate, _))
-      .WillOnce(Return(false));
-
-  UpdateEngineStatus status;
-  attempter_.GetStatus(&status);
-  EXPECT_EQ(kEolDateInvalid, status.eol_date);
-}
-
 TEST_F(UpdateAttempterTest, MissingEolTest) {
-  EXPECT_CALL(*prefs_, Exists(kPrefsOmahaEolDate)).WillOnce(Return(false));
-
   UpdateEngineStatus status;
   attempter_.GetStatus(&status);
   EXPECT_EQ(kEolDateInvalid, status.eol_date);
@@ -2371,13 +2278,11 @@
 
 TEST_F(UpdateAttempterTest, CalculateDlcParamsInstallTest) {
   string dlc_id = "dlc0";
-  FakePrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
   attempter_.is_install_ = true;
   attempter_.dlc_ids_ = {dlc_id};
   attempter_.CalculateDlcParams();
 
-  OmahaRequestParams* params = fake_system_state_.request_params();
+  OmahaRequestParams* params = FakeSystemState::Get()->request_params();
   EXPECT_EQ(1, params->dlc_apps_params().count(params->GetDlcAppId(dlc_id)));
   OmahaRequestParams::AppParams dlc_app_params =
       params->dlc_apps_params().at(params->GetDlcAppId(dlc_id));
@@ -2387,16 +2292,14 @@
   // the values sent by Omaha.
   auto last_active_key = PrefsInterface::CreateSubKey(
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastActive});
-  EXPECT_FALSE(fake_system_state_.prefs()->Exists(last_active_key));
+  EXPECT_FALSE(FakeSystemState::Get()->prefs()->Exists(last_active_key));
   auto last_rollcall_key = PrefsInterface::CreateSubKey(
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastRollcall});
-  EXPECT_FALSE(fake_system_state_.prefs()->Exists(last_rollcall_key));
+  EXPECT_FALSE(FakeSystemState::Get()->prefs()->Exists(last_rollcall_key));
 }
 
 TEST_F(UpdateAttempterTest, CalculateDlcParamsNoPrefFilesTest) {
   string dlc_id = "dlc0";
-  FakePrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
   EXPECT_CALL(mock_dlcservice_, GetDlcsToUpdate(_))
       .WillOnce(
           DoAll(SetArgPointee<0>(std::vector<string>({dlc_id})), Return(true)));
@@ -2404,7 +2307,7 @@
   attempter_.is_install_ = false;
   attempter_.CalculateDlcParams();
 
-  OmahaRequestParams* params = fake_system_state_.request_params();
+  OmahaRequestParams* params = FakeSystemState::Get()->request_params();
   EXPECT_EQ(1, params->dlc_apps_params().count(params->GetDlcAppId(dlc_id)));
   OmahaRequestParams::AppParams dlc_app_params =
       params->dlc_apps_params().at(params->GetDlcAppId(dlc_id));
@@ -2419,7 +2322,7 @@
 TEST_F(UpdateAttempterTest, CalculateDlcParamsNonParseableValuesTest) {
   string dlc_id = "dlc0";
   MemoryPrefs prefs;
-  fake_system_state_.set_prefs(&prefs);
+  FakeSystemState::Get()->set_prefs(&prefs);
   EXPECT_CALL(mock_dlcservice_, GetDlcsToUpdate(_))
       .WillOnce(
           DoAll(SetArgPointee<0>(std::vector<string>({dlc_id})), Return(true)));
@@ -2431,13 +2334,13 @@
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastActive});
   auto last_rollcall_key = PrefsInterface::CreateSubKey(
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastRollcall});
-  fake_system_state_.prefs()->SetString(active_key, "z2yz");
-  fake_system_state_.prefs()->SetString(last_active_key, "z2yz");
-  fake_system_state_.prefs()->SetString(last_rollcall_key, "z2yz");
+  FakeSystemState::Get()->prefs()->SetString(active_key, "z2yz");
+  FakeSystemState::Get()->prefs()->SetString(last_active_key, "z2yz");
+  FakeSystemState::Get()->prefs()->SetString(last_rollcall_key, "z2yz");
   attempter_.is_install_ = false;
   attempter_.CalculateDlcParams();
 
-  OmahaRequestParams* params = fake_system_state_.request_params();
+  OmahaRequestParams* params = FakeSystemState::Get()->request_params();
   EXPECT_EQ(1, params->dlc_apps_params().count(params->GetDlcAppId(dlc_id)));
   OmahaRequestParams::AppParams dlc_app_params =
       params->dlc_apps_params().at(params->GetDlcAppId(dlc_id));
@@ -2451,8 +2354,6 @@
 
 TEST_F(UpdateAttempterTest, CalculateDlcParamsValidValuesTest) {
   string dlc_id = "dlc0";
-  MemoryPrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
   EXPECT_CALL(mock_dlcservice_, GetDlcsToUpdate(_))
       .WillOnce(
           DoAll(SetArgPointee<0>(std::vector<string>({dlc_id})), Return(true)));
@@ -2465,13 +2366,13 @@
   auto last_rollcall_key = PrefsInterface::CreateSubKey(
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastRollcall});
 
-  fake_system_state_.prefs()->SetInt64(active_key, 1);
-  fake_system_state_.prefs()->SetInt64(last_active_key, 78);
-  fake_system_state_.prefs()->SetInt64(last_rollcall_key, 99);
+  FakeSystemState::Get()->prefs()->SetInt64(active_key, 1);
+  FakeSystemState::Get()->prefs()->SetInt64(last_active_key, 78);
+  FakeSystemState::Get()->prefs()->SetInt64(last_rollcall_key, 99);
   attempter_.is_install_ = false;
   attempter_.CalculateDlcParams();
 
-  OmahaRequestParams* params = fake_system_state_.request_params();
+  OmahaRequestParams* params = FakeSystemState::Get()->request_params();
   EXPECT_EQ(1, params->dlc_apps_params().count(params->GetDlcAppId(dlc_id)));
   OmahaRequestParams::AppParams dlc_app_params =
       params->dlc_apps_params().at(params->GetDlcAppId(dlc_id));
@@ -2485,62 +2386,56 @@
 
 TEST_F(UpdateAttempterTest, CalculateDlcParamsRemoveStaleMetadata) {
   string dlc_id = "dlc0";
-  FakePrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
   auto active_key =
       PrefsInterface::CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
   auto last_active_key = PrefsInterface::CreateSubKey(
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastActive});
   auto last_rollcall_key = PrefsInterface::CreateSubKey(
       {kDlcPrefsSubDir, dlc_id, kPrefsPingLastRollcall});
-  fake_system_state_.prefs()->SetInt64(active_key, kPingInactiveValue);
-  fake_system_state_.prefs()->SetInt64(last_active_key, 0);
-  fake_system_state_.prefs()->SetInt64(last_rollcall_key, 0);
-  EXPECT_TRUE(fake_system_state_.prefs()->Exists(active_key));
-  EXPECT_TRUE(fake_system_state_.prefs()->Exists(last_active_key));
-  EXPECT_TRUE(fake_system_state_.prefs()->Exists(last_rollcall_key));
+  FakeSystemState::Get()->prefs()->SetInt64(active_key, kPingInactiveValue);
+  FakeSystemState::Get()->prefs()->SetInt64(last_active_key, 0);
+  FakeSystemState::Get()->prefs()->SetInt64(last_rollcall_key, 0);
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->Exists(active_key));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->Exists(last_active_key));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->Exists(last_rollcall_key));
 
   attempter_.dlc_ids_ = {dlc_id};
   attempter_.is_install_ = true;
   attempter_.CalculateDlcParams();
 
-  EXPECT_FALSE(fake_system_state_.prefs()->Exists(last_active_key));
-  EXPECT_FALSE(fake_system_state_.prefs()->Exists(last_rollcall_key));
+  EXPECT_FALSE(FakeSystemState::Get()->prefs()->Exists(last_active_key));
+  EXPECT_FALSE(FakeSystemState::Get()->prefs()->Exists(last_rollcall_key));
   // Active key is set on install.
-  EXPECT_TRUE(fake_system_state_.prefs()->Exists(active_key));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->Exists(active_key));
   int64_t temp_int;
-  EXPECT_TRUE(fake_system_state_.prefs()->GetInt64(active_key, &temp_int));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->GetInt64(active_key, &temp_int));
   EXPECT_EQ(temp_int, kPingActiveValue);
 }
 
 TEST_F(UpdateAttempterTest, SetDlcActiveValue) {
   string dlc_id = "dlc0";
-  FakePrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
   attempter_.SetDlcActiveValue(true, dlc_id);
   int64_t temp_int;
   auto active_key =
       PrefsInterface::CreateSubKey({kDlcPrefsSubDir, dlc_id, kPrefsPingActive});
-  EXPECT_TRUE(fake_system_state_.prefs()->Exists(active_key));
-  EXPECT_TRUE(fake_system_state_.prefs()->GetInt64(active_key, &temp_int));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->Exists(active_key));
+  EXPECT_TRUE(FakeSystemState::Get()->prefs()->GetInt64(active_key, &temp_int));
   EXPECT_EQ(temp_int, kPingActiveValue);
 }
 
 TEST_F(UpdateAttempterTest, SetDlcInactive) {
   string dlc_id = "dlc0";
-  MemoryPrefs fake_prefs;
-  fake_system_state_.set_prefs(&fake_prefs);
   auto sub_keys = {
       kPrefsPingActive, kPrefsPingLastActive, kPrefsPingLastRollcall};
   for (auto& sub_key : sub_keys) {
     auto key = PrefsInterface::CreateSubKey({kDlcPrefsSubDir, dlc_id, sub_key});
-    fake_system_state_.prefs()->SetInt64(key, 1);
-    EXPECT_TRUE(fake_system_state_.prefs()->Exists(key));
+    FakeSystemState::Get()->prefs()->SetInt64(key, 1);
+    EXPECT_TRUE(FakeSystemState::Get()->prefs()->Exists(key));
   }
   attempter_.SetDlcActiveValue(false, dlc_id);
   for (auto& sub_key : sub_keys) {
     auto key = PrefsInterface::CreateSubKey({kDlcPrefsSubDir, dlc_id, sub_key});
-    EXPECT_FALSE(fake_system_state_.prefs()->Exists(key));
+    EXPECT_FALSE(FakeSystemState::Get()->prefs()->Exists(key));
   }
 }
 
@@ -2553,4 +2448,34 @@
   EXPECT_THAT(attempter_.GetSuccessfulDlcIds(), ElementsAre(dlc_2));
 }
 
+TEST_F(UpdateAttempterTest, MoveToPrefs) {
+  string key1 = kPrefsLastActivePingDay;
+  string key2 = kPrefsPingLastRollcall;
+
+  FakePrefs fake_prefs;
+  EXPECT_TRUE(fake_prefs.SetString(key2, "current-rollcall"));
+  FakeSystemState::Get()->set_prefs(&fake_prefs);
+
+  FakePrefs powerwash_safe_prefs;
+  EXPECT_TRUE(powerwash_safe_prefs.SetString(key1, "powerwash-last-active"));
+  EXPECT_TRUE(powerwash_safe_prefs.SetString(key2, "powerwash-last-rollcall"));
+  FakeSystemState::Get()->set_powerwash_safe_prefs(&powerwash_safe_prefs);
+
+  attempter_.Init();
+  attempter_.MoveToPrefs({key1, key2});
+
+  string pref_value_1;
+  fake_prefs.GetString(key1, &pref_value_1);
+  EXPECT_EQ(pref_value_1, "powerwash-last-active");
+  // Do not overwrite if value already exists.
+  string pref_value_2;
+  fake_prefs.GetString(key2, &pref_value_2);
+  EXPECT_EQ(pref_value_2, "current-rollcall");
+
+  // Make sure keys are deleted from powerwash safe prefs regardless of whether
+  // they are written to prefs.
+  EXPECT_FALSE(FakeSystemState::Get()->powerwash_safe_prefs()->Exists(key1));
+  EXPECT_FALSE(FakeSystemState::Get()->powerwash_safe_prefs()->Exists(key2));
+}
+
 }  // namespace chromeos_update_engine
diff --git a/download_action.cc b/download_action.cc
index 10dffd2..fa29139 100644
--- a/download_action.cc
+++ b/download_action.cc
@@ -29,6 +29,7 @@
 #include "update_engine/common/boot_control_interface.h"
 #include "update_engine/common/error_code_utils.h"
 #include "update_engine/common/multi_range_http_fetcher.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/omaha_request_params.h"
 #include "update_engine/cros/p2p_manager.h"
@@ -42,13 +43,11 @@
 DownloadAction::DownloadAction(PrefsInterface* prefs,
                                BootControlInterface* boot_control,
                                HardwareInterface* hardware,
-                               SystemState* system_state,
                                HttpFetcher* http_fetcher,
                                bool interactive)
     : prefs_(prefs),
       boot_control_(boot_control),
       hardware_(hardware),
-      system_state_(system_state),
       http_fetcher_(new MultiRangeHttpFetcher(http_fetcher)),
       interactive_(interactive),
       writer_(nullptr),
@@ -68,7 +67,8 @@
   }
 
   if (delete_p2p_file) {
-    FilePath path = system_state_->p2p_manager()->FileGetPath(p2p_file_id_);
+    FilePath path =
+        SystemState::Get()->p2p_manager()->FileGetPath(p2p_file_id_);
     if (unlink(path.value().c_str()) != 0) {
       PLOG(ERROR) << "Error deleting p2p file " << path.value();
     } else {
@@ -81,7 +81,7 @@
 }
 
 bool DownloadAction::SetupP2PSharingFd() {
-  P2PManager* p2p_manager = system_state_->p2p_manager();
+  P2PManager* p2p_manager = SystemState::Get()->p2p_manager();
 
   if (!p2p_manager->FileShare(p2p_file_id_, payload_->size)) {
     LOG(ERROR) << "Unable to share file via p2p";
@@ -295,8 +295,10 @@
     }
   }
 
-  if (system_state_ != nullptr) {
-    const PayloadStateInterface* payload_state = system_state_->payload_state();
+#ifndef __ANDROID__
+  if (SystemState::Get() != nullptr) {
+    const PayloadStateInterface* payload_state =
+        SystemState::Get()->payload_state();
     string file_id = utils::CalculateP2PFileId(payload_->hash, payload_->size);
     if (payload_state->GetUsingP2PForSharing()) {
       // If we're sharing the update, store the file_id to convey
@@ -309,7 +311,7 @@
       // hash. If this is the case, we NEED to clean it up otherwise
       // we're essentially timing out other peers downloading from us
       // (since we're never going to complete the file).
-      FilePath path = system_state_->p2p_manager()->FileGetPath(file_id);
+      FilePath path = SystemState::Get()->p2p_manager()->FileGetPath(file_id);
       if (!path.empty()) {
         if (unlink(path.value().c_str()) != 0) {
           PLOG(ERROR) << "Error deleting p2p file " << path.value();
@@ -331,6 +333,7 @@
       http_fetcher_->set_connect_timeout(kDownloadP2PConnectTimeoutSeconds);
     }
   }
+#endif
 
   http_fetcher_->BeginTransfer(install_plan_.download_url);
 }
@@ -391,10 +394,10 @@
 
   // Call p2p_manager_->FileMakeVisible() when we've successfully
   // verified the manifest!
-  if (!p2p_visible_ && system_state_ && delta_performer_.get() &&
+  if (!p2p_visible_ && SystemState::Get() && delta_performer_.get() &&
       delta_performer_->IsManifestValid()) {
     LOG(INFO) << "Manifest has been validated. Making p2p file visible.";
-    system_state_->p2p_manager()->FileMakeVisible(p2p_file_id_);
+    SystemState::Get()->p2p_manager()->FileMakeVisible(p2p_file_id_);
     p2p_visible_ = true;
   }
   return true;
@@ -416,7 +419,7 @@
       code = delta_performer_->VerifyPayload(payload_->hash, payload_->size);
     if (code == ErrorCode::kSuccess) {
       if (payload_ < &install_plan_.payloads.back() &&
-          system_state_->payload_state()->NextPayload()) {
+          SystemState::Get()->payload_state()->NextPayload()) {
         LOG(INFO) << "Incrementing to next payload";
         // No need to reset if this payload was already applied.
         if (delta_performer_ && !payload_->already_applied)
@@ -425,7 +428,7 @@
         bytes_received_previous_payloads_ += payload_->size;
         payload_++;
         install_plan_.download_url =
-            system_state_->payload_state()->GetCurrentUrl();
+            SystemState::Get()->payload_state()->GetCurrentUrl();
         StartDownloading();
         return;
       }
diff --git a/download_action_android_unittest.cc b/download_action_android_unittest.cc
index f222977..7db1c60 100644
--- a/download_action_android_unittest.cc
+++ b/download_action_android_unittest.cc
@@ -77,7 +77,6 @@
       std::make_unique<DownloadAction>(&prefs,
                                        &boot_control,
                                        nullptr,
-                                       nullptr,
                                        http_fetcher,
                                        false /* interactive */);
   download_action->set_in_pipe(action_pipe);
diff --git a/download_action_unittest.cc b/download_action_unittest.cc
index 5264b0f..24b03cd 100644
--- a/download_action_unittest.cc
+++ b/download_action_unittest.cc
@@ -36,7 +36,6 @@
 #include "update_engine/common/hash_calculator.h"
 #include "update_engine/common/mock_download_action.h"
 #include "update_engine/common/mock_http_fetcher.h"
-#include "update_engine/common/mock_prefs.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/fake_p2p_manager_configuration.h"
@@ -57,7 +56,9 @@
 using testing::Return;
 using testing::SetArgPointee;
 
-class DownloadActionTest : public ::testing::Test {};
+class DownloadActionTest : public ::testing::Test {
+  void SetUp() { FakeSystemState::CreateInstance(); }
+};
 
 namespace {
 
@@ -128,9 +129,9 @@
 void TestWithData(const brillo::Blob& data,
                   int fail_write,
                   bool use_download_delegate) {
+  FakeSystemState::CreateInstance();
   brillo::FakeMessageLoop loop(nullptr);
   loop.SetAsCurrent();
-  FakeSystemState fake_system_state;
 
   ScopedTempFile output_temp_file;
   TestDirectFileWriter writer;
@@ -149,9 +150,9 @@
   install_plan.target_slot = 1;
   // We mark both slots as bootable. Only the target slot should be unbootable
   // after the download starts.
-  fake_system_state.fake_boot_control()->SetSlotBootable(
+  FakeSystemState::Get()->fake_boot_control()->SetSlotBootable(
       install_plan.source_slot, true);
-  fake_system_state.fake_boot_control()->SetSlotBootable(
+  FakeSystemState::Get()->fake_boot_control()->SetSlotBootable(
       install_plan.target_slot, true);
   auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
   feeder_action->set_obj(install_plan);
@@ -161,9 +162,8 @@
   // takes ownership of passed in HttpFetcher
   auto download_action =
       std::make_unique<DownloadAction>(&prefs,
-                                       fake_system_state.boot_control(),
-                                       fake_system_state.hardware(),
-                                       &fake_system_state,
+                                       FakeSystemState::Get()->boot_control(),
+                                       FakeSystemState::Get()->hardware(),
                                        http_fetcher,
                                        false /* interactive */);
   download_action->SetTestFileWriter(&writer);
@@ -194,9 +194,9 @@
   loop.Run();
   EXPECT_FALSE(loop.PendingTasks());
 
-  EXPECT_TRUE(fake_system_state.fake_boot_control()->IsSlotBootable(
+  EXPECT_TRUE(FakeSystemState::Get()->fake_boot_control()->IsSlotBootable(
       install_plan.source_slot));
-  EXPECT_FALSE(fake_system_state.fake_boot_control()->IsSlotBootable(
+  EXPECT_FALSE(FakeSystemState::Get()->fake_boot_control()->IsSlotBootable(
       install_plan.target_slot));
 }
 }  // namespace
@@ -251,8 +251,7 @@
   payload_datas.emplace_back(2 * kMockHttpFetcherChunkSize);
   brillo::FakeMessageLoop loop(nullptr);
   loop.SetAsCurrent();
-  FakeSystemState fake_system_state;
-  EXPECT_CALL(*fake_system_state.mock_payload_state(), NextPayload())
+  EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(), NextPayload())
       .WillOnce(Return(true));
 
   MockFileWriter mock_file_writer;
@@ -277,9 +276,8 @@
   // takes ownership of passed in HttpFetcher
   auto download_action =
       std::make_unique<DownloadAction>(&prefs,
-                                       fake_system_state.boot_control(),
-                                       fake_system_state.hardware(),
-                                       &fake_system_state,
+                                       FakeSystemState::Get()->boot_control(),
+                                       FakeSystemState::Get()->hardware(),
                                        http_fetcher,
                                        false /* interactive */);
   download_action->SetTestFileWriter(&mock_file_writer);
@@ -346,6 +344,7 @@
 }
 
 void TestTerminateEarly(bool use_download_delegate) {
+  FakeSystemState::CreateInstance();
   brillo::FakeMessageLoop loop(nullptr);
   loop.SetAsCurrent();
 
@@ -362,13 +361,12 @@
     InstallPlan install_plan;
     install_plan.payloads.resize(1);
     feeder_action->set_obj(install_plan);
-    FakeSystemState fake_system_state_;
+
     MockPrefs prefs;
     auto download_action = std::make_unique<DownloadAction>(
         &prefs,
-        fake_system_state_.boot_control(),
-        fake_system_state_.hardware(),
-        &fake_system_state_,
+        FakeSystemState::Get()->boot_control(),
+        FakeSystemState::Get()->hardware(),
         new MockHttpFetcher(data.data(), data.size(), nullptr),
         false /* interactive */);
     download_action->SetTestFileWriter(&writer);
@@ -461,6 +459,7 @@
 }  // namespace
 
 TEST(DownloadActionTest, PassObjectOutTest) {
+  FakeSystemState::CreateInstance();
   brillo::FakeMessageLoop loop(nullptr);
   loop.SetAsCurrent();
 
@@ -475,12 +474,10 @@
   auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
   feeder_action->set_obj(install_plan);
   MockPrefs prefs;
-  FakeSystemState fake_system_state_;
   auto download_action =
       std::make_unique<DownloadAction>(&prefs,
-                                       fake_system_state_.boot_control(),
-                                       fake_system_state_.hardware(),
-                                       &fake_system_state_,
+                                       FakeSystemState::Get()->boot_control(),
+                                       FakeSystemState::Get()->hardware(),
                                        new MockHttpFetcher("x", 1, nullptr),
                                        false /* interactive */);
   download_action->SetTestFileWriter(&writer);
@@ -511,13 +508,15 @@
 // Test fixture for P2P tests.
 class P2PDownloadActionTest : public testing::Test {
  protected:
-  P2PDownloadActionTest()
-      : start_at_offset_(0), fake_um_(fake_system_state_.fake_clock()) {}
+  P2PDownloadActionTest() : start_at_offset_(0) {}
 
   ~P2PDownloadActionTest() override {}
 
   // Derived from testing::Test.
-  void SetUp() override { loop_.SetAsCurrent(); }
+  void SetUp() override {
+    loop_.SetAsCurrent();
+    FakeSystemState::CreateInstance();
+  }
 
   // Derived from testing::Test.
   void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); }
@@ -534,19 +533,18 @@
     // Setup p2p.
     FakeP2PManagerConfiguration* test_conf = new FakeP2PManagerConfiguration();
     p2p_manager_.reset(P2PManager::Construct(test_conf,
-                                             nullptr,
                                              &fake_um_,
                                              "cros_au",
                                              3,
                                              base::TimeDelta::FromDays(5)));
-    fake_system_state_.set_p2p_manager(p2p_manager_.get());
+    FakeSystemState::Get()->set_p2p_manager(p2p_manager_.get());
   }
 
   // To be called by tests to perform the download. The
   // |use_p2p_to_share| parameter is used to indicate whether the
   // payload should be shared via p2p.
   void StartDownload(bool use_p2p_to_share) {
-    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+    EXPECT_CALL(*FakeSystemState::Get()->mock_payload_state(),
                 GetUsingP2PForSharing())
         .WillRepeatedly(Return(use_p2p_to_share));
 
@@ -564,9 +562,8 @@
     // Note that DownloadAction takes ownership of the passed in HttpFetcher.
     auto download_action = std::make_unique<DownloadAction>(
         &prefs,
-        fake_system_state_.boot_control(),
-        fake_system_state_.hardware(),
-        &fake_system_state_,
+        FakeSystemState::Get()->boot_control(),
+        FakeSystemState::Get()->hardware(),
         new MockHttpFetcher(data_.c_str(), data_.length(), nullptr),
         false /* interactive */);
     auto http_fetcher = download_action->http_fetcher();
@@ -603,9 +600,6 @@
   // The ActionProcessor used for running the actions.
   ActionProcessor processor_;
 
-  // A fake system state.
-  FakeSystemState fake_system_state_;
-
   // The data being downloaded.
   string data_;
 
diff --git a/metrics_utils.h b/metrics_utils.h
index 5952ec3..3aac4e5 100644
--- a/metrics_utils.h
+++ b/metrics_utils.h
@@ -30,8 +30,6 @@
 
 namespace chromeos_update_engine {
 
-class SystemState;
-
 namespace metrics_utils {
 
 // Transforms a ErrorCode value into a metrics::DownloadErrorCode.
diff --git a/metrics_utils_unittest.cc b/metrics_utils_unittest.cc
index cedd269..93b48fb 100644
--- a/metrics_utils_unittest.cc
+++ b/metrics_utils_unittest.cc
@@ -18,9 +18,6 @@
 
 #include <gtest/gtest.h>
 
-#include "update_engine/common/fake_clock.h"
-#include "update_engine/common/fake_prefs.h"
-
 namespace chromeos_update_engine {
 namespace metrics_utils {
 
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index 374131e..e7ccff5 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -464,7 +464,11 @@
 
     EXPECT_TRUE(base::CopyFile(mnt_path.Append("regular-small"),
                                mnt_path.Append("regular-small2")));
+#if BASE_VER < 800000
     EXPECT_TRUE(base::DeleteFile(mnt_path.Append("regular-small"), false));
+#else
+    EXPECT_TRUE(base::DeleteFile(mnt_path.Append("regular-small")));
+#endif
     EXPECT_TRUE(base::Move(mnt_path.Append("regular-small2"),
                            mnt_path.Append("regular-small")));
     EXPECT_TRUE(
@@ -491,7 +495,11 @@
     EXPECT_TRUE(base::Move(mnt_path.Append("tmp"),
                            mnt_path.Append("link-hard-regular-16k")));
 
+#if BASE_VER < 800000
     EXPECT_TRUE(base::DeleteFile(mnt_path.Append("link-short_symlink"), false));
+#else
+    EXPECT_TRUE(base::DeleteFile(mnt_path.Append("link-short_symlink")));
+#endif
     EXPECT_TRUE(test_utils::WriteFileString(
         mnt_path.Append("link-short_symlink").value(), "foobar"));
 
diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc
index f4bbeb4..39827a4 100644
--- a/payload_consumer/install_plan.cc
+++ b/payload_consumer/install_plan.cc
@@ -16,6 +16,9 @@
 
 #include "update_engine/payload_consumer/install_plan.h"
 
+#include <algorithm>
+#include <utility>
+
 #include <base/format_macros.h>
 #include <base/logging.h>
 #include <base/strings/string_number_conversions.h>
@@ -26,14 +29,29 @@
 #include "update_engine/payload_consumer/payload_constants.h"
 
 using std::string;
+using std::vector;
 
 namespace chromeos_update_engine {
 
+namespace {
 string PayloadUrlsToString(
     const decltype(InstallPlan::Payload::payload_urls)& payload_urls) {
   return "(" + base::JoinString(payload_urls, ",") + ")";
 }
 
+string VectorToString(const vector<std::pair<string, string>>& input,
+                      const string& separator) {
+  vector<string> vec;
+  std::transform(input.begin(),
+                 input.end(),
+                 std::back_inserter(vec),
+                 [](const auto& pair) {
+                   return base::JoinString({pair.first, pair.second}, ": ");
+                 });
+  return base::JoinString(vec, separator);
+}
+}  // namespace
+
 string InstallPayloadTypeToString(InstallPayloadType type) {
   switch (type) {
     case InstallPayloadType::kUnknown:
@@ -58,30 +76,10 @@
 }
 
 void InstallPlan::Dump() const {
-  string partitions_str;
-  for (const auto& partition : partitions) {
-    partitions_str +=
-        base::StringPrintf(", part: %s (source_size: %" PRIu64
-                           ", target_size %" PRIu64 ", postinst:%s)",
-                           partition.name.c_str(),
-                           partition.source_size,
-                           partition.target_size,
-                           utils::ToString(partition.run_postinstall).c_str());
-  }
-  string payloads_str;
-  for (const auto& payload : payloads) {
-    payloads_str += base::StringPrintf(
-        ", payload: (urls: %s, size: %" PRIu64 ", metadata_size: %" PRIu64
-        ", metadata signature: %s, hash: %s, payload type: %s)",
-        PayloadUrlsToString(payload.payload_urls).c_str(),
-        payload.size,
-        payload.metadata_size,
-        payload.metadata_signature.c_str(),
-        base::HexEncode(payload.hash.data(), payload.hash.size()).c_str(),
-        InstallPayloadTypeToString(payload.type).c_str());
-  }
+  LOG(INFO) << "InstallPlan: \n" << ToString();
+}
 
-  string version_str = base::StringPrintf(", version: %s", version.c_str());
+string InstallPlan::ToString() const {
   string url_str = download_url;
   if (base::StartsWith(
           url_str, "fd://", base::CompareCase::INSENSITIVE_ASCII)) {
@@ -89,19 +87,65 @@
     url_str = utils::GetFilePath(fd);
   }
 
-  LOG(INFO) << "InstallPlan: " << (is_resume ? "resume" : "new_update")
-            << version_str
-            << ", source_slot: " << BootControlInterface::SlotName(source_slot)
-            << ", target_slot: " << BootControlInterface::SlotName(target_slot)
-            << ", initial url: " << url_str << payloads_str << partitions_str
-            << ", hash_checks_mandatory: "
-            << utils::ToString(hash_checks_mandatory)
-            << ", powerwash_required: " << utils::ToString(powerwash_required)
-            << ", switch_slot_on_reboot: "
-            << utils::ToString(switch_slot_on_reboot)
-            << ", run_post_install: " << utils::ToString(run_post_install)
-            << ", is_rollback: " << utils::ToString(is_rollback)
-            << ", write_verity: " << utils::ToString(write_verity);
+  vector<string> result_str;
+  result_str.emplace_back(VectorToString(
+      {
+          {"type", (is_resume ? "resume" : "new_update")},
+          {"version", version},
+          {"source_slot", BootControlInterface::SlotName(source_slot)},
+          {"target_slot", BootControlInterface::SlotName(target_slot)},
+          {"initial url", url_str},
+          {"hash_checks_mandatory", utils::ToString(hash_checks_mandatory)},
+          {"powerwash_required", utils::ToString(powerwash_required)},
+          {"switch_slot_on_reboot", utils::ToString(switch_slot_on_reboot)},
+          {"run_post_install", utils::ToString(run_post_install)},
+          {"is_rollback", utils::ToString(is_rollback)},
+          {"rollback_data_save_requested",
+           utils::ToString(rollback_data_save_requested)},
+          {"write_verity", utils::ToString(write_verity)},
+      },
+      "\n"));
+
+  for (const auto& partition : partitions) {
+    result_str.emplace_back(VectorToString(
+        {
+            {"Partition", partition.name},
+            {"source_size", base::NumberToString(partition.source_size)},
+            {"source_path", partition.source_path},
+            {"source_hash",
+             base::HexEncode(partition.source_hash.data(),
+                             partition.source_hash.size())},
+            {"target_size", base::NumberToString(partition.target_size)},
+            {"target_path", partition.target_path},
+            {"target_hash",
+             base::HexEncode(partition.target_hash.data(),
+                             partition.target_hash.size())},
+            {"run_postinstall", utils::ToString(partition.run_postinstall)},
+            {"postinstall_path", partition.postinstall_path},
+            {"filesystem_type", partition.filesystem_type},
+        },
+        "\n  "));
+  }
+
+  for (unsigned int i = 0; i < payloads.size(); ++i) {
+    const auto& payload = payloads[i];
+    result_str.emplace_back(VectorToString(
+        {
+            {"Payload", base::NumberToString(i)},
+            {"urls", PayloadUrlsToString(payload.payload_urls)},
+            {"size", base::NumberToString(payload.size)},
+            {"metadata_size", base::NumberToString(payload.metadata_size)},
+            {"metadata_signature", payload.metadata_signature},
+            {"hash", base::HexEncode(payload.hash.data(), payload.hash.size())},
+            {"type", InstallPayloadTypeToString(payload.type)},
+            {"fingerprint", payload.fp},
+            {"app_id", payload.app_id},
+            {"already_applied", utils::ToString(payload.already_applied)},
+        },
+        "\n  "));
+  }
+
+  return base::JoinString(result_str, "\n");
 }
 
 bool InstallPlan::LoadPartitionsFromSlots(BootControlInterface* boot_control) {
diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h
index 7068f6c..43b94fc 100644
--- a/payload_consumer/install_plan.h
+++ b/payload_consumer/install_plan.h
@@ -45,6 +45,7 @@
   bool operator!=(const InstallPlan& that) const;
 
   void Dump() const;
+  std::string ToString() const;
 
   // Loads the |source_path| and |target_path| of all |partitions| based on the
   // |source_slot| and |target_slot| if available. Returns whether it succeeded
@@ -62,6 +63,8 @@
     std::string metadata_signature;  // signature of the metadata in base64
     brillo::Blob hash;               // SHA256 hash of the payload
     InstallPayloadType type{InstallPayloadType::kUnknown};
+    std::string fp;      // fingerprint value unique to the payload
+    std::string app_id;  // App ID of the payload
     // Only download manifest and fill in partitions in install plan without
     // apply the payload if true. Will be set by DownloadAction when resuming
     // multi-payload.
@@ -72,7 +75,8 @@
              metadata_size == that.metadata_size &&
              metadata_signature == that.metadata_signature &&
              hash == that.hash && type == that.type &&
-             already_applied == that.already_applied;
+             already_applied == that.already_applied && fp == that.fp &&
+             app_id == that.app_id;
     }
   };
   std::vector<Payload> payloads;
diff --git a/payload_consumer/install_plan_unittest.cc b/payload_consumer/install_plan_unittest.cc
new file mode 100644
index 0000000..2ca8d81
--- /dev/null
+++ b/payload_consumer/install_plan_unittest.cc
@@ -0,0 +1,82 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <gtest/gtest.h>
+
+#include "update_engine/payload_consumer/install_plan.h"
+
+namespace chromeos_update_engine {
+
+TEST(InstallPlanTest, Dump) {
+  InstallPlan install_plan{
+      .download_url = "foo-download-url",
+      .version = "foo-version",
+      .payloads = {{
+          .payload_urls = {"url1", "url2"},
+          .metadata_signature = "foo-signature",
+          .hash = {0xb2, 0xb3},
+          .fp = "foo-fp",
+          .app_id = "foo-app-id",
+      }},
+      .source_slot = BootControlInterface::kInvalidSlot,
+      .target_slot = BootControlInterface::kInvalidSlot,
+      .partitions = {{
+          .name = "foo-partition_name",
+          .source_path = "foo-source-path",
+          .source_hash = {0xb1, 0xb2},
+          .target_path = "foo-target-path",
+          .target_hash = {0xb3, 0xb4},
+          .postinstall_path = "foo-path",
+          .filesystem_type = "foo-type",
+      }},
+  };
+
+  EXPECT_EQ(install_plan.ToString(),
+            R"(type: new_update
+version: foo-version
+source_slot: INVALID
+target_slot: INVALID
+initial url: foo-download-url
+hash_checks_mandatory: false
+powerwash_required: false
+switch_slot_on_reboot: true
+run_post_install: true
+is_rollback: false
+rollback_data_save_requested: false
+write_verity: true
+Partition: foo-partition_name
+  source_size: 0
+  source_path: foo-source-path
+  source_hash: B1B2
+  target_size: 0
+  target_path: foo-target-path
+  target_hash: B3B4
+  run_postinstall: false
+  postinstall_path: foo-path
+  filesystem_type: foo-type
+Payload: 0
+  urls: (url1,url2)
+  size: 0
+  metadata_size: 0
+  metadata_signature: foo-signature
+  hash: B2B3
+  type: unknown
+  fingerprint: foo-fp
+  app_id: foo-app-id
+  already_applied: false)");
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index 37a8577..d452a64 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -302,10 +302,14 @@
 void PostinstallRunnerAction::Cleanup() {
   utils::UnmountFilesystem(fs_mount_dir_);
 #ifndef __ANDROID__
-  if (!base::DeleteFile(base::FilePath(fs_mount_dir_), false)) {
+#if BASE_VER < 800000
+  if (!base::DeleteFile(base::FilePath(fs_mount_dir_), true)) {
+#else
+  if (!base::DeleteFile(base::FilePath(fs_mount_dir_))) {
+#endif
     PLOG(WARNING) << "Not removing temporary mountpoint " << fs_mount_dir_;
   }
-#endif  // !__ANDROID__
+#endif
   fs_mount_dir_.clear();
 
   progress_fd_ = -1;
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index 0537310..a187b32 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -224,7 +224,6 @@
       std::make_unique<DownloadAction>(&prefs,
                                        &fake_boot_control,
                                        &fake_hardware,
-                                       nullptr,
                                        new FileFetcher(),
                                        true /* interactive */);
   auto filesystem_verifier_action = std::make_unique<FilesystemVerifierAction>(
diff --git a/update_manager/android_things_policy.cc b/update_manager/android_things_policy.cc
deleted file mode 100644
index c4fa75a..0000000
--- a/update_manager/android_things_policy.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/update_manager/android_things_policy.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <base/logging.h>
-#include <base/time/time.h>
-
-#include "update_engine/update_manager/api_restricted_downloads_policy_impl.h"
-#include "update_engine/update_manager/enough_slots_ab_updates_policy_impl.h"
-#include "update_engine/update_manager/interactive_update_policy_impl.h"
-#include "update_engine/update_manager/official_build_check_policy_impl.h"
-
-using base::Time;
-using chromeos_update_engine::ErrorCode;
-using std::string;
-using std::unique_ptr;
-using std::vector;
-
-namespace chromeos_update_manager {
-
-unique_ptr<Policy> GetSystemPolicy() {
-  return std::make_unique<AndroidThingsPolicy>();
-}
-
-const NextUpdateCheckPolicyConstants
-    AndroidThingsPolicy::kNextUpdateCheckPolicyConstants = {
-        .timeout_initial_interval = 7 * 60,
-        .timeout_periodic_interval = 5 * 60 * 60,
-        .timeout_max_backoff_interval = 26 * 60 * 60,
-        .timeout_regular_fuzz = 10 * 60,
-        .attempt_backoff_max_interval_in_days = 16,
-        .attempt_backoff_fuzz_in_hours = 12,
-};
-
-EvalStatus AndroidThingsPolicy::UpdateCheckAllowed(
-    EvaluationContext* ec,
-    State* state,
-    string* error,
-    UpdateCheckParams* result) const {
-  // Set the default return values.
-  result->updates_enabled = true;
-  result->target_channel.clear();
-  result->lts_tag.clear();
-  result->target_version_prefix.clear();
-  result->rollback_allowed = false;
-  result->rollback_data_save_requested = false;
-  result->rollback_allowed_milestones = -1;
-  result->rollback_on_channel_downgrade = false;
-  result->interactive = false;
-
-  // Build a list of policies to consult.  Note that each policy may modify the
-  // result structure, even if it signals kContinue.
-  EnoughSlotsAbUpdatesPolicyImpl enough_slots_ab_updates_policy;
-  OnlyUpdateOfficialBuildsPolicyImpl only_update_official_builds_policy;
-  InteractiveUpdatePolicyImpl interactive_update_policy;
-  NextUpdateCheckTimePolicyImpl next_update_check_time_policy(
-      kNextUpdateCheckPolicyConstants);
-
-  vector<Policy const*> policies_to_consult = {
-      // Do not perform any updates if there are not enough slots to do
-      // A/B updates
-      &enough_slots_ab_updates_policy,
-
-      // Check to see if an interactive update was requested.
-      &interactive_update_policy,
-
-      // Unofficial builds should not perform periodic update checks.
-      &only_update_official_builds_policy,
-
-      // Ensure that periodic update checks are timed properly.
-      &next_update_check_time_policy,
-  };
-
-  // Now that the list of policy implementations, and the order to consult them,
-  // as been setup, do that.  If none of the policies make a definitive
-  // decisions about whether or not to check for updates, then allow the update
-  // check to happen.
-  EvalStatus status = ConsultPolicies(policies_to_consult,
-                                      &Policy::UpdateCheckAllowed,
-                                      ec,
-                                      state,
-                                      error,
-                                      result);
-  if (status != EvalStatus::kContinue) {
-    return status;
-  } else {
-    // It is time to check for an update.
-    LOG(INFO) << "Allowing update check.";
-    return EvalStatus::kSucceeded;
-  }
-}
-
-// Uses the |UpdateRestrictions| to determine if the download and apply can
-// occur at this time.
-EvalStatus AndroidThingsPolicy::UpdateCanBeApplied(
-    EvaluationContext* ec,
-    State* state,
-    string* error,
-    ErrorCode* result,
-    chromeos_update_engine::InstallPlan* install_plan) const {
-  // Build a list of policies to consult.  Note that each policy may modify the
-  // result structure, even if it signals kContinue.
-  ApiRestrictedDownloadsPolicyImpl api_restricted_downloads_policy;
-
-  vector<Policy const*> policies_to_consult = {
-      // Do not apply the update if all updates are restricted by the API.
-      &api_restricted_downloads_policy,
-  };
-
-  // Now that the list of policy implementations, and the order to consult them,
-  // as been setup, do that.  If none of the policies make a definitive
-  // decisions about whether or not to check for updates, then allow the update
-  // check to happen.
-  EvalStatus status = ConsultPolicies(policies_to_consult,
-                                      &Policy::UpdateCanBeApplied,
-                                      ec,
-                                      state,
-                                      error,
-                                      result,
-                                      install_plan);
-  if (EvalStatus::kContinue != status) {
-    return status;
-  } else {
-    // The update can proceed.
-    LOG(INFO) << "Allowing update to be applied.";
-    *result = ErrorCode::kSuccess;
-    return EvalStatus::kSucceeded;
-  }
-}
-
-// Always returns |EvalStatus::kSucceeded|
-EvalStatus AndroidThingsPolicy::UpdateCanStart(EvaluationContext* ec,
-                                               State* state,
-                                               string* error,
-                                               UpdateDownloadParams* result,
-                                               UpdateState update_state) const {
-  // Update is good to go.
-  result->update_can_start = true;
-  return EvalStatus::kSucceeded;
-}
-
-// Always returns |EvalStatus::kSucceeded|
-EvalStatus AndroidThingsPolicy::UpdateDownloadAllowed(EvaluationContext* ec,
-                                                      State* state,
-                                                      string* error,
-                                                      bool* result) const {
-  // By default, we allow updates.
-  *result = true;
-  return EvalStatus::kSucceeded;
-}
-
-// P2P is always disabled.  Returns |result|==|false| and
-// |EvalStatus::kSucceeded|
-EvalStatus AndroidThingsPolicy::P2PEnabled(EvaluationContext* ec,
-                                           State* state,
-                                           string* error,
-                                           bool* result) const {
-  *result = false;
-  return EvalStatus::kSucceeded;
-}
-
-// This will return immediately with |EvalStatus::kSucceeded| and set
-// |result|==|false|
-EvalStatus AndroidThingsPolicy::P2PEnabledChanged(EvaluationContext* ec,
-                                                  State* state,
-                                                  string* error,
-                                                  bool* result,
-                                                  bool prev_result) const {
-  *result = false;
-  return EvalStatus::kSucceeded;
-}
-
-}  // namespace chromeos_update_manager
diff --git a/update_manager/android_things_policy.h b/update_manager/android_things_policy.h
deleted file mode 100644
index 9fd8bc4..0000000
--- a/update_manager/android_things_policy.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_UPDATE_MANAGER_ANDROID_THINGS_POLICY_H_
-#define UPDATE_ENGINE_UPDATE_MANAGER_ANDROID_THINGS_POLICY_H_
-
-#include <string>
-
-#include "update_engine/update_manager/next_update_check_policy_impl.h"
-#include "update_engine/update_manager/policy_utils.h"
-
-namespace chromeos_update_manager {
-
-// AndroidThingsPolicy implements the policy-related logic used in
-// AndroidThings.
-class AndroidThingsPolicy : public Policy {
- public:
-  AndroidThingsPolicy() = default;
-  ~AndroidThingsPolicy() override = default;
-
-  // Policy overrides.
-  EvalStatus UpdateCheckAllowed(EvaluationContext* ec,
-                                State* state,
-                                std::string* error,
-                                UpdateCheckParams* result) const override;
-
-  // Uses the |UpdateRestrictions| to determine if the download and apply can
-  // occur at this time.
-  EvalStatus UpdateCanBeApplied(
-      EvaluationContext* ec,
-      State* state,
-      std::string* error,
-      chromeos_update_engine::ErrorCode* result,
-      chromeos_update_engine::InstallPlan* install_plan) const override;
-
-  // Always returns |EvalStatus::kSucceeded|
-  EvalStatus UpdateCanStart(EvaluationContext* ec,
-                            State* state,
-                            std::string* error,
-                            UpdateDownloadParams* result,
-                            UpdateState update_state) const override;
-
-  // Always returns |EvalStatus::kSucceeded|
-  EvalStatus UpdateDownloadAllowed(EvaluationContext* ec,
-                                   State* state,
-                                   std::string* error,
-                                   bool* result) const override;
-
-  // P2P is always disabled.  Returns |result|==|false| and
-  // |EvalStatus::kSucceeded|
-  EvalStatus P2PEnabled(EvaluationContext* ec,
-                        State* state,
-                        std::string* error,
-                        bool* result) const override;
-
-  // This will return immediately with |EvalStatus::kSucceeded| and set
-  // |result|==|false|
-  EvalStatus P2PEnabledChanged(EvaluationContext* ec,
-                               State* state,
-                               std::string* error,
-                               bool* result,
-                               bool prev_result) const override;
-
- protected:
-  // Policy override.
-  std::string PolicyName() const override { return "AndroidThingsPolicy"; }
-
- private:
-  friend class UmAndroidThingsPolicyTest;
-  FRIEND_TEST(UmAndroidThingsPolicyTest, UpdateCheckAllowedWaitsForTheTimeout);
-
-  static const NextUpdateCheckPolicyConstants kNextUpdateCheckPolicyConstants;
-
-  DISALLOW_COPY_AND_ASSIGN(AndroidThingsPolicy);
-};
-
-}  // namespace chromeos_update_manager
-
-#endif  // UPDATE_ENGINE_UPDATE_MANAGER_ANDROID_THINGS_POLICY_H_
diff --git a/update_manager/android_things_policy_unittest.cc b/update_manager/android_things_policy_unittest.cc
deleted file mode 100644
index 6961efc..0000000
--- a/update_manager/android_things_policy_unittest.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/update_manager/android_things_policy.h"
-
-#include <memory>
-
-#include "update_engine/update_manager/next_update_check_policy_impl.h"
-#include "update_engine/update_manager/policy_test_utils.h"
-
-using base::Time;
-using base::TimeDelta;
-using chromeos_update_engine::ErrorCode;
-using chromeos_update_engine::InstallPlan;
-
-namespace chromeos_update_manager {
-
-class UmAndroidThingsPolicyTest : public UmPolicyTestBase {
- protected:
-  UmAndroidThingsPolicyTest() {
-    policy_ = std::make_unique<AndroidThingsPolicy>();
-  }
-
-  void SetUpDefaultState() override {
-    UmPolicyTestBase::SetUpDefaultState();
-
-    // For the purpose of the tests, this is an official build
-    fake_state_.system_provider()->var_is_official_build()->reset(
-        new bool(true));
-    // NOLINTNEXTLINE(readability/casting)
-    fake_state_.system_provider()->var_num_slots()->reset(new unsigned int(2));
-  }
-
-  // Configures the policy to return a desired value from UpdateCheckAllowed by
-  // faking the current wall clock time as needed. Restores the default state.
-  // This is used when testing policies that depend on this one.
-  virtual void SetUpdateCheckAllowed(bool allow_check) {
-    Time next_update_check;
-    CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
-                          &next_update_check,
-                          AndroidThingsPolicy::kNextUpdateCheckPolicyConstants);
-    SetUpDefaultState();
-    Time curr_time = next_update_check;
-    if (allow_check)
-      curr_time += TimeDelta::FromSeconds(1);
-    else
-      curr_time -= TimeDelta::FromSeconds(1);
-    fake_clock_.SetWallclockTime(curr_time);
-  }
-};
-
-TEST_F(UmAndroidThingsPolicyTest, UpdateCheckAllowedWaitsForTheTimeout) {
-  // We get the next update_check timestamp from the policy's private method
-  // and then we check the public method respects that value on the normal
-  // case.
-  Time next_update_check;
-  Time last_checked_time =
-      fake_clock_.GetWallclockTime() + TimeDelta::FromMinutes(1234);
-
-  LOG(INFO) << "last_checked_time: " << last_checked_time;
-  fake_state_.updater_provider()->var_last_checked_time()->reset(
-      new Time(last_checked_time));
-  CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
-                        &next_update_check,
-                        AndroidThingsPolicy::kNextUpdateCheckPolicyConstants);
-  LOG(INFO) << "Next check allowed at: " << next_update_check;
-
-  // Check that the policy blocks until the next_update_check is reached.
-  SetUpDefaultClock();
-  SetUpDefaultState();
-  fake_state_.updater_provider()->var_last_checked_time()->reset(
-      new Time(last_checked_time));
-  fake_clock_.SetWallclockTime(next_update_check - TimeDelta::FromSeconds(1));
-
-  UpdateCheckParams result;
-  ExpectPolicyStatus(
-      EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
-
-  SetUpDefaultClock();
-  SetUpDefaultState();
-  fake_state_.updater_provider()->var_last_checked_time()->reset(
-      new Time(last_checked_time));
-  fake_clock_.SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
-  EXPECT_TRUE(result.updates_enabled);
-  EXPECT_FALSE(result.interactive);
-}
-
-TEST_F(UmAndroidThingsPolicyTest,
-       UpdateCheckAllowedUpdatesDisabledForUnofficialBuilds) {
-  // UpdateCheckAllowed should return kAskMeAgainLater if this is an unofficial
-  // build; we don't want periodic update checks on developer images.
-
-  fake_state_.system_provider()->var_is_official_build()->reset(
-      new bool(false));
-
-  UpdateCheckParams result;
-  ExpectPolicyStatus(
-      EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
-}
-
-TEST_F(UmAndroidThingsPolicyTest,
-       UpdateCheckAllowedUpdatesDisabledWhenNotEnoughSlotsAbUpdates) {
-  // UpdateCheckAllowed should return false (kSucceeded) if the image booted
-  // without enough slots to do A/B updates.
-
-  // NOLINTNEXTLINE(readability/casting)
-  fake_state_.system_provider()->var_num_slots()->reset(new unsigned int(1));
-
-  UpdateCheckParams result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
-  EXPECT_FALSE(result.updates_enabled);
-}
-
-TEST_F(UmAndroidThingsPolicyTest,
-       UpdateCheckAllowedForcedUpdateRequestedInteractive) {
-  // UpdateCheckAllowed should return true because a forced update request was
-  // signaled for an interactive update.
-
-  SetUpdateCheckAllowed(true);
-  fake_state_.updater_provider()->var_forced_update_requested()->reset(
-      new UpdateRequestStatus(UpdateRequestStatus::kInteractive));
-
-  UpdateCheckParams result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
-  EXPECT_TRUE(result.updates_enabled);
-  EXPECT_TRUE(result.interactive);
-}
-
-TEST_F(UmAndroidThingsPolicyTest,
-       UpdateCheckAllowedForcedUpdateRequestedPeriodic) {
-  // UpdateCheckAllowed should return true because a forced update request was
-  // signaled for a periodic check.
-
-  SetUpdateCheckAllowed(true);
-  fake_state_.updater_provider()->var_forced_update_requested()->reset(
-      new UpdateRequestStatus(UpdateRequestStatus::kPeriodic));
-
-  UpdateCheckParams result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
-  EXPECT_TRUE(result.updates_enabled);
-  EXPECT_FALSE(result.interactive);
-}
-
-TEST_F(UmAndroidThingsPolicyTest, UpdateCanBeAppliedOk) {
-  // UpdateCanBeApplied should return kSucceeded in the base case
-
-  InstallPlan plan;
-  ErrorCode result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateCanBeApplied, &result, &plan);
-
-  EXPECT_EQ(ErrorCode::kSuccess, result);
-}
-
-TEST_F(UmAndroidThingsPolicyTest, UpdateCanBeAppliedRestricted) {
-  // UpdateCanBeApplied should return kOmahaUpdateDeferredPerPolicy in
-  // when the restricted flag is set in the Updater.
-
-  fake_state_.updater_provider()->var_update_restrictions()->reset(
-      new UpdateRestrictions(UpdateRestrictions::kRestrictDownloading));
-
-  InstallPlan plan;
-  ErrorCode result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateCanBeApplied, &result, &plan);
-
-  EXPECT_EQ(ErrorCode::kOmahaUpdateDeferredPerPolicy, result);
-}
-
-}  // namespace chromeos_update_manager
diff --git a/update_manager/chromeos_policy.cc b/update_manager/chromeos_policy.cc
index 4c651b7..24b8293 100644
--- a/update_manager/chromeos_policy.cc
+++ b/update_manager/chromeos_policy.cc
@@ -223,6 +223,7 @@
   result->rollback_allowed_milestones = -1;
   result->rollback_on_channel_downgrade = false;
   result->interactive = false;
+  result->quick_fix_build_token.clear();
 
   EnoughSlotsAbUpdatesPolicyImpl enough_slots_ab_updates_policy;
   EnterpriseDevicePolicyImpl enterprise_device_policy;
@@ -465,88 +466,6 @@
   return EvalStatus::kSucceeded;
 }
 
-// TODO(garnold) Logic in this method is based on
-// ConnectionManager::IsUpdateAllowedOver(); be sure to deprecate the latter.
-//
-// TODO(garnold) The current logic generally treats the list of allowed
-// connections coming from the device policy as an allowlist, meaning that it
-// can only be used for enabling connections, but not disable them. Further,
-// certain connection types cannot be enabled even by policy.
-// In effect, the only thing that device policy can change is to enable
-// updates over a cellular network (disabled by default). We may want to
-// revisit this semantics, allowing greater flexibility in defining specific
-// permissions over all types of networks.
-EvalStatus ChromeOSPolicy::UpdateDownloadAllowed(EvaluationContext* ec,
-                                                 State* state,
-                                                 string* error,
-                                                 bool* result) const {
-  // Get the current connection type.
-  ShillProvider* const shill_provider = state->shill_provider();
-  const ConnectionType* conn_type_p =
-      ec->GetValue(shill_provider->var_conn_type());
-  POLICY_CHECK_VALUE_AND_FAIL(conn_type_p, error);
-  ConnectionType conn_type = *conn_type_p;
-
-  // If we're tethering, treat it as a cellular connection.
-  if (conn_type != ConnectionType::kCellular) {
-    const ConnectionTethering* conn_tethering_p =
-        ec->GetValue(shill_provider->var_conn_tethering());
-    POLICY_CHECK_VALUE_AND_FAIL(conn_tethering_p, error);
-    if (*conn_tethering_p == ConnectionTethering::kConfirmed)
-      conn_type = ConnectionType::kCellular;
-  }
-
-  // By default, we allow updates for all connection types, with exceptions as
-  // noted below. This also determines whether a device policy can override the
-  // default.
-  *result = true;
-  bool device_policy_can_override = false;
-  switch (conn_type) {
-    case ConnectionType::kCellular:
-      *result = false;
-      device_policy_can_override = true;
-      break;
-
-    case ConnectionType::kUnknown:
-      if (error)
-        *error = "Unknown connection type";
-      return EvalStatus::kFailed;
-
-    default:
-      break;  // Nothing to do.
-  }
-
-  // If update is allowed, we're done.
-  if (*result)
-    return EvalStatus::kSucceeded;
-
-  // Check whether the device policy specifically allows this connection.
-  if (device_policy_can_override) {
-    DevicePolicyProvider* const dp_provider = state->device_policy_provider();
-    const bool* device_policy_is_loaded_p =
-        ec->GetValue(dp_provider->var_device_policy_is_loaded());
-    if (device_policy_is_loaded_p && *device_policy_is_loaded_p) {
-      const set<ConnectionType>* allowed_conn_types_p =
-          ec->GetValue(dp_provider->var_allowed_connection_types_for_update());
-      if (allowed_conn_types_p) {
-        if (allowed_conn_types_p->count(conn_type)) {
-          *result = true;
-          return EvalStatus::kSucceeded;
-        }
-      } else if (conn_type == ConnectionType::kCellular) {
-        // Local user settings can allow updates over cellular iff a policy was
-        // loaded but no allowed connections were specified in it.
-        const bool* update_over_cellular_allowed_p =
-            ec->GetValue(state->updater_provider()->var_cellular_enabled());
-        if (update_over_cellular_allowed_p && *update_over_cellular_allowed_p)
-          *result = true;
-      }
-    }
-  }
-
-  return (*result ? EvalStatus::kSucceeded : EvalStatus::kAskMeAgainLater);
-}
-
 EvalStatus ChromeOSPolicy::P2PEnabled(EvaluationContext* ec,
                                       State* state,
                                       string* error,
diff --git a/update_manager/chromeos_policy.h b/update_manager/chromeos_policy.h
index ded5164..3c196da 100644
--- a/update_manager/chromeos_policy.h
+++ b/update_manager/chromeos_policy.h
@@ -72,11 +72,6 @@
                             UpdateDownloadParams* result,
                             UpdateState update_state) const override;
 
-  EvalStatus UpdateDownloadAllowed(EvaluationContext* ec,
-                                   State* state,
-                                   std::string* error,
-                                   bool* result) const override;
-
   EvalStatus P2PEnabled(EvaluationContext* ec,
                         State* state,
                         std::string* error,
diff --git a/update_manager/chromeos_policy_unittest.cc b/update_manager/chromeos_policy_unittest.cc
index 996db2b..5bd416d 100644
--- a/update_manager/chromeos_policy_unittest.cc
+++ b/update_manager/chromeos_policy_unittest.cc
@@ -109,7 +109,7 @@
       curr_time += TimeDelta::FromSeconds(1);
     else
       curr_time -= TimeDelta::FromSeconds(1);
-    fake_clock_.SetWallclockTime(curr_time);
+    fake_clock_->SetWallclockTime(curr_time);
   }
 
   // Sets the policies required for a kiosk app to control Chrome OS version:
@@ -180,7 +180,7 @@
   // case.
   Time next_update_check;
   Time last_checked_time =
-      fake_clock_.GetWallclockTime() + TimeDelta::FromMinutes(1234);
+      fake_clock_->GetWallclockTime() + TimeDelta::FromMinutes(1234);
 
   fake_state_.updater_provider()->var_last_checked_time()->reset(
       new Time(last_checked_time));
@@ -195,7 +195,7 @@
   SetUpDefaultState();
   fake_state_.updater_provider()->var_last_checked_time()->reset(
       new Time(last_checked_time));
-  fake_clock_.SetWallclockTime(next_update_check - TimeDelta::FromSeconds(1));
+  fake_clock_->SetWallclockTime(next_update_check - TimeDelta::FromSeconds(1));
   ExpectPolicyStatus(
       EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
 
@@ -203,7 +203,7 @@
   SetUpDefaultState();
   fake_state_.updater_provider()->var_last_checked_time()->reset(
       new Time(last_checked_time));
-  fake_clock_.SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
+  fake_clock_->SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
   ExpectPolicyStatus(
       EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
   EXPECT_TRUE(result.updates_enabled);
@@ -216,7 +216,7 @@
   // Ensure that update is not allowed even if wait period is satisfied.
   Time next_update_check;
   Time last_checked_time =
-      fake_clock_.GetWallclockTime() + TimeDelta::FromMinutes(1234);
+      fake_clock_->GetWallclockTime() + TimeDelta::FromMinutes(1234);
 
   fake_state_.updater_provider()->var_last_checked_time()->reset(
       new Time(last_checked_time));
@@ -228,7 +228,7 @@
   SetUpDefaultState();
   fake_state_.updater_provider()->var_last_checked_time()->reset(
       new Time(last_checked_time));
-  fake_clock_.SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
+  fake_clock_->SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
   fake_state_.system_provider()->var_is_oobe_complete()->reset(new bool(false));
 
   UpdateCheckParams result;
@@ -240,7 +240,7 @@
   SetUpDefaultState();
   fake_state_.updater_provider()->var_last_checked_time()->reset(
       new Time(last_checked_time));
-  fake_clock_.SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
+  fake_clock_->SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
   ExpectPolicyStatus(
       EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
   EXPECT_TRUE(result.updates_enabled);
@@ -264,6 +264,8 @@
       new string("foo-channel"));
   fake_state_.device_policy_provider()->var_release_lts_tag()->reset(
       new string("foo-hint"));
+  fake_state_.device_policy_provider()->var_quick_fix_build_token()->reset(
+      new string("foo-token"));
 
   UpdateCheckParams result;
   ExpectPolicyStatus(
@@ -273,6 +275,7 @@
   EXPECT_EQ(5, result.rollback_allowed_milestones);
   EXPECT_EQ("foo-channel", result.target_channel);
   EXPECT_EQ("foo-hint", result.lts_tag);
+  EXPECT_EQ("foo-token", result.quick_fix_build_token);
   EXPECT_FALSE(result.interactive);
 }
 
@@ -355,8 +358,8 @@
 
   // After moving the time forward more than the update check interval, it
   // should now allow for update.
-  fake_clock_.SetWallclockTime(fake_clock_.GetWallclockTime() +
-                               TimeDelta::FromSeconds(11));
+  fake_clock_->SetWallclockTime(fake_clock_->GetWallclockTime() +
+                                TimeDelta::FromSeconds(11));
   ExpectPolicyStatus(
       EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
 }
@@ -569,7 +572,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -599,7 +602,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -632,7 +635,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -666,7 +669,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -699,7 +702,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -732,7 +735,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -765,7 +768,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -1141,7 +1144,7 @@
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromMinutes(10));
   update_state.p2p_num_attempts = 1;
   update_state.p2p_first_attempted =
-      fake_clock_.GetWallclockTime() -
+      fake_clock_->GetWallclockTime() -
       TimeDelta::FromSeconds(ChromeOSPolicy::kMaxP2PAttemptsPeriodInSeconds +
                              1);
   UpdateDownloadParams result;
@@ -1215,7 +1218,7 @@
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromMinutes(10));
   update_state.num_checks = 5;
   update_state.download_urls.emplace_back("http://another/fake/url/");
-  Time t = fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(12);
+  Time t = fake_clock_->GetWallclockTime() - TimeDelta::FromSeconds(12);
   for (int i = 0; i < 5; i++) {
     update_state.download_errors.emplace_back(
         0, ErrorCode::kDownloadTransferError, t);
@@ -1244,7 +1247,7 @@
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromMinutes(10));
   update_state.num_checks = 10;
   update_state.download_urls.emplace_back("http://another/fake/url/");
-  Time t = fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(12);
+  Time t = fake_clock_->GetWallclockTime() - TimeDelta::FromSeconds(12);
   for (int i = 0; i < 11; i++) {
     update_state.download_errors.emplace_back(
         0, ErrorCode::kDownloadTransferError, t);
@@ -1276,7 +1279,7 @@
   update_state.download_errors.emplace_back(
       0,
       ErrorCode::kPayloadHashMismatchError,
-      fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(1));
+      fake_clock_->GetWallclockTime() - TimeDelta::FromSeconds(1));
 
   // Check that the UpdateCanStart returns true.
   UpdateDownloadParams result;
@@ -1305,7 +1308,7 @@
   update_state.download_errors.emplace_back(
       1,
       ErrorCode::kPayloadHashMismatchError,
-      fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(1));
+      fake_clock_->GetWallclockTime() - TimeDelta::FromSeconds(1));
 
   // Check that the UpdateCanStart returns true.
   UpdateDownloadParams result;
@@ -1406,107 +1409,6 @@
   EXPECT_FALSE(result.do_increment_failures);
 }
 
-TEST_F(UmChromeOSPolicyTest, UpdateDownloadAllowedEthernetDefault) {
-  // Ethernet is always allowed.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kEthernet));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateDownloadAllowed, &result);
-  EXPECT_TRUE(result);
-}
-
-TEST_F(UmChromeOSPolicyTest, UpdateDownloadAllowedWifiDefault) {
-  // Wifi is allowed if not tethered.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kWifi));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateDownloadAllowed, &result);
-  EXPECT_TRUE(result);
-}
-
-TEST_F(UmChromeOSPolicyTest,
-       UpdateCurrentConnectionNotAllowedWifiTetheredDefault) {
-  // Tethered wifi is not allowed by default.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kWifi));
-  fake_state_.shill_provider()->var_conn_tethering()->reset(
-      new ConnectionTethering(ConnectionTethering::kConfirmed));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kAskMeAgainLater, &Policy::UpdateDownloadAllowed, &result);
-}
-
-TEST_F(UmChromeOSPolicyTest, UpdateDownloadAllowedWifiTetheredPolicyOverride) {
-  // Tethered wifi can be allowed by policy.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kWifi));
-  fake_state_.shill_provider()->var_conn_tethering()->reset(
-      new ConnectionTethering(ConnectionTethering::kConfirmed));
-  set<ConnectionType> allowed_connections;
-  allowed_connections.insert(ConnectionType::kCellular);
-  fake_state_.device_policy_provider()
-      ->var_allowed_connection_types_for_update()
-      ->reset(new set<ConnectionType>(allowed_connections));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateDownloadAllowed, &result);
-  EXPECT_TRUE(result);
-}
-
-TEST_F(UmChromeOSPolicyTest, UpdateCurrentConnectionNotAllowedCellularDefault) {
-  // Cellular is not allowed by default.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kCellular));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kAskMeAgainLater, &Policy::UpdateDownloadAllowed, &result);
-}
-
-TEST_F(UmChromeOSPolicyTest, UpdateDownloadAllowedCellularPolicyOverride) {
-  // Update over cellular can be enabled by policy.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kCellular));
-  set<ConnectionType> allowed_connections;
-  allowed_connections.insert(ConnectionType::kCellular);
-  fake_state_.device_policy_provider()
-      ->var_allowed_connection_types_for_update()
-      ->reset(new set<ConnectionType>(allowed_connections));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateDownloadAllowed, &result);
-  EXPECT_TRUE(result);
-}
-
-TEST_F(UmChromeOSPolicyTest, UpdateDownloadAllowedCellularUserOverride) {
-  // Update over cellular can be enabled by user settings, but only if policy
-  // is present and does not determine allowed connections.
-
-  fake_state_.shill_provider()->var_conn_type()->reset(
-      new ConnectionType(ConnectionType::kCellular));
-  set<ConnectionType> allowed_connections;
-  allowed_connections.insert(ConnectionType::kCellular);
-  fake_state_.updater_provider()->var_cellular_enabled()->reset(new bool(true));
-
-  bool result;
-  ExpectPolicyStatus(
-      EvalStatus::kSucceeded, &Policy::UpdateDownloadAllowed, &result);
-  EXPECT_TRUE(result);
-}
-
 TEST_F(UmChromeOSPolicyTest, UpdateCanStartAllowedScatteringSupressedDueToP2P) {
   // The UpdateCanStart policy returns true; scattering should have applied, but
   // P2P download is allowed. Scattering values are nonetheless returned, and so
@@ -1541,7 +1443,7 @@
 
   SetUpdateCheckAllowed(false);
 
-  const Time curr_time = fake_clock_.GetWallclockTime();
+  const Time curr_time = fake_clock_->GetWallclockTime();
   UpdateState update_state = GetDefaultUpdateState(TimeDelta::FromSeconds(10));
   update_state.download_errors_max = 1;
   update_state.download_errors.emplace_back(
@@ -1607,7 +1509,7 @@
 
 TEST_F(UmChromeOSPolicyTest,
        UpdateCanBeAppliedForcedUpdatesDisablesTimeRestrictions) {
-  Time curr_time = fake_clock_.GetWallclockTime();
+  Time curr_time = fake_clock_->GetWallclockTime();
   fake_state_.updater_provider()->var_forced_update_requested()->reset(
       new UpdateRequestStatus(UpdateRequestStatus::kInteractive));
   // Should return kAskMeAgainLater when updated are not forced.
@@ -1620,7 +1522,7 @@
 }
 
 TEST_F(UmChromeOSPolicyTest, UpdateCanBeAppliedFailsInDisallowedTime) {
-  Time curr_time = fake_clock_.GetWallclockTime();
+  Time curr_time = fake_clock_->GetWallclockTime();
   TestDisallowedTimeIntervals(
       {WeeklyTimeInterval(
           WeeklyTime::FromTime(curr_time),
@@ -1630,7 +1532,7 @@
 }
 
 TEST_F(UmChromeOSPolicyTest, UpdateCanBeAppliedOutsideDisallowedTime) {
-  Time curr_time = fake_clock_.GetWallclockTime();
+  Time curr_time = fake_clock_->GetWallclockTime();
   TestDisallowedTimeIntervals(
       {WeeklyTimeInterval(
           WeeklyTime::FromTime(curr_time - TimeDelta::FromHours(3)),
@@ -1640,7 +1542,7 @@
 }
 
 TEST_F(UmChromeOSPolicyTest, UpdateCanBeAppliedPassesOnNonKiosk) {
-  Time curr_time = fake_clock_.GetWallclockTime();
+  Time curr_time = fake_clock_->GetWallclockTime();
   TestDisallowedTimeIntervals(
       {WeeklyTimeInterval(
           WeeklyTime::FromTime(curr_time),
diff --git a/update_manager/default_policy.cc b/update_manager/default_policy.cc
index 7ca414b..0713e06 100644
--- a/update_manager/default_policy.cc
+++ b/update_manager/default_policy.cc
@@ -14,10 +14,12 @@
 // limitations under the License.
 //
 
+#include "update_engine/common/system_state.h"
 #include "update_engine/update_manager/default_policy.h"
 
 using chromeos_update_engine::ErrorCode;
 using chromeos_update_engine::InstallPlan;
+using chromeos_update_engine::SystemState;
 
 namespace {
 
@@ -31,9 +33,6 @@
 
 namespace chromeos_update_manager {
 
-DefaultPolicy::DefaultPolicy(chromeos_update_engine::ClockInterface* clock)
-    : clock_(clock), aux_state_(new DefaultPolicyState()) {}
-
 EvalStatus DefaultPolicy::UpdateCheckAllowed(EvaluationContext* ec,
                                              State* state,
                                              std::string* error,
@@ -46,6 +45,7 @@
   result->rollback_allowed_milestones = -1;  // No version rolls should happen.
   result->rollback_on_channel_downgrade = false;
   result->interactive = false;
+  result->quick_fix_build_token.clear();
 
   // Ensure that the minimum interval is set. If there's no clock, this defaults
   // to always allowing the update.
@@ -53,8 +53,8 @@
       ec->IsMonotonicTimeGreaterThan(
           aux_state_->last_check_allowed_time() +
           base::TimeDelta::FromSeconds(kCheckIntervalInSeconds))) {
-    if (clock_)
-      aux_state_->set_last_check_allowed_time(clock_->GetMonotonicTime());
+    aux_state_->set_last_check_allowed_time(
+        SystemState::Get()->clock()->GetMonotonicTime());
     return EvalStatus::kSucceeded;
   }
 
@@ -89,14 +89,6 @@
   return EvalStatus::kSucceeded;
 }
 
-EvalStatus DefaultPolicy::UpdateDownloadAllowed(EvaluationContext* ec,
-                                                State* state,
-                                                std::string* error,
-                                                bool* result) const {
-  *result = true;
-  return EvalStatus::kSucceeded;
-}
-
 EvalStatus DefaultPolicy::P2PEnabled(EvaluationContext* ec,
                                      State* state,
                                      std::string* error,
diff --git a/update_manager/default_policy.h b/update_manager/default_policy.h
index 1b284f4..c93bb46 100644
--- a/update_manager/default_policy.h
+++ b/update_manager/default_policy.h
@@ -22,7 +22,6 @@
 
 #include <base/time/time.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/update_manager/policy.h"
 
 namespace chromeos_update_manager {
@@ -60,9 +59,8 @@
 // actual policy being used by the UpdateManager.
 class DefaultPolicy : public Policy {
  public:
-  explicit DefaultPolicy(chromeos_update_engine::ClockInterface* clock);
-  DefaultPolicy() : DefaultPolicy(nullptr) {}
-  ~DefaultPolicy() override {}
+  DefaultPolicy() : aux_state_(new DefaultPolicyState()) {}
+  ~DefaultPolicy() override = default;
 
   // Policy overrides.
   EvalStatus UpdateCheckAllowed(EvaluationContext* ec,
@@ -83,11 +81,6 @@
                             UpdateDownloadParams* result,
                             UpdateState update_state) const override;
 
-  EvalStatus UpdateDownloadAllowed(EvaluationContext* ec,
-                                   State* state,
-                                   std::string* error,
-                                   bool* result) const override;
-
   EvalStatus P2PEnabled(EvaluationContext* ec,
                         State* state,
                         std::string* error,
@@ -104,9 +97,6 @@
   std::string PolicyName() const override { return "DefaultPolicy"; }
 
  private:
-  // A clock interface.
-  chromeos_update_engine::ClockInterface* clock_;
-
   // An auxiliary state object.
   std::unique_ptr<DefaultPolicyState> aux_state_;
 
diff --git a/update_manager/device_policy_provider.h b/update_manager/device_policy_provider.h
index a59f2a3..5112f68 100644
--- a/update_manager/device_policy_provider.h
+++ b/update_manager/device_policy_provider.h
@@ -97,6 +97,10 @@
   // Chrome OS version number.
   virtual Variable<base::Version>* var_device_minimum_version() = 0;
 
+  // Variable that contains a token which maps to a Chrome OS Quick Fix Build to
+  // which the device would be updated if not blocked by another policy.
+  virtual Variable<std::string>* var_quick_fix_build_token() = 0;
+
  protected:
   DevicePolicyProvider() {}
 
diff --git a/update_manager/enterprise_device_policy_impl.cc b/update_manager/enterprise_device_policy_impl.cc
index ce8150e..b9a11e1 100644
--- a/update_manager/enterprise_device_policy_impl.cc
+++ b/update_manager/enterprise_device_policy_impl.cc
@@ -165,6 +165,12 @@
     if (release_lts_tag_p) {
       result->lts_tag = *release_lts_tag_p;
     }
+
+    const string* quick_fix_build_token_p =
+        ec->GetValue(dp_provider->var_quick_fix_build_token());
+    if (quick_fix_build_token_p) {
+      result->quick_fix_build_token = *quick_fix_build_token_p;
+    }
   }
   return EvalStatus::kContinue;
 }
diff --git a/update_manager/enterprise_device_policy_impl_unittest.cc b/update_manager/enterprise_device_policy_impl_unittest.cc
index f27715e..30f54b1 100644
--- a/update_manager/enterprise_device_policy_impl_unittest.cc
+++ b/update_manager/enterprise_device_policy_impl_unittest.cc
@@ -158,4 +158,13 @@
   EXPECT_TRUE(result.rollback_on_channel_downgrade);
 }
 
+TEST_F(UmEnterpriseDevicePolicyImplTest, QuickFixBuildToken) {
+  fake_state_.device_policy_provider()->var_quick_fix_build_token()->reset(
+      new std::string("token"));
+  UpdateCheckParams result;
+  ExpectPolicyStatus(
+      EvalStatus::kContinue, &Policy::UpdateCheckAllowed, &result);
+  EXPECT_EQ(result.quick_fix_build_token, "token");
+}
+
 }  // namespace chromeos_update_manager
diff --git a/update_manager/enterprise_rollback_policy_impl.cc b/update_manager/enterprise_rollback_policy_impl.cc
new file mode 100644
index 0000000..ab4e38c
--- /dev/null
+++ b/update_manager/enterprise_rollback_policy_impl.cc
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/update_manager/enterprise_rollback_policy_impl.h"
+
+using chromeos_update_engine::ErrorCode;
+using chromeos_update_engine::InstallPlan;
+using std::string;
+
+namespace chromeos_update_manager {
+
+EvalStatus EnterpriseRollbackPolicyImpl::UpdateCanBeApplied(
+    EvaluationContext* ec,
+    State* state,
+    string* error,
+    ErrorCode* result,
+    InstallPlan* install_plan) const {
+  if (install_plan && install_plan->is_rollback) {
+    LOG(INFO)
+        << "Update is enterprise rollback, allowing update to be applied.";
+    *result = ErrorCode::kSuccess;
+    return EvalStatus::kSucceeded;
+  }
+  return EvalStatus::kContinue;
+}
+
+}  // namespace chromeos_update_manager
diff --git a/update_manager/enterprise_rollback_policy_impl.h b/update_manager/enterprise_rollback_policy_impl.h
new file mode 100644
index 0000000..bcaf95e
--- /dev/null
+++ b/update_manager/enterprise_rollback_policy_impl.h
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_UPDATE_MANAGER_ENTERPRISE_ROLLBACK_POLICY_IMPL_H_
+#define UPDATE_ENGINE_UPDATE_MANAGER_ENTERPRISE_ROLLBACK_POLICY_IMPL_H_
+
+#include <string>
+
+#include "update_engine/common/error_code.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/update_manager/policy_utils.h"
+
+namespace chromeos_update_manager {
+
+// If the update is an enterprise rollback, this should not block the update
+// to be applied.
+class EnterpriseRollbackPolicyImpl : public PolicyImplBase {
+ public:
+  EnterpriseRollbackPolicyImpl() = default;
+  ~EnterpriseRollbackPolicyImpl() override = default;
+
+  // Policy overrides.
+  EvalStatus UpdateCanBeApplied(
+      EvaluationContext* ec,
+      State* state,
+      std::string* error,
+      chromeos_update_engine::ErrorCode* result,
+      chromeos_update_engine::InstallPlan* install_plan) const override;
+
+ protected:
+  std::string PolicyName() const override {
+    return "EnterpriseRollbackPolicyImpl";
+  }
+
+ private:
+  EnterpriseRollbackPolicyImpl(const EnterpriseRollbackPolicyImpl&) = delete;
+  EnterpriseRollbackPolicyImpl& operator=(const EnterpriseRollbackPolicyImpl&) =
+      delete;
+};
+
+}  // namespace chromeos_update_manager
+
+#endif  // UPDATE_ENGINE_UPDATE_MANAGER_ENTERPRISE_ROLLBACK_POLICY_IMPL_H_
diff --git a/update_manager/enterprise_rollback_policy_impl_unittest.cc b/update_manager/enterprise_rollback_policy_impl_unittest.cc
new file mode 100644
index 0000000..5cc5c75
--- /dev/null
+++ b/update_manager/enterprise_rollback_policy_impl_unittest.cc
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <memory>
+
+#include "update_engine/update_manager/enterprise_rollback_policy_impl.h"
+#include "update_engine/update_manager/policy_test_utils.h"
+#include "update_engine/update_manager/weekly_time.h"
+
+using chromeos_update_engine::ErrorCode;
+using chromeos_update_engine::InstallPlan;
+
+namespace chromeos_update_manager {
+
+class UmEnterpriseRollbackPolicyImplTest : public UmPolicyTestBase {
+ protected:
+  UmEnterpriseRollbackPolicyImplTest() {
+    policy_ = std::make_unique<EnterpriseRollbackPolicyImpl>();
+  }
+};
+
+TEST_F(UmEnterpriseRollbackPolicyImplTest,
+       ContinueWhenUpdateIsNotEnterpriseRollback) {
+  InstallPlan install_plan{.is_rollback = false};
+  ErrorCode result;
+  ExpectPolicyStatus(EvalStatus::kContinue,
+                     &Policy::UpdateCanBeApplied,
+                     &result,
+                     &install_plan);
+}
+
+TEST_F(UmEnterpriseRollbackPolicyImplTest,
+       SuccessWhenUpdateIsEnterpriseRollback) {
+  InstallPlan install_plan{.is_rollback = true};
+  ErrorCode result;
+  ExpectPolicyStatus(EvalStatus::kSucceeded,
+                     &Policy::UpdateCanBeApplied,
+                     &result,
+                     &install_plan);
+  EXPECT_EQ(result, ErrorCode::kSuccess);
+}
+
+}  // namespace chromeos_update_manager
diff --git a/update_manager/evaluation_context.cc b/update_manager/evaluation_context.cc
index e796fec..b86f41c 100644
--- a/update_manager/evaluation_context.cc
+++ b/update_manager/evaluation_context.cc
@@ -27,6 +27,7 @@
 #include <base/strings/string_util.h>
 #include <base/values.h>
 
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 
 using base::Callback;
@@ -34,7 +35,7 @@
 using base::Time;
 using base::TimeDelta;
 using brillo::MessageLoop;
-using chromeos_update_engine::ClockInterface;
+using chromeos_update_engine::SystemState;
 using std::string;
 using std::unique_ptr;
 
@@ -65,12 +66,10 @@
 namespace chromeos_update_manager {
 
 EvaluationContext::EvaluationContext(
-    ClockInterface* clock,
     TimeDelta evaluation_timeout,
     TimeDelta expiration_timeout,
     unique_ptr<Callback<void(EvaluationContext*)>> unregister_cb)
-    : clock_(clock),
-      evaluation_timeout_(evaluation_timeout),
+    : evaluation_timeout_(evaluation_timeout),
       expiration_timeout_(expiration_timeout),
       unregister_cb_(std::move(unregister_cb)),
       weak_ptr_factory_(this) {
@@ -98,13 +97,15 @@
 TimeDelta EvaluationContext::RemainingTime(Time monotonic_deadline) const {
   if (monotonic_deadline.is_max())
     return TimeDelta::Max();
-  TimeDelta remaining = monotonic_deadline - clock_->GetMonotonicTime();
+  TimeDelta remaining =
+      monotonic_deadline - SystemState::Get()->clock()->GetMonotonicTime();
   return std::max(remaining, TimeDelta());
 }
 
 Time EvaluationContext::MonotonicDeadline(TimeDelta timeout) {
-  return (timeout.is_max() ? Time::Max()
-                           : clock_->GetMonotonicTime() + timeout);
+  return (timeout.is_max()
+              ? Time::Max()
+              : SystemState::Get()->clock()->GetMonotonicTime() + timeout);
 }
 
 void EvaluationContext::ValueChanged(BaseVariable* var) {
@@ -139,8 +140,9 @@
 }
 
 void EvaluationContext::ResetEvaluation() {
-  evaluation_start_wallclock_ = clock_->GetWallclockTime();
-  evaluation_start_monotonic_ = clock_->GetMonotonicTime();
+  const auto* clock = SystemState::Get()->clock();
+  evaluation_start_wallclock_ = clock->GetWallclockTime();
+  evaluation_start_monotonic_ = clock->GetMonotonicTime();
   reevaluation_time_wallclock_ = Time::Max();
   reevaluation_time_monotonic_ = Time::Max();
   evaluation_monotonic_deadline_ = MonotonicDeadline(evaluation_timeout_);
diff --git a/update_manager/evaluation_context.h b/update_manager/evaluation_context.h
index 5c5b013..3460f2a 100644
--- a/update_manager/evaluation_context.h
+++ b/update_manager/evaluation_context.h
@@ -27,7 +27,6 @@
 #include <base/time/time.h>
 #include <brillo/message_loops/message_loop.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/update_manager/boxed_value.h"
 #include "update_engine/update_manager/variable.h"
 
@@ -64,14 +63,11 @@
 class EvaluationContext : private BaseVariable::ObserverInterface {
  public:
   EvaluationContext(
-      chromeos_update_engine::ClockInterface* clock,
       base::TimeDelta evaluation_timeout,
       base::TimeDelta expiration_timeout,
       std::unique_ptr<base::Callback<void(EvaluationContext*)>> unregister_cb);
-  EvaluationContext(chromeos_update_engine::ClockInterface* clock,
-                    base::TimeDelta evaluation_timeout)
+  explicit EvaluationContext(base::TimeDelta evaluation_timeout)
       : EvaluationContext(
-            clock,
             evaluation_timeout,
             base::TimeDelta::Max(),
             std::unique_ptr<base::Callback<void(EvaluationContext*)>>()) {}
@@ -172,9 +168,6 @@
   // Whether the evaluation context has indeed expired.
   bool is_expired_ = false;
 
-  // Pointer to the mockable clock interface;
-  chromeos_update_engine::ClockInterface* const clock_;
-
   // The timestamps when the evaluation of this EvaluationContext started,
   // corresponding to ClockInterface::GetWallclockTime() and
   // ClockInterface::GetMonotonicTime(), respectively. These values are reset
diff --git a/update_manager/evaluation_context_unittest.cc b/update_manager/evaluation_context_unittest.cc
index cd0b2e6..fdb408b 100644
--- a/update_manager/evaluation_context_unittest.cc
+++ b/update_manager/evaluation_context_unittest.cc
@@ -26,6 +26,7 @@
 #include <gtest/gtest.h>
 
 #include "update_engine/common/fake_clock.h"
+#include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/fake_variable.h"
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/update_manager/mock_variable.h"
@@ -39,6 +40,7 @@
 using brillo::MessageLoopRunMaxIterations;
 using brillo::MessageLoopRunUntil;
 using chromeos_update_engine::FakeClock;
+using chromeos_update_engine::FakeSystemState;
 using std::shared_ptr;
 using std::string;
 using std::unique_ptr;
@@ -88,13 +90,14 @@
 class UmEvaluationContextTest : public ::testing::Test {
  protected:
   void SetUp() override {
+    FakeSystemState::CreateInstance();
+    fake_clock_ = FakeSystemState::Get()->fake_clock();
     loop_.SetAsCurrent();
     // Apr 22, 2009 19:25:00 UTC (this is a random reference point).
-    fake_clock_.SetMonotonicTime(Time::FromTimeT(1240428300));
+    fake_clock_->SetMonotonicTime(Time::FromTimeT(1240428300));
     // Mar 2, 2006 1:23:45 UTC.
-    fake_clock_.SetWallclockTime(Time::FromTimeT(1141262625));
+    fake_clock_->SetWallclockTime(Time::FromTimeT(1141262625));
     eval_ctx_.reset(new EvaluationContext(
-        &fake_clock_,
         default_timeout_,
         default_timeout_,
         unique_ptr<base::Callback<void(EvaluationContext*)>>(nullptr)));
@@ -126,7 +129,7 @@
   TimeDelta default_timeout_ = TimeDelta::FromSeconds(5);
 
   brillo::FakeMessageLoop loop_{nullptr};
-  FakeClock fake_clock_;
+  FakeClock* fake_clock_;
   shared_ptr<EvaluationContext> eval_ctx_;
 
   // FakeVariables used for testing the EvaluationContext. These are required
@@ -365,8 +368,8 @@
 }
 
 TEST_F(UmEvaluationContextTest, TimeoutUpdatesWithMonotonicTime) {
-  fake_clock_.SetMonotonicTime(fake_clock_.GetMonotonicTime() +
-                               TimeDelta::FromSeconds(1));
+  fake_clock_->SetMonotonicTime(fake_clock_->GetMonotonicTime() +
+                                TimeDelta::FromSeconds(1));
 
   TimeDelta timeout = default_timeout_ - TimeDelta::FromSeconds(1);
 
@@ -375,9 +378,9 @@
 }
 
 TEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesWallclock) {
-  Time cur_time = fake_clock_.GetWallclockTime();
+  Time cur_time = fake_clock_->GetWallclockTime();
   // Advance the time on the clock but don't call ResetEvaluation yet.
-  fake_clock_.SetWallclockTime(cur_time + TimeDelta::FromSeconds(4));
+  fake_clock_->SetWallclockTime(cur_time + TimeDelta::FromSeconds(4));
 
   EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time -
                                                     TimeDelta::FromSeconds(1)));
@@ -387,7 +390,7 @@
   // Call ResetEvaluation now, which should use the new evaluation time.
   eval_ctx_->ResetEvaluation();
 
-  cur_time = fake_clock_.GetWallclockTime();
+  cur_time = fake_clock_->GetWallclockTime();
   EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time -
                                                     TimeDelta::FromSeconds(1)));
   EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
@@ -396,9 +399,9 @@
 }
 
 TEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesMonotonic) {
-  Time cur_time = fake_clock_.GetMonotonicTime();
+  Time cur_time = fake_clock_->GetMonotonicTime();
   // Advance the time on the clock but don't call ResetEvaluation yet.
-  fake_clock_.SetMonotonicTime(cur_time + TimeDelta::FromSeconds(4));
+  fake_clock_->SetMonotonicTime(cur_time + TimeDelta::FromSeconds(4));
 
   EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time -
                                                     TimeDelta::FromSeconds(1)));
@@ -408,7 +411,7 @@
   // Call ResetEvaluation now, which should use the new evaluation time.
   eval_ctx_->ResetEvaluation();
 
-  cur_time = fake_clock_.GetMonotonicTime();
+  cur_time = fake_clock_->GetMonotonicTime();
   EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time -
                                                     TimeDelta::FromSeconds(1)));
   EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
@@ -419,7 +422,7 @@
 TEST_F(UmEvaluationContextTest,
        IsWallclockTimeGreaterThanSignalsTriggerReevaluation) {
   EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
-      fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(1)));
+      fake_clock_->GetWallclockTime() + TimeDelta::FromSeconds(1)));
 
   // The "false" from IsWallclockTimeGreaterThan means that's not that timestamp
   // yet, so this should schedule a callback for when that happens.
@@ -429,7 +432,7 @@
 TEST_F(UmEvaluationContextTest,
        IsMonotonicTimeGreaterThanSignalsTriggerReevaluation) {
   EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
-      fake_clock_.GetMonotonicTime() + TimeDelta::FromSeconds(1)));
+      fake_clock_->GetMonotonicTime() + TimeDelta::FromSeconds(1)));
 
   // The "false" from IsMonotonicTimeGreaterThan means that's not that timestamp
   // yet, so this should schedule a callback for when that happens.
@@ -441,9 +444,9 @@
   // IsWallclockTimeGreaterThan() should ignore timestamps on the past for
   // reevaluation.
   EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
-      fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(20)));
+      fake_clock_->GetWallclockTime() - TimeDelta::FromSeconds(20)));
   EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
-      fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(1)));
+      fake_clock_->GetWallclockTime() - TimeDelta::FromSeconds(1)));
 
   // Callback should not be scheduled.
   EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(base::DoNothing()));
@@ -454,9 +457,9 @@
   // IsMonotonicTimeGreaterThan() should ignore timestamps on the past for
   // reevaluation.
   EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
-      fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(20)));
+      fake_clock_->GetMonotonicTime() - TimeDelta::FromSeconds(20)));
   EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
-      fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(1)));
+      fake_clock_->GetMonotonicTime() - TimeDelta::FromSeconds(1)));
 
   // Callback should not be scheduled.
   EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(base::DoNothing()));
diff --git a/update_manager/fake_device_policy_provider.h b/update_manager/fake_device_policy_provider.h
index 55d66b3..762bfc5 100644
--- a/update_manager/fake_device_policy_provider.h
+++ b/update_manager/fake_device_policy_provider.h
@@ -104,6 +104,10 @@
     return &var_device_minimum_version_;
   }
 
+  FakeVariable<std::string>* var_quick_fix_build_token() override {
+    return &var_quick_fix_build_token_;
+  }
+
  private:
   FakeVariable<bool> var_device_policy_is_loaded_{"policy_is_loaded",
                                                   kVariableModePoll};
@@ -134,11 +138,13 @@
   FakeVariable<std::string> var_auto_launched_kiosk_app_id_{
       "auto_launched_kiosk_app_id", kVariableModePoll};
   FakeVariable<WeeklyTimeIntervalVector> var_disallowed_time_intervals_{
-      "disallowed_time_intervals", kVariableModePoll};
+      "disallowed_time_intervals", kVariableModeAsync};
   FakeVariable<ChannelDowngradeBehavior> var_channel_downgrade_behavior_{
       "channel_downgrade_behavior", kVariableModePoll};
   FakeVariable<base::Version> var_device_minimum_version_{
       "device_minimum_version", kVariableModePoll};
+  FakeVariable<std::string> var_quick_fix_build_token_{"quick_fix_build_token",
+                                                       kVariableModePoll};
 
   DISALLOW_COPY_AND_ASSIGN(FakeDevicePolicyProvider);
 };
diff --git a/update_manager/fake_update_manager.h b/update_manager/fake_update_manager.h
index 173b1a9..b880582 100644
--- a/update_manager/fake_update_manager.h
+++ b/update_manager/fake_update_manager.h
@@ -26,13 +26,12 @@
 
 class FakeUpdateManager : public UpdateManager {
  public:
-  explicit FakeUpdateManager(chromeos_update_engine::ClockInterface* clock)
-      : UpdateManager(clock,
-                      base::TimeDelta::FromSeconds(5),
+  FakeUpdateManager()
+      : UpdateManager(base::TimeDelta::FromSeconds(5),
                       base::TimeDelta::FromHours(1),
                       new FakeState()) {
     // The FakeUpdateManager uses a DefaultPolicy.
-    set_policy(new DefaultPolicy(clock));
+    set_policy(new DefaultPolicy());
   }
 
   // UpdateManager overrides.
diff --git a/update_manager/minimum_version_policy_impl.cc b/update_manager/minimum_version_policy_impl.cc
new file mode 100644
index 0000000..fb94ee4
--- /dev/null
+++ b/update_manager/minimum_version_policy_impl.cc
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/update_manager/minimum_version_policy_impl.h"
+
+#include <base/version.h>
+
+using chromeos_update_engine::ErrorCode;
+using chromeos_update_engine::InstallPlan;
+
+namespace chromeos_update_manager {
+
+EvalStatus MinimumVersionPolicyImpl::UpdateCanBeApplied(
+    EvaluationContext* ec,
+    State* state,
+    std::string* error,
+    ErrorCode* result,
+    InstallPlan* install_plan) const {
+  const base::Version* current_version(
+      ec->GetValue(state->system_provider()->var_chromeos_version()));
+  if (current_version == nullptr || !current_version->IsValid()) {
+    LOG(WARNING) << "Unable to access current version";
+    return EvalStatus::kContinue;
+  }
+
+  const base::Version* minimum_version = ec->GetValue(
+      state->device_policy_provider()->var_device_minimum_version());
+  if (minimum_version == nullptr || !minimum_version->IsValid()) {
+    LOG(WARNING) << "Unable to access minimum version";
+    return EvalStatus::kContinue;
+  }
+
+  if (*current_version < *minimum_version) {
+    LOG(INFO) << "Updating from version less than minimum required"
+                 ", allowing update to be applied.";
+    *result = ErrorCode::kSuccess;
+    return EvalStatus::kSucceeded;
+  }
+
+  return EvalStatus::kContinue;
+}
+
+}  // namespace chromeos_update_manager
diff --git a/update_manager/minimum_version_policy_impl.h b/update_manager/minimum_version_policy_impl.h
new file mode 100644
index 0000000..600d624
--- /dev/null
+++ b/update_manager/minimum_version_policy_impl.h
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_UPDATE_MANAGER_MINIMUM_VERSION_POLICY_IMPL_H_
+#define UPDATE_ENGINE_UPDATE_MANAGER_MINIMUM_VERSION_POLICY_IMPL_H_
+
+#include <string>
+
+#include "update_engine/common/error_code.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/update_manager/policy_utils.h"
+
+namespace chromeos_update_manager {
+
+// Check to see if an update happens from a version less than the minimum
+// required one.
+class MinimumVersionPolicyImpl : public PolicyImplBase {
+ public:
+  MinimumVersionPolicyImpl() = default;
+  ~MinimumVersionPolicyImpl() override = default;
+
+  // If current version is less than the minimum required one, then this should
+  // not block the update to be applied.
+  EvalStatus UpdateCanBeApplied(
+      EvaluationContext* ec,
+      State* state,
+      std::string* error,
+      chromeos_update_engine::ErrorCode* result,
+      chromeos_update_engine::InstallPlan* install_plan) const override;
+
+ protected:
+  std::string PolicyName() const override { return "MinimumVersionPolicyImpl"; }
+
+ private:
+  MinimumVersionPolicyImpl(const MinimumVersionPolicyImpl&) = delete;
+  MinimumVersionPolicyImpl& operator=(const MinimumVersionPolicyImpl&) = delete;
+};
+
+}  // namespace chromeos_update_manager
+
+#endif  // UPDATE_ENGINE_UPDATE_MANAGER_MINIMUM_VERSION_POLICY_IMPL_H_
diff --git a/update_manager/minimum_version_policy_impl_unittest.cc b/update_manager/minimum_version_policy_impl_unittest.cc
new file mode 100644
index 0000000..8e4dba5
--- /dev/null
+++ b/update_manager/minimum_version_policy_impl_unittest.cc
@@ -0,0 +1,111 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <memory>
+
+#include "update_engine/update_manager/minimum_version_policy_impl.h"
+#include "update_engine/update_manager/policy_test_utils.h"
+
+using chromeos_update_engine::ErrorCode;
+using chromeos_update_engine::InstallPlan;
+
+namespace {
+
+const char* kInvalidVersion = "13315.woops.12";
+const char* kOldVersion = "13315.60.12";
+const char* kNewVersion = "13315.60.15";
+
+}  // namespace
+
+namespace chromeos_update_manager {
+
+class UmMinimumVersionPolicyImplTest : public UmPolicyTestBase {
+ protected:
+  UmMinimumVersionPolicyImplTest() {
+    policy_ = std::make_unique<MinimumVersionPolicyImpl>();
+  }
+
+  void SetCurrentVersion(const std::string& version) {
+    fake_state_.system_provider()->var_chromeos_version()->reset(
+        new base::Version(version));
+  }
+
+  void SetMinimumVersion(const std::string& version) {
+    fake_state_.device_policy_provider()->var_device_minimum_version()->reset(
+        new base::Version(version));
+  }
+
+  void TestPolicy(const EvalStatus& expected_status) {
+    InstallPlan install_plan;
+    ErrorCode result;
+    ExpectPolicyStatus(
+        expected_status, &Policy::UpdateCanBeApplied, &result, &install_plan);
+    if (expected_status == EvalStatus::kSucceeded)
+      EXPECT_EQ(result, ErrorCode::kSuccess);
+  }
+};
+
+TEST_F(UmMinimumVersionPolicyImplTest, ContinueWhenCurrentVersionIsNotSet) {
+  SetMinimumVersion(kNewVersion);
+
+  TestPolicy(EvalStatus::kContinue);
+}
+
+TEST_F(UmMinimumVersionPolicyImplTest, ContinueWhenCurrentVersionIsInvalid) {
+  SetCurrentVersion(kInvalidVersion);
+  SetMinimumVersion(kNewVersion);
+
+  TestPolicy(EvalStatus::kContinue);
+}
+
+TEST_F(UmMinimumVersionPolicyImplTest, ContinueWhenMinumumVersionIsNotSet) {
+  SetCurrentVersion(kOldVersion);
+
+  TestPolicy(EvalStatus::kContinue);
+}
+
+TEST_F(UmMinimumVersionPolicyImplTest, ContinueWhenMinumumVersionIsInvalid) {
+  SetCurrentVersion(kOldVersion);
+  SetMinimumVersion(kInvalidVersion);
+
+  TestPolicy(EvalStatus::kContinue);
+}
+
+TEST_F(UmMinimumVersionPolicyImplTest,
+       ContinueWhenCurrentVersionIsGreaterThanMinimumVersion) {
+  SetCurrentVersion(kNewVersion);
+  SetMinimumVersion(kOldVersion);
+
+  TestPolicy(EvalStatus::kContinue);
+}
+
+TEST_F(UmMinimumVersionPolicyImplTest,
+       ContinueWhenCurrentVersionIsEqualToMinimumVersion) {
+  SetCurrentVersion(kNewVersion);
+  SetMinimumVersion(kNewVersion);
+
+  TestPolicy(EvalStatus::kContinue);
+}
+
+TEST_F(UmMinimumVersionPolicyImplTest,
+       SuccessWhenCurrentVersionIsLessThanMinimumVersion) {
+  SetCurrentVersion(kOldVersion);
+  SetMinimumVersion(kNewVersion);
+
+  TestPolicy(EvalStatus::kSucceeded);
+}
+
+}  // namespace chromeos_update_manager
diff --git a/update_manager/mock_policy.h b/update_manager/mock_policy.h
index 46b6c78..3c6313f 100644
--- a/update_manager/mock_policy.h
+++ b/update_manager/mock_policy.h
@@ -29,8 +29,7 @@
 // A mocked implementation of Policy.
 class MockPolicy : public Policy {
  public:
-  explicit MockPolicy(chromeos_update_engine::ClockInterface* clock)
-      : default_policy_(clock) {
+  MockPolicy() {
     // We defer to the corresponding DefaultPolicy methods, by default.
     ON_CALL(*this,
             UpdateCheckAllowed(testing::_, testing::_, testing::_, testing::_))
@@ -46,11 +45,6 @@
                 testing::_, testing::_, testing::_, testing::_, testing::_))
         .WillByDefault(
             testing::Invoke(&default_policy_, &DefaultPolicy::UpdateCanStart));
-    ON_CALL(
-        *this,
-        UpdateDownloadAllowed(testing::_, testing::_, testing::_, testing::_))
-        .WillByDefault(testing::Invoke(&default_policy_,
-                                       &DefaultPolicy::UpdateDownloadAllowed));
     ON_CALL(*this, P2PEnabled(testing::_, testing::_, testing::_, testing::_))
         .WillByDefault(
             testing::Invoke(&default_policy_, &DefaultPolicy::P2PEnabled));
@@ -60,8 +54,6 @@
         .WillByDefault(testing::Invoke(&default_policy_,
                                        &DefaultPolicy::P2PEnabledChanged));
   }
-
-  MockPolicy() : MockPolicy(nullptr) {}
   ~MockPolicy() override {}
 
   // Policy overrides.
diff --git a/update_manager/mock_update_manager.h b/update_manager/mock_update_manager.h
index 07e4689..06e17d8 100644
--- a/update_manager/mock_update_manager.h
+++ b/update_manager/mock_update_manager.h
@@ -28,7 +28,7 @@
 class MockUpdateManager : public UpdateManager {
  public:
   MockUpdateManager()
-      : UpdateManager(nullptr, base::TimeDelta(), base::TimeDelta(), nullptr) {}
+      : UpdateManager(base::TimeDelta(), base::TimeDelta(), nullptr) {}
 
   MOCK_METHOD2(
       AsyncPolicyRequestUpdateCheckAllowed,
diff --git a/update_manager/next_update_check_policy_impl_unittest.cc b/update_manager/next_update_check_policy_impl_unittest.cc
index 58aff66..d80063d 100644
--- a/update_manager/next_update_check_policy_impl_unittest.cc
+++ b/update_manager/next_update_check_policy_impl_unittest.cc
@@ -52,14 +52,14 @@
   // Set the last update time so it'll appear as if this is a first update check
   // in the lifetime of the current updater.
   fake_state_.updater_provider()->var_last_checked_time()->reset(
-      new Time(fake_clock_.GetWallclockTime() - TimeDelta::FromMinutes(10)));
+      new Time(fake_clock_->GetWallclockTime() - TimeDelta::FromMinutes(10)));
 
   CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
                         &next_update_check,
                         policy_test_constants);
 
-  EXPECT_LE(fake_clock_.GetWallclockTime(), next_update_check);
-  EXPECT_GE(fake_clock_.GetWallclockTime() +
+  EXPECT_LE(fake_clock_->GetWallclockTime(), next_update_check);
+  EXPECT_GE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(
                     policy_test_constants.timeout_initial_interval +
                     policy_test_constants.timeout_regular_fuzz / 2),
@@ -75,12 +75,12 @@
                         &next_update_check,
                         policy_test_constants);
 
-  EXPECT_LE(fake_clock_.GetWallclockTime() +
+  EXPECT_LE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(
                     policy_test_constants.timeout_periodic_interval -
                     policy_test_constants.timeout_regular_fuzz / 2),
             next_update_check);
-  EXPECT_GE(fake_clock_.GetWallclockTime() +
+  EXPECT_GE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(
                     policy_test_constants.timeout_periodic_interval +
                     policy_test_constants.timeout_regular_fuzz / 2),
@@ -103,11 +103,11 @@
 
   int expected_interval = policy_test_constants.timeout_periodic_interval * 4;
   EXPECT_LE(
-      fake_clock_.GetWallclockTime() +
+      fake_clock_->GetWallclockTime() +
           TimeDelta::FromSeconds(expected_interval - expected_interval / 2),
       next_update_check);
   EXPECT_GE(
-      fake_clock_.GetWallclockTime() +
+      fake_clock_->GetWallclockTime() +
           TimeDelta::FromSeconds(expected_interval + expected_interval / 2),
       next_update_check);
 }
@@ -129,10 +129,10 @@
                &next_update_check,
                policy_test_constants);
 
-  EXPECT_LE(fake_clock_.GetWallclockTime() +
+  EXPECT_LE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(kInterval - kInterval / 2),
             next_update_check);
-  EXPECT_GE(fake_clock_.GetWallclockTime() +
+  EXPECT_GE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(kInterval + kInterval / 2),
             next_update_check);
 }
@@ -148,12 +148,12 @@
                &next_update_check,
                policy_test_constants);
 
-  EXPECT_LE(fake_clock_.GetWallclockTime() +
+  EXPECT_LE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(
                     policy_test_constants.timeout_max_backoff_interval -
                     policy_test_constants.timeout_max_backoff_interval / 2),
             next_update_check);
-  EXPECT_GE(fake_clock_.GetWallclockTime() +
+  EXPECT_GE(fake_clock_->GetWallclockTime() +
                 TimeDelta::FromSeconds(
                     policy_test_constants.timeout_max_backoff_interval +
                     policy_test_constants.timeout_max_backoff_interval / 2),
diff --git a/update_manager/policy.h b/update_manager/policy.h
index ad6994c..fb4a129 100644
--- a/update_manager/policy.h
+++ b/update_manager/policy.h
@@ -66,6 +66,9 @@
   std::string target_channel;
   // Specifies if the channel hint, e.g. LTS (Long Term Support) updates.
   std::string lts_tag;
+  // Specifies a token which maps to a Chrome OS Quick Fix Build, if imposed by
+  // policy; otherwise, an empty string.
+  std::string quick_fix_build_token;
 
   // Whether the allowed update is interactive (user-initiated) or periodic.
   bool interactive{false};
@@ -227,9 +230,6 @@
     if (reinterpret_cast<typeof(&Policy::UpdateCanStart)>(policy_method) ==
         &Policy::UpdateCanStart)
       return class_name + "UpdateCanStart";
-    if (reinterpret_cast<typeof(&Policy::UpdateDownloadAllowed)>(
-            policy_method) == &Policy::UpdateDownloadAllowed)
-      return class_name + "UpdateDownloadAllowed";
     if (reinterpret_cast<typeof(&Policy::P2PEnabled)>(policy_method) ==
         &Policy::P2PEnabled)
       return class_name + "P2PEnabled";
@@ -278,17 +278,6 @@
                                     UpdateDownloadParams* result,
                                     UpdateState update_state) const = 0;
 
-  // Checks whether downloading of an update is allowed; currently, this checks
-  // whether the network connection type is suitable for updating over.  May
-  // consult the shill provider as well as the device policy (if available).
-  // Returns |EvalStatus::kSucceeded|, setting |result| according to whether or
-  // not the current connection can be used; on error, returns
-  // |EvalStatus::kFailed| and sets |error| accordingly.
-  virtual EvalStatus UpdateDownloadAllowed(EvaluationContext* ec,
-                                           State* state,
-                                           std::string* error,
-                                           bool* result) const = 0;
-
   // Checks whether P2P is enabled. This may consult device policy and other
   // global settings.
   virtual EvalStatus P2PEnabled(EvaluationContext* ec,
@@ -317,9 +306,7 @@
   DISALLOW_COPY_AND_ASSIGN(Policy);
 };
 
-// Get system dependent (Chrome OS vs. Android) policy
-// implementation. Implementations can be found in chromeos_policy.cc and
-// android_things_policy.cc.
+// Get system dependent policy implementation.
 std::unique_ptr<Policy> GetSystemPolicy();
 
 }  // namespace chromeos_update_manager
diff --git a/update_manager/policy_test_utils.cc b/update_manager/policy_test_utils.cc
index 653592a..e8961b1 100644
--- a/update_manager/policy_test_utils.cc
+++ b/update_manager/policy_test_utils.cc
@@ -20,11 +20,13 @@
 #include <tuple>
 #include <vector>
 
+#include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/next_update_check_policy_impl.h"
 
 using base::Time;
 using base::TimeDelta;
 using chromeos_update_engine::ErrorCode;
+using chromeos_update_engine::FakeSystemState;
 using std::string;
 using std::tuple;
 using std::vector;
@@ -33,9 +35,10 @@
 
 void UmPolicyTestBase::SetUp() {
   loop_.SetAsCurrent();
+  FakeSystemState::CreateInstance();
+  fake_clock_ = FakeSystemState::Get()->fake_clock();
   SetUpDefaultClock();
-  eval_ctx_.reset(
-      new EvaluationContext(&fake_clock_, TimeDelta::FromSeconds(5)));
+  eval_ctx_.reset(new EvaluationContext(TimeDelta::FromSeconds(5)));
   SetUpDefaultState();
 }
 
@@ -45,12 +48,12 @@
 
 // Sets the clock to fixed values.
 void UmPolicyTestBase::SetUpDefaultClock() {
-  fake_clock_.SetMonotonicTime(Time::FromInternalValue(12345678L));
-  fake_clock_.SetWallclockTime(Time::FromInternalValue(12345678901234L));
+  fake_clock_->SetMonotonicTime(Time::FromInternalValue(12345678L));
+  fake_clock_->SetWallclockTime(Time::FromInternalValue(12345678901234L));
 }
 
 void UmPolicyTestBase::SetUpDefaultTimeProvider() {
-  Time current_time = fake_clock_.GetWallclockTime();
+  Time current_time = FakeSystemState::Get()->clock()->GetWallclockTime();
   base::Time::Exploded exploded;
   current_time.LocalExplode(&exploded);
   fake_state_.time_provider()->var_curr_hour()->reset(new int(exploded.hour));
@@ -62,9 +65,9 @@
 
 void UmPolicyTestBase::SetUpDefaultState() {
   fake_state_.updater_provider()->var_updater_started_time()->reset(
-      new Time(fake_clock_.GetWallclockTime()));
+      new Time(fake_clock_->GetWallclockTime()));
   fake_state_.updater_provider()->var_last_checked_time()->reset(
-      new Time(fake_clock_.GetWallclockTime()));
+      new Time(fake_clock_->GetWallclockTime()));
   fake_state_.updater_provider()->var_consecutive_failed_update_checks()->reset(
       new unsigned int(0));  // NOLINT(readability/casting)
   fake_state_.updater_provider()->var_server_dictated_poll_interval()->reset(
@@ -79,7 +82,8 @@
 // Returns a default UpdateState structure:
 UpdateState UmPolicyTestBase::GetDefaultUpdateState(
     TimeDelta first_seen_period) {
-  Time first_seen_time = fake_clock_.GetWallclockTime() - first_seen_period;
+  Time first_seen_time =
+      FakeSystemState::Get()->clock()->GetWallclockTime() - first_seen_period;
   UpdateState update_state = UpdateState();
 
   // This is a non-interactive check returning a delta payload, seen for the
diff --git a/update_manager/policy_test_utils.h b/update_manager/policy_test_utils.h
index cd94907..72bd3bc 100644
--- a/update_manager/policy_test_utils.h
+++ b/update_manager/policy_test_utils.h
@@ -91,7 +91,7 @@
   }
 
   brillo::FakeMessageLoop loop_{nullptr};
-  chromeos_update_engine::FakeClock fake_clock_;
+  chromeos_update_engine::FakeClock* fake_clock_;
   FakeState fake_state_;
   std::shared_ptr<EvaluationContext> eval_ctx_;
   std::unique_ptr<Policy> policy_;
diff --git a/update_manager/policy_utils.h b/update_manager/policy_utils.h
index dc606f2..aedb90c 100644
--- a/update_manager/policy_utils.h
+++ b/update_manager/policy_utils.h
@@ -92,13 +92,6 @@
     return EvalStatus::kContinue;
   };
 
-  EvalStatus UpdateDownloadAllowed(EvaluationContext* ec,
-                                   State* state,
-                                   std::string* error,
-                                   bool* result) const override {
-    return EvalStatus::kContinue;
-  };
-
   EvalStatus P2PEnabled(EvaluationContext* ec,
                         State* state,
                         std::string* error,
diff --git a/update_manager/real_device_policy_provider.cc b/update_manager/real_device_policy_provider.cc
index 05091d9..e7b964b 100644
--- a/update_manager/real_device_policy_provider.cc
+++ b/update_manager/real_device_policy_provider.cc
@@ -266,6 +266,8 @@
                  &RealDevicePolicyProvider::ConvertChannelDowngradeBehavior);
   UpdateVariable(&var_device_minimum_version_,
                  &DevicePolicy::GetHighestDeviceMinimumVersion);
+  UpdateVariable(&var_quick_fix_build_token_,
+                 &DevicePolicy::GetDeviceQuickFixBuildToken);
 }
 
 }  // namespace chromeos_update_manager
diff --git a/update_manager/real_device_policy_provider.h b/update_manager/real_device_policy_provider.h
index ebda8fd..0f84b77 100644
--- a/update_manager/real_device_policy_provider.h
+++ b/update_manager/real_device_policy_provider.h
@@ -122,6 +122,10 @@
     return &var_device_minimum_version_;
   }
 
+  Variable<std::string>* var_quick_fix_build_token() override {
+    return &var_quick_fix_build_token_;
+  }
+
  private:
   FRIEND_TEST(UmRealDevicePolicyProviderTest, RefreshScheduledTest);
   FRIEND_TEST(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded);
@@ -234,6 +238,8 @@
       "channel_downgrade_behavior"};
   AsyncCopyVariable<base::Version> var_device_minimum_version_{
       "device_minimum_version"};
+  AsyncCopyVariable<std::string> var_quick_fix_build_token_{
+      "quick_fix_build_token"};
 
   DISALLOW_COPY_AND_ASSIGN(RealDevicePolicyProvider);
 };
diff --git a/update_manager/real_device_policy_provider_unittest.cc b/update_manager/real_device_policy_provider_unittest.cc
index 32396d6..fd55859 100644
--- a/update_manager/real_device_policy_provider_unittest.cc
+++ b/update_manager/real_device_policy_provider_unittest.cc
@@ -197,6 +197,7 @@
   UmTestUtils::ExpectVariableNotSet(provider_->var_disallowed_time_intervals());
   UmTestUtils::ExpectVariableNotSet(
       provider_->var_channel_downgrade_behavior());
+  UmTestUtils::ExpectVariableNotSet(provider_->var_quick_fix_build_token());
 }
 
 TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) {
@@ -445,4 +446,17 @@
                                       provider_->var_device_minimum_version());
 }
 
+TEST_F(UmRealDevicePolicyProviderTest, DeviceQuickFixBuildTokenSet) {
+  SetUpExistentDevicePolicy();
+
+  EXPECT_CALL(mock_device_policy_, GetDeviceQuickFixBuildToken(_))
+      .WillRepeatedly(
+          DoAll(SetArgPointee<0>(string("some_token")), Return(true)));
+  EXPECT_TRUE(provider_->Init());
+  loop_.RunOnce(false);
+
+  UmTestUtils::ExpectVariableHasValue(string("some_token"),
+                                      provider_->var_quick_fix_build_token());
+}
+
 }  // namespace chromeos_update_manager
diff --git a/update_manager/real_shill_provider.cc b/update_manager/real_shill_provider.cc
index 0144603..4d067fd 100644
--- a/update_manager/real_shill_provider.cc
+++ b/update_manager/real_shill_provider.cc
@@ -24,6 +24,7 @@
 #include <shill/dbus-constants.h>
 #include <shill/dbus-proxies.h>
 
+using chromeos_update_engine::SystemState;
 using chromeos_update_engine::connection_utils::ParseConnectionType;
 using org::chromium::flimflam::ManagerProxyInterface;
 using org::chromium::flimflam::ServiceProxyInterface;
@@ -97,7 +98,8 @@
   bool is_connected =
       (default_service_path_.IsValid() && default_service_path_.value() != "/");
   var_is_connected_.SetValue(is_connected);
-  var_conn_last_changed_.SetValue(clock_->GetWallclockTime());
+  var_conn_last_changed_.SetValue(
+      SystemState::Get()->clock()->GetWallclockTime());
 
   if (!is_connected) {
     var_conn_type_.UnsetValue();
diff --git a/update_manager/real_shill_provider.h b/update_manager/real_shill_provider.h
index baa2cdc..cd53d92 100644
--- a/update_manager/real_shill_provider.h
+++ b/update_manager/real_shill_provider.h
@@ -27,7 +27,7 @@
 #include <base/time/time.h>
 #include <dbus/object_path.h>
 
-#include "update_engine/common/clock_interface.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/cros/shill_proxy_interface.h"
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/update_manager/shill_provider.h"
@@ -37,9 +37,9 @@
 // ShillProvider concrete implementation.
 class RealShillProvider : public ShillProvider {
  public:
-  RealShillProvider(chromeos_update_engine::ShillProxyInterface* shill_proxy,
-                    chromeos_update_engine::ClockInterface* clock)
-      : shill_proxy_(shill_proxy), clock_(clock) {}
+  explicit RealShillProvider(
+      chromeos_update_engine::ShillProxyInterface* shill_proxy)
+      : shill_proxy_(shill_proxy) {}
 
   ~RealShillProvider() override = default;
 
@@ -81,9 +81,6 @@
   // The mockable interface to access the shill DBus proxies.
   std::unique_ptr<chromeos_update_engine::ShillProxyInterface> shill_proxy_;
 
-  // A clock abstraction (mockable).
-  chromeos_update_engine::ClockInterface* const clock_;
-
   // The provider's variables.
   AsyncCopyVariable<bool> var_is_connected_{"is_connected"};
   AsyncCopyVariable<chromeos_update_engine::ConnectionType> var_conn_type_{
diff --git a/update_manager/real_shill_provider_unittest.cc b/update_manager/real_shill_provider_unittest.cc
index 682c233..9a2d8a8 100644
--- a/update_manager/real_shill_provider_unittest.cc
+++ b/update_manager/real_shill_provider_unittest.cc
@@ -27,17 +27,17 @@
 #include <shill/dbus-proxies.h>
 #include <shill/dbus-proxy-mocks.h>
 
-#include "update_engine/common/fake_clock.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/cros/dbus_test_utils.h"
 #include "update_engine/cros/fake_shill_proxy.h"
+#include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/umtest_utils.h"
 
 using base::Time;
 using base::TimeDelta;
 using chromeos_update_engine::ConnectionTethering;
 using chromeos_update_engine::ConnectionType;
-using chromeos_update_engine::FakeClock;
+using chromeos_update_engine::FakeSystemState;
 using org::chromium::flimflam::ManagerProxyMock;
 using org::chromium::flimflam::ServiceProxyMock;
 using std::unique_ptr;
@@ -63,10 +63,10 @@
  protected:
   // Initialize the RealShillProvider under test.
   void SetUp() override {
-    fake_clock_.SetWallclockTime(InitTime());
+    FakeSystemState::Get()->fake_clock()->SetWallclockTime(InitTime());
     loop_.SetAsCurrent();
     fake_shill_proxy_ = new chromeos_update_engine::FakeShillProxy();
-    provider_.reset(new RealShillProvider(fake_shill_proxy_, &fake_clock_));
+    provider_.reset(new RealShillProvider(fake_shill_proxy_));
 
     ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_->GetManagerProxy();
 
@@ -127,11 +127,12 @@
   void SendDefaultServiceSignal(const std::string& service_path,
                                 Time* conn_change_time_p) {
     const Time conn_change_time = ConnChangedTime();
-    fake_clock_.SetWallclockTime(conn_change_time);
+    FakeSystemState::Get()->fake_clock()->SetWallclockTime(conn_change_time);
     ASSERT_TRUE(manager_property_changed_.IsHandlerRegistered());
     manager_property_changed_.signal_callback().Run(
         shill::kDefaultServiceProperty, dbus::ObjectPath(service_path));
-    fake_clock_.SetWallclockTime(conn_change_time + TimeDelta::FromSeconds(5));
+    FakeSystemState::Get()->fake_clock()->SetWallclockTime(
+        conn_change_time + TimeDelta::FromSeconds(5));
     if (conn_change_time_p)
       *conn_change_time_p = conn_change_time;
   }
@@ -202,7 +203,6 @@
   }
 
   brillo::FakeMessageLoop loop_{nullptr};
-  FakeClock fake_clock_;
   chromeos_update_engine::FakeShillProxy* fake_shill_proxy_;
 
   // The registered signal handler for the signal Manager.PropertyChanged.
diff --git a/update_manager/real_system_provider.cc b/update_manager/real_system_provider.cc
index 4e88b07..34397f3 100644
--- a/update_manager/real_system_provider.cc
+++ b/update_manager/real_system_provider.cc
@@ -20,17 +20,17 @@
 #include <base/callback.h>
 #include <base/logging.h>
 #include <base/time/time.h>
-#if USE_CHROME_KIOSK_APP
 #include <kiosk-app/dbus-proxies.h>
-#endif  // USE_CHROME_KIOSK_APP
 
 #include "update_engine/common/boot_control_interface.h"
 #include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/cros/omaha_request_params.h"
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/update_manager/variable.h"
 
+using chromeos_update_engine::SystemState;
 using std::string;
 
 namespace chromeos_update_manager {
@@ -100,19 +100,20 @@
 
 bool RealSystemProvider::Init() {
   var_is_normal_boot_mode_.reset(new ConstCopyVariable<bool>(
-      "is_normal_boot_mode", system_state_->hardware()->IsNormalBootMode()));
+      "is_normal_boot_mode",
+      SystemState::Get()->hardware()->IsNormalBootMode()));
 
   var_is_official_build_.reset(new ConstCopyVariable<bool>(
-      "is_official_build", system_state_->hardware()->IsOfficialBuild()));
+      "is_official_build", SystemState::Get()->hardware()->IsOfficialBuild()));
 
   var_is_oobe_complete_.reset(new CallCopyVariable<bool>(
       "is_oobe_complete",
       base::Bind(&chromeos_update_engine::HardwareInterface::IsOOBEComplete,
-                 base::Unretained(system_state_->hardware()),
+                 base::Unretained(SystemState::Get()->hardware()),
                  nullptr)));
 
   var_num_slots_.reset(new ConstCopyVariable<unsigned int>(
-      "num_slots", system_state_->boot_control()->GetNumSlots()));
+      "num_slots", SystemState::Get()->boot_control()->GetNumSlots()));
 
   var_kiosk_required_platform_version_.reset(new RetryPollVariable<string>(
       "kiosk_required_platform_version",
@@ -122,14 +123,13 @@
 
   var_chromeos_version_.reset(new ConstCopyVariable<base::Version>(
       "chromeos_version",
-      base::Version(system_state_->request_params()->app_version())));
+      base::Version(SystemState::Get()->request_params()->app_version())));
 
   return true;
 }
 
 bool RealSystemProvider::GetKioskAppRequiredPlatformVersion(
     string* required_platform_version) {
-#if USE_CHROME_KIOSK_APP
   brillo::ErrorPtr error;
   if (!kiosk_app_proxy_->GetRequiredPlatformVersion(required_platform_version,
                                                     &error)) {
@@ -137,7 +137,6 @@
     required_platform_version->clear();
     return false;
   }
-#endif  // USE_CHROME_KIOSK_APP
 
   return true;
 }
diff --git a/update_manager/real_system_provider.h b/update_manager/real_system_provider.h
index ffa1467..558d3be 100644
--- a/update_manager/real_system_provider.h
+++ b/update_manager/real_system_provider.h
@@ -22,7 +22,6 @@
 
 #include <base/version.h>
 
-#include "update_engine/common/system_state.h"
 #include "update_engine/update_manager/system_provider.h"
 
 namespace org {
@@ -37,15 +36,8 @@
 class RealSystemProvider : public SystemProvider {
  public:
   RealSystemProvider(
-      chromeos_update_engine::SystemState* system_state,
       org::chromium::KioskAppServiceInterfaceProxyInterface* kiosk_app_proxy)
-#if USE_CHROME_KIOSK_APP
-      : system_state_(system_state), kiosk_app_proxy_(kiosk_app_proxy) {
-  }
-#else
-      system_state_(system_state) {
-  }
-#endif  // USE_CHROME_KIOSK_APP
+      : kiosk_app_proxy_(kiosk_app_proxy) {}
 
   // Initializes the provider and returns whether it succeeded.
   bool Init();
@@ -85,10 +77,7 @@
   std::unique_ptr<Variable<std::string>> var_kiosk_required_platform_version_;
   std::unique_ptr<Variable<base::Version>> var_chromeos_version_;
 
-  chromeos_update_engine::SystemState* const system_state_;
-#if USE_CHROME_KIOSK_APP
   org::chromium::KioskAppServiceInterfaceProxyInterface* const kiosk_app_proxy_;
-#endif  // USE_CHROME_KIOSK_APP
 
   DISALLOW_COPY_AND_ASSIGN(RealSystemProvider);
 };
diff --git a/update_manager/real_system_provider_unittest.cc b/update_manager/real_system_provider_unittest.cc
index 8add690..9abcad0 100644
--- a/update_manager/real_system_provider_unittest.cc
+++ b/update_manager/real_system_provider_unittest.cc
@@ -21,54 +21,44 @@
 #include <base/time/time.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <kiosk-app/dbus-proxies.h>
+#include <kiosk-app/dbus-proxy-mocks.h>
 
 #include "update_engine/common/fake_boot_control.h"
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/umtest_utils.h"
-#if USE_CHROME_KIOSK_APP
-#include "kiosk-app/dbus-proxies.h"
-#include "kiosk-app/dbus-proxy-mocks.h"
 
+using chromeos_update_engine::FakeSystemState;
 using org::chromium::KioskAppServiceInterfaceProxyMock;
-#endif  // USE_CHROME_KIOSK_APP
 using std::unique_ptr;
 using testing::_;
 using testing::DoAll;
 using testing::Return;
 using testing::SetArgPointee;
 
-#if USE_CHROME_KIOSK_APP
 namespace {
 const char kRequiredPlatformVersion[] = "1234.0.0";
 }  // namespace
-#endif  // USE_CHROME_KIOSK_APP
 
 namespace chromeos_update_manager {
 
 class UmRealSystemProviderTest : public ::testing::Test {
  protected:
   void SetUp() override {
-#if USE_CHROME_KIOSK_APP
+    FakeSystemState::CreateInstance();
     kiosk_app_proxy_mock_.reset(new KioskAppServiceInterfaceProxyMock());
     ON_CALL(*kiosk_app_proxy_mock_, GetRequiredPlatformVersion(_, _, _))
         .WillByDefault(
             DoAll(SetArgPointee<0>(kRequiredPlatformVersion), Return(true)));
 
-    provider_.reset(new RealSystemProvider(&fake_system_state_,
-                                           kiosk_app_proxy_mock_.get()));
-#else
-    provider_.reset(new RealSystemProvider(&fake_system_state, nullptr));
-#endif  // USE_CHROME_KIOSK_APP
+    provider_.reset(new RealSystemProvider(kiosk_app_proxy_mock_.get()));
     EXPECT_TRUE(provider_->Init());
   }
 
-  chromeos_update_engine::FakeSystemState fake_system_state_;
   unique_ptr<RealSystemProvider> provider_;
 
-#if USE_CHROME_KIOSK_APP
   unique_ptr<KioskAppServiceInterfaceProxyMock> kiosk_app_proxy_mock_;
-#endif  // USE_CHROME_KIOSK_APP
 };
 
 TEST_F(UmRealSystemProviderTest, InitTest) {
@@ -80,17 +70,17 @@
 }
 
 TEST_F(UmRealSystemProviderTest, IsOOBECompleteTrue) {
-  fake_system_state_.fake_hardware()->SetIsOOBEComplete(base::Time());
+  FakeSystemState::Get()->fake_hardware()->SetIsOOBEComplete(base::Time());
   UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_oobe_complete());
 }
 
 TEST_F(UmRealSystemProviderTest, IsOOBECompleteFalse) {
-  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
+  FakeSystemState::Get()->fake_hardware()->UnsetIsOOBEComplete();
   UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_oobe_complete());
 }
 
 TEST_F(UmRealSystemProviderTest, VersionFromRequestParams) {
-  fake_system_state_.request_params()->set_app_version("1.2.3");
+  FakeSystemState::Get()->request_params()->set_app_version("1.2.3");
   // Call |Init| again to pick up the version.
   EXPECT_TRUE(provider_->Init());
 
@@ -99,7 +89,6 @@
                                       provider_->var_chromeos_version());
 }
 
-#if USE_CHROME_KIOSK_APP
 TEST_F(UmRealSystemProviderTest, KioskRequiredPlatformVersion) {
   UmTestUtils::ExpectVariableHasValue(
       std::string(kRequiredPlatformVersion),
@@ -145,11 +134,5 @@
   UmTestUtils::ExpectVariableHasValue(
       std::string(""), provider_->var_kiosk_required_platform_version());
 }
-#else
-TEST_F(UmRealSystemProviderTest, KioskRequiredPlatformVersion) {
-  UmTestUtils::ExpectVariableHasValue(
-      std::string(), provider_->var_kiosk_required_platform_version());
-}
-#endif  // USE_CHROME_KIOSK_APP
 
 }  // namespace chromeos_update_manager
diff --git a/update_manager/real_time_provider.cc b/update_manager/real_time_provider.cc
index efd1747..2b71fa0 100644
--- a/update_manager/real_time_provider.cc
+++ b/update_manager/real_time_provider.cc
@@ -20,11 +20,11 @@
 
 #include <base/time/time.h>
 
-#include "update_engine/common/clock_interface.h"
+#include "update_engine/common/system_state.h"
 
 using base::Time;
 using base::TimeDelta;
-using chromeos_update_engine::ClockInterface;
+using chromeos_update_engine::SystemState;
 using std::string;
 
 namespace chromeos_update_manager {
@@ -34,13 +34,13 @@
  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) {}
+  explicit CurrDateVariable(const string& name)
+      : Variable<Time>(name, TimeDelta::FromHours(1)) {}
 
  protected:
   virtual const Time* GetValue(TimeDelta /* timeout */, string* /* errmsg */) {
     Time::Exploded now_exp;
-    clock_->GetWallclockTime().LocalExplode(&now_exp);
+    SystemState::Get()->clock()->GetWallclockTime().LocalExplode(&now_exp);
     now_exp.hour = now_exp.minute = now_exp.second = now_exp.millisecond = 0;
     Time* now = new Time();
     bool success = Time::FromLocalExploded(now_exp, now);
@@ -49,8 +49,6 @@
   }
 
  private:
-  ClockInterface* clock_;
-
   DISALLOW_COPY_AND_ASSIGN(CurrDateVariable);
 };
 
@@ -59,44 +57,40 @@
  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) {}
+  explicit CurrHourVariable(const string& name)
+      : Variable<int>(name, TimeDelta::FromMinutes(5)) {}
 
  protected:
   virtual const int* GetValue(TimeDelta /* timeout */, string* /* errmsg */) {
     Time::Exploded exploded;
-    clock_->GetWallclockTime().LocalExplode(&exploded);
+    SystemState::Get()->clock()->GetWallclockTime().LocalExplode(&exploded);
     return new int(exploded.hour);
   }
 
  private:
-  ClockInterface* clock_;
-
   DISALLOW_COPY_AND_ASSIGN(CurrHourVariable);
 };
 
 class CurrMinuteVariable : public Variable<int> {
  public:
-  CurrMinuteVariable(const string& name, ClockInterface* clock)
-      : Variable<int>(name, TimeDelta::FromSeconds(15)), clock_(clock) {}
+  explicit CurrMinuteVariable(const string& name)
+      : Variable<int>(name, TimeDelta::FromSeconds(15)) {}
 
  protected:
   virtual const int* GetValue(TimeDelta /* timeout */, string* /* errmsg */) {
     Time::Exploded exploded;
-    clock_->GetWallclockTime().LocalExplode(&exploded);
+    SystemState::Get()->clock()->GetWallclockTime().LocalExplode(&exploded);
     return new int(exploded.minute);
   }
 
  private:
-  ClockInterface* clock_;
-
   DISALLOW_COPY_AND_ASSIGN(CurrMinuteVariable);
 };
 
 bool RealTimeProvider::Init() {
-  var_curr_date_.reset(new CurrDateVariable("curr_date", clock_));
-  var_curr_hour_.reset(new CurrHourVariable("curr_hour", clock_));
-  var_curr_minute_.reset(new CurrMinuteVariable("curr_minute", clock_));
+  var_curr_date_.reset(new CurrDateVariable("curr_date"));
+  var_curr_hour_.reset(new CurrHourVariable("curr_hour"));
+  var_curr_minute_.reset(new CurrMinuteVariable("curr_minute"));
   return true;
 }
 
diff --git a/update_manager/real_time_provider.h b/update_manager/real_time_provider.h
index 40dab36..58b0fa5 100644
--- a/update_manager/real_time_provider.h
+++ b/update_manager/real_time_provider.h
@@ -21,7 +21,6 @@
 
 #include <base/time/time.h>
 
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/update_manager/time_provider.h"
 
 namespace chromeos_update_manager {
@@ -29,8 +28,7 @@
 // TimeProvider concrete implementation.
 class RealTimeProvider : public TimeProvider {
  public:
-  explicit RealTimeProvider(chromeos_update_engine::ClockInterface* clock)
-      : clock_(clock) {}
+  RealTimeProvider() = default;
 
   // Initializes the provider and returns whether it succeeded.
   bool Init();
@@ -44,9 +42,6 @@
   Variable<int>* var_curr_minute() override { return var_curr_minute_.get(); }
 
  private:
-  // A clock abstraction (fakeable).
-  chromeos_update_engine::ClockInterface* const clock_;
-
   std::unique_ptr<Variable<base::Time>> var_curr_date_;
   std::unique_ptr<Variable<int>> var_curr_hour_;
   std::unique_ptr<Variable<int>> var_curr_minute_;
diff --git a/update_manager/real_time_provider_unittest.cc b/update_manager/real_time_provider_unittest.cc
index ce2a718..f8ed0d2 100644
--- a/update_manager/real_time_provider_unittest.cc
+++ b/update_manager/real_time_provider_unittest.cc
@@ -22,11 +22,11 @@
 #include <base/time/time.h>
 #include <gtest/gtest.h>
 
-#include "update_engine/common/fake_clock.h"
+#include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/umtest_utils.h"
 
 using base::Time;
-using chromeos_update_engine::FakeClock;
+using chromeos_update_engine::FakeSystemState;
 using std::unique_ptr;
 
 namespace chromeos_update_manager {
@@ -34,8 +34,9 @@
 class UmRealTimeProviderTest : public ::testing::Test {
  protected:
   void SetUp() override {
+    FakeSystemState::CreateInstance();
     // The provider initializes correctly.
-    provider_.reset(new RealTimeProvider(&fake_clock_));
+    provider_.reset(new RealTimeProvider());
     ASSERT_NE(nullptr, provider_.get());
     ASSERT_TRUE(provider_->Init());
   }
@@ -56,7 +57,6 @@
     return time;
   }
 
-  FakeClock fake_clock_;
   unique_ptr<RealTimeProvider> provider_;
 };
 
@@ -71,7 +71,7 @@
   Time expected;
   ignore_result(Time::FromLocalExploded(exploded, &expected));
 
-  fake_clock_.SetWallclockTime(now);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(now);
   UmTestUtils::ExpectVariableHasValue(expected, provider_->var_curr_date());
 }
 
@@ -79,7 +79,7 @@
   const Time now = CurrTime();
   Time::Exploded expected;
   now.LocalExplode(&expected);
-  fake_clock_.SetWallclockTime(now);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(now);
   UmTestUtils::ExpectVariableHasValue(expected.hour,
                                       provider_->var_curr_hour());
 }
@@ -88,7 +88,7 @@
   const Time now = CurrTime();
   Time::Exploded expected;
   now.LocalExplode(&expected);
-  fake_clock_.SetWallclockTime(now);
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(now);
   UmTestUtils::ExpectVariableHasValue(expected.minute,
                                       provider_->var_curr_minute());
 }
diff --git a/update_manager/real_updater_provider.cc b/update_manager/real_updater_provider.cc
index e975b80..5b76332 100644
--- a/update_manager/real_updater_provider.cc
+++ b/update_manager/real_updater_provider.cc
@@ -27,8 +27,8 @@
 #include <update_engine/dbus-constants.h>
 
 #include "update_engine/client_library/include/update_engine/update_status.h"
-#include "update_engine/common/clock_interface.h"
 #include "update_engine/common/prefs.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/cros/omaha_request_params.h"
 #include "update_engine/cros/update_attempter.h"
 #include "update_engine/update_status_utils.h"
@@ -49,25 +49,16 @@
 template <typename T>
 class UpdaterVariableBase : public Variable<T> {
  public:
-  UpdaterVariableBase(const string& name,
-                      VariableMode mode,
-                      SystemState* system_state)
-      : Variable<T>(name, mode), system_state_(system_state) {}
-
- protected:
-  // The system state used for pulling information from the updater.
-  inline SystemState* system_state() const { return system_state_; }
-
- private:
-  SystemState* const system_state_;
+  UpdaterVariableBase(const string& name, VariableMode mode)
+      : Variable<T>(name, mode) {}
 };
 
 // Helper class for issuing a GetStatus() to the UpdateAttempter.
 class GetStatusHelper {
  public:
-  GetStatusHelper(SystemState* system_state, string* errmsg) {
-    is_success_ =
-        system_state->update_attempter()->GetStatus(&update_engine_status_);
+  explicit GetStatusHelper(string* errmsg) {
+    is_success_ = SystemState::Get()->update_attempter()->GetStatus(
+        &update_engine_status_);
     if (!is_success_ && errmsg) {
       *errmsg = "Failed to get a status update from the update engine";
     }
@@ -97,12 +88,12 @@
 // A variable reporting the time when a last update check was issued.
 class LastCheckedTimeVariable : public UpdaterVariableBase<Time> {
  public:
-  LastCheckedTimeVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {}
+  explicit LastCheckedTimeVariable(const string& name)
+      : UpdaterVariableBase<Time>(name, kVariableModePoll) {}
 
  private:
   const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
-    GetStatusHelper raw(system_state(), errmsg);
+    GetStatusHelper raw(errmsg);
     if (!raw.is_success())
       return nullptr;
 
@@ -116,12 +107,12 @@
 // between 0.0 and 1.0.
 class ProgressVariable : public UpdaterVariableBase<double> {
  public:
-  ProgressVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<double>(name, kVariableModePoll, system_state) {}
+  explicit ProgressVariable(const string& name)
+      : UpdaterVariableBase<double>(name, kVariableModePoll) {}
 
  private:
   const double* GetValue(TimeDelta /* timeout */, string* errmsg) override {
-    GetStatusHelper raw(system_state(), errmsg);
+    GetStatusHelper raw(errmsg);
     if (!raw.is_success())
       return nullptr;
 
@@ -142,8 +133,8 @@
 // A variable reporting the stage in which the update process is.
 class StageVariable : public UpdaterVariableBase<Stage> {
  public:
-  StageVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<Stage>(name, kVariableModePoll, system_state) {}
+  explicit StageVariable(const string& name)
+      : UpdaterVariableBase<Stage>(name, kVariableModePoll) {}
 
  private:
   struct CurrOpStrToStage {
@@ -175,7 +166,7 @@
 };
 
 const Stage* StageVariable::GetValue(TimeDelta /* timeout */, string* errmsg) {
-  GetStatusHelper raw(system_state(), errmsg);
+  GetStatusHelper raw(errmsg);
   if (!raw.is_success())
     return nullptr;
 
@@ -191,12 +182,12 @@
 // A variable reporting the version number that an update is updating to.
 class NewVersionVariable : public UpdaterVariableBase<string> {
  public:
-  NewVersionVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
+  explicit NewVersionVariable(const string& name)
+      : UpdaterVariableBase<string>(name, kVariableModePoll) {}
 
  private:
   const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
-    GetStatusHelper raw(system_state(), errmsg);
+    GetStatusHelper raw(errmsg);
     if (!raw.is_success())
       return nullptr;
 
@@ -209,12 +200,12 @@
 // A variable reporting the size of the update being processed in bytes.
 class PayloadSizeVariable : public UpdaterVariableBase<uint64_t> {
  public:
-  PayloadSizeVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<uint64_t>(name, kVariableModePoll, system_state) {}
+  explicit PayloadSizeVariable(const string& name)
+      : UpdaterVariableBase<uint64_t>(name, kVariableModePoll) {}
 
  private:
   const uint64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
-    GetStatusHelper raw(system_state(), errmsg);
+    GetStatusHelper raw(errmsg);
     if (!raw.is_success())
       return nullptr;
 
@@ -233,20 +224,20 @@
 // policy request.
 class UpdateCompletedTimeVariable : public UpdaterVariableBase<Time> {
  public:
-  UpdateCompletedTimeVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {}
+  explicit UpdateCompletedTimeVariable(const string& name)
+      : UpdaterVariableBase<Time>(name, kVariableModePoll) {}
 
  private:
   const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
     Time update_boottime;
-    if (!system_state()->update_attempter()->GetBootTimeAtUpdate(
+    if (!SystemState::Get()->update_attempter()->GetBootTimeAtUpdate(
             &update_boottime)) {
       if (errmsg)
         *errmsg = "Update completed time could not be read";
       return nullptr;
     }
 
-    chromeos_update_engine::ClockInterface* clock = system_state()->clock();
+    const auto* clock = SystemState::Get()->clock();
     Time curr_boottime = clock->GetBootTime();
     if (curr_boottime < update_boottime) {
       if (errmsg)
@@ -263,12 +254,12 @@
 // Variables reporting the current image channel.
 class CurrChannelVariable : public UpdaterVariableBase<string> {
  public:
-  CurrChannelVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
+  explicit CurrChannelVariable(const string& name)
+      : UpdaterVariableBase<string>(name, kVariableModePoll) {}
 
  private:
   const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
-    OmahaRequestParams* request_params = system_state()->request_params();
+    OmahaRequestParams* request_params = SystemState::Get()->request_params();
     string channel = request_params->current_channel();
     if (channel.empty()) {
       if (errmsg)
@@ -284,12 +275,12 @@
 // Variables reporting the new image channel.
 class NewChannelVariable : public UpdaterVariableBase<string> {
  public:
-  NewChannelVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
+  explicit NewChannelVariable(const string& name)
+      : UpdaterVariableBase<string>(name, kVariableModePoll) {}
 
  private:
   const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
-    OmahaRequestParams* request_params = system_state()->request_params();
+    OmahaRequestParams* request_params = SystemState::Get()->request_params();
     string channel = request_params->target_channel();
     if (channel.empty()) {
       if (errmsg)
@@ -308,24 +299,25 @@
       public chromeos_update_engine::PrefsInterface::ObserverInterface {
  public:
   BooleanPrefVariable(const string& name,
-                      chromeos_update_engine::PrefsInterface* prefs,
                       const char* key,
                       bool default_val)
       : AsyncCopyVariable<bool>(name),
-        prefs_(prefs),
         key_(key),
         default_val_(default_val) {
-    prefs->AddObserver(key, this);
+    SystemState::Get()->prefs()->AddObserver(key, this);
     OnPrefSet(key);
   }
-  ~BooleanPrefVariable() { prefs_->RemoveObserver(key_, this); }
+  ~BooleanPrefVariable() {
+    SystemState::Get()->prefs()->RemoveObserver(key_, this);
+  }
 
  private:
   // Reads the actual value from the Prefs instance and updates the Variable
   // value.
   void OnPrefSet(const string& key) override {
     bool result = default_val_;
-    if (prefs_ && prefs_->Exists(key_) && !prefs_->GetBoolean(key_, &result))
+    auto* prefs = SystemState::Get()->prefs();
+    if (prefs->Exists(key_) && !prefs->GetBoolean(key_, &result))
       result = default_val_;
     // AsyncCopyVariable will take care of values that didn't change.
     SetValue(result);
@@ -333,8 +325,6 @@
 
   void OnPrefDeleted(const string& key) override { SetValue(default_val_); }
 
-  chromeos_update_engine::PrefsInterface* prefs_;
-
   // The Boolean preference key and default value.
   const char* const key_;
   const bool default_val_;
@@ -346,16 +336,16 @@
 class ConsecutiveFailedUpdateChecksVariable
     : public UpdaterVariableBase<unsigned int> {
  public:
-  ConsecutiveFailedUpdateChecksVariable(const string& name,
-                                        SystemState* system_state)
-      : UpdaterVariableBase<unsigned int>(
-            name, kVariableModePoll, system_state) {}
+  explicit ConsecutiveFailedUpdateChecksVariable(const string& name)
+      : UpdaterVariableBase<unsigned int>(name, kVariableModePoll) {}
 
  private:
   const unsigned int* GetValue(TimeDelta /* timeout */,
                                string* /* errmsg */) override {
-    return new unsigned int(
-        system_state()->update_attempter()->consecutive_failed_update_checks());
+    // NOLINTNEXTLINE(readability/casting)
+    return new unsigned int(SystemState::Get()
+                                ->update_attempter()
+                                ->consecutive_failed_update_checks());
   }
 
   DISALLOW_COPY_AND_ASSIGN(ConsecutiveFailedUpdateChecksVariable);
@@ -365,16 +355,16 @@
 class ServerDictatedPollIntervalVariable
     : public UpdaterVariableBase<unsigned int> {
  public:
-  ServerDictatedPollIntervalVariable(const string& name,
-                                     SystemState* system_state)
-      : UpdaterVariableBase<unsigned int>(
-            name, kVariableModePoll, system_state) {}
+  explicit ServerDictatedPollIntervalVariable(const string& name)
+      : UpdaterVariableBase<unsigned int>(name, kVariableModePoll) {}
 
  private:
   const unsigned int* GetValue(TimeDelta /* timeout */,
                                string* /* errmsg */) override {
-    return new unsigned int(
-        system_state()->update_attempter()->server_dictated_poll_interval());
+    // NOLINTNEXTLINE(readability/casting)
+    return new unsigned int(SystemState::Get()
+                                ->update_attempter()
+                                ->server_dictated_poll_interval());
   }
 
   DISALLOW_COPY_AND_ASSIGN(ServerDictatedPollIntervalVariable);
@@ -384,10 +374,10 @@
 class ForcedUpdateRequestedVariable
     : public UpdaterVariableBase<UpdateRequestStatus> {
  public:
-  ForcedUpdateRequestedVariable(const string& name, SystemState* system_state)
+  explicit ForcedUpdateRequestedVariable(const string& name)
       : UpdaterVariableBase<UpdateRequestStatus>::UpdaterVariableBase(
-            name, kVariableModeAsync, system_state) {
-    system_state->update_attempter()->set_forced_update_pending_callback(
+            name, kVariableModeAsync) {
+    SystemState::Get()->update_attempter()->set_forced_update_pending_callback(
         new base::Callback<void(bool, bool)>(  // NOLINT(readability/function)
             base::Bind(&ForcedUpdateRequestedVariable::Reset,
                        base::Unretained(this))));
@@ -419,15 +409,14 @@
 class UpdateRestrictionsVariable
     : public UpdaterVariableBase<UpdateRestrictions> {
  public:
-  UpdateRestrictionsVariable(const string& name, SystemState* system_state)
-      : UpdaterVariableBase<UpdateRestrictions>(
-            name, kVariableModePoll, system_state) {}
+  explicit UpdateRestrictionsVariable(const string& name)
+      : UpdaterVariableBase<UpdateRestrictions>(name, kVariableModePoll) {}
 
  private:
   const UpdateRestrictions* GetValue(TimeDelta /* timeout */,
                                      string* /* errmsg */) override {
     UpdateAttemptFlags attempt_flags =
-        system_state()->update_attempter()->GetCurrentUpdateAttemptFlags();
+        SystemState::Get()->update_attempter()->GetCurrentUpdateAttemptFlags();
     UpdateRestrictions restriction_flags = UpdateRestrictions::kNone;
     // Don't blindly copy the whole value, test and set bits that should
     // transfer from one set of flags to the other.
@@ -445,11 +434,8 @@
 // A variable class for reading timeout interval prefs value.
 class TestUpdateCheckIntervalTimeoutVariable : public Variable<int64_t> {
  public:
-  TestUpdateCheckIntervalTimeoutVariable(
-      const string& name, chromeos_update_engine::PrefsInterface* prefs)
-      : Variable<int64_t>(name, kVariableModePoll),
-        prefs_(prefs),
-        read_count_(0) {
+  explicit TestUpdateCheckIntervalTimeoutVariable(const string& name)
+      : Variable<int64_t>(name, kVariableModePoll), read_count_(0) {
     SetMissingOk();
   }
   ~TestUpdateCheckIntervalTimeoutVariable() = default;
@@ -458,12 +444,13 @@
   const int64_t* GetValue(TimeDelta /* timeout */,
                           string* /* errmsg */) override {
     auto key = chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout;
+    auto* prefs = SystemState::Get()->prefs();
     int64_t result;
-    if (prefs_ && prefs_->Exists(key) && prefs_->GetInt64(key, &result)) {
+    if (prefs->Exists(key) && prefs->GetInt64(key, &result)) {
       // This specific value is used for testing only. So it should not be kept
       // around and should be deleted after a few reads.
       if (++read_count_ > 5)
-        prefs_->Delete(key);
+        prefs->Delete(key);
 
       // Limit the timeout interval to 10 minutes so it is not abused if it is
       // seen on official images.
@@ -472,8 +459,6 @@
     return nullptr;
   }
 
-  chromeos_update_engine::PrefsInterface* prefs_;
-
   // Counts how many times this variable is read. This is used to delete the
   // underlying file defining the variable after a certain number of reads in
   // order to prevent any abuse of this variable.
@@ -484,40 +469,35 @@
 
 // RealUpdaterProvider methods.
 
-RealUpdaterProvider::RealUpdaterProvider(SystemState* system_state)
-    : system_state_(system_state),
-      var_updater_started_time_("updater_started_time",
-                                system_state->clock()->GetWallclockTime()),
-      var_last_checked_time_(
-          new LastCheckedTimeVariable("last_checked_time", system_state_)),
-      var_update_completed_time_(new UpdateCompletedTimeVariable(
-          "update_completed_time", system_state_)),
-      var_progress_(new ProgressVariable("progress", system_state_)),
-      var_stage_(new StageVariable("stage", system_state_)),
-      var_new_version_(new NewVersionVariable("new_version", system_state_)),
-      var_payload_size_(new PayloadSizeVariable("payload_size", system_state_)),
-      var_curr_channel_(new CurrChannelVariable("curr_channel", system_state_)),
-      var_new_channel_(new NewChannelVariable("new_channel", system_state_)),
-      var_p2p_enabled_(
-          new BooleanPrefVariable("p2p_enabled",
-                                  system_state_->prefs(),
-                                  chromeos_update_engine::kPrefsP2PEnabled,
-                                  false)),
+RealUpdaterProvider::RealUpdaterProvider()
+    : var_updater_started_time_(
+          "updater_started_time",
+          SystemState::Get()->clock()->GetWallclockTime()),
+      var_last_checked_time_(new LastCheckedTimeVariable("last_checked_time")),
+      var_update_completed_time_(
+          new UpdateCompletedTimeVariable("update_completed_time")),
+      var_progress_(new ProgressVariable("progress")),
+      var_stage_(new StageVariable("stage")),
+      var_new_version_(new NewVersionVariable("new_version")),
+      var_payload_size_(new PayloadSizeVariable("payload_size")),
+      var_curr_channel_(new CurrChannelVariable("curr_channel")),
+      var_new_channel_(new NewChannelVariable("new_channel")),
+      var_p2p_enabled_(new BooleanPrefVariable(
+          "p2p_enabled", chromeos_update_engine::kPrefsP2PEnabled, false)),
       var_cellular_enabled_(new BooleanPrefVariable(
           "cellular_enabled",
-          system_state_->prefs(),
           chromeos_update_engine::kPrefsUpdateOverCellularPermission,
           false)),
       var_consecutive_failed_update_checks_(
           new ConsecutiveFailedUpdateChecksVariable(
-              "consecutive_failed_update_checks", system_state_)),
+              "consecutive_failed_update_checks")),
       var_server_dictated_poll_interval_(new ServerDictatedPollIntervalVariable(
-          "server_dictated_poll_interval", system_state_)),
-      var_forced_update_requested_(new ForcedUpdateRequestedVariable(
-          "forced_update_requested", system_state_)),
+          "server_dictated_poll_interval")),
+      var_forced_update_requested_(
+          new ForcedUpdateRequestedVariable("forced_update_requested")),
       var_update_restrictions_(
-          new UpdateRestrictionsVariable("update_restrictions", system_state_)),
+          new UpdateRestrictionsVariable("update_restrictions")),
       var_test_update_check_interval_timeout_(
           new TestUpdateCheckIntervalTimeoutVariable(
-              "test_update_check_interval_timeout", system_state_->prefs())) {}
+              "test_update_check_interval_timeout")) {}
 }  // namespace chromeos_update_manager
diff --git a/update_manager/real_updater_provider.h b/update_manager/real_updater_provider.h
index a32e7e9..24298d7 100644
--- a/update_manager/real_updater_provider.h
+++ b/update_manager/real_updater_provider.h
@@ -20,7 +20,6 @@
 #include <memory>
 #include <string>
 
-#include "update_engine/common/system_state.h"
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/update_manager/updater_provider.h"
 
@@ -34,8 +33,7 @@
   // guarantees that parts of the system state can be mocked out at any time
   // during testing. We further assume that, by the time Init() is called, the
   // system state object is fully populated and usable.
-  explicit RealUpdaterProvider(
-      chromeos_update_engine::SystemState* system_state);
+  RealUpdaterProvider();
 
   // Initializes the provider and returns whether it succeeded.
   bool Init() { return true; }
@@ -99,9 +97,6 @@
   }
 
  private:
-  // A pointer to the update engine's system state aggregator.
-  chromeos_update_engine::SystemState* system_state_;
-
   // Variable implementations.
   ConstCopyVariable<base::Time> var_updater_started_time_;
   std::unique_ptr<Variable<base::Time>> var_last_checked_time_;
diff --git a/update_manager/real_updater_provider_unittest.cc b/update_manager/real_updater_provider_unittest.cc
index 0dc56ac..4afe7fc 100644
--- a/update_manager/real_updater_provider_unittest.cc
+++ b/update_manager/real_updater_provider_unittest.cc
@@ -23,8 +23,6 @@
 #include <gtest/gtest.h>
 #include <update_engine/dbus-constants.h>
 
-#include "update_engine/common/fake_clock.h"
-#include "update_engine/common/fake_prefs.h"
 #include "update_engine/cros/fake_system_state.h"
 #include "update_engine/cros/mock_update_attempter.h"
 #include "update_engine/cros/omaha_request_params.h"
@@ -32,7 +30,6 @@
 
 using base::Time;
 using base::TimeDelta;
-using chromeos_update_engine::FakeClock;
 using chromeos_update_engine::FakePrefs;
 using chromeos_update_engine::FakeSystemState;
 using chromeos_update_engine::OmahaRequestParams;
@@ -100,10 +97,8 @@
 class UmRealUpdaterProviderTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    fake_clock_ = fake_sys_state_.fake_clock();
-    fake_sys_state_.set_prefs(&fake_prefs_);
-    provider_.reset(new RealUpdaterProvider(&fake_sys_state_));
-    ASSERT_NE(nullptr, provider_.get());
+    FakeSystemState::CreateInstance();
+    provider_.reset(new RealUpdaterProvider());
     // Check that provider initializes correctly.
     ASSERT_TRUE(provider_->Init());
   }
@@ -117,31 +112,31 @@
     const Time kCurrBootTime = (valid ? kUpdateBootTime + kDurationSinceUpdate
                                       : kUpdateBootTime - kDurationSinceUpdate);
     const Time kCurrWallclockTime = FixedTime();
-    EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
+    EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(),
                 GetBootTimeAtUpdate(_))
         .WillOnce(DoAll(SetArgPointee<0>(kUpdateBootTime), Return(true)));
-    fake_clock_->SetBootTime(kCurrBootTime);
-    fake_clock_->SetWallclockTime(kCurrWallclockTime);
+    FakeSystemState::Get()->fake_clock()->SetBootTime(kCurrBootTime);
+    FakeSystemState::Get()->fake_clock()->SetWallclockTime(kCurrWallclockTime);
     return kCurrWallclockTime - kDurationSinceUpdate;
   }
 
-  FakeSystemState fake_sys_state_;
-  FakeClock* fake_clock_;  // Short for fake_sys_state_.fake_clock()
-  FakePrefs fake_prefs_;
   unique_ptr<RealUpdaterProvider> provider_;
 };
 
 TEST_F(UmRealUpdaterProviderTest, UpdaterStartedTimeIsWallclockTime) {
-  fake_clock_->SetWallclockTime(Time::FromDoubleT(123.456));
-  fake_clock_->SetMonotonicTime(Time::FromDoubleT(456.123));
-  // Run SetUp again to re-setup the provider under test to use these values.
-  SetUp();
+  FakeSystemState::Get()->fake_clock()->SetWallclockTime(
+      Time::FromDoubleT(123.456));
+  FakeSystemState::Get()->fake_clock()->SetMonotonicTime(
+      Time::FromDoubleT(456.123));
+  // Re-initialize to re-setup the provider under test to use these values.
+  provider_.reset(new RealUpdaterProvider());
+  ASSERT_TRUE(provider_->Init());
   UmTestUtils::ExpectVariableHasValue(Time::FromDoubleT(123.456),
                                       provider_->var_updater_started_time());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeOkay) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(
           ActionSetUpdateEngineStatusLastCheckedTime(FixedTime().ToTimeT()),
           Return(true)));
@@ -150,49 +145,49 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_last_checked_time());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMin) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(0.0), Return(true)));
   UmTestUtils::ExpectVariableHasValue(0.0, provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMid) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(0.3), Return(true)));
   UmTestUtils::ExpectVariableHasValue(0.3, provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMax) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(1.0), Return(true)));
   UmTestUtils::ExpectVariableHasValue(1.0, provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooSmall) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(-2.0), Return(true)));
   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooBig) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(2.0), Return(true)));
   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayIdle) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(
           ActionSetUpdateEngineStatusStatus(update_engine::UpdateStatus::IDLE),
           Return(true)));
@@ -200,7 +195,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayCheckingForUpdate) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::CHECKING_FOR_UPDATE),
                       Return(true)));
@@ -209,7 +204,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdateAvailable) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::UPDATE_AVAILABLE),
                       Return(true)));
@@ -218,7 +213,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayDownloading) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::DOWNLOADING),
                       Return(true)));
@@ -227,7 +222,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayVerifying) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::VERIFYING),
                       Return(true)));
@@ -236,7 +231,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayFinalizing) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::FINALIZING),
                       Return(true)));
@@ -245,7 +240,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdatedNeedReboot) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::UPDATED_NEED_REBOOT),
                       Return(true)));
@@ -254,7 +249,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayReportingErrorEvent) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::REPORTING_ERROR_EVENT),
                       Return(true)));
@@ -263,7 +258,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageOkayAttemptingRollback) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
                           update_engine::UpdateStatus::ATTEMPTING_ROLLBACK),
                       Return(true)));
@@ -272,13 +267,13 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetStageFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_stage());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetNewVersionOkay) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(
           DoAll(ActionSetUpdateEngineStatusNewVersion("1.2.0"), Return(true)));
   UmTestUtils::ExpectVariableHasValue(string("1.2.0"),
@@ -286,13 +281,13 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetNewVersionFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_new_version());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayZero) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(
           ActionSetUpdateEngineStatusNewSizeBytes(static_cast<uint64_t>(0)),
           Return(true)));
@@ -301,7 +296,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayArbitrary) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusNewSizeBytes(
                           static_cast<uint64_t>(567890)),
                       Return(true)));
@@ -310,7 +305,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayTwoGigabytes) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(DoAll(ActionSetUpdateEngineStatusNewSizeBytes(
                           static_cast<uint64_t>(1) << 31),
                       Return(true)));
@@ -319,44 +314,44 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(), GetStatus(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_payload_size());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelOkay) {
   const string kChannelName("foo-channel");
-  OmahaRequestParams request_params(&fake_sys_state_);
+  OmahaRequestParams request_params;
   request_params.Init("", "", {});
   request_params.set_current_channel(kChannelName);
-  fake_sys_state_.set_request_params(&request_params);
+  FakeSystemState::Get()->set_request_params(&request_params);
   UmTestUtils::ExpectVariableHasValue(kChannelName,
                                       provider_->var_curr_channel());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelFailEmpty) {
-  OmahaRequestParams request_params(&fake_sys_state_);
+  OmahaRequestParams request_params;
   request_params.Init("", "", {});
   request_params.set_current_channel("");
-  fake_sys_state_.set_request_params(&request_params);
+  FakeSystemState::Get()->set_request_params(&request_params);
   UmTestUtils::ExpectVariableNotSet(provider_->var_curr_channel());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetNewChannelOkay) {
   const string kChannelName("foo-channel");
-  OmahaRequestParams request_params(&fake_sys_state_);
+  OmahaRequestParams request_params;
   request_params.Init("", "", {});
   request_params.set_target_channel(kChannelName);
-  fake_sys_state_.set_request_params(&request_params);
+  FakeSystemState::Get()->set_request_params(&request_params);
   UmTestUtils::ExpectVariableHasValue(kChannelName,
                                       provider_->var_new_channel());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetNewChannelFailEmpty) {
-  OmahaRequestParams request_params(&fake_sys_state_);
+  OmahaRequestParams request_params;
   request_params.Init("", "", {});
   request_params.set_target_channel("");
-  fake_sys_state_.set_request_params(&request_params);
+  FakeSystemState::Get()->set_request_params(&request_params);
   UmTestUtils::ExpectVariableNotSet(provider_->var_new_channel());
 }
 
@@ -365,22 +360,26 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefReadsFalse) {
-  fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false);
+  FakeSystemState::Get()->fake_prefs()->SetBoolean(
+      chromeos_update_engine::kPrefsP2PEnabled, false);
   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledReadWhenInitialized) {
-  fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true);
-  SetUp();
+  FakeSystemState::Get()->fake_prefs()->SetBoolean(
+      chromeos_update_engine::kPrefsP2PEnabled, true);
+  provider_.reset(new RealUpdaterProvider());
+  ASSERT_TRUE(provider_->Init());
   UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled());
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledUpdated) {
-  fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false);
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
+  fake_prefs->SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false);
   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
-  fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true);
+  fake_prefs->SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true);
   UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled());
-  fake_prefs_.Delete(chromeos_update_engine::kPrefsP2PEnabled);
+  fake_prefs->Delete(chromeos_update_engine::kPrefsP2PEnabled);
   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
 }
 
@@ -389,7 +388,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefReadsTrue) {
-  fake_prefs_.SetBoolean(
+  FakeSystemState::Get()->fake_prefs()->SetBoolean(
       chromeos_update_engine::kPrefsUpdateOverCellularPermission, true);
   UmTestUtils::ExpectVariableHasValue(true, provider_->var_cellular_enabled());
 }
@@ -401,7 +400,8 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeFailNoValue) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetBootTimeAtUpdate(_))
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(),
+              GetBootTimeAtUpdate(_))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(provider_->var_update_completed_time());
 }
@@ -413,7 +413,7 @@
 
 TEST_F(UmRealUpdaterProviderTest, GetConsecutiveFailedUpdateChecks) {
   const unsigned int kNumFailedChecks = 3;
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(),
               consecutive_failed_update_checks())
       .WillRepeatedly(Return(kNumFailedChecks));
   UmTestUtils::ExpectVariableHasValue(
@@ -422,7 +422,7 @@
 
 TEST_F(UmRealUpdaterProviderTest, GetServerDictatedPollInterval) {
   const unsigned int kPollInterval = 2 * 60 * 60;  // Two hours.
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(),
               server_dictated_poll_interval())
       .WillRepeatedly(Return(kPollInterval));
   UmTestUtils::ExpectVariableHasValue(
@@ -430,7 +430,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetUpdateRestrictions) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(),
               GetCurrentUpdateAttemptFlags())
       .WillRepeatedly(Return(UpdateAttemptFlags::kFlagRestrictDownload |
                              UpdateAttemptFlags::kFlagNonInteractive));
@@ -439,7 +439,7 @@
 }
 
 TEST_F(UmRealUpdaterProviderTest, GetUpdateRestrictionsNone) {
-  EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
+  EXPECT_CALL(*FakeSystemState::Get()->mock_update_attempter(),
               GetCurrentUpdateAttemptFlags())
       .WillRepeatedly(Return(UpdateAttemptFlags::kNone));
   UmTestUtils::ExpectVariableHasValue(UpdateRestrictions::kNone,
@@ -449,14 +449,15 @@
 TEST_F(UmRealUpdaterProviderTest, TestUpdateCheckIntervalTimeout) {
   UmTestUtils::ExpectVariableNotSet(
       provider_->var_test_update_check_interval_timeout());
-  fake_prefs_.SetInt64(
+  auto* fake_prefs = FakeSystemState::Get()->fake_prefs();
+  fake_prefs->SetInt64(
       chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout, 1);
   UmTestUtils::ExpectVariableHasValue(
       static_cast<int64_t>(1),
       provider_->var_test_update_check_interval_timeout());
 
   // Make sure the value does not exceed a threshold of 10 minutes.
-  fake_prefs_.SetInt64(
+  fake_prefs->SetInt64(
       chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout, 11 * 60);
   // The next 5 reads should return valid values.
   for (int i = 0; i < 5; ++i)
diff --git a/update_manager/staging_utils.cc b/update_manager/staging_utils.cc
index e8f07bb..a992975 100644
--- a/update_manager/staging_utils.cc
+++ b/update_manager/staging_utils.cc
@@ -26,12 +26,11 @@
 
 #include "update_engine/common/constants.h"
 #include "update_engine/common/hardware_interface.h"
-#include "update_engine/common/prefs_interface.h"
 #include "update_engine/common/system_state.h"
 
 using base::TimeDelta;
 using chromeos_update_engine::kPrefsWallClockStagingWaitPeriod;
-using chromeos_update_engine::PrefsInterface;
+using chromeos_update_engine::SystemState;
 using policy::DevicePolicy;
 
 namespace chromeos_update_manager {
@@ -98,7 +97,6 @@
 }
 
 StagingCase CalculateStagingCase(const DevicePolicy* device_policy,
-                                 PrefsInterface* prefs,
                                  TimeDelta* staging_wait_time,
                                  StagingSchedule* staging_schedule) {
   // Check that the schedule in the device policy is correct.
@@ -128,7 +126,8 @@
   int64_t wait_period_in_days;
   // There exists a persisted value that is valid. That is, it's smaller than
   // the maximum amount of days of staging set by the user.
-  if (prefs->GetInt64(kPrefsWallClockStagingWaitPeriod, &wait_period_in_days) &&
+  if (SystemState::Get()->prefs()->GetInt64(kPrefsWallClockStagingWaitPeriod,
+                                            &wait_period_in_days) &&
       wait_period_in_days > 0 && wait_period_in_days <= max_days) {
     *staging_wait_time = TimeDelta::FromDays(wait_period_in_days);
     return StagingCase::kSetStagingFromPref;
diff --git a/update_manager/staging_utils.h b/update_manager/staging_utils.h
index e91bfeb..0de1dfd 100644
--- a/update_manager/staging_utils.h
+++ b/update_manager/staging_utils.h
@@ -62,7 +62,6 @@
 // contain the previous staging schedule, if there is a new schedule found, its
 // value will be replaced with the new one.
 StagingCase CalculateStagingCase(const policy::DevicePolicy* device_policy,
-                                 chromeos_update_engine::PrefsInterface* prefs,
                                  base::TimeDelta* staging_wait_time,
                                  StagingSchedule* staging_schedule);
 
diff --git a/update_manager/staging_utils_unittest.cc b/update_manager/staging_utils_unittest.cc
index 8d75acd..126617f 100644
--- a/update_manager/staging_utils_unittest.cc
+++ b/update_manager/staging_utils_unittest.cc
@@ -24,10 +24,10 @@
 #include <policy/mock_device_policy.h>
 
 #include "update_engine/common/constants.h"
-#include "update_engine/common/fake_prefs.h"
+#include "update_engine/cros/fake_system_state.h"
 
 using base::TimeDelta;
-using chromeos_update_engine::FakePrefs;
+using chromeos_update_engine::FakeSystemState;
 using chromeos_update_engine::kPrefsWallClockStagingWaitPeriod;
 using testing::_;
 using testing::DoAll;
@@ -44,6 +44,7 @@
 class StagingUtilsScheduleTest : public testing::Test {
  protected:
   void SetUp() override {
+    FakeSystemState::CreateInstance();
     test_wait_time_ = TimeDelta();
     test_staging_schedule_ = StagingSchedule();
   }
@@ -55,14 +56,13 @@
   }
 
   void SetPersistedStagingVal(int64_t wait_time) {
-    EXPECT_TRUE(
-        fake_prefs_.SetInt64(kPrefsWallClockStagingWaitPeriod, wait_time));
+    EXPECT_TRUE(FakeSystemState::Get()->fake_prefs()->SetInt64(
+        kPrefsWallClockStagingWaitPeriod, wait_time));
   }
 
   void TestStagingCase(const StagingCase& expected) {
     EXPECT_EQ(expected,
               CalculateStagingCase(&device_policy_,
-                                   &fake_prefs_,
                                    &test_wait_time_,
                                    &test_staging_schedule_));
   }
@@ -75,7 +75,6 @@
   policy::MockDevicePolicy device_policy_;
   TimeDelta test_wait_time_;
   StagingSchedule test_staging_schedule_;
-  FakePrefs fake_prefs_;
 };
 
 // Last element should be 100, if not return false.
diff --git a/update_manager/state_factory.cc b/update_manager/state_factory.cc
index a95a5a8..0ab4f7b 100644
--- a/update_manager/state_factory.cc
+++ b/update_manager/state_factory.cc
@@ -23,34 +23,31 @@
 #include <session_manager/dbus-proxies.h>
 #endif  // USE_DBUS
 
-#include "update_engine/common/clock_interface.h"
 #if USE_DBUS
 #include "update_engine/cros/dbus_connection.h"
 #endif  // USE_DBUS
+#include "update_engine/common/system_state.h"
+#include "update_engine/cros/shill_proxy.h"
 #include "update_engine/update_manager/fake_shill_provider.h"
 #include "update_engine/update_manager/real_config_provider.h"
 #include "update_engine/update_manager/real_device_policy_provider.h"
 #include "update_engine/update_manager/real_random_provider.h"
+#include "update_engine/update_manager/real_shill_provider.h"
 #include "update_engine/update_manager/real_state.h"
 #include "update_engine/update_manager/real_system_provider.h"
 #include "update_engine/update_manager/real_time_provider.h"
 #include "update_engine/update_manager/real_updater_provider.h"
-#if USE_SHILL
-#include "update_engine/cros/shill_proxy.h"
-#include "update_engine/update_manager/real_shill_provider.h"
-#endif  // USE_SHILL
 
+using chromeos_update_engine::SystemState;
 using std::unique_ptr;
 
 namespace chromeos_update_manager {
 
 State* DefaultStateFactory(
     policy::PolicyProvider* policy_provider,
-    org::chromium::KioskAppServiceInterfaceProxyInterface* kiosk_app_proxy,
-    chromeos_update_engine::SystemState* system_state) {
-  chromeos_update_engine::ClockInterface* const clock = system_state->clock();
+    org::chromium::KioskAppServiceInterfaceProxyInterface* kiosk_app_proxy) {
   unique_ptr<RealConfigProvider> config_provider(
-      new RealConfigProvider(system_state->hardware()));
+      new RealConfigProvider(SystemState::Get()->hardware()));
 #if USE_DBUS
   scoped_refptr<dbus::Bus> bus =
       chromeos_update_engine::DBusConnection::Get()->GetDBus();
@@ -62,25 +59,18 @@
   unique_ptr<RealDevicePolicyProvider> device_policy_provider(
       new RealDevicePolicyProvider(policy_provider));
 #endif  // USE_DBUS
-#if USE_SHILL
   unique_ptr<RealShillProvider> shill_provider(
-      new RealShillProvider(new chromeos_update_engine::ShillProxy(), clock));
-#else
-  unique_ptr<FakeShillProvider> shill_provider(new FakeShillProvider());
-#endif  // USE_SHILL
+      new RealShillProvider(new chromeos_update_engine::ShillProxy()));
   unique_ptr<RealRandomProvider> random_provider(new RealRandomProvider());
   unique_ptr<RealSystemProvider> system_provider(
-      new RealSystemProvider(system_state, kiosk_app_proxy));
+      new RealSystemProvider(kiosk_app_proxy));
 
-  unique_ptr<RealTimeProvider> time_provider(new RealTimeProvider(clock));
-  unique_ptr<RealUpdaterProvider> updater_provider(
-      new RealUpdaterProvider(system_state));
+  unique_ptr<RealTimeProvider> time_provider(new RealTimeProvider());
+  unique_ptr<RealUpdaterProvider> updater_provider(new RealUpdaterProvider());
 
   if (!(config_provider->Init() && device_policy_provider->Init() &&
         random_provider->Init() &&
-#if USE_SHILL
         shill_provider->Init() &&
-#endif  // USE_SHILL
         system_provider->Init() && time_provider->Init() &&
         updater_provider->Init())) {
     LOG(ERROR) << "Error initializing providers";
diff --git a/update_manager/state_factory.h b/update_manager/state_factory.h
index ac3bf6b..c53bb9c 100644
--- a/update_manager/state_factory.h
+++ b/update_manager/state_factory.h
@@ -17,7 +17,6 @@
 #ifndef UPDATE_ENGINE_UPDATE_MANAGER_STATE_FACTORY_H_
 #define UPDATE_ENGINE_UPDATE_MANAGER_STATE_FACTORY_H_
 
-#include "update_engine/common/system_state.h"
 #include "update_engine/update_manager/state.h"
 
 namespace org {
@@ -35,8 +34,7 @@
 // to initialize.
 State* DefaultStateFactory(
     policy::PolicyProvider* policy_provider,
-    org::chromium::KioskAppServiceInterfaceProxyInterface* kiosk_app_proxy,
-    chromeos_update_engine::SystemState* system_state);
+    org::chromium::KioskAppServiceInterfaceProxyInterface* kiosk_app_proxy);
 
 }  // namespace chromeos_update_manager
 
diff --git a/update_manager/update_manager-inl.h b/update_manager/update_manager-inl.h
index 550642c..045ecff 100644
--- a/update_manager/update_manager-inl.h
+++ b/update_manager/update_manager-inl.h
@@ -116,7 +116,7 @@
         EvaluationContext*, State*, std::string*, R*, ExpectedArgs...) const,
     R* result,
     ActualArgs... args) {
-  auto ec = std::make_shared<EvaluationContext>(clock_, evaluation_timeout_);
+  auto ec = std::make_shared<EvaluationContext>(evaluation_timeout_);
   // A PolicyRequest always consists on a single evaluation on a new
   // EvaluationContext.
   // IMPORTANT: To ensure that ActualArgs can be converted to ExpectedArgs, we
@@ -138,7 +138,6 @@
         EvaluationContext*, State*, std::string*, R*, ExpectedArgs...) const,
     ActualArgs... args) {
   auto ec = std::make_shared<EvaluationContext>(
-      clock_,
       evaluation_timeout_,
       expiration_timeout_,
       std::unique_ptr<base::Callback<void(EvaluationContext*)>>(
diff --git a/update_manager/update_manager.cc b/update_manager/update_manager.cc
index 2974d7d..dbb6b33 100644
--- a/update_manager/update_manager.cc
+++ b/update_manager/update_manager.cc
@@ -19,14 +19,11 @@
 
 namespace chromeos_update_manager {
 
-UpdateManager::UpdateManager(chromeos_update_engine::ClockInterface* clock,
-                             base::TimeDelta evaluation_timeout,
+UpdateManager::UpdateManager(base::TimeDelta evaluation_timeout,
                              base::TimeDelta expiration_timeout,
                              State* state)
     : policy_(GetSystemPolicy()),
-      default_policy_(clock),
       state_(state),
-      clock_(clock),
       evaluation_timeout_(evaluation_timeout),
       expiration_timeout_(expiration_timeout),
       weak_ptr_factory_(this) {}
diff --git a/update_manager/update_manager.h b/update_manager/update_manager.h
index 8ab61d0..e266b57 100644
--- a/update_manager/update_manager.h
+++ b/update_manager/update_manager.h
@@ -24,7 +24,7 @@
 #include <base/callback.h>
 #include <base/time/time.h>
 
-#include "update_engine/common/clock_interface.h"
+#include "update_engine/common/system_state.h"
 #include "update_engine/update_manager/default_policy.h"
 #include "update_engine/update_manager/evaluation_context.h"
 #include "update_engine/update_manager/policy.h"
@@ -56,8 +56,7 @@
  public:
   // Creates the UpdateManager instance, assuming ownership on the provided
   // |state|.
-  UpdateManager(chromeos_update_engine::ClockInterface* clock,
-                base::TimeDelta evaluation_timeout,
+  UpdateManager(base::TimeDelta evaluation_timeout,
                 base::TimeDelta expiration_timeout,
                 State* state);
 
@@ -162,9 +161,6 @@
   // State Providers.
   std::unique_ptr<State> state_;
 
-  // Pointer to the mockable clock interface;
-  chromeos_update_engine::ClockInterface* clock_;
-
   // Timeout for a policy evaluation.
   const base::TimeDelta evaluation_timeout_;
 
diff --git a/update_manager/update_manager_unittest.cc b/update_manager/update_manager_unittest.cc
index f1a8d17..a02d7ef 100644
--- a/update_manager/update_manager_unittest.cc
+++ b/update_manager/update_manager_unittest.cc
@@ -34,7 +34,7 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
-#include "update_engine/common/fake_clock.h"
+#include "update_engine/cros/fake_system_state.h"
 #include "update_engine/update_manager/default_policy.h"
 #include "update_engine/update_manager/fake_state.h"
 #include "update_engine/update_manager/mock_policy.h"
@@ -48,6 +48,7 @@
 using brillo::MessageLoopRunMaxIterations;
 using chromeos_update_engine::ErrorCode;
 using chromeos_update_engine::FakeClock;
+using chromeos_update_engine::FakeSystemState;
 using std::pair;
 using std::string;
 using std::tuple;
@@ -80,11 +81,10 @@
  protected:
   void SetUp() override {
     loop_.SetAsCurrent();
+    FakeSystemState::CreateInstance();
     fake_state_ = new FakeState();
-    umut_.reset(new UpdateManager(&fake_clock_,
-                                  TimeDelta::FromSeconds(5),
-                                  TimeDelta::FromSeconds(1),
-                                  fake_state_));
+    umut_.reset(new UpdateManager(
+        TimeDelta::FromSeconds(5), TimeDelta::FromSeconds(1), fake_state_));
   }
 
   void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); }
@@ -92,7 +92,6 @@
   base::SimpleTestClock test_clock_;
   brillo::FakeMessageLoop loop_{&test_clock_};
   FakeState* fake_state_;  // Owned by the umut_.
-  FakeClock fake_clock_;
   unique_ptr<UpdateManager> umut_;
 };
 
@@ -291,13 +290,14 @@
 }
 
 TEST_F(UmUpdateManagerTest, AsyncPolicyRequestTimesOut) {
+  auto* fake_clock = FakeSystemState::Get()->fake_clock();
   // Set up an async policy call to exceed its expiration timeout, make sure
   // that the default policy was not used (no callback) and that evaluation is
   // reattempted.
   int num_called = 0;
   umut_->set_policy(new DelayPolicy(
       0,
-      fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(3),
+      fake_clock->GetWallclockTime() + TimeDelta::FromSeconds(3),
       &num_called));
 
   vector<pair<EvalStatus, UpdateCheckParams>> calls;
@@ -314,7 +314,7 @@
   // ensure that reevaluation occurred but callback was not invoked (i.e.
   // default policy was not consulted).
   test_clock_.Advance(TimeDelta::FromSeconds(2));
-  fake_clock_.SetWallclockTime(fake_clock_.GetWallclockTime() +
+  fake_clock->SetWallclockTime(fake_clock->GetWallclockTime() +
                                TimeDelta::FromSeconds(2));
   MessageLoopRunMaxIterations(MessageLoop::current(), 10);
   EXPECT_EQ(2, num_called);
@@ -322,7 +322,7 @@
   // Wait for reevaluation due to delay to happen, ensure that it occurs and
   // that the callback is invoked.
   test_clock_.Advance(TimeDelta::FromSeconds(2));
-  fake_clock_.SetWallclockTime(fake_clock_.GetWallclockTime() +
+  fake_clock->SetWallclockTime(fake_clock->GetWallclockTime() +
                                TimeDelta::FromSeconds(2));
   MessageLoopRunMaxIterations(MessageLoop::current(), 10);
   EXPECT_EQ(3, num_called);
diff --git a/update_manager/update_time_restrictions_monitor.cc b/update_manager/update_time_restrictions_monitor.cc
new file mode 100644
index 0000000..00e6ec3
--- /dev/null
+++ b/update_manager/update_time_restrictions_monitor.cc
@@ -0,0 +1,132 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/update_manager/update_time_restrictions_monitor.h"
+
+#include <base/bind.h>
+#include <base/time/time.h>
+
+#include "update_engine/common/system_state.h"
+
+using base::TimeDelta;
+using brillo::MessageLoop;
+using chromeos_update_engine::SystemState;
+
+namespace chromeos_update_manager {
+
+namespace {
+
+const WeeklyTimeInterval* FindNextNearestInterval(
+    const WeeklyTimeIntervalVector& intervals, const WeeklyTime& now) {
+  const WeeklyTimeInterval* result_interval = nullptr;
+  // As we are dealing with weekly time here, the maximum duration can be one
+  // week.
+  TimeDelta duration_till_next_interval = TimeDelta::FromDays(7);
+  for (const auto& interval : intervals) {
+    if (interval.InRange(now)) {
+      return &interval;
+    }
+    const TimeDelta current_duration = now.GetDurationTo(interval.start());
+    if (current_duration < duration_till_next_interval) {
+      result_interval = &interval;
+      duration_till_next_interval = current_duration;
+    }
+  }
+  return result_interval;
+}
+
+WeeklyTime Now() {
+  return WeeklyTime::FromTime(SystemState::Get()->clock()->GetWallclockTime());
+}
+
+}  // namespace
+
+UpdateTimeRestrictionsMonitor::UpdateTimeRestrictionsMonitor(
+    DevicePolicyProvider* device_policy_provider, Delegate* delegate)
+    : evaluation_context_(/* evaluation_timeout = */ TimeDelta::Max(),
+                          /* expiration_timeout = */ TimeDelta::Max(),
+                          /* unregister_cb = */ {}),
+      device_policy_provider_(device_policy_provider),
+      delegate_(delegate),
+      weak_ptr_factory_(this) {
+  if (device_policy_provider_ != nullptr && delegate_ != nullptr)
+    StartMonitoring();
+}
+
+UpdateTimeRestrictionsMonitor::~UpdateTimeRestrictionsMonitor() {
+  StopMonitoring();
+}
+
+void UpdateTimeRestrictionsMonitor::StartMonitoring() {
+  DCHECK(device_policy_provider_);
+  const WeeklyTimeIntervalVector* new_intervals = evaluation_context_.GetValue(
+      device_policy_provider_->var_disallowed_time_intervals());
+  if (new_intervals && !new_intervals->empty())
+    WaitForRestrictedIntervalStarts(*new_intervals);
+
+  const bool is_registered = evaluation_context_.RunOnValueChangeOrTimeout(
+      base::Bind(&UpdateTimeRestrictionsMonitor::OnIntervalsChanged,
+                 base::Unretained(this)));
+  DCHECK(is_registered);
+}
+
+void UpdateTimeRestrictionsMonitor::WaitForRestrictedIntervalStarts(
+    const WeeklyTimeIntervalVector& restricted_time_intervals) {
+  DCHECK(!restricted_time_intervals.empty());
+
+  const WeeklyTimeInterval* current_interval =
+      FindNextNearestInterval(restricted_time_intervals, Now());
+  if (current_interval == nullptr) {
+    LOG(WARNING) << "Could not find next nearest restricted interval.";
+    return;
+  }
+
+  // If |current_interval| happens right now, set delay to zero.
+  const TimeDelta duration_till_start =
+      current_interval->InRange(Now())
+          ? TimeDelta::FromMicroseconds(0)
+          : Now().GetDurationTo(current_interval->start());
+  LOG(INFO) << "Found restricted interval starting at "
+            << (SystemState::Get()->clock()->GetWallclockTime() +
+                duration_till_start);
+
+  timeout_event_ = MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&UpdateTimeRestrictionsMonitor::HandleRestrictedIntervalStarts,
+                 weak_ptr_factory_.GetWeakPtr()),
+      duration_till_start);
+}
+
+void UpdateTimeRestrictionsMonitor::HandleRestrictedIntervalStarts() {
+  timeout_event_ = MessageLoop::kTaskIdNull;
+  if (delegate_)
+    delegate_->OnRestrictedIntervalStarts();
+}
+
+void UpdateTimeRestrictionsMonitor::StopMonitoring() {
+  MessageLoop::current()->CancelTask(timeout_event_);
+  timeout_event_ = MessageLoop::kTaskIdNull;
+}
+
+void UpdateTimeRestrictionsMonitor::OnIntervalsChanged() {
+  DCHECK(!evaluation_context_.is_expired());
+
+  StopMonitoring();
+  evaluation_context_.ResetEvaluation();
+  StartMonitoring();
+}
+
+}  // namespace chromeos_update_manager
diff --git a/update_manager/update_time_restrictions_monitor.h b/update_manager/update_time_restrictions_monitor.h
new file mode 100644
index 0000000..034ac87
--- /dev/null
+++ b/update_manager/update_time_restrictions_monitor.h
@@ -0,0 +1,105 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_TIME_RESTRICTIONS_MONITOR_H_
+#define UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_TIME_RESTRICTIONS_MONITOR_H_
+
+#include <memory>
+
+#include <base/memory/weak_ptr.h>
+#include <brillo/message_loops/message_loop.h>
+
+#include "update_engine/update_manager/device_policy_provider.h"
+#include "update_engine/update_manager/evaluation_context.h"
+#include "update_engine/update_manager/weekly_time.h"
+
+namespace chromeos_update_manager {
+
+// Represents a monitor tracking start of restricted time intervals during which
+// update download is not allowed. It reads |var_disallowed_time_intervals|,
+// chooses the next interval according to current time, awaits its start and
+// notifies the delegate. If the chosen interval is already happening, the
+// monitor notifies immediately. The monitor will never notify the delegate
+// while the current list of restricted intervals is empty.
+//
+// The monitor detects changes in the restricted intervals and handles the
+// change with following cases:
+// 1. No restricted time intervals or none of the intervals is in progress -> no
+//    new restricted intervals or none of the new intervals matches the current
+//    time.
+//    The monitor starts tracking the next interval from the new ones, if any.
+// 2. No restricted time intervals or none of the intervals is in progress ->
+//    there is a new interval matching current time.
+//    The monitor shall pick this new interval and notify the delegate
+//    immediately about the start of the restricted interval.
+class UpdateTimeRestrictionsMonitor {
+ public:
+  // Interface to handle start of a restricted time interval.
+  class Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    virtual void OnRestrictedIntervalStarts() = 0;
+  };
+
+  // Creates an instance and starts monitoring the next nearest restricted time
+  // interval if present. If no intervals are available yet the monitor will be
+  // idle until intervals list changes.
+  UpdateTimeRestrictionsMonitor(DevicePolicyProvider* device_policy_provider,
+                                Delegate* delegate);
+
+  UpdateTimeRestrictionsMonitor(const UpdateTimeRestrictionsMonitor&) = delete;
+  UpdateTimeRestrictionsMonitor& operator=(
+      const UpdateTimeRestrictionsMonitor&) = delete;
+
+  ~UpdateTimeRestrictionsMonitor();
+
+  bool IsMonitoringInterval() {
+    return timeout_event_ != brillo::MessageLoop::kTaskIdNull;
+  }
+
+ private:
+  // Starts monitoring the start of nearest restricted time interval if present
+  // and any change in restricted time intervals from policy.
+  void StartMonitoring();
+  void WaitForRestrictedIntervalStarts(
+      const WeeklyTimeIntervalVector& restricted_time_intervals);
+
+  // Called when current time lies within a restricted interval.
+  void HandleRestrictedIntervalStarts();
+
+  // Stop monotoring any restricted intervals.
+  void StopMonitoring();
+
+  // Called upon change of restricted intervals.
+  void OnIntervalsChanged();
+
+  // To access restricted time intervals from |device_policy_provider_|.
+  EvaluationContext evaluation_context_;
+
+  DevicePolicyProvider* const device_policy_provider_;
+  Delegate* const delegate_;
+
+  // The TaskId returned by the message loop identifying the timeout callback.
+  // Used for cancelling the timeout callback.
+  brillo::MessageLoop::TaskId timeout_event_{brillo::MessageLoop::kTaskIdNull};
+
+  base::WeakPtrFactory<UpdateTimeRestrictionsMonitor> weak_ptr_factory_;
+};
+
+}  // namespace chromeos_update_manager
+
+#endif  // UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_TIME_RESTRICTIONS_MONITOR_H_
diff --git a/update_manager/update_time_restrictions_monitor_unittest.cc b/update_manager/update_time_restrictions_monitor_unittest.cc
new file mode 100644
index 0000000..2e474e2
--- /dev/null
+++ b/update_manager/update_time_restrictions_monitor_unittest.cc
@@ -0,0 +1,279 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <memory>
+
+#include <base/optional.h>
+#include <base/time/time.h>
+#include <base/test/simple_test_clock.h>
+#include <brillo/message_loops/fake_message_loop.h>
+#include <brillo/message_loops/message_loop_utils.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/update_manager/fake_state.h"
+#include "update_engine/update_manager/update_time_restrictions_monitor.h"
+
+using brillo::FakeMessageLoop;
+using brillo::MessageLoop;
+using brillo::MessageLoopRunMaxIterations;
+using chromeos_update_engine::FakeSystemState;
+
+namespace chromeos_update_manager {
+
+namespace {
+
+constexpr base::TimeDelta kDurationOffset = base::TimeDelta::FromMinutes(1);
+constexpr base::TimeDelta kHourDuration = base::TimeDelta::FromHours(1);
+constexpr base::TimeDelta kMinuteDuration = base::TimeDelta::FromMinutes(1);
+// Initial time: Monday, May 4th 2020 8:13 AM before interval.
+constexpr base::Time::Exploded kInitialTimeBeforeInterval{
+    2020, 5, 0, 4, 10, 13, 0, 0};
+// Initial time: Monday, May 4th 2020 10:20 AM within interval.
+constexpr base::Time::Exploded kInitialTimeWithinInterval{
+    2020, 5, 0, 4, 10, 20, 0, 0};
+const int current_restricted_interval_index = 0;
+
+const WeeklyTimeIntervalVector kTestOneDisallowedTimeIntervals{
+    // Monday 8:15 AM to Monday 9:30 PM.
+    WeeklyTimeInterval(WeeklyTime(1, kHourDuration * 8 + kMinuteDuration * 15),
+                       WeeklyTime(1, kHourDuration * 9 + kMinuteDuration * 30)),
+};
+
+const WeeklyTimeIntervalVector kTestTwoDisallowedTimeIntervals{
+    // Monday 10:15 AM to Monday 3:30 PM.
+    WeeklyTimeInterval(
+        WeeklyTime(1, kHourDuration * 10 + kMinuteDuration * 15),
+        WeeklyTime(1, kHourDuration * 15 + kMinuteDuration * 30)),
+    // Wednesday 8:30 PM to Thursday 8:40 AM.
+    WeeklyTimeInterval(WeeklyTime(3, kHourDuration * 20 + kMinuteDuration * 30),
+                       WeeklyTime(4, kHourDuration * 8 + kMinuteDuration * 40)),
+};
+
+}  // namespace
+
+class MockUpdateTimeRestrictionsMonitorDelegate
+    : public UpdateTimeRestrictionsMonitor::Delegate {
+ public:
+  virtual ~MockUpdateTimeRestrictionsMonitorDelegate() = default;
+
+  MOCK_METHOD0(OnRestrictedIntervalStarts, void());
+};
+
+class UmUpdateTimeRestrictionsMonitorTest : public ::testing::Test {
+ protected:
+  UmUpdateTimeRestrictionsMonitorTest() {
+    fake_loop_.SetAsCurrent();
+    FakeSystemState::CreateInstance();
+  }
+
+  void TearDown() override { EXPECT_FALSE(fake_loop_.PendingTasks()); }
+
+  bool SetNow(const base::Time::Exploded& exploded_now) {
+    base::Time now;
+    if (!base::Time::FromLocalExploded(exploded_now, &now))
+      return false;
+
+    test_clock_.SetNow(now);
+    FakeSystemState::Get()->fake_clock()->SetWallclockTime(now);
+    return true;
+  }
+
+  void AdvanceAfterTimestamp(const WeeklyTime& timestamp) {
+    const WeeklyTime now = WeeklyTime::FromTime(test_clock_.Now());
+    const base::TimeDelta duration =
+        now.GetDurationTo(timestamp) + kDurationOffset;
+    test_clock_.Advance(duration);
+    FakeSystemState::Get()->fake_clock()->SetWallclockTime(test_clock_.Now());
+  }
+
+  void VerifyExpectationsOnDelegate() {
+    testing::Mock::VerifyAndClearExpectations(&mock_delegate_);
+  }
+
+  void UpdateRestrictedIntervals(const WeeklyTimeIntervalVector& policy_value) {
+    auto* policy_variable =
+        fake_state_.device_policy_provider()->var_disallowed_time_intervals();
+    policy_variable->reset(new WeeklyTimeIntervalVector(policy_value));
+    policy_variable->NotifyValueChanged();
+  }
+
+  bool IsMonitoringInterval() {
+    return monitor_.has_value() && monitor_.value().IsMonitoringInterval();
+  }
+
+  void BuildMonitorAndVerify(const WeeklyTimeIntervalVector* policy_value,
+                             bool expect_delegate_called,
+                             bool expect_monitoring) {
+    if (expect_delegate_called)
+      EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(1);
+    else
+      EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(0);
+
+    fake_state_.device_policy_provider()
+        ->var_disallowed_time_intervals()
+        ->reset(policy_value != nullptr
+                    ? new WeeklyTimeIntervalVector(*policy_value)
+                    : nullptr);
+    monitor_.emplace(fake_state_.device_policy_provider(), &mock_delegate_);
+    if (expect_delegate_called)
+      MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+    VerifyExpectationsOnDelegate();
+
+    if (expect_monitoring)
+      EXPECT_TRUE(IsMonitoringInterval());
+    else
+      EXPECT_FALSE(IsMonitoringInterval());
+  }
+
+  base::SimpleTestClock test_clock_;
+  FakeMessageLoop fake_loop_{&test_clock_};
+  FakeState fake_state_;
+  MockUpdateTimeRestrictionsMonitorDelegate mock_delegate_;
+  base::Optional<UpdateTimeRestrictionsMonitor> monitor_;
+};
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest, PolicyIsNotSet) {
+  BuildMonitorAndVerify(
+      nullptr, /*expect_delegate_called=*/false, /*expect_monitoring=*/false);
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest, PolicyHasEmptyIntervalList) {
+  WeeklyTimeIntervalVector empty_policy;
+  BuildMonitorAndVerify(&empty_policy,
+                        /*expect_delegate_called=*/false,
+                        /*expect_monitoring=*/false);
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       CurrentTimeOutsideOfRestrictedInterval) {
+  ASSERT_TRUE(SetNow(kInitialTimeBeforeInterval));
+  BuildMonitorAndVerify(&kTestTwoDisallowedTimeIntervals,
+                        /*expect_delegate_called=*/false,
+                        /*expect_monitoring=*/true);
+
+  // Monitor should only notify start when passing start of interval.
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(1);
+  AdvanceAfterTimestamp(
+      kTestTwoDisallowedTimeIntervals[current_restricted_interval_index]
+          .start());
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       CurrentTimeWithinRestrictedInterval) {
+  // Monitor should notify start when it is built with current
+  // time within interval.
+  ASSERT_TRUE(SetNow(kInitialTimeWithinInterval));
+  BuildMonitorAndVerify(&kTestTwoDisallowedTimeIntervals,
+                        /*expect_delegate_called=*/true,
+                        /*expect_monitoring=*/false);
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       PolicyChangeFromNotSetToOutsideInterval) {
+  // Build monitor with empty initial list of intervals.
+  BuildMonitorAndVerify(
+      nullptr, /*expect_delegate_called=*/false, /*expect_monitoring=*/false);
+
+  // Monitor should not do any notification right after intervals update.
+  ASSERT_TRUE(SetNow(kInitialTimeBeforeInterval));
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(0);
+  UpdateRestrictedIntervals(kTestTwoDisallowedTimeIntervals);
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+  EXPECT_TRUE(IsMonitoringInterval());
+
+  // Advance time within new interval and check that notification happen.
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(1);
+  AdvanceAfterTimestamp(
+      kTestTwoDisallowedTimeIntervals[current_restricted_interval_index]
+          .start());
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       PolicyChangeFromNotSetToWithinInterval) {
+  // Build monitor with empty initial list of intervals.
+  BuildMonitorAndVerify(
+      nullptr, /*expect_delegate_called=*/false, /*expect_monitoring=*/false);
+
+  // Advance time inside upcoming new interval and update the intervals.
+  // Monitor should immediately notify about started interval.
+  ASSERT_TRUE(SetNow(kInitialTimeWithinInterval));
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(1);
+  UpdateRestrictedIntervals(kTestTwoDisallowedTimeIntervals);
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       PolicyChangeFromNotSetToEmptyInterval) {
+  BuildMonitorAndVerify(
+      nullptr, /*expect_delegate_called=*/false, /*expect_monitoring=*/false);
+
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(0);
+  UpdateRestrictedIntervals(WeeklyTimeIntervalVector());
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+  EXPECT_FALSE(IsMonitoringInterval());
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       PolicyChangeFromOneOutsideIntervalToAnother) {
+  // Build monitor with current time outside the intervals.
+  BuildMonitorAndVerify(&kTestTwoDisallowedTimeIntervals,
+                        /*expect_delegate_called=*/false,
+                        /*expect_monitoring=*/true);
+
+  // Update the intervals to outide of current time and no notification should
+  // happen yet.
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(0);
+  UpdateRestrictedIntervals(kTestOneDisallowedTimeIntervals);
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+
+  // Advance time within new interval. Monitor should notify about started
+  // interval.
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(1);
+  AdvanceAfterTimestamp(
+      kTestOneDisallowedTimeIntervals[current_restricted_interval_index]
+          .start());
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+}
+
+TEST_F(UmUpdateTimeRestrictionsMonitorTest,
+       PolicyChangeFromOutsideIntervalToWithin) {
+  ASSERT_TRUE(SetNow(kInitialTimeWithinInterval));
+
+  // Build monitor with current time outside the intervals.
+  BuildMonitorAndVerify(&kTestOneDisallowedTimeIntervals,
+                        /*expect_delegate_called=*/false,
+                        /*expect_monitoring=*/true);
+
+  // Update interval such that current time is within it. Monitor should notify
+  // about started interval.
+  EXPECT_CALL(mock_delegate_, OnRestrictedIntervalStarts()).Times(1);
+  UpdateRestrictedIntervals(kTestTwoDisallowedTimeIntervals);
+  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
+  VerifyExpectationsOnDelegate();
+}
+
+}  // namespace chromeos_update_manager
diff --git a/update_manager/update_time_restrictions_policy_impl_unittest.cc b/update_manager/update_time_restrictions_policy_impl_unittest.cc
index 74e7f3c..f99a285 100644
--- a/update_manager/update_time_restrictions_policy_impl_unittest.cc
+++ b/update_manager/update_time_restrictions_policy_impl_unittest.cc
@@ -60,7 +60,7 @@
 
     Time time;
     EXPECT_TRUE(Time::FromLocalExploded(exploded, &time));
-    fake_clock_.SetWallclockTime(time);
+    fake_clock_->SetWallclockTime(time);
     SetUpDefaultTimeProvider();
     fake_state_.device_policy_provider()
         ->var_disallowed_time_intervals()