Loading tools/aapt2/cmd/Link.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -2120,6 +2120,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) .OptionalFlag("--compile-sdk-version-code", "Version code (integer) to inject into the AndroidManifest.xml if none is\n" "present.", Loading tools/aapt2/link/ManifestFixer.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,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 @@ -269,6 +272,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 +7 −2 Original line number Diff line number Diff line Loading @@ -44,10 +44,12 @@ struct ManifestFixerOptions { // <instrumentation>. Maybe<std::string> rename_instrumentation_target_package; // The version name to set if 'android:versionName' is not defined in <manifest>. // 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>. // 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; // The version of the framework being compiled against to set for 'android:compileSdkVersion' in Loading @@ -65,6 +67,9 @@ struct ManifestFixerOptions { // Whether to inject the android:debuggable="true" flag into the manifest bool debug_mode = false; // Whether to replace the manifest version with the the command line version bool replace_version = false; }; // Verifies that the manifest is correctly formed and inserts defaults where specified with Loading tools/aapt2/link/ManifestFixer_test.cpp +130 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,136 @@ TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) { EXPECT_THAT(attr->value, StrEq("0x10000000")); } 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_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull()); EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull()); Loading tools/aapt2/xml/XmlDom.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -423,6 +423,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()); } Attribute* Element::FindOrCreateAttribute(const StringPiece& ns, const StringPiece& name) { Attribute* attr = FindAttribute(ns, name); if (attr == nullptr) { Loading Loading
tools/aapt2/cmd/Link.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -2120,6 +2120,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) .OptionalFlag("--compile-sdk-version-code", "Version code (integer) to inject into the AndroidManifest.xml if none is\n" "present.", Loading
tools/aapt2/link/ManifestFixer.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,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 @@ -269,6 +272,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 +7 −2 Original line number Diff line number Diff line Loading @@ -44,10 +44,12 @@ struct ManifestFixerOptions { // <instrumentation>. Maybe<std::string> rename_instrumentation_target_package; // The version name to set if 'android:versionName' is not defined in <manifest>. // 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>. // 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; // The version of the framework being compiled against to set for 'android:compileSdkVersion' in Loading @@ -65,6 +67,9 @@ struct ManifestFixerOptions { // Whether to inject the android:debuggable="true" flag into the manifest bool debug_mode = false; // Whether to replace the manifest version with the the command line version bool replace_version = false; }; // Verifies that the manifest is correctly formed and inserts defaults where specified with Loading
tools/aapt2/link/ManifestFixer_test.cpp +130 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,136 @@ TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) { EXPECT_THAT(attr->value, StrEq("0x10000000")); } 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_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull()); EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull()); Loading
tools/aapt2/xml/XmlDom.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -423,6 +423,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()); } Attribute* Element::FindOrCreateAttribute(const StringPiece& ns, const StringPiece& name) { Attribute* attr = FindAttribute(ns, name); if (attr == nullptr) { Loading