update_engine: Allow deprecation of DLC(s)
Currently, platform updates would block if any supported DLC(s) are
installed on the device and later CrOS version deprecates any of the
installed DLC(s).
[INFO:omaha_request_action.cc(501)] Request: <?xml version="1.0" encoding="UTF-8"?>
<request requestid="b59a48ec-6364-4a11-9400-860a35c1d85e" sessionid="" protocol="3.0" updater="ChromeOSUpdateEngine" updaterversion="0.1.0.0" installsource="scheduler" ismachine="1">
<os version="Indy" platform="Chrome OS" sp="service_pack"></os>
<app appid="test-app-id" version="0.1.0.0" track="" from_track="unittest" board="x86-generic" hardware_class="OEM MODEL 09235 7471" delta_okay="true" installdate="14" lang="en-US" fw_version="ChromeOSFirmware.1.0" ec_version="0X0A1" >
<ping active="1" a="-1" r="-1"></ping>
<updatecheck></updatecheck>
<event eventtype="54" eventresult="1" previousversion="0.0.0.0"></event>
</app>
<app appid="test-app-id_dlc-id-1" version="0.1.0.0" track="" from_track="unittest" board="x86-generic" hardware_class="OEM MODEL 09235 7471" delta_okay="true" installdate="14" >
<updatecheck></updatecheck>
</app>
<app appid="test-app-id_dlc-id-2" version="0.1.0.0" track="" from_track="unittest" board="x86-generic" hardware_class="OEM MODEL 09235 7471" delta_okay="true" installdate="14" >
<updatecheck></updatecheck>
</app>
</request>
[INFO:omaha_request_action.cc(903)] Omaha request response: <?xml version="1.0" encoding="UTF-8"?><response protocol="3.0"><daystart elapsed_seconds="100" elapsed_days="42"/><app appid="test-app-id" status="ok"><ping status="ok"/><updatecheck status="ok" _firmware_version_0="" _kernel_version_0=""><urls><url codebase="http://code/base/"/></urls><manifest version="1.2.3.4"><packages><package hash="not-used" name="file.signed" size="123" hash_sha256="4841534831323334"/></packages><actions><action event="postinstall" MetadataSize="11" MoreInfo="http://more/info" Prompt="true" IsDeltaPayload="true" MaxDaysToScatter="7" sha256="not-used" /></actions></manifest></updatecheck></app><app appid="test-app-id_dlc-id-1" status="ok"><updatecheck status="ok"><urls><url codebase="http://code/base/"/></urls><manifest version="1.2.3.4"><packages><package name="package3" size="333" hash_sha256="hash3"/></packages><actions><action event="install" run=".signed"/><action event="postinstall" MetadataSize="33"/></actions></manifest></updatecheck></app><app appid="test-app-id_dlc-id-2"><updatecheck status="noupdate"/></app></response>
...
[INFO:omaha_request_action.cc(706)] Found 3 <app>.
[INFO:omaha_request_action.cc(811)] Update for <app> test-app-id
[INFO:omaha_request_action.cc(811)] Update for <app> test-app-id_dlc-id-1
[INFO:omaha_request_action.cc(794)] No update for <app> test-app-id_dlc-id-2 but update continuing since a DLC.
...
BUG=chromium:1050777
TEST=# update_engine unittest
Change-Id: I43640f3463aa74c67465a2027bc530794eb73210
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2053077
Tested-by: Jae Hoon Kim <kimjae@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index b6b4356..58e7f47 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -788,6 +788,13 @@
for (const auto& app : parser_data->apps) {
const string& status = app.updatecheck_status;
if (status == kValNoUpdate) {
+ // If the app is a DLC, allow status "noupdate" to support DLC
+ // deprecations.
+ if (params_->IsDlcAppId(app.id)) {
+ LOG(INFO) << "No update for <app> " << app.id
+ << " but update continuing since a DLC.";
+ continue;
+ }
// Don't update if any app has status="noupdate".
LOG(INFO) << "No update for <app> " << app.id;
output_object->update_exists = false;
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index d1cb4ed..2528f7b 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -86,6 +86,8 @@
const char kTestAppId[] = "test-app-id";
const char kTestAppId2[] = "test-app2-id";
const char kTestAppIdSkipUpdatecheck[] = "test-app-id-skip-updatecheck";
+const char kDlcId1[] = "dlc-id-1";
+const char kDlcId2[] = "dlc-id-2";
// This is a helper struct to allow unit tests build an update response with the
// values they care about.
@@ -131,6 +133,8 @@
}
string GetUpdateResponse() const {
+ chromeos_update_engine::OmahaRequestParams request_params{nullptr};
+ request_params.set_app_id(app_id);
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
"protocol=\"3.0\">"
"<daystart elapsed_seconds=\"100\"" +
@@ -196,6 +200,21 @@
(multi_app_skip_updatecheck
? "<app appid=\"" + app_id_skip_updatecheck + "\"></app>"
: "") +
+ (dlc_app_update
+ ? "<app appid=\"" + request_params.GetDlcAppId(kDlcId1) +
+ "\" status=\"ok\">"
+ "<updatecheck status=\"ok\"><urls><url codebase=\"" +
+ codebase + "\"/></urls><manifest version=\"" + version +
+ "\"><packages><package name=\"package3\" size=\"333\" "
+ "hash_sha256=\"hash3\"/></packages><actions>"
+ "<action event=\"install\" run=\".signed\"/>"
+ "<action event=\"postinstall\" MetadataSize=\"33\"/>"
+ "</actions></manifest></updatecheck></app>"
+ : "") +
+ (dlc_app_no_update
+ ? "<app appid=\"" + request_params.GetDlcAppId(kDlcId2) +
+ "\"><updatecheck status=\"noupdate\"/></app>"
+ : "") +
"</response>";
}
@@ -244,6 +263,10 @@
bool multi_app_skip_updatecheck = false;
// Whether to include more than one package in an app.
bool multi_package = false;
+ // Whether to include a DLC app with updatecheck tag.
+ bool dlc_app_update = false;
+ // Whether to include a DLC app with no updatecheck tag.
+ bool dlc_app_no_update = false;
// Whether the payload is a rollback.
bool rollback = false;
@@ -2688,6 +2711,7 @@
pos++;
}
EXPECT_EQ(request_params_.dlc_apps_params().size(), updatecheck_count);
+ EXPECT_TRUE(response.update_exists);
}
TEST_F(OmahaRequestActionTest, InstallMissingPlatformVersionTest) {
@@ -2706,6 +2730,38 @@
EXPECT_EQ(fake_update_response_.current_version, response.version);
}
+TEST_F(OmahaRequestActionTest, UpdateWithDlcTest) {
+ request_params_.set_dlc_apps_params(
+ {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}}});
+ fake_update_response_.dlc_app_update = true;
+ tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
+ ASSERT_TRUE(TestUpdateCheck());
+
+ EXPECT_TRUE(response.update_exists);
+}
+
+TEST_F(OmahaRequestActionTest, UpdateWithDeprecatedDlcTest) {
+ request_params_.set_dlc_apps_params(
+ {{request_params_.GetDlcAppId(kDlcId2), {.name = kDlcId2}}});
+ fake_update_response_.dlc_app_no_update = true;
+ tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
+ ASSERT_TRUE(TestUpdateCheck());
+
+ EXPECT_TRUE(response.update_exists);
+}
+
+TEST_F(OmahaRequestActionTest, UpdateWithDlcAndDeprecatedDlcTest) {
+ request_params_.set_dlc_apps_params(
+ {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}},
+ {request_params_.GetDlcAppId(kDlcId2), {.name = kDlcId2}}});
+ fake_update_response_.dlc_app_update = true;
+ fake_update_response_.dlc_app_no_update = true;
+ tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
+ ASSERT_TRUE(TestUpdateCheck());
+
+ EXPECT_TRUE(response.update_exists);
+}
+
TEST_F(OmahaRequestActionTest, PastRollbackVersionsNoEntries) {
fake_update_response_.rollback = true;
fake_update_response_.rollback_allowed_milestones = 4;
diff --git a/omaha_request_params.cc b/omaha_request_params.cc
index e6d96a4..1cfbc9c 100644
--- a/omaha_request_params.cc
+++ b/omaha_request_params.cc
@@ -249,10 +249,14 @@
: image_props_.product_id;
}
-string OmahaRequestParams::GetDlcAppId(std::string dlc_id) const {
+string OmahaRequestParams::GetDlcAppId(const std::string& dlc_id) const {
// Create APP ID according to |dlc_id| (sticking the current AppID to the
// DLC module ID with an underscode).
return GetAppId() + "_" + dlc_id;
}
+bool OmahaRequestParams::IsDlcAppId(const std::string& app_id) const {
+ return dlc_apps_params().find(app_id) != dlc_apps_params().end();
+}
+
} // namespace chromeos_update_engine
diff --git a/omaha_request_params.h b/omaha_request_params.h
index b984002..14f3eaf 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -225,9 +225,12 @@
// download channel.
virtual std::string GetAppId() const;
- // Returns the DLC app ID corresponding to the current value of the
- // download channel.
- virtual std::string GetDlcAppId(std::string dlc_id) const;
+ // Returns the DLC app ID.
+ virtual std::string GetDlcAppId(const std::string& dlc_id) const;
+
+ // Returns true if the App ID is a DLC App ID that is currently part of the
+ // request parameters.
+ virtual bool IsDlcAppId(const std::string& app_id) const;
// Suggested defaults
static const char kOsVersion[];
@@ -404,7 +407,7 @@
// The metadata/prefs root path for DLCs.
std::string dlc_prefs_root_;
- // A list of DLC modules to install.
+ // A list of DLC modules to install. A mapping from DLC App ID to |AppParams|.
std::map<std::string, AppParams> dlc_apps_params_;
// This variable defines whether the payload is being installed in the current