Loading tools/aapt2/cmd/Link.h +5 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,11 @@ class LinkCommand : public Command { "are separated by ',' and the name is separated from the value by '='.\n" "Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).", &feature_flags_args_); AddOptionalSwitch("--non-updatable-system", "Mark the app as a non-updatable system app. This inserts\n" "updatableSystem=\"false\" to the root manifest node, overwriting any\n" "existing attribute. This is ignored if the manifest has a versionCode.", &options_.manifest_fixer_options.non_updatable_system); } int Action(const std::vector<std::string>& args) override; Loading tools/aapt2/link/ManifestFixer.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, android::IDiagn } } if (options_.non_updatable_system) { if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) { el->RemoveAttribute("", "updatableSystem"); el->attributes.push_back(xml::Attribute{"", "updatableSystem", "false"}); } else { diag->Note(android::DiagMessage(el->line_number) << "Ignoring --non-updatable-system because the manifest has a versionCode"); } } return true; }); Loading tools/aapt2/link/ManifestFixer.h +5 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,11 @@ struct ManifestFixerOptions { // Whether to suppress `android:compileSdkVersion*` and `platformBuildVersion*` attributes. bool no_compile_sdk_metadata = false; // Whether to mark the app as a non-updatable system app. This adds `updatableSystem="false"` to // the <manifest> tag. Not used if a version code is set either explicitly in the manifest or // through version_code_default. bool non_updatable_system = false; }; // Verifies that the manifest is correctly formed and inserts defaults where specified with Loading tools/aapt2/link/ManifestFixer_test.cpp +77 −0 Original line number Diff line number Diff line Loading @@ -677,6 +677,83 @@ TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) { EXPECT_THAT(attr->value, StrEq("0x00000002")); } TEST_F(ManifestFixerTest, MarkNonUpdatableSystem) { ManifestFixerOptions options; options.non_updatable_system = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("false")); } TEST_F(ManifestFixerTest, MarkNonUpdatableSystemOverwritingValue) { ManifestFixerOptions options; options.non_updatable_system = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" updatableSystem="true" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("false")); } TEST_F(ManifestFixerTest, DontMarkNonUpdatableSystemWhenExplicitVersion) { ManifestFixerOptions options; options.non_updatable_system = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" android:versionCode="0x00000001" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, IsNull()); } TEST_F(ManifestFixerTest, DontMarkNonUpdatableSystemWhenAddedVersion) { ManifestFixerOptions options; options.non_updatable_system = true; options.version_code_default = std::string("0x10000000"); std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, IsNull()); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x10000000")); } TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) { EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull()); EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull()); Loading Loading
tools/aapt2/cmd/Link.h +5 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,11 @@ class LinkCommand : public Command { "are separated by ',' and the name is separated from the value by '='.\n" "Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).", &feature_flags_args_); AddOptionalSwitch("--non-updatable-system", "Mark the app as a non-updatable system app. This inserts\n" "updatableSystem=\"false\" to the root manifest node, overwriting any\n" "existing attribute. This is ignored if the manifest has a versionCode.", &options_.manifest_fixer_options.non_updatable_system); } int Action(const std::vector<std::string>& args) override; Loading
tools/aapt2/link/ManifestFixer.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, android::IDiagn } } if (options_.non_updatable_system) { if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) { el->RemoveAttribute("", "updatableSystem"); el->attributes.push_back(xml::Attribute{"", "updatableSystem", "false"}); } else { diag->Note(android::DiagMessage(el->line_number) << "Ignoring --non-updatable-system because the manifest has a versionCode"); } } return true; }); Loading
tools/aapt2/link/ManifestFixer.h +5 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,11 @@ struct ManifestFixerOptions { // Whether to suppress `android:compileSdkVersion*` and `platformBuildVersion*` attributes. bool no_compile_sdk_metadata = false; // Whether to mark the app as a non-updatable system app. This adds `updatableSystem="false"` to // the <manifest> tag. Not used if a version code is set either explicitly in the manifest or // through version_code_default. bool non_updatable_system = false; }; // Verifies that the manifest is correctly formed and inserts defaults where specified with Loading
tools/aapt2/link/ManifestFixer_test.cpp +77 −0 Original line number Diff line number Diff line Loading @@ -677,6 +677,83 @@ TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) { EXPECT_THAT(attr->value, StrEq("0x00000002")); } TEST_F(ManifestFixerTest, MarkNonUpdatableSystem) { ManifestFixerOptions options; options.non_updatable_system = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("false")); } TEST_F(ManifestFixerTest, MarkNonUpdatableSystemOverwritingValue) { ManifestFixerOptions options; options.non_updatable_system = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" updatableSystem="true" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("false")); } TEST_F(ManifestFixerTest, DontMarkNonUpdatableSystemWhenExplicitVersion) { ManifestFixerOptions options; options.non_updatable_system = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" android:versionCode="0x00000001" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, IsNull()); } TEST_F(ManifestFixerTest, DontMarkNonUpdatableSystemWhenAddedVersion) { ManifestFixerOptions options; options.non_updatable_system = true; options.version_code_default = std::string("0x10000000"); std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem"); ASSERT_THAT(attr, IsNull()); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x10000000")); } TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) { EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull()); EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull()); Loading