update_engine: new error message for update to rollback version

When an update is skipped because it corresponds to the rollback
version, an error message appears saying that the updates are disabled
by the administrator. This error message appears for both managed and
consumer users.

The expected behavior is to silently skip the update.

Currently this behavior is assigned to
ErrorCode::kOmahaUpdateIgnoredPerPolicy, which causes to display the
error message in the UI. As this error is also assigned to cases where
updates are actually blocked by admin policy, we need a new error
message specific for ignoring updates to rollback version.

Create kUpdateIgnoredRollbackVersion error code. When this error is
encountered, users should see the "No updates" message, so no further
error handling is required in Chromium.

BUG=b:246691369
TEST=1) FEATURES=test emerge-amd64-generic update_engine
     2a) Fake a preceding legacy rollback update.
     2b) Ensure "Your Chromebook is up to date" message appears for
     both managed and consumer accounts.

Change-Id: I3626298b34af12f39f57ad91c45169c34a36a073
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/4100471
Tested-by: Cristina Guerrero <[email protected]>
Reviewed-by: Jae Hoon Kim <[email protected]>
Commit-Queue: Cristina Guerrero <[email protected]>
diff --git a/common/error_code.h b/common/error_code.h
index e9e1156..f74ee19 100644
--- a/common/error_code.h
+++ b/common/error_code.h
@@ -92,6 +92,7 @@
   kOmahaUpdateIgnoredOverMetered = 66,
   kScaledInstallationError = 67,
   kNonCriticalUpdateEnrollmentRecovery = 68,
+  kUpdateIgnoredRollbackVersion = 69,
 
   // VERY IMPORTANT! When adding new error codes:
   //
diff --git a/common/error_code_utils.cc b/common/error_code_utils.cc
index 39f495c..af27d54 100644
--- a/common/error_code_utils.cc
+++ b/common/error_code_utils.cc
@@ -185,6 +185,8 @@
       return "ErrorCode::kScaledInstallationError";
     case ErrorCode::kNonCriticalUpdateEnrollmentRecovery:
       return "ErrorCode::kNonCriticalUpdateEnrollmentRecovery";
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
+      return "ErrorCode::kUpdateIgnoredRollbackVersion";
       // Don't add a default case to let the compiler warn about newly added
       // error codes which should be added here.
   }
diff --git a/cros/omaha_request_action.cc b/cros/omaha_request_action.cc
index 6708e5a..08d7acb 100644
--- a/cros/omaha_request_action.cc
+++ b/cros/omaha_request_action.cc
@@ -1209,6 +1209,7 @@
     case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
     case ErrorCode::kOmahaUpdateIgnoredOverCellular:
     case ErrorCode::kOmahaUpdateIgnoredOverMetered:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
       result = metrics::CheckResult::kUpdateAvailable;
       reaction = metrics::CheckReaction::kIgnored;
       break;
@@ -1256,7 +1257,7 @@
     LOG(INFO) << "Detected previous rollback from version " << rollback_version;
     if (rollback_version == response_.version) {
       LOG(INFO) << "Received version that we rolled back from. Ignoring.";
-      *error = ErrorCode::kOmahaUpdateIgnoredPerPolicy;
+      *error = ErrorCode::kUpdateIgnoredRollbackVersion;
       return true;
     }
   }
diff --git a/cros/omaha_request_action_unittest.cc b/cros/omaha_request_action_unittest.cc
index 0e6b49d..f5050a0 100644
--- a/cros/omaha_request_action_unittest.cc
+++ b/cros/omaha_request_action_unittest.cc
@@ -1050,13 +1050,16 @@
   EXPECT_FALSE(response_.update_exists);
 }
 
+// Verify that update checks will not try to download an update if it
+// corresponds to the rollback version. It should be ignored.
 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByRollback) {
   string rollback_version = "1234.0.0";
   MockPayloadState mock_payload_state;
   FakeSystemState::Get()->set_payload_state(&mock_payload_state);
   fake_update_response_.version = rollback_version;
   tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
-  tuc_params_.expected_code = ErrorCode::kOmahaUpdateIgnoredPerPolicy;
+  tuc_params_.expected_code = ErrorCode::kUpdateIgnoredRollbackVersion;
+  tuc_params_.expected_check_result = metrics::CheckResult::kUpdateAvailable;
   tuc_params_.expected_check_reaction = metrics::CheckReaction::kIgnored;
 
   EXPECT_CALL(mock_payload_state, GetRollbackVersion())
diff --git a/cros/omaha_request_builder_xml.h b/cros/omaha_request_builder_xml.h
index 9a49e42..4a382a4 100644
--- a/cros/omaha_request_builder_xml.h
+++ b/cros/omaha_request_builder_xml.h
@@ -65,7 +65,7 @@
   enum Result {
     kResultError = 0,
     kResultSuccess = 1,
-    kResultUpdateDeferred = 9,  // When we ignore/defer updates due to policy.
+    kResultUpdateDeferred = 9,  // When we ignore/defer updates.
   };
 
   OmahaEvent()
diff --git a/cros/payload_state.cc b/cros/payload_state.cc
index 1937fb9..77a69ff 100644
--- a/cros/payload_state.cc
+++ b/cros/payload_state.cc
@@ -381,6 +381,7 @@
     case ErrorCode::kOmahaUpdateIgnoredOverMetered:
     case ErrorCode::kScaledInstallationError:
     case ErrorCode::kNonCriticalUpdateEnrollmentRecovery:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
       LOG(INFO) << "Not incrementing URL index or failure count for this error";
       break;
 
diff --git a/cros/update_attempter.cc b/cros/update_attempter.cc
index 0da6a0e..9a37759 100644
--- a/cros/update_attempter.cc
+++ b/cros/update_attempter.cc
@@ -1872,6 +1872,7 @@
     case ErrorCode::kNoUpdate:
     case ErrorCode::kInvalidateLastUpdate:
     case ErrorCode::kOmahaErrorInHTTPResponse:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
       return attempt_error_code_;
     case ErrorCode::kInternalLibCurlError:
     case ErrorCode::kUnresolvedHostError:
@@ -1949,6 +1950,7 @@
   OmahaEvent::Result event_result;
   switch (code) {
     case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
     case ErrorCode::kOmahaUpdateDeferredPerPolicy:
     case ErrorCode::kOmahaUpdateDeferredForBackoff:
       event_result = OmahaEvent::kResultUpdateDeferred;
diff --git a/metrics_utils.cc b/metrics_utils.cc
index 6196d98..a16d5d9 100644
--- a/metrics_utils.cc
+++ b/metrics_utils.cc
@@ -131,6 +131,7 @@
     case ErrorCode::kDownloadCancelledPerPolicy:
     case ErrorCode::kNonCriticalUpdateEnrollmentRecovery:
     case ErrorCode::kRepeatedFpFromOmahaError:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
       return metrics::AttemptResult::kUpdateSkipped;
 
     // Special flags. These can't happen (we mask them out above) but
@@ -254,6 +255,7 @@
     case ErrorCode::kOmahaUpdateIgnoredOverMetered:
     case ErrorCode::kScaledInstallationError:
     case ErrorCode::kNonCriticalUpdateEnrollmentRecovery:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
       break;
 
     // Special flags. These can't happen (we mask them out above) but
diff --git a/update_manager/update_can_start_policy.cc b/update_manager/update_can_start_policy.cc
index 164d1d6..014cd02 100644
--- a/update_manager/update_can_start_policy.cc
+++ b/update_manager/update_can_start_policy.cc
@@ -147,6 +147,7 @@
     case ErrorCode::kOmahaUpdateIgnoredOverMetered:
     case ErrorCode::kScaledInstallationError:
     case ErrorCode::kNonCriticalUpdateEnrollmentRecovery:
+    case ErrorCode::kUpdateIgnoredRollbackVersion:
       LOG(INFO) << "Not changing URL index or failure count due to error "
                 << chromeos_update_engine::utils::ErrorCodeToString(err_code)
                 << " (" << static_cast<int>(err_code) << ")";