diff options
-rw-r--r-- | tools/aapt2/Android.mk | 2 | ||||
-rw-r--r-- | tools/aapt2/AppInfo.h | 7 | ||||
-rw-r--r-- | tools/aapt2/ResourceUtils.cpp | 16 | ||||
-rw-r--r-- | tools/aapt2/ResourceUtils.h | 5 | ||||
-rw-r--r-- | tools/aapt2/SdkConstants.cpp | 7 | ||||
-rw-r--r-- | tools/aapt2/SdkConstants.h | 3 | ||||
-rw-r--r-- | tools/aapt2/compile/Compile.cpp | 4 | ||||
-rw-r--r-- | tools/aapt2/diff/Diff.cpp | 4 | ||||
-rw-r--r-- | tools/aapt2/dump/Dump.cpp | 4 | ||||
-rw-r--r-- | tools/aapt2/flatten/TableFlattener_test.cpp | 10 | ||||
-rw-r--r-- | tools/aapt2/link/AutoVersioner.cpp | 2 | ||||
-rw-r--r-- | tools/aapt2/link/AutoVersioner_test.cpp | 9 | ||||
-rw-r--r-- | tools/aapt2/link/Link.cpp | 66 | ||||
-rw-r--r-- | tools/aapt2/link/Linkers.h | 11 | ||||
-rw-r--r-- | tools/aapt2/link/VersionCollapser.cpp | 126 | ||||
-rw-r--r-- | tools/aapt2/link/VersionCollapser_test.cpp | 93 | ||||
-rw-r--r-- | tools/aapt2/process/IResourceTableConsumer.h | 1 | ||||
-rw-r--r-- | tools/aapt2/split/TableSplitter_test.cpp | 7 | ||||
-rw-r--r-- | tools/aapt2/test/Builders.h | 18 | ||||
-rw-r--r-- | tools/aapt2/test/Context.h | 15 |
20 files changed, 371 insertions, 39 deletions
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk index 4b5ea65d8fed..f2c13ba2e0d3 100644 --- a/tools/aapt2/Android.mk +++ b/tools/aapt2/Android.mk @@ -39,6 +39,7 @@ sources := \ link/PrivateAttributeMover.cpp \ link/ReferenceLinker.cpp \ link/TableMerger.cpp \ + link/VersionCollapser.cpp \ link/XmlReferenceLinker.cpp \ process/SymbolTable.cpp \ proto/ProtoHelpers.cpp \ @@ -87,6 +88,7 @@ testSources := \ link/ProductFilter_test.cpp \ link/ReferenceLinker_test.cpp \ link/TableMerger_test.cpp \ + link/VersionCollapser_test.cpp \ link/XmlReferenceLinker_test.cpp \ process/SymbolTable_test.cpp \ proto/TableProtoSerializer_test.cpp \ diff --git a/tools/aapt2/AppInfo.h b/tools/aapt2/AppInfo.h index 30047f71cc04..51d8ca60b1e3 100644 --- a/tools/aapt2/AppInfo.h +++ b/tools/aapt2/AppInfo.h @@ -17,6 +17,8 @@ #ifndef AAPT_APP_INFO_H #define AAPT_APP_INFO_H +#include "util/Maybe.h" + #include <string> namespace aapt { @@ -30,6 +32,11 @@ struct AppInfo { * App's package name. */ std::u16string package; + + /** + * The App's minimum SDK version. + */ + Maybe<std::u16string> minSdkVersion; }; } // namespace aapt diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp index a0a7efc46476..302c04fc3780 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -16,6 +16,7 @@ #include "NameMangler.h" #include "ResourceUtils.h" +#include "SdkConstants.h" #include "flatten/ResourceTypeExtensions.h" #include "util/Files.h" #include "util/Util.h" @@ -402,6 +403,21 @@ bool tryParseBool(const StringPiece16& str, bool* outValue) { return false; } +Maybe<int> tryParseSdkVersion(const StringPiece16& str) { + StringPiece16 trimmedStr(util::trimWhitespace(str)); + android::Res_value value; + if (android::ResTable::stringToInt(trimmedStr.data(), trimmedStr.size(), &value)) { + return static_cast<int>(value.data); + } + + // Try parsing the code name. + std::pair<StringPiece16, int> entry = getDevelopmentSdkCodeNameAndVersion(); + if (entry.first == trimmedStr) { + return entry.second; + } + return {}; +} + std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str) { bool result = false; if (tryParseBool(str, &result)) { diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h index a0fbcc6e700b..3a03caf04c77 100644 --- a/tools/aapt2/ResourceUtils.h +++ b/tools/aapt2/ResourceUtils.h @@ -79,6 +79,11 @@ bool isAttributeReference(const StringPiece16& str); */ bool tryParseBool(const StringPiece16& str, bool* outValue); +/** + * Parses an SDK version, which can be an integer, or a letter from A-Z. + */ +Maybe<int> tryParseSdkVersion(const StringPiece16& str); + /* * Returns a Reference, or None Maybe instance if the string `str` was parsed as a * valid reference to a style. diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp index c2a22bf2a373..7312ee3b5b20 100644 --- a/tools/aapt2/SdkConstants.cpp +++ b/tools/aapt2/SdkConstants.cpp @@ -23,6 +23,9 @@ namespace aapt { +static const char16_t* sDevelopmentSdkCodeName = u"O"; +static int sDevelopmentSdkLevel = 26; + static const std::vector<std::pair<uint16_t, size_t>> sAttrIdMap = { { 0x021c, 1 }, { 0x021d, 2 }, @@ -735,4 +738,8 @@ size_t findAttributeSdkLevel(const ResourceName& name) { return SDK_LOLLIPOP_MR1; } +std::pair<StringPiece16, int> getDevelopmentSdkCodeNameAndVersion() { + return std::make_pair(StringPiece16(sDevelopmentSdkCodeName), sDevelopmentSdkLevel); +} + } // namespace aapt diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h index 282ed9a56f5c..a6dba8b0cd2b 100644 --- a/tools/aapt2/SdkConstants.h +++ b/tools/aapt2/SdkConstants.h @@ -19,6 +19,8 @@ #include "Resource.h" +#include <utility> + namespace aapt { enum { @@ -47,6 +49,7 @@ enum { size_t findAttributeSdkLevel(ResourceId id); size_t findAttributeSdkLevel(const ResourceName& name); +std::pair<StringPiece16, int> getDevelopmentSdkCodeNameAndVersion(); } // namespace aapt diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp index 2452a1d29410..5d11c404cfe3 100644 --- a/tools/aapt2/compile/Compile.cpp +++ b/tools/aapt2/compile/Compile.cpp @@ -454,6 +454,10 @@ public: return nullptr; } + int getMinSdkVersion() override { + return 0; + } + private: StdErrDiagnostics mDiagnostics; bool mVerbose = false; diff --git a/tools/aapt2/diff/Diff.cpp b/tools/aapt2/diff/Diff.cpp index 20b7b59642ca..67333a228cdf 100644 --- a/tools/aapt2/diff/Diff.cpp +++ b/tools/aapt2/diff/Diff.cpp @@ -51,6 +51,10 @@ public: return false; } + int getMinSdkVersion() override { + return 0; + } + private: std::u16string mEmpty; StdErrDiagnostics mDiagnostics; diff --git a/tools/aapt2/dump/Dump.cpp b/tools/aapt2/dump/Dump.cpp index 56b9f9a3e081..dba2d280fa30 100644 --- a/tools/aapt2/dump/Dump.cpp +++ b/tools/aapt2/dump/Dump.cpp @@ -142,6 +142,10 @@ public: mVerbose = val; } + int getMinSdkVersion() override { + return 0; + } + private: StdErrDiagnostics mDiagnostics; bool mVerbose = false; diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp index 39c4fd318508..d0f831e16203 100644 --- a/tools/aapt2/flatten/TableFlattener_test.cpp +++ b/tools/aapt2/flatten/TableFlattener_test.cpp @@ -15,14 +15,10 @@ */ #include "flatten/TableFlattener.h" -#include "test/Builders.h" -#include "test/Context.h" +#include "test/Test.h" #include "unflatten/BinaryResourceParser.h" #include "util/Util.h" - -#include <gtest/gtest.h> - using namespace android; namespace aapt { @@ -150,8 +146,8 @@ TEST_F(TableFlattenerTest, FlattenFullyLinkedTable) { test::buildReference(u"@com.app.test:id/one", ResourceId(0x7f020000))) .addValue(u"@com.app.test:integer/one", ResourceId(0x7f030000), util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 1u)) - .addValue(u"@com.app.test:integer/one", ResourceId(0x7f030000), - test::parseConfigOrDie("v1"), + .addValue(u"@com.app.test:integer/one", test::parseConfigOrDie("v1"), + ResourceId(0x7f030000), util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 2u)) .addString(u"@com.app.test:string/test", ResourceId(0x7f040000), u"foo") .addString(u"@com.app.test:layout/bar", ResourceId(0x7f050000), u"res/layout/bar.xml") diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp index 459c330cfbdc..8ed27c3b95f6 100644 --- a/tools/aapt2/link/AutoVersioner.cpp +++ b/tools/aapt2/link/AutoVersioner.cpp @@ -27,7 +27,9 @@ namespace aapt { bool shouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config, const int sdkVersionToGenerate) { + // We assume the caller is trying to generate a version greater than the current configuration. assert(sdkVersionToGenerate > config.sdkVersion); + const auto endIter = entry->values.end(); auto iter = entry->values.begin(); for (; iter != endIter; ++iter) { diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp index 9b3a87c4eed0..99a7c02d1a3f 100644 --- a/tools/aapt2/link/AutoVersioner_test.cpp +++ b/tools/aapt2/link/AutoVersioner_test.cpp @@ -16,10 +16,7 @@ #include "ConfigDescription.h" #include "link/Linkers.h" -#include "test/Builders.h" -#include "test/Context.h" - -#include <gtest/gtest.h> +#include "test/Test.h" namespace aapt { @@ -54,7 +51,7 @@ TEST(AutoVersionerTest, GenerateVersionedResourceWhenHigherVersionExists) { TEST(AutoVersionerTest, VersionStylesForTable) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .setPackageId(u"app", 0x7f) - .addValue(u"@app:style/Foo", ResourceId(0x7f020000), test::parseConfigOrDie("v4"), + .addValue(u"@app:style/Foo", test::parseConfigOrDie("v4"), ResourceId(0x7f020000), test::StyleBuilder() .addItem(u"@android:attr/onClick", ResourceId(0x0101026f), util::make_unique<Id>()) @@ -65,7 +62,7 @@ TEST(AutoVersionerTest, VersionStylesForTable) { .addItem(u"@android:attr/colorAccent", ResourceId(0x01010435), util::make_unique<Id>()) .build()) - .addValue(u"@app:style/Foo", ResourceId(0x7f020000), test::parseConfigOrDie("v21"), + .addValue(u"@app:style/Foo", test::parseConfigOrDie("v21"), ResourceId(0x7f020000), test::StyleBuilder() .addItem(u"@android:attr/paddingEnd", ResourceId(0x010103b4), util::make_unique<Id>()) diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp index 4767bc99141d..9411053170db 100644 --- a/tools/aapt2/link/Link.cpp +++ b/tools/aapt2/link/Link.cpp @@ -123,6 +123,14 @@ public: mVerbose = val; } + int getMinSdkVersion() override { + return mMinSdkVersion; + } + + void setMinSdkVersion(int minSdk) { + mMinSdkVersion = minSdk; + } + private: StdErrDiagnostics mDiagnostics; NameMangler mNameMangler; @@ -130,6 +138,7 @@ private: uint8_t mPackageId = 0x0; SymbolTable mSymbols; bool mVerbose = false; + int mMinSdkVersion = 0; }; static bool copyFileToArchive(io::IFile* file, const std::string& outPath, @@ -578,14 +587,33 @@ public: return true; } - Maybe<AppInfo> extractAppInfoFromManifest(xml::XmlResource* xmlRes) { + Maybe<AppInfo> extractAppInfoFromManifest(xml::XmlResource* xmlRes, IDiagnostics* diag) { // Make sure the first element is <manifest> with package attribute. if (xml::Element* manifestEl = xml::findRootElement(xmlRes->root.get())) { - if (manifestEl->namespaceUri.empty() && manifestEl->name == u"manifest") { - if (xml::Attribute* packageAttr = manifestEl->findAttribute({}, u"package")) { - return AppInfo{ packageAttr->value }; + AppInfo appInfo; + + if (!manifestEl->namespaceUri.empty() || manifestEl->name != u"manifest") { + diag->error(DiagMessage(xmlRes->file.source) << "root tag must be <manifest>"); + return {}; + } + + xml::Attribute* packageAttr = manifestEl->findAttribute({}, u"package"); + if (!packageAttr) { + diag->error(DiagMessage(xmlRes->file.source) + << "<manifest> must have a 'package' attribute"); + return {}; + } + + appInfo.package = packageAttr->value; + + if (xml::Element* usesSdkEl = manifestEl->findChild({}, u"uses-sdk")) { + if (xml::Attribute* minSdk = + usesSdkEl->findAttribute(xml::kSchemaAndroid, u"minSdkVersion")) { + appInfo.minSdkVersion = minSdk->value; } } + + return appInfo; } return {}; } @@ -1089,11 +1117,11 @@ public: return 1; } - if (Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest(manifestXml.get())) { - mContext->setCompilationPackage(maybeAppInfo.value().package); + if (Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest(manifestXml.get(), + mContext->getDiagnostics())) { + AppInfo& appInfo = maybeAppInfo.value(); + mContext->setCompilationPackage(appInfo.package); } else { - mContext->getDiagnostics()->error(DiagMessage(mOptions.manifestPath) - << "no package specified in <manifest> tag"); return 1; } @@ -1297,6 +1325,28 @@ public: } } + Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest(manifestXml.get(), + mContext->getDiagnostics()); + if (maybeAppInfo && maybeAppInfo.value().minSdkVersion) { + if (Maybe<int> maybeMinSdkVersion = + ResourceUtils::tryParseSdkVersion(maybeAppInfo.value().minSdkVersion.value())) { + mContext->setMinSdkVersion(maybeMinSdkVersion.value()); + } + } + + if (!mOptions.staticLib && mContext->getMinSdkVersion() > 0) { + if (mContext->verbose()) { + mContext->getDiagnostics()->note( + DiagMessage() << "collapsing resource versions for minimum SDK " + << mContext->getMinSdkVersion()); + } + + VersionCollapser collapser; + if (!collapser.consume(mContext, &mFinalTable)) { + return 1; + } + } + if (mOptions.staticLib) { if (!flattenTableToPb(&mFinalTable, archiveWriter.get())) { mContext->getDiagnostics()->error(DiagMessage() diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h index ec532aba465f..43b8fb494f2c 100644 --- a/tools/aapt2/link/Linkers.h +++ b/tools/aapt2/link/Linkers.h @@ -44,14 +44,21 @@ struct CallSite { bool shouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config, const int sdkVersionToGenerate); -struct AutoVersioner : public IResourceTableConsumer { +class AutoVersioner : public IResourceTableConsumer { +public: bool consume(IAaptContext* context, ResourceTable* table) override; }; -struct XmlAutoVersioner : public IXmlResourceConsumer { +class XmlAutoVersioner : public IXmlResourceConsumer { +public: bool consume(IAaptContext* context, xml::XmlResource* resource) override; }; +class VersionCollapser : public IResourceTableConsumer { +public: + bool consume(IAaptContext* context, ResourceTable* table) override; +}; + /** * If any attribute resource values are defined as public, this consumer will move all private * attribute resource values to a private ^private-attr type, avoiding backwards compatibility diff --git a/tools/aapt2/link/VersionCollapser.cpp b/tools/aapt2/link/VersionCollapser.cpp new file mode 100644 index 000000000000..c0e96be1cc9d --- /dev/null +++ b/tools/aapt2/link/VersionCollapser.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ResourceTable.h" +#include "link/Linkers.h" + +#include <algorithm> +#include <vector> + +namespace aapt { + +template <typename Iterator, typename Pred> +class FilterIterator { +public: + FilterIterator(Iterator begin, Iterator end, Pred pred=Pred()) : + mCurrent(begin), mEnd(end), mPred(pred) { + advance(); + } + + bool hasNext() { + return mCurrent != mEnd; + } + + Iterator nextIter() { + Iterator iter = mCurrent; + ++mCurrent; + advance(); + return iter; + } + + typename Iterator::reference next() { + return *nextIter(); + } + +private: + void advance() { + for (; mCurrent != mEnd; ++mCurrent) { + if (mPred(*mCurrent)) { + return; + } + } + } + + Iterator mCurrent, mEnd; + Pred mPred; +}; + +template <typename Iterator, typename Pred> +FilterIterator<Iterator, Pred> makeFilterIterator(Iterator begin, Iterator end=Iterator(), + Pred pred=Pred()) { + return FilterIterator<Iterator, Pred>(begin, end, pred); +} + +/** + * Every Configuration with an SDK version specified that is less than minSdk will be removed. + * The exception is when there is no exact matching resource for the minSdk. The next smallest + * one will be kept. + */ +static void collapseVersions(int minSdk, ResourceEntry* entry) { + // First look for all sdks less than minSdk. + for (auto iter = entry->values.rbegin(); iter != entry->values.rend(); ++iter) { + // Check if the item was already marked for removal. + if (!(*iter)) { + continue; + } + + const ConfigDescription& config = (*iter)->config; + if (config.sdkVersion <= minSdk) { + // This is the first configuration we've found with a smaller or equal SDK level + // to the minimum. We MUST keep this one, but remove all others we find, which get + // overridden by this one. + + ConfigDescription configWithoutSdk = config; + configWithoutSdk.sdkVersion = 0; + auto pred = [&](const std::unique_ptr<ResourceConfigValue>& val) -> bool { + // Check that the value hasn't already been marked for removal. + if (!val) { + return false; + } + + // Only return Configs that differ in SDK version. + configWithoutSdk.sdkVersion = val->config.sdkVersion; + return configWithoutSdk == val->config && val->config.sdkVersion <= minSdk; + }; + + // Remove the rest that match. + auto filterIter = makeFilterIterator(iter + 1, entry->values.rend(), pred); + while (filterIter.hasNext()) { + filterIter.next() = {}; + } + } + } + + // Now erase the nullptr values. + entry->values.erase(std::remove_if(entry->values.begin(), entry->values.end(), + [](const std::unique_ptr<ResourceConfigValue>& val) -> bool { + return val == nullptr; + }), entry->values.end()); +} + +bool VersionCollapser::consume(IAaptContext* context, ResourceTable* table) { + const int minSdk = context->getMinSdkVersion(); + for (auto& package : table->packages) { + for (auto& type : package->types) { + for (auto& entry : type->entries) { + collapseVersions(minSdk, entry.get()); + } + } + } + return true; +} + +} // namespace aapt diff --git a/tools/aapt2/link/VersionCollapser_test.cpp b/tools/aapt2/link/VersionCollapser_test.cpp new file mode 100644 index 000000000000..b5387fe132cc --- /dev/null +++ b/tools/aapt2/link/VersionCollapser_test.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "link/Linkers.h" +#include "test/Test.h" + +namespace aapt { + +template <typename T> +using uptr = std::unique_ptr<T>; + +static uptr<ResourceTable> buildTableWithConfigs(const StringPiece16& name, + std::initializer_list<std::string> list) { + test::ResourceTableBuilder builder; + for (const std::string& item : list) { + builder.addSimple(name, test::parseConfigOrDie(item)); + } + return builder.build(); +} + +TEST(VersionCollapserTest, CollapseVersions) { + uptr<IAaptContext> context = test::ContextBuilder().setMinSdkVersion(7).build(); + + const StringPiece16 resName = u"@android:string/foo"; + + uptr<ResourceTable> table = + buildTableWithConfigs(resName, + { "land-v4", "land-v5", "sw600dp", "land-v6", + "land-v14", "land-v21" }); + + VersionCollapser collapser; + ASSERT_TRUE(collapser.consume(context.get(), table.get())); + + // These should be removed. + EXPECT_EQ(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v4"))); + EXPECT_EQ(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v5"))); + + // These should remain. + EXPECT_NE(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("sw600dp"))); + EXPECT_NE(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v6"))); + EXPECT_NE(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v14"))); + EXPECT_NE(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v21"))); +} + +TEST(VersionCollapserTest, CollapseVersionsWhenMinSdkIsHighest) { + uptr<IAaptContext> context = test::ContextBuilder().setMinSdkVersion(26).build(); + + const StringPiece16 resName = u"@android:string/foo"; + + uptr<ResourceTable> table = + buildTableWithConfigs(resName, + { "land-v4", "land-v5", "sw600dp", "land-v6", + "land-v14", "land-v21" }); + VersionCollapser collapser; + ASSERT_TRUE(collapser.consume(context.get(), table.get())); + + // These should all be removed. + EXPECT_EQ(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v4"))); + EXPECT_EQ(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v5"))); + EXPECT_EQ(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v6"))); + EXPECT_EQ(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v14"))); + + // These should remain. + EXPECT_NE(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("sw600dp"))); + EXPECT_NE(nullptr, + test::getValueForConfig<Id>(table.get(), resName, test::parseConfigOrDie("land-v21"))); +} + +} // namespace aapt diff --git a/tools/aapt2/process/IResourceTableConsumer.h b/tools/aapt2/process/IResourceTableConsumer.h index 9affb836340c..762725d40f53 100644 --- a/tools/aapt2/process/IResourceTableConsumer.h +++ b/tools/aapt2/process/IResourceTableConsumer.h @@ -41,6 +41,7 @@ struct IAaptContext { virtual uint8_t getPackageId() = 0; virtual NameMangler* getNameMangler() = 0; virtual bool verbose() = 0; + virtual int getMinSdkVersion() = 0; }; struct IResourceTableConsumer { diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp index 74ca32e04a30..2d013e4764aa 100644 --- a/tools/aapt2/split/TableSplitter_test.cpp +++ b/tools/aapt2/split/TableSplitter_test.cpp @@ -15,10 +15,7 @@ */ #include "split/TableSplitter.h" -#include "test/Builders.h" -#include "test/Common.h" - -#include <gtest/gtest.h> +#include "test/Test.h" namespace aapt { @@ -32,7 +29,7 @@ TEST(TableSplitterTest, NoSplitPreferredDensity) { test::parseConfigOrDie("xhdpi")) .addFileReference(u"@android:drawable/icon", u"res/drawable-xxhdpi/icon.png", test::parseConfigOrDie("xxhdpi")) - .addSimple(u"@android:string/one", {}) + .addSimple(u"@android:string/one") .build(); TableSplitterOptions options; diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h index 8eb4bc88168d..fb1d8f864fef 100644 --- a/tools/aapt2/test/Builders.h +++ b/tools/aapt2/test/Builders.h @@ -50,6 +50,11 @@ public: return addValue(name, id, util::make_unique<Id>()); } + ResourceTableBuilder& addSimple(const StringPiece16& name, const ConfigDescription& config, + const ResourceId id = {}) { + return addValue(name, config, id, util::make_unique<Id>()); + } + ResourceTableBuilder& addReference(const StringPiece16& name, const StringPiece16& ref) { return addReference(name, {}, ref); } @@ -70,7 +75,7 @@ public: ResourceTableBuilder& addString(const StringPiece16& name, const ResourceId id, const ConfigDescription& config, const StringPiece16& str) { - return addValue(name, id, config, + return addValue(name, config, id, util::make_unique<String>(mTable->stringPool.makeRef(str))); } @@ -86,7 +91,7 @@ public: ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path, const ConfigDescription& config) { - return addValue(name, {}, config, + return addValue(name, config, {}, util::make_unique<FileReference>(mTable->stringPool.makeRef(path))); } @@ -96,13 +101,12 @@ public: } ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id, - std::unique_ptr<Value> value) { - return addValue(name, id, {}, std::move(value)); + std::unique_ptr<Value> value) { + return addValue(name, {}, id, std::move(value)); } - ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id, - const ConfigDescription& config, - std::unique_ptr<Value> value) { + ResourceTableBuilder& addValue(const StringPiece16& name, const ConfigDescription& config, + const ResourceId id, std::unique_ptr<Value> value) { ResourceName resName = parseNameOrDie(name); bool result = mTable->addResourceAllowMangled(resName, id, config, std::string(), std::move(value), &mDiagnostics); diff --git a/tools/aapt2/test/Context.h b/tools/aapt2/test/Context.h index 96752d33dd9a..36f568be4069 100644 --- a/tools/aapt2/test/Context.h +++ b/tools/aapt2/test/Context.h @@ -58,17 +58,19 @@ public: return false; } + int getMinSdkVersion() override { + return mMinSdkVersion; + } + private: friend class ContextBuilder; - Context() : mNameMangler({}) { - } - Maybe<std::u16string> mCompilationPackage; Maybe<uint8_t> mPackageId; StdErrDiagnostics mDiagnostics; SymbolTable mSymbols; - NameMangler mNameMangler; + NameMangler mNameMangler = NameMangler({}); + int mMinSdkVersion = 0; }; class ContextBuilder { @@ -96,6 +98,11 @@ public: return *this; } + ContextBuilder& setMinSdkVersion(int minSdk) { + mContext->mMinSdkVersion = minSdk; + return *this; + } + std::unique_ptr<Context> build() { return std::move(mContext); } |