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/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