Loading tools/aapt2/AppInfo.h +4 −1 Original line number Diff line number Diff line Loading @@ -31,9 +31,12 @@ struct AppInfo { // The app's minimum SDK version, if it is defined. Maybe<int> min_sdk_version; // The app's version code, if it is defined. // The app's version code (the lower 32 bits of the long version code), if it is defined. Maybe<uint32_t> version_code; // The app's version code major (the upper 32 bits of the long version code), if it is defined. Maybe<uint32_t> version_code_major; // The app's revision code, if it is defined. Maybe<uint32_t> revision_code; Loading tools/aapt2/cmd/Link.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -908,6 +908,18 @@ class Linker { app_info.version_code = maybe_code.value(); } if (xml::Attribute* version_code_major_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor")) { Maybe<uint32_t> maybe_code = ResourceUtils::ParseInt(version_code_major_attr->value); if (!maybe_code) { diag->Error(DiagMessage(xml_res->file.source.WithLine(manifest_el->line_number)) << "invalid android:versionCodeMajor '" << version_code_major_attr->value << "'"); return {}; } app_info.version_code_major = maybe_code.value(); } if (xml::Attribute* revision_code_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) { Maybe<uint32_t> maybe_code = ResourceUtils::ParseInt(revision_code_attr->value); Loading tools/aapt2/cmd/Util.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "util/Util.h" using ::android::StringPiece; using ::android::base::StringPrintf; namespace aapt { Loading Loading @@ -168,6 +169,7 @@ std::string MakePackageSafeName(const std::string &name) { std::unique_ptr<xml::XmlResource> GenerateSplitManifest(const AppInfo& app_info, const SplitConstraints& constraints) { const ResourceId kVersionCode(0x0101021b); const ResourceId kVersionCodeMajor(0x01010576); const ResourceId kRevisionCode(0x010104d5); const ResourceId kHasCode(0x0101000c); Loading @@ -184,6 +186,14 @@ std::unique_ptr<xml::XmlResource> GenerateSplitManifest(const AppInfo& app_info, util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_DEC, version_code)}); } if (app_info.version_code_major) { const uint32_t version_code_major = app_info.version_code_major.value(); manifest_el->attributes.push_back(xml::Attribute{ xml::kSchemaAndroid, "versionCodeMajor", std::to_string(version_code_major), CreateAttributeWithId(kVersionCodeMajor), util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_DEC, version_code_major)}); } if (app_info.revision_code) { const uint32_t revision_code = app_info.revision_code.value(); manifest_el->attributes.push_back(xml::Attribute{ Loading Loading @@ -355,6 +365,17 @@ Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res, app_info.version_code = maybe_code.value(); } if (const xml::Attribute* version_code_major_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor")) { Maybe<uint32_t> maybe_code = ExtractCompiledInt(*version_code_major_attr, &error_msg); if (!maybe_code) { diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number)) << "invalid android:versionCodeMajor: " << error_msg); return {}; } app_info.version_code_major = maybe_code.value(); } if (const xml::Attribute* revision_code_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) { Maybe<uint32_t> maybe_code = ExtractCompiledInt(*revision_code_attr, &error_msg); Loading Loading @@ -391,4 +412,21 @@ Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res, return app_info; } void SetLongVersionCode(xml::Element* manifest, uint64_t version) { // Write the low bits of the version code to android:versionCode auto version_code = manifest->FindOrCreateAttribute(xml::kSchemaAndroid, "versionCode"); version_code->value = StringPrintf("0x%08x", (uint32_t) (version & 0xffffffff)); version_code->compiled_value = ResourceUtils::TryParseInt(version_code->value); auto version_high = (uint32_t) (version >> 32); if (version_high != 0) { // Write the high bits of the version code to android:versionCodeMajor auto version_major = manifest->FindOrCreateAttribute(xml::kSchemaAndroid, "versionCodeMajor"); version_major->value = StringPrintf("0x%08x", version_high); version_major->compiled_value = ResourceUtils::TryParseInt(version_major->value); } else { manifest->RemoveAttribute(xml::kSchemaAndroid, "versionCodeMajor"); } } } // namespace aapt tools/aapt2/cmd/Util.h +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res, // checks this at runtime. std::string MakePackageSafeName(const std::string &name); // Sets the versionCode and versionCodeMajor attributes to the version code. Attempts to encode the // version code using the versionCode attribute only, and encodes using both versionCode and // versionCodeMajor if the version code requires more than 32 bits. void SetLongVersionCode(xml::Element* manifest, uint64_t version_code); } // namespace aapt #endif /* AAPT_SPLIT_UTIL_H */ tools/aapt2/cmd/Util_test.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "AppInfo.h" #include "split/TableSplitter.h" #include "test/Builders.h" #include "test/Test.h" namespace aapt { Loading @@ -36,4 +37,51 @@ TEST(UtilTest, SplitNamesAreSanitized) { EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land"); } TEST (UtilTest, LongVersionCodeDefined) { auto doc = test::BuildXmlDom(R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.aapt.test" android:versionCode="0x1" android:versionCodeMajor="0x1"> </manifest>)"); SetLongVersionCode(doc->root.get(), 42); auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_NE(version_code, nullptr); EXPECT_EQ(version_code->value, "0x0000002a"); ASSERT_NE(version_code->compiled_value, nullptr); auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get()); ASSERT_NE(compiled_version_code, nullptr); EXPECT_EQ(compiled_version_code->value.data, 42U); auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); EXPECT_EQ(version_code_major, nullptr); } TEST (UtilTest, LongVersionCodeUndefined) { auto doc = test::BuildXmlDom(R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.aapt.test"> </manifest>)"); SetLongVersionCode(doc->root.get(), 420000000000); auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_NE(version_code, nullptr); EXPECT_EQ(version_code->value, "0xc9f36800"); ASSERT_NE(version_code->compiled_value, nullptr); auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get()); ASSERT_NE(compiled_version_code, nullptr); EXPECT_EQ(compiled_version_code->value.data, 0xc9f36800); auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); ASSERT_NE(version_code_major, nullptr); EXPECT_EQ(version_code_major->value, "0x00000061"); ASSERT_NE(version_code_major->compiled_value, nullptr); auto compiled_version_code_major = ValueCast<BinaryPrimitive>( version_code_major->compiled_value.get()); ASSERT_NE(compiled_version_code_major, nullptr); EXPECT_EQ(compiled_version_code_major->value.data, 0x61); } } // namespace aapt Loading
tools/aapt2/AppInfo.h +4 −1 Original line number Diff line number Diff line Loading @@ -31,9 +31,12 @@ struct AppInfo { // The app's minimum SDK version, if it is defined. Maybe<int> min_sdk_version; // The app's version code, if it is defined. // The app's version code (the lower 32 bits of the long version code), if it is defined. Maybe<uint32_t> version_code; // The app's version code major (the upper 32 bits of the long version code), if it is defined. Maybe<uint32_t> version_code_major; // The app's revision code, if it is defined. Maybe<uint32_t> revision_code; Loading
tools/aapt2/cmd/Link.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -908,6 +908,18 @@ class Linker { app_info.version_code = maybe_code.value(); } if (xml::Attribute* version_code_major_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor")) { Maybe<uint32_t> maybe_code = ResourceUtils::ParseInt(version_code_major_attr->value); if (!maybe_code) { diag->Error(DiagMessage(xml_res->file.source.WithLine(manifest_el->line_number)) << "invalid android:versionCodeMajor '" << version_code_major_attr->value << "'"); return {}; } app_info.version_code_major = maybe_code.value(); } if (xml::Attribute* revision_code_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) { Maybe<uint32_t> maybe_code = ResourceUtils::ParseInt(revision_code_attr->value); Loading
tools/aapt2/cmd/Util.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "util/Util.h" using ::android::StringPiece; using ::android::base::StringPrintf; namespace aapt { Loading Loading @@ -168,6 +169,7 @@ std::string MakePackageSafeName(const std::string &name) { std::unique_ptr<xml::XmlResource> GenerateSplitManifest(const AppInfo& app_info, const SplitConstraints& constraints) { const ResourceId kVersionCode(0x0101021b); const ResourceId kVersionCodeMajor(0x01010576); const ResourceId kRevisionCode(0x010104d5); const ResourceId kHasCode(0x0101000c); Loading @@ -184,6 +186,14 @@ std::unique_ptr<xml::XmlResource> GenerateSplitManifest(const AppInfo& app_info, util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_DEC, version_code)}); } if (app_info.version_code_major) { const uint32_t version_code_major = app_info.version_code_major.value(); manifest_el->attributes.push_back(xml::Attribute{ xml::kSchemaAndroid, "versionCodeMajor", std::to_string(version_code_major), CreateAttributeWithId(kVersionCodeMajor), util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_DEC, version_code_major)}); } if (app_info.revision_code) { const uint32_t revision_code = app_info.revision_code.value(); manifest_el->attributes.push_back(xml::Attribute{ Loading Loading @@ -355,6 +365,17 @@ Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res, app_info.version_code = maybe_code.value(); } if (const xml::Attribute* version_code_major_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor")) { Maybe<uint32_t> maybe_code = ExtractCompiledInt(*version_code_major_attr, &error_msg); if (!maybe_code) { diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number)) << "invalid android:versionCodeMajor: " << error_msg); return {}; } app_info.version_code_major = maybe_code.value(); } if (const xml::Attribute* revision_code_attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) { Maybe<uint32_t> maybe_code = ExtractCompiledInt(*revision_code_attr, &error_msg); Loading Loading @@ -391,4 +412,21 @@ Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res, return app_info; } void SetLongVersionCode(xml::Element* manifest, uint64_t version) { // Write the low bits of the version code to android:versionCode auto version_code = manifest->FindOrCreateAttribute(xml::kSchemaAndroid, "versionCode"); version_code->value = StringPrintf("0x%08x", (uint32_t) (version & 0xffffffff)); version_code->compiled_value = ResourceUtils::TryParseInt(version_code->value); auto version_high = (uint32_t) (version >> 32); if (version_high != 0) { // Write the high bits of the version code to android:versionCodeMajor auto version_major = manifest->FindOrCreateAttribute(xml::kSchemaAndroid, "versionCodeMajor"); version_major->value = StringPrintf("0x%08x", version_high); version_major->compiled_value = ResourceUtils::TryParseInt(version_major->value); } else { manifest->RemoveAttribute(xml::kSchemaAndroid, "versionCodeMajor"); } } } // namespace aapt
tools/aapt2/cmd/Util.h +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res, // checks this at runtime. std::string MakePackageSafeName(const std::string &name); // Sets the versionCode and versionCodeMajor attributes to the version code. Attempts to encode the // version code using the versionCode attribute only, and encodes using both versionCode and // versionCodeMajor if the version code requires more than 32 bits. void SetLongVersionCode(xml::Element* manifest, uint64_t version_code); } // namespace aapt #endif /* AAPT_SPLIT_UTIL_H */
tools/aapt2/cmd/Util_test.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "AppInfo.h" #include "split/TableSplitter.h" #include "test/Builders.h" #include "test/Test.h" namespace aapt { Loading @@ -36,4 +37,51 @@ TEST(UtilTest, SplitNamesAreSanitized) { EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land"); } TEST (UtilTest, LongVersionCodeDefined) { auto doc = test::BuildXmlDom(R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.aapt.test" android:versionCode="0x1" android:versionCodeMajor="0x1"> </manifest>)"); SetLongVersionCode(doc->root.get(), 42); auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_NE(version_code, nullptr); EXPECT_EQ(version_code->value, "0x0000002a"); ASSERT_NE(version_code->compiled_value, nullptr); auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get()); ASSERT_NE(compiled_version_code, nullptr); EXPECT_EQ(compiled_version_code->value.data, 42U); auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); EXPECT_EQ(version_code_major, nullptr); } TEST (UtilTest, LongVersionCodeUndefined) { auto doc = test::BuildXmlDom(R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.aapt.test"> </manifest>)"); SetLongVersionCode(doc->root.get(), 420000000000); auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_NE(version_code, nullptr); EXPECT_EQ(version_code->value, "0xc9f36800"); ASSERT_NE(version_code->compiled_value, nullptr); auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get()); ASSERT_NE(compiled_version_code, nullptr); EXPECT_EQ(compiled_version_code->value.data, 0xc9f36800); auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); ASSERT_NE(version_code_major, nullptr); EXPECT_EQ(version_code_major->value, "0x00000061"); ASSERT_NE(version_code_major->compiled_value, nullptr); auto compiled_version_code_major = ValueCast<BinaryPrimitive>( version_code_major->compiled_value.get()); ASSERT_NE(compiled_version_code_major, nullptr); EXPECT_EQ(compiled_version_code_major->value.data, 0x61); } } // namespace aapt