update_engine: add variable for DeviceQuickFixBuildToken policy

This CL makes DeviceQuickFixBuildToken policy visible in update_manager
which would be used in a follow up CL to skip applying
DeviceAutoUpdateTimeRestrictions when a quick fix build token is set.
This CL also adds quick fix token in UpdateCheckParams which is used
by UpdateAttempter to pass the token in OmahaRequestParams.

BUG=chromium:1117450
TEST=FEATURES=test emerge-${BOARD} update_engine

Change-Id: If43ad8cd2955bbeb1cbd1dcacac79742fa0a6a20
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2521189
Commit-Queue: Saurabh Nijhara <snijhara@google.com>
Tested-by: Saurabh Nijhara <snijhara@google.com>
Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
diff --git a/cros/omaha_request_params.cc b/cros/omaha_request_params.cc
index 0d69b24..adcfc75 100644
--- a/cros/omaha_request_params.cc
+++ b/cros/omaha_request_params.cc
@@ -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.
diff --git a/cros/omaha_request_params_unittest.cc b/cros/omaha_request_params_unittest.cc
index fbcd1a3..fdbb834 100644
--- a/cros/omaha_request_params_unittest.cc
+++ b/cros/omaha_request_params_unittest.cc
@@ -290,4 +290,9 @@
   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/update_attempter.cc b/cros/update_attempter.cc
index 745272c..0291199 100644
--- a/cros/update_attempter.cc
+++ b/cros/update_attempter.cc
@@ -409,16 +409,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 (SystemState::Get()->device_policy()) {
-    if (!SystemState::Get()->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 = "
diff --git a/cros/update_attempter.h b/cros/update_attempter.h
index 09e613f..3678707 100644
--- a/cros/update_attempter.h
+++ b/cros/update_attempter.h
@@ -289,6 +289,7 @@
   FRIEND_TEST(UpdateAttempterTest, UpdateDeferredByPolicyTest);
   FRIEND_TEST(UpdateAttempterTest, UpdateIsNotRunningWhenUpdateAvailable);
   FRIEND_TEST(UpdateAttempterTest, GetSuccessfulDlcIds);
+  FRIEND_TEST(UpdateAttempterTest, QuickFixTokenWhenDeviceIsEnterpriseEnrolled);
 
   // Returns the special flags to be added to ErrorCode values based on the
   // parameters used in the current update attempt.
diff --git a/cros/update_attempter_unittest.cc b/cros/update_attempter_unittest.cc
index ab4a5f2..b348d50 100644
--- a/cros/update_attempter_unittest.cc
+++ b/cros/update_attempter_unittest.cc
@@ -288,7 +288,6 @@
   void SessionIdTestEnforceEmptyStrPingOmaha();
   void SessionIdTestConsistencyInUpdateFlow();
   void SessionIdTestInDownloadAction();
-  void UpdateToQuickFixBuildStart(bool set_token);
   void ResetRollbackHappenedStart(bool is_consumer,
                                   bool is_policy_available,
                                   bool expected_reset);
@@ -2153,43 +2152,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>();
-  FakeSystemState::Get()->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) {
diff --git a/update_manager/chromeos_policy.cc b/update_manager/chromeos_policy.cc
index 262987e..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;
diff --git a/update_manager/chromeos_policy_unittest.cc b/update_manager/chromeos_policy_unittest.cc
index 53e8a52..97a4599 100644
--- a/update_manager/chromeos_policy_unittest.cc
+++ b/update_manager/chromeos_policy_unittest.cc
@@ -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);
 }
 
diff --git a/update_manager/default_policy.cc b/update_manager/default_policy.cc
index 5a38180..cb9977f 100644
--- a/update_manager/default_policy.cc
+++ b/update_manager/default_policy.cc
@@ -46,6 +46,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.
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/fake_device_policy_provider.h b/update_manager/fake_device_policy_provider.h
index 55d66b3..87691cb 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};
@@ -139,6 +143,8 @@
       "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/policy.h b/update_manager/policy.h
index 595fb7c..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};
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