Merge "AAPT2: Add version collapsing"
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index 4b5ea65..f2c13ba 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -39,6 +39,7 @@
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 @@
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 30047f7..51d8ca6 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 @@
* 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 a0a7efc..302c04f 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 @@
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 a0fbcc6..3a03caf 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -79,6 +79,11 @@
*/
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 c2a22bf..7312ee3 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 @@
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 282ed9a..a6dba8b 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 @@
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 2452a1d..5d11c40 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -454,6 +454,10 @@
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 20b7b59..67333a2 100644
--- a/tools/aapt2/diff/Diff.cpp
+++ b/tools/aapt2/diff/Diff.cpp
@@ -51,6 +51,10 @@
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 56b9f9a..dba2d28 100644
--- a/tools/aapt2/dump/Dump.cpp
+++ b/tools/aapt2/dump/Dump.cpp
@@ -142,6 +142,10 @@
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 39c4fd3..d0f831e 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::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 459c330..8ed27c3 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -27,7 +27,9 @@
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 9b3a87c..99a7c02 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, 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 @@
.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 4767bc9..9411053 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -123,6 +123,14 @@
mVerbose = val;
}
+ int getMinSdkVersion() override {
+ return mMinSdkVersion;
+ }
+
+ void setMinSdkVersion(int minSdk) {
+ mMinSdkVersion = minSdk;
+ }
+
private:
StdErrDiagnostics mDiagnostics;
NameMangler mNameMangler;
@@ -130,6 +138,7 @@
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 @@
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 @@
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 @@
}
}
+ 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 ec532ab..43b8fb4 100644
--- a/tools/aapt2/link/Linkers.h
+++ b/tools/aapt2/link/Linkers.h
@@ -44,14 +44,21 @@
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 0000000..c0e96be
--- /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 0000000..b5387fe
--- /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 9affb83..762725d 100644
--- a/tools/aapt2/process/IResourceTableConsumer.h
+++ b/tools/aapt2/process/IResourceTableConsumer.h
@@ -41,6 +41,7 @@
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 74ca32e..2d013e4 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::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 8eb4bc8..fb1d8f8 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -50,6 +50,11 @@
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 @@
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 @@
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 @@
}
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 96752d3..36f568b 100644
--- a/tools/aapt2/test/Context.h
+++ b/tools/aapt2/test/Context.h
@@ -58,17 +58,19 @@
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 @@
return *this;
}
+ ContextBuilder& setMinSdkVersion(int minSdk) {
+ mContext->mMinSdkVersion = minSdk;
+ return *this;
+ }
+
std::unique_ptr<Context> build() {
return std::move(mContext);
}