update_engine: Add ChannelDowngradeBehavior
Add the ChannelDowngradeBehaviorPolicy to update_engine.
It will be used to decide whether to rollback and powerwash or wait
until the target channel catches up on a channel downgrade
(e.g. beta to stable).
BUG=chromium:1122531
TEST=FEATURES=test emerge-amd64-generic update_engine
TEST=manual test on device
Change-Id: Iad075e1019084fafec8509c23f2bd55e9755b39e
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2379690
Tested-by: Miriam Polzer <mpolzer@google.com>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/update_manager/boxed_value.cc b/update_manager/boxed_value.cc
index 4dff9ef..b499c30 100644
--- a/update_manager/boxed_value.cc
+++ b/update_manager/boxed_value.cc
@@ -232,4 +232,22 @@
return retval;
}
+template <>
+string BoxedValue::ValuePrinter<ChannelDowngradeBehavior>(const void* value) {
+ const ChannelDowngradeBehavior* val =
+ reinterpret_cast<const ChannelDowngradeBehavior*>(value);
+ switch (*val) {
+ case ChannelDowngradeBehavior::kUnspecified:
+ return "Unspecified";
+ case ChannelDowngradeBehavior::kWaitForVersionToCatchUp:
+ return "Wait for the target channel to catch up";
+ case ChannelDowngradeBehavior::kRollback:
+ return "Roll back and powerwash on channel downgrade";
+ case ChannelDowngradeBehavior::kAllowUserToConfigure:
+ return "User decides on channel downgrade behavior";
+ }
+ NOTREACHED();
+ return "Unknown";
+}
+
} // namespace chromeos_update_manager
diff --git a/update_manager/device_policy_provider.h b/update_manager/device_policy_provider.h
index d63c416..f177e71 100644
--- a/update_manager/device_policy_provider.h
+++ b/update_manager/device_policy_provider.h
@@ -87,6 +87,11 @@
virtual Variable<WeeklyTimeIntervalVector>*
var_disallowed_time_intervals() = 0;
+ // Variable that determins whether we should powerwash and rollback on channel
+ // downgrade for enrolled devices.
+ virtual Variable<ChannelDowngradeBehavior>*
+ var_channel_downgrade_behavior() = 0;
+
protected:
DevicePolicyProvider() {}
diff --git a/update_manager/fake_device_policy_provider.h b/update_manager/fake_device_policy_provider.h
index 352e51e..44a9464 100644
--- a/update_manager/fake_device_policy_provider.h
+++ b/update_manager/fake_device_policy_provider.h
@@ -95,6 +95,11 @@
return &var_disallowed_time_intervals_;
}
+ FakeVariable<ChannelDowngradeBehavior>* var_channel_downgrade_behavior()
+ override {
+ return &var_channel_downgrade_behavior_;
+ }
+
private:
FakeVariable<bool> var_device_policy_is_loaded_{"policy_is_loaded",
kVariableModePoll};
@@ -126,6 +131,8 @@
"auto_launched_kiosk_app_id", kVariableModePoll};
FakeVariable<WeeklyTimeIntervalVector> var_disallowed_time_intervals_{
"disallowed_time_intervals", kVariableModePoll};
+ FakeVariable<ChannelDowngradeBehavior> var_channel_downgrade_behavior_{
+ "channel_downgrade_behavior", kVariableModePoll};
DISALLOW_COPY_AND_ASSIGN(FakeDevicePolicyProvider);
};
diff --git a/update_manager/real_device_policy_provider.cc b/update_manager/real_device_policy_provider.cc
index bd9d415..51d01d5 100644
--- a/update_manager/real_device_policy_provider.cc
+++ b/update_manager/real_device_policy_provider.cc
@@ -209,6 +209,21 @@
return true;
}
+bool RealDevicePolicyProvider::ConvertChannelDowngradeBehavior(
+ ChannelDowngradeBehavior* channel_downgrade_behavior) const {
+ int behavior;
+ if (!policy_provider_->GetDevicePolicy().GetChannelDowngradeBehavior(
+ &behavior)) {
+ return false;
+ }
+ if (behavior < static_cast<int>(ChannelDowngradeBehavior::kFirstValue) ||
+ behavior > static_cast<int>(ChannelDowngradeBehavior::kLastValue)) {
+ return false;
+ }
+ *channel_downgrade_behavior = static_cast<ChannelDowngradeBehavior>(behavior);
+ return true;
+}
+
void RealDevicePolicyProvider::RefreshDevicePolicy() {
if (!policy_provider_->Reload()) {
LOG(INFO) << "No device policies/settings present.";
@@ -247,6 +262,8 @@
&DevicePolicy::GetAutoLaunchedKioskAppId);
UpdateVariable(&var_disallowed_time_intervals_,
&RealDevicePolicyProvider::ConvertDisallowedTimeIntervals);
+ UpdateVariable(&var_channel_downgrade_behavior_,
+ &RealDevicePolicyProvider::ConvertChannelDowngradeBehavior);
}
} // namespace chromeos_update_manager
diff --git a/update_manager/real_device_policy_provider.h b/update_manager/real_device_policy_provider.h
index e6df18c..134e118 100644
--- a/update_manager/real_device_policy_provider.h
+++ b/update_manager/real_device_policy_provider.h
@@ -113,6 +113,11 @@
return &var_disallowed_time_intervals_;
}
+ Variable<ChannelDowngradeBehavior>* var_channel_downgrade_behavior()
+ override {
+ return &var_channel_downgrade_behavior_;
+ }
+
private:
FRIEND_TEST(UmRealDevicePolicyProviderTest, RefreshScheduledTest);
FRIEND_TEST(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded);
@@ -174,6 +179,11 @@
// devices do not have an owner).
bool ConvertHasOwner(bool* has_owner) const;
+ // Wrapper for |DevicePolicy::GetChannelDowngradeBehavior| that converts the
+ // result to |ChannelDowngradeBehavior|.
+ bool ConvertChannelDowngradeBehavior(
+ ChannelDowngradeBehavior* channel_downgrade_behavior) const;
+
// Used for fetching information about the device policy.
policy::PolicyProvider* policy_provider_;
@@ -216,6 +226,8 @@
"update_time_restrictions"};
AsyncCopyVariable<std::string> var_auto_launched_kiosk_app_id_{
"auto_launched_kiosk_app_id"};
+ AsyncCopyVariable<ChannelDowngradeBehavior> var_channel_downgrade_behavior_{
+ "channel_downgrade_behavior"};
DISALLOW_COPY_AND_ASSIGN(RealDevicePolicyProvider);
};
diff --git a/update_manager/real_device_policy_provider_unittest.cc b/update_manager/real_device_policy_provider_unittest.cc
index 1384e6f..fd46d6e 100644
--- a/update_manager/real_device_policy_provider_unittest.cc
+++ b/update_manager/real_device_policy_provider_unittest.cc
@@ -195,6 +195,8 @@
UmTestUtils::ExpectVariableNotSet(
provider_->var_auto_launched_kiosk_app_id());
UmTestUtils::ExpectVariableNotSet(provider_->var_disallowed_time_intervals());
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_channel_downgrade_behavior());
}
TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) {
@@ -377,4 +379,55 @@
provider_->var_disallowed_time_intervals());
}
+TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorConverted) {
+ SetUpExistentDevicePolicy();
+ EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
+#if USE_DBUS
+ .Times(2)
+#else
+ .Times(1)
+#endif // USE_DBUS
+ .WillRepeatedly(DoAll(SetArgPointee<0>(static_cast<int>(
+ ChannelDowngradeBehavior::kRollback)),
+ Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableHasValue(
+ ChannelDowngradeBehavior::kRollback,
+ provider_->var_channel_downgrade_behavior());
+}
+
+TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorTooSmall) {
+ SetUpExistentDevicePolicy();
+ EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
+#if USE_DBUS
+ .Times(2)
+#else
+ .Times(1)
+#endif // USE_DBUS
+ .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_channel_downgrade_behavior());
+}
+
+TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorTooLarge) {
+ SetUpExistentDevicePolicy();
+ EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
+#if USE_DBUS
+ .Times(2)
+#else
+ .Times(1)
+#endif // USE_DBUS
+ .WillRepeatedly(DoAll(SetArgPointee<0>(10), Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_channel_downgrade_behavior());
+}
+
} // namespace chromeos_update_manager
diff --git a/update_manager/rollback_prefs.h b/update_manager/rollback_prefs.h
index 9567701..6cbc447 100644
--- a/update_manager/rollback_prefs.h
+++ b/update_manager/rollback_prefs.h
@@ -35,6 +35,19 @@
kMaxValue = 4
};
+// Whether the device should do rollback and powerwash on channel downgrade.
+// Matches chrome_device_policy.proto's
+// |AutoUpdateSettingsProto::ChannelDowngradeBehavior|.
+enum class ChannelDowngradeBehavior {
+ kUnspecified = 0,
+ kWaitForVersionToCatchUp = 1,
+ kRollback = 2,
+ kAllowUserToConfigure = 3,
+ // These values must be kept up to date.
+ kFirstValue = kUnspecified,
+ kLastValue = kAllowUserToConfigure
+};
+
} // namespace chromeos_update_manager
#endif // UPDATE_ENGINE_UPDATE_MANAGER_ROLLBACK_PREFS_H_