ResetStatus if update_engine boot in different slot but same build
Old behavior:
When update_engine starts up after device take OTA and reboot, if
device booted into a different build(check build fingerprint),
ResetStatus().
When we apply a self-ota, device will boot into the same build, so
ResetStatus() is never called. If we apply the same OTA at this point,
this OTA will be treated as a "resume", and will fail to install because
we never call libsnapshot's API to allocate snapshot for new update.
Changed to ResetStatus() if boot slot changed, or build fingerprint
changed.
Bug: 185019674
Test: apply self-full OTA, reboot, repeat 2 times.
Change-Id: Idcc29dc1c02f3b9b2c84ed1978abedb651a3875a
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index ba61f25..2ffa0da 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -884,20 +884,25 @@
string current_version =
android::base::GetProperty("ro.build.version.incremental", "");
TEST_AND_RETURN(!current_version.empty());
+ const auto current_slot = boot_control_->GetCurrentSlot();
// If there's no record of previous version (e.g. due to a data wipe), we
// save the info of current boot and skip the metrics report.
if (!prefs_->Exists(kPrefsPreviousVersion)) {
prefs_->SetString(kPrefsBootId, current_boot_id);
prefs_->SetString(kPrefsPreviousVersion, current_version);
+ prefs_->SetInt64(std::string{kPrefsPreviousSlot},
+ boot_control_->GetCurrentSlot());
ClearMetricsPrefs();
return;
}
+ int64_t previous_slot = -1;
+ prefs_->GetInt64(kPrefsPreviousSlot, &previous_slot);
string previous_version;
- // update_engine restarted under the same build.
+ // update_engine restarted under the same build and same slot.
// TODO(xunchang) identify and report rollback by checking UpdateMarker.
if (prefs_->GetString(kPrefsPreviousVersion, &previous_version) &&
- previous_version == current_version) {
+ previous_version == current_version && previous_slot == current_slot) {
string last_boot_id;
bool is_reboot = prefs_->Exists(kPrefsBootId) &&
(prefs_->GetString(kPrefsBootId, &last_boot_id) &&
@@ -917,6 +922,8 @@
// TODO(xunchang) check the build version is larger than the previous one.
prefs_->SetString(kPrefsBootId, current_boot_id);
prefs_->SetString(kPrefsPreviousVersion, current_version);
+ prefs_->SetInt64(std::string{kPrefsPreviousSlot},
+ boot_control_->GetCurrentSlot());
bool previous_attempt_exists = prefs_->Exists(kPrefsPayloadAttemptNumber);
// |kPrefsPayloadAttemptNumber| should be cleared upon successful update.
diff --git a/aosp/update_attempter_android_unittest.cc b/aosp/update_attempter_android_unittest.cc
index f799df3..f73df16 100644
--- a/aosp/update_attempter_android_unittest.cc
+++ b/aosp/update_attempter_android_unittest.cc
@@ -24,6 +24,7 @@
#include <base/time/time.h>
#include <gtest/gtest.h>
+#include "common/constants.h"
#include "update_engine/aosp/daemon_state_android.h"
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_clock.h"
@@ -81,6 +82,8 @@
prefs_.SetString(kPrefsPreviousVersion, build_version);
prefs_.SetString(kPrefsBootId, "oldboot");
prefs_.SetInt64(kPrefsNumReboots, 1);
+ prefs_.SetInt64(kPrefsPreviousSlot, 1);
+ boot_control_.SetCurrentSlot(1);
EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(_)).Times(0);
update_attempter_android_.Init();
@@ -88,15 +91,15 @@
// Check that the boot_id and reboot_count are updated.
std::string boot_id;
utils::GetBootId(&boot_id);
- EXPECT_TRUE(prefs_.Exists(kPrefsBootId));
+ ASSERT_TRUE(prefs_.Exists(kPrefsBootId));
std::string prefs_boot_id;
- EXPECT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
- EXPECT_EQ(boot_id, prefs_boot_id);
+ ASSERT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
+ ASSERT_EQ(boot_id, prefs_boot_id);
- EXPECT_TRUE(prefs_.Exists(kPrefsNumReboots));
+ ASSERT_TRUE(prefs_.Exists(kPrefsNumReboots));
int64_t reboot_count;
- EXPECT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
- EXPECT_EQ(2, reboot_count);
+ ASSERT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
+ ASSERT_EQ(2, reboot_count);
}
TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) {