update_engine: Add enterprise rollback update policy impl

This CL adds a new rollback update policy which checks if the
update to be downloaded is a rollback by checking the value of
InstallPlan::is_rollback which is set in omaha_response_handler_action.
The intent is to consult this policy in a later CL in
ChromeOSPolicy::UpdateCanBeApplied as download time restrictions will
not be applied if current update being downloaded is a rollback.

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

Change-Id: Ib3a23a57fb60d4d0e983688f78941cdbd587718e
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2532793
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
Tested-by: Saurabh Nijhara <snijhara@google.com>
Commit-Queue: Saurabh Nijhara <snijhara@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 5ac0a3f..3674f50 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -225,6 +225,7 @@
     "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",
@@ -531,6 +532,7 @@
       "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",
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