update_engine: Add new rollback policy values

The new values are:
- RollbackAndRestoreIfPossible: always roll back, but try to save and
  restore data if possible. This is rollback_allowed=true.
- RollbackWithRestoreOnly: only roll back if it's possible to save and
  restore data. This is rollback_allowed=false until data save and
  restore is implemented.

BUG=chromium:878736
TEST='cros_run_unit_tests --board=caroline --packages update_engine'

Change-Id: Ifd198610c26d11521b39da8fce5f44dc97609bf5
Reviewed-on: https://chromium-review.googlesource.com/1194229
Commit-Ready: Marton Hunyady <hunyadym@chromium.org>
Tested-by: Marton Hunyady <hunyadym@chromium.org>
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: Sen Jiang <senj@chromium.org>
diff --git a/update_manager/boxed_value.cc b/update_manager/boxed_value.cc
index 971e9b7..c987110 100644
--- a/update_manager/boxed_value.cc
+++ b/update_manager/boxed_value.cc
@@ -146,6 +146,10 @@
       return "Disabled";
     case RollbackToTargetVersion::kRollbackWithFullPowerwash:
       return "Rollback with full powerwash";
+    case RollbackToTargetVersion::kRollbackAndRestoreIfPossible:
+      return "Rollback and restore if possible";
+    case RollbackToTargetVersion::kRollbackWithRestoreOnly:
+      return "Rollback with restore only";
     case RollbackToTargetVersion::kMaxValue:
       NOTREACHED();
       return "Max value";
diff --git a/update_manager/boxed_value_unittest.cc b/update_manager/boxed_value_unittest.cc
index 3fa0f1a..b15a504 100644
--- a/update_manager/boxed_value_unittest.cc
+++ b/update_manager/boxed_value_unittest.cc
@@ -207,6 +207,15 @@
             BoxedValue(new RollbackToTargetVersion(
                            RollbackToTargetVersion::kRollbackWithFullPowerwash))
                 .ToString());
+  EXPECT_EQ(
+      "Rollback and restore if possible",
+      BoxedValue(new RollbackToTargetVersion(
+                     RollbackToTargetVersion::kRollbackAndRestoreIfPossible))
+          .ToString());
+  EXPECT_EQ("Rollback with restore only",
+            BoxedValue(new RollbackToTargetVersion(
+                           RollbackToTargetVersion::kRollbackWithRestoreOnly))
+                .ToString());
 }
 
 TEST(UmBoxedValueTest, SetConnectionTypeToString) {
diff --git a/update_manager/chromeos_policy_unittest.cc b/update_manager/chromeos_policy_unittest.cc
index 96f3d79..f97d4ed 100644
--- a/update_manager/chromeos_policy_unittest.cc
+++ b/update_manager/chromeos_policy_unittest.cc
@@ -278,6 +278,18 @@
       true, RollbackToTargetVersion::kRollbackWithFullPowerwash));
 }
 
+TEST_F(UmChromeOSPolicyTest, UpdateCheckAllowedRollbackAndRestoreIfPossible) {
+  // We're doing rollback even if we don't support data save and restore.
+  EXPECT_TRUE(TestRollbackAllowed(
+      true, RollbackToTargetVersion::kRollbackAndRestoreIfPossible));
+}
+
+TEST_F(UmChromeOSPolicyTest, UpdateCheckAllowedRollbackWithRestoreOnly) {
+  // We're not allowed to do rollback until we support data save and restore.
+  EXPECT_FALSE(TestRollbackAllowed(
+      true, RollbackToTargetVersion::kRollbackWithRestoreOnly));
+}
+
 TEST_F(UmChromeOSPolicyTest, UpdateCheckAllowedRollbackDisabled) {
   EXPECT_FALSE(TestRollbackAllowed(true, RollbackToTargetVersion::kDisabled));
 }
diff --git a/update_manager/enterprise_device_policy_impl.cc b/update_manager/enterprise_device_policy_impl.cc
index 6f14b1f..27f3d19 100644
--- a/update_manager/enterprise_device_policy_impl.cc
+++ b/update_manager/enterprise_device_policy_impl.cc
@@ -96,6 +96,17 @@
           LOG(INFO) << "Policy allows rollbacks.";
           result->rollback_allowed = true;
           break;
+        case RollbackToTargetVersion::kRollbackAndRestoreIfPossible:
+          LOG(INFO) << "Policy allows rollbacks, also restore if possible.";
+          // We don't support restore yet, but policy still allows rollback.
+          result->rollback_allowed = true;
+          break;
+        case RollbackToTargetVersion::kRollbackWithRestoreOnly:
+          LOG(INFO) << "Policy only allows rollbacks if restore is possible.";
+          // We don't support restore yet, policy doesn't allow rollback in this
+          // case.
+          result->rollback_allowed = false;
+          break;
         case RollbackToTargetVersion::kMaxValue:
           NOTREACHED();
           // Don't add a default case to let the compiler warn about newly
diff --git a/update_manager/rollback_prefs.h b/update_manager/rollback_prefs.h
index 1783eb0..07e1834 100644
--- a/update_manager/rollback_prefs.h
+++ b/update_manager/rollback_prefs.h
@@ -30,8 +30,10 @@
   kUnspecified = 0,
   kDisabled = 1,
   kRollbackWithFullPowerwash = 2,
+  kRollbackAndRestoreIfPossible = 3,
+  kRollbackWithRestoreOnly = 4,
   // This value must be the last entry.
-  kMaxValue = 3
+  kMaxValue = 5
 };
 
 }  // namespace chromeos_update_manager