update_engine: Add powerwash flag to update status

Add a powerwash flag to the update status which is set to true if and
only if a powerwash takes place. This will ensure that the user is
informed of a pending powerwash exactly when it is going to happen.

BUG=chromium:1070563
TEST=FEATURES=test emerge-amd64-generic update_engine
channel change and update on test device

Cq-Depend: chromium:2187671
Change-Id: I58314ecc7c9c2e64c906ef5b31cb780948196296
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2187672
Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Tested-by: Miriam Polzer <mpolzer@google.com>
Commit-Queue: Miriam Polzer <mpolzer@google.com>
diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc
index 5ca519a..8e9a7fd 100644
--- a/client_library/client_dbus.cc
+++ b/client_library/client_dbus.cc
@@ -56,6 +56,8 @@
   out_status->is_enterprise_rollback = status.is_enterprise_rollback();
   out_status->is_install = status.is_install();
   out_status->eol_date = status.eol_date();
+  out_status->will_powerwash_after_reboot =
+      status.will_powerwash_after_reboot();
 }
 }  // namespace
 
diff --git a/client_library/include/update_engine/update_status.h b/client_library/include/update_engine/update_status.h
index c1d0968..b1cf1f8 100644
--- a/client_library/include/update_engine/update_status.h
+++ b/client_library/include/update_engine/update_status.h
@@ -90,6 +90,8 @@
   bool is_install;
   // The end-of-life date of the device in the number of days since Unix Epoch.
   int64_t eol_date;
+  // The system will powerwash once the update is applied.
+  bool will_powerwash_after_reboot;
 };
 
 }  // namespace update_engine
diff --git a/dbus_service.cc b/dbus_service.cc
index 46ac1d1..a282d1e 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -47,6 +47,8 @@
   out_status->set_is_enterprise_rollback(ue_status.is_enterprise_rollback);
   out_status->set_is_install(ue_status.is_install);
   out_status->set_eol_date(ue_status.eol_date);
+  out_status->set_will_powerwash_after_reboot(
+      ue_status.will_powerwash_after_reboot);
 }
 }  // namespace
 
diff --git a/update_attempter.cc b/update_attempter.cc
index 0ead18a..6324a48 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -1507,6 +1507,12 @@
   system_state_->prefs()->GetString(kPrefsOmahaEolDate, &str_eol_date);
   out_status->eol_date = StringToEolDate(str_eol_date);
 
+  // A powerwash will take place either if the install plan says it is required
+  // or if an enterprise rollback is happening.
+  out_status->will_powerwash_after_reboot =
+      install_plan_ &&
+      (install_plan_->powerwash_required || install_plan_->is_rollback);
+
   return true;
 }
 
diff --git a/update_attempter.h b/update_attempter.h
index e270b59..1bf552b 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -265,9 +265,11 @@
   FRIEND_TEST(UpdateAttempterTest, DisableDeltaUpdateIfNeededTest);
   FRIEND_TEST(UpdateAttempterTest, DownloadProgressAccumulationTest);
   FRIEND_TEST(UpdateAttempterTest, InstallSetsStatusIdle);
-  FRIEND_TEST(UpdateAttempterTest, IsEnterpriseRollbackInGetStatusDefault);
   FRIEND_TEST(UpdateAttempterTest, IsEnterpriseRollbackInGetStatusTrue);
   FRIEND_TEST(UpdateAttempterTest, IsEnterpriseRollbackInGetStatusFalse);
+  FRIEND_TEST(UpdateAttempterTest,
+              PowerwashInGetStatusTrueBecausePowerwashRequired);
+  FRIEND_TEST(UpdateAttempterTest, PowerwashInGetStatusTrueBecauseRollback);
   FRIEND_TEST(UpdateAttempterTest, MarkDeltaUpdateFailureTest);
   FRIEND_TEST(UpdateAttempterTest, PingOmahaTest);
   FRIEND_TEST(UpdateAttempterTest, ProcessingDoneInstallError);
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 5a6a23e..3a1646f 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -2317,6 +2317,30 @@
   EXPECT_TRUE(status.is_enterprise_rollback);
 }
 
+TEST_F(UpdateAttempterTest, PowerwashInGetStatusDefault) {
+  UpdateEngineStatus status;
+  attempter_.GetStatus(&status);
+  EXPECT_FALSE(status.will_powerwash_after_reboot);
+}
+
+TEST_F(UpdateAttempterTest, PowerwashInGetStatusTrueBecausePowerwashRequired) {
+  attempter_.install_plan_.reset(new InstallPlan);
+  attempter_.install_plan_->powerwash_required = true;
+
+  UpdateEngineStatus status;
+  attempter_.GetStatus(&status);
+  EXPECT_TRUE(status.will_powerwash_after_reboot);
+}
+
+TEST_F(UpdateAttempterTest, PowerwashInGetStatusTrueBecauseRollback) {
+  attempter_.install_plan_.reset(new InstallPlan);
+  attempter_.install_plan_->is_rollback = true;
+
+  UpdateEngineStatus status;
+  attempter_.GetStatus(&status);
+  EXPECT_TRUE(status.will_powerwash_after_reboot);
+}
+
 TEST_F(UpdateAttempterTest, FutureEolTest) {
   EolDate eol_date = std::numeric_limits<int64_t>::max();
   EXPECT_CALL(*prefs_, GetString(kPrefsOmahaEolDate, _))
diff --git a/update_status_utils.cc b/update_status_utils.cc
index f88bb1a..6c618ec 100644
--- a/update_status_utils.cc
+++ b/update_status_utils.cc
@@ -38,6 +38,7 @@
 const char kNewSize[] = "NEW_SIZE";
 const char kNewVersion[] = "NEW_VERSION";
 const char kProgress[] = "PROGRESS";
+const char kWillPowerwashAfterReboot[] = "WILL_POWERWASH_AFTER_REBOOT";
 
 }  // namespace
 
@@ -84,6 +85,8 @@
   key_value_store.SetBoolean(kIsEnterpriseRollback,
                              status.is_enterprise_rollback);
   key_value_store.SetBoolean(kIsInstall, status.is_install);
+  key_value_store.SetBoolean(kWillPowerwashAfterReboot,
+                             status.will_powerwash_after_reboot);
 
   return key_value_store.SaveToString();
 }
diff --git a/update_status_utils_unittest.cc b/update_status_utils_unittest.cc
index e3dd037..228201c 100644
--- a/update_status_utils_unittest.cc
+++ b/update_status_utils_unittest.cc
@@ -35,6 +35,7 @@
       .new_version = "12345.0.0",
       .is_enterprise_rollback = true,
       .is_install = true,
+      .will_powerwash_after_reboot = true,
   };
   string print =
       R"(CURRENT_OP=UPDATE_STATUS_CHECKING_FOR_UPDATE
@@ -44,6 +45,7 @@
 NEW_SIZE=888
 NEW_VERSION=12345.0.0
 PROGRESS=0.5
+WILL_POWERWASH_AFTER_REBOOT=true
 )";
   EXPECT_EQ(print, UpdateEngineStatusToString(update_engine_status));
 }