Loading tools/aapt2/cmd/Link.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -1923,6 +1923,12 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) { .OptionalFlag("--version-name", "Version name to inject into the AndroidManifest.xml if none is present.", &options.manifest_fixer_options.version_name_default) .OptionalSwitch("--replace-version", "If --version-code and/or --version-name are specified, these\n" "values will replace any value already in the manifest. By\n" "default, nothing is changed if the manifest already defines\n" "these attributes.", &options.manifest_fixer_options.replace_version) .OptionalSwitch("--shared-lib", "Generates a shared Android runtime library.", &shared_lib) .OptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib) Loading tools/aapt2/link/ManifestFixer.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -237,6 +237,9 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, manifest_action.Action(FixCoreAppAttribute); manifest_action.Action([&](xml::Element* el) -> bool { if (options_.version_name_default) { if (options_.replace_version) { el->RemoveAttribute(xml::kSchemaAndroid, "versionName"); } if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) { el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionName", Loading @@ -245,6 +248,9 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, } if (options_.version_code_default) { if (options_.replace_version) { el->RemoveAttribute(xml::kSchemaAndroid, "versionCode"); } if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) { el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionCode", Loading tools/aapt2/link/ManifestFixer.h +9 −0 Original line number Diff line number Diff line Loading @@ -33,13 +33,22 @@ struct ManifestFixerOptions { Maybe<std::string> target_sdk_version_default; Maybe<std::string> rename_manifest_package; Maybe<std::string> rename_instrumentation_target_package; // The version name to set if 'android:versionName' is not defined in <manifest> or if // replace_version is set. Maybe<std::string> version_name_default; // The version code to set if 'android:versionCode' is not defined in <manifest> or if // replace_version is set. Maybe<std::string> version_code_default; // Wether validation errors should be treated only as warnings. If this is 'true', then an // incorrect node will not result in an error, but only as a warning, and the parsing will // continue. bool warn_validation = false; // Whether to replace the manifest version with the the command line version bool replace_version = false; }; /** Loading tools/aapt2/link/ManifestFixer_test.cpp +131 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ using ::android::StringPiece; using ::testing::IsNull; using ::testing::NotNull; using ::testing::StrEq; namespace aapt { Loading Loading @@ -339,6 +340,136 @@ TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) { EXPECT_EQ(std::string("0x10000000"), attr->value); } TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) { ManifestFixerOptions options; options.version_name_default = std::string("Beta"); 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" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Alpha")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x20000000")); } TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) { ManifestFixerOptions options; options.replace_version = true; options.version_name_default = std::string("Beta"); 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" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Beta")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x10000000")); } TEST_F(ManifestFixerTest, ReplaceVersionName) { ManifestFixerOptions options; options.replace_version = true; options.version_name_default = std::string("Beta"); std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Beta")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x20000000")); } TEST_F(ManifestFixerTest, ReplaceVersionCode) { ManifestFixerOptions options; options.replace_version = 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" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Alpha")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x10000000")); } TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) { ManifestFixerOptions options; options.replace_version = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Alpha")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x20000000")); } TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) { EXPECT_EQ(nullptr, Verify("<manifest package=\"android\" coreApp=\"hello\" />")); Loading tools/aapt2/xml/XmlDom.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -394,6 +394,15 @@ const Attribute* Element::FindAttribute(const StringPiece& ns, const StringPiece return nullptr; } void Element::RemoveAttribute(const StringPiece& ns, const StringPiece& name) { auto new_attr_end = std::remove_if(attributes.begin(), attributes.end(), [&](const Attribute& attr) -> bool { return ns == attr.namespace_uri && name == attr.name; }); attributes.erase(new_attr_end, attributes.end()); } Element* Element::FindChild(const StringPiece& ns, const StringPiece& name) { return FindChildWithAttribute(ns, name, {}, {}, {}); } Loading Loading
tools/aapt2/cmd/Link.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -1923,6 +1923,12 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) { .OptionalFlag("--version-name", "Version name to inject into the AndroidManifest.xml if none is present.", &options.manifest_fixer_options.version_name_default) .OptionalSwitch("--replace-version", "If --version-code and/or --version-name are specified, these\n" "values will replace any value already in the manifest. By\n" "default, nothing is changed if the manifest already defines\n" "these attributes.", &options.manifest_fixer_options.replace_version) .OptionalSwitch("--shared-lib", "Generates a shared Android runtime library.", &shared_lib) .OptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib) Loading
tools/aapt2/link/ManifestFixer.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -237,6 +237,9 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, manifest_action.Action(FixCoreAppAttribute); manifest_action.Action([&](xml::Element* el) -> bool { if (options_.version_name_default) { if (options_.replace_version) { el->RemoveAttribute(xml::kSchemaAndroid, "versionName"); } if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) { el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionName", Loading @@ -245,6 +248,9 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, } if (options_.version_code_default) { if (options_.replace_version) { el->RemoveAttribute(xml::kSchemaAndroid, "versionCode"); } if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) { el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionCode", Loading
tools/aapt2/link/ManifestFixer.h +9 −0 Original line number Diff line number Diff line Loading @@ -33,13 +33,22 @@ struct ManifestFixerOptions { Maybe<std::string> target_sdk_version_default; Maybe<std::string> rename_manifest_package; Maybe<std::string> rename_instrumentation_target_package; // The version name to set if 'android:versionName' is not defined in <manifest> or if // replace_version is set. Maybe<std::string> version_name_default; // The version code to set if 'android:versionCode' is not defined in <manifest> or if // replace_version is set. Maybe<std::string> version_code_default; // Wether validation errors should be treated only as warnings. If this is 'true', then an // incorrect node will not result in an error, but only as a warning, and the parsing will // continue. bool warn_validation = false; // Whether to replace the manifest version with the the command line version bool replace_version = false; }; /** Loading
tools/aapt2/link/ManifestFixer_test.cpp +131 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ using ::android::StringPiece; using ::testing::IsNull; using ::testing::NotNull; using ::testing::StrEq; namespace aapt { Loading Loading @@ -339,6 +340,136 @@ TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) { EXPECT_EQ(std::string("0x10000000"), attr->value); } TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) { ManifestFixerOptions options; options.version_name_default = std::string("Beta"); 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" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Alpha")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x20000000")); } TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) { ManifestFixerOptions options; options.replace_version = true; options.version_name_default = std::string("Beta"); 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" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Beta")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x10000000")); } TEST_F(ManifestFixerTest, ReplaceVersionName) { ManifestFixerOptions options; options.replace_version = true; options.version_name_default = std::string("Beta"); std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Beta")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x20000000")); } TEST_F(ManifestFixerTest, ReplaceVersionCode) { ManifestFixerOptions options; options.replace_version = 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" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Alpha")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x10000000")); } TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) { ManifestFixerOptions options; options.replace_version = true; std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" android:versionCode="0x20000000" android:versionName="Alpha" />)EOF", options); ASSERT_THAT(doc, NotNull()); xml::Element* manifest_el = doc->root.get(); ASSERT_THAT(manifest_el, NotNull()); xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("Alpha")); attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_THAT(attr, NotNull()); EXPECT_THAT(attr->value, StrEq("0x20000000")); } TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) { EXPECT_EQ(nullptr, Verify("<manifest package=\"android\" coreApp=\"hello\" />")); Loading
tools/aapt2/xml/XmlDom.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -394,6 +394,15 @@ const Attribute* Element::FindAttribute(const StringPiece& ns, const StringPiece return nullptr; } void Element::RemoveAttribute(const StringPiece& ns, const StringPiece& name) { auto new_attr_end = std::remove_if(attributes.begin(), attributes.end(), [&](const Attribute& attr) -> bool { return ns == attr.namespace_uri && name == attr.name; }); attributes.erase(new_attr_end, attributes.end()); } Element* Element::FindChild(const StringPiece& ns, const StringPiece& name) { return FindChildWithAttribute(ns, name, {}, {}, {}); } Loading