AAPT2: Expose split support to command line

Bug:30445078
Change-Id: If4b8530dba71b9059b8e62c04757da99c1119d22
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 2dfe2a2..08b9ee9 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -17,6 +17,7 @@
 #include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "split/TableSplitter.h"
+#include "util/Util.h"
 
 #include <algorithm>
 #include <map>
@@ -76,7 +77,6 @@
             // in multiple splits.
             const ConfigDescription& config = entry.first;
             const std::vector<ResourceConfigValue*>& relatedValues = entry.second;
-
             auto densityValueIter = mDensityDependentConfigToDensityMap.find(config);
             if (densityValueIter != mDensityDependentConfigToDensityMap.end()) {
                 // Select the best one!
@@ -89,12 +89,12 @@
                             thisValue->config.isBetterThan(bestValue->config, &targetDensity)) {
                         bestValue = thisValue;
                     }
-
-                    // When we select one of these, they are all claimed such that the base
-                    // doesn't include any anymore.
-                    (*claimedValues)[thisValue] = true;
                 }
                 assert(bestValue);
+
+                // When we select one of these, they are all claimed such that the base
+                // doesn't include any anymore.
+                (*claimedValues)[bestValue] = true;
                 selected.push_back(bestValue);
             }
         }
@@ -135,7 +135,6 @@
         assert(bestValue);
     }
 }
-
 bool TableSplitter::verifySplitConstraints(IAaptContext* context) {
     bool error = false;
     for (size_t i = 0; i < mSplitConstraints.size(); i++) {
diff --git a/tools/aapt2/split/TableSplitter.h b/tools/aapt2/split/TableSplitter.h
index 15e0764..2fa5c47 100644
--- a/tools/aapt2/split/TableSplitter.h
+++ b/tools/aapt2/split/TableSplitter.h
@@ -60,7 +60,7 @@
 
     void splitTable(ResourceTable* originalTable);
 
-    const std::vector<std::unique_ptr<ResourceTable>>& getSplits() {
+    std::vector<std::unique_ptr<ResourceTable>>& getSplits() {
         return mSplits;
     }
 
diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp
index bad02a5..5150e82 100644
--- a/tools/aapt2/split/TableSplitter_test.cpp
+++ b/tools/aapt2/split/TableSplitter_test.cpp
@@ -52,6 +52,71 @@
     EXPECT_NE(nullptr, test::getValue<Id>(table.get(), "android:string/one"));
 }
 
+TEST(TableSplitterTest, SplitTableByDensity) {
+    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
+            .addFileReference("android:drawable/foo", "res/drawable-mdpi/foo.png",
+                              test::parseConfigOrDie("mdpi"))
+            .addFileReference("android:drawable/foo", "res/drawable-hdpi/foo.png",
+                              test::parseConfigOrDie("hdpi"))
+            .addFileReference("android:drawable/foo", "res/drawable-xhdpi/foo.png",
+                              test::parseConfigOrDie("xhdpi"))
+            .addFileReference("android:drawable/foo", "res/drawable-xxhdpi/foo.png",
+                              test::parseConfigOrDie("xxhdpi"))
+            .build();
+
+    std::vector<SplitConstraints> constraints;
+    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("mdpi") } });
+    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("hdpi") } });
+    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("xhdpi") } });
+
+    TableSplitter splitter(constraints, TableSplitterOptions{});
+    splitter.splitTable(table.get());
+
+    ASSERT_EQ(3u, splitter.getSplits().size());
+
+    ResourceTable* splitOne = splitter.getSplits()[0].get();
+    ResourceTable* splitTwo = splitter.getSplits()[1].get();
+    ResourceTable* splitThree = splitter.getSplits()[2].get();
+
+    // Just xxhdpi should be in the base.
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
+                                                              test::parseConfigOrDie("mdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
+                                                              test::parseConfigOrDie("hdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
+                                                              test::parseConfigOrDie("xhdpi")));
+    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
+                                                              test::parseConfigOrDie("xxhdpi")));
+
+    // Each split should have one and only one drawable.
+    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
+                                                              test::parseConfigOrDie("mdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
+                                                              test::parseConfigOrDie("hdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
+                                                              test::parseConfigOrDie("xhdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
+                                                              test::parseConfigOrDie("xxhdpi")));
+
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
+                                                              test::parseConfigOrDie("mdpi")));
+    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
+                                                              test::parseConfigOrDie("hdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
+                                                              test::parseConfigOrDie("xhdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
+                                                              test::parseConfigOrDie("xxhdpi")));
+
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
+                                                              test::parseConfigOrDie("mdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
+                                                              test::parseConfigOrDie("hdpi")));
+    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
+                                                              test::parseConfigOrDie("xhdpi")));
+    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
+                                                              test::parseConfigOrDie("xxhdpi")));
+}
+
 TEST(TableSplitterTest, SplitTableByConfigAndDensity) {
     ResourceTable table;
 
@@ -78,12 +143,12 @@
     ResourceTable* splitOne = splitter.getSplits()[0].get();
     ResourceTable* splitTwo = splitter.getSplits()[1].get();
 
-    // Since a split was defined, all densities should be gone from base.
+    // All but the xxhdpi resource should be gone, since there were closer matches in land-xhdpi.
     EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
                                                    test::parseConfigOrDie("land-hdpi")));
     EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
                                                    test::parseConfigOrDie("land-xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
+    EXPECT_NE(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
                                                    test::parseConfigOrDie("land-xxhdpi")));
 
     EXPECT_NE(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo",