update_engine: Don't do force updates after rollback.

If the device was rolled back via enterprise policy since the
last update check where policy was present, we shouldn't do a
forced update, because this could lead to an infinite
rollback-update loop.

This is achieved by adding a new pref 'rollback-happened' to
'powerwash_safe_prefs'. This creates a file at '/mnt/
stateful_partition/unencrypted/preserve/update_engine/prefs/
rollback-happened', which is not deleted during powerwash
(crrev.com/c/1005180). If this file exists after powerwash and
its content is 'true', it means the device was rolled back, and
forced updates must not be applied before the device is enrolled
and policy is available again.

When an update check happens and policy is available or device
becomes a consumer device, the file is deleted.

BUG=chromium:831266
TEST='cros_run_unit_tests --board=cyan --packages update_engine'

Change-Id: I0a06696701530c93d4ed388c42e43b65fe78f777
Reviewed-on: https://chromium-review.googlesource.com/1005181
Commit-Ready: Marton Hunyady <hunyadym@chromium.org>
Tested-by: Marton Hunyady <hunyadym@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/payload_state_unittest.cc b/payload_state_unittest.cc
index f1c3835..bcb196a 100644
--- a/payload_state_unittest.cc
+++ b/payload_state_unittest.cc
@@ -984,6 +984,37 @@
   EXPECT_EQ(0U, payload_state.GetNumReboots());
 }
 
+TEST(PayloadStateTest, RollbackHappened) {
+  FakeSystemState fake_system_state;
+  PayloadState payload_state;
+
+  NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
+      fake_system_state.mock_powerwash_safe_prefs();
+  EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+
+  // Verify pre-conditions are good.
+  EXPECT_FALSE(payload_state.GetRollbackHappened());
+
+  // Set to true.
+  EXPECT_CALL(*mock_powerwash_safe_prefs,
+              SetBoolean(kPrefsRollbackHappened, true));
+  payload_state.SetRollbackHappened(true);
+  EXPECT_TRUE(payload_state.GetRollbackHappened());
+
+  // Set to false.
+  EXPECT_CALL(*mock_powerwash_safe_prefs, Delete(kPrefsRollbackHappened));
+  payload_state.SetRollbackHappened(false);
+  EXPECT_FALSE(payload_state.GetRollbackHappened());
+
+  // Let's verify we can reload it correctly.
+  EXPECT_CALL(*mock_powerwash_safe_prefs, GetBoolean(kPrefsRollbackHappened, _))
+      .WillOnce(DoAll(SetArgPointee<1>(true), Return(true)));
+  EXPECT_CALL(*mock_powerwash_safe_prefs,
+              SetBoolean(kPrefsRollbackHappened, true));
+  payload_state.LoadRollbackHappened();
+  EXPECT_TRUE(payload_state.GetRollbackHappened());
+}
+
 TEST(PayloadStateTest, RollbackVersion) {
   FakeSystemState fake_system_state;
   PayloadState payload_state;