Filter products during compile phase

Unfortunately there is no good way to deal with products in the link phase.
Products are like preprocessor defines in that they are processed early
and change the composition of the compiled unit.

Change-Id: I6d5e15ef60d29df8e83e059ba857c09333993779
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 992a45c..ac91865 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -27,7 +27,7 @@
 
 #include <androidfw/ResourceTypes.h>
 #include <androidfw/TypeWrappers.h>
-#include <utils/misc.h>
+#include <base/macros.h>
 
 #include <map>
 #include <string>
@@ -289,7 +289,7 @@
     }
 
     // Extract the package name.
-    size_t len = strnlen16((const char16_t*) packageHeader->name, NELEM(packageHeader->name));
+    size_t len = strnlen16((const char16_t*) packageHeader->name, arraysize(packageHeader->name));
     std::u16string packageName;
     packageName.resize(len);
     for (size_t i = 0; i < len; i++) {
@@ -416,13 +416,11 @@
             return false;
         }
 
-        const ResourceId resId = {
-                package->id.value(), header->typeId, util::deviceToHost16(entry->entryId) };
+        const ResourceId resId(package->id.value(), header->typeId,
+                               util::deviceToHost16(entry->entryId));
 
-        const ResourceName name = {
-                package->name,
-                *parsedType,
-                util::getString(mKeyPool, entry->key.index).toString() };
+        const ResourceName name(package->name, *parsedType,
+                                util::getString(mKeyPool, entry->key.index).toString());
 
         Source source;
         if (mSourcePool.getError() == NO_ERROR) {
@@ -516,13 +514,11 @@
             continue;
         }
 
-        const ResourceName name = {
-                package->name,
-                *parsedType,
-                util::getString(mKeyPool, util::deviceToHost32(entry->key.index)).toString() };
+        const ResourceName name(package->name, *parsedType,
+                                util::getString(mKeyPool,
+                                                util::deviceToHost32(entry->key.index)).toString());
 
-        const ResourceId resId =
-                { package->id.value(), type->id, static_cast<uint16_t>(it.index()) };
+        const ResourceId resId(package->id.value(), type->id, static_cast<uint16_t>(it.index()));
 
         std::unique_ptr<Value> resourceValue;
         const ResTable_entry_source* sourceBlock = nullptr;
@@ -598,7 +594,9 @@
         StringPiece16 str = util::getString(mValuePool, data);
 
         const ResStringPool_span* spans = mValuePool.styleAt(data);
-        if (spans != nullptr) {
+
+        // Check if the string has a valid style associated with it.
+        if (spans != nullptr && spans->name.index != ResStringPool_span::END) {
             StyleString styleStr = { str.toString() };
             while (spans->name.index != ResStringPool_span::END) {
                 styleStr.spans.push_back(Span{
@@ -662,8 +660,12 @@
     switch (name.type) {
         case ResourceType::kStyle:
             return parseStyle(name, config, map);
+        case ResourceType::kAttrPrivate:
+            // fallthrough
         case ResourceType::kAttr:
             return parseAttr(name, config, map);
+        case ResourceType::kIntegerArray:
+            // fallthrough
         case ResourceType::kArray:
             return parseArray(name, config, map);
         case ResourceType::kStyleable:
@@ -671,6 +673,7 @@
         case ResourceType::kPlurals:
             return parsePlural(name, config, map);
         default:
+            assert(false && "unknown map type");
             break;
     }
     return {};