Store frro configs in idmap file

This also includes the change to use the configs to decide which (if
any) frros to use at runtime

Bug: 243066074
Test: Manual, updated and created automated tests
Change-Id: I3f1d23e2958ad170799880b9f5eb5bd8ceb1fa67
diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
index bf63327..f1eeab9 100644
--- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
+++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
@@ -84,8 +84,10 @@
   const auto& target_inline_entries2 = data2->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries1.size(), target_inline_entries2.size());
   ASSERT_EQ(target_inline_entries1[0].target_id, target_inline_entries2[0].target_id);
-  ASSERT_EQ(target_inline_entries1[0].value.data_type, target_inline_entries2[0].value.data_type);
-  ASSERT_EQ(target_inline_entries1[0].value.data_value, target_inline_entries2[0].value.data_value);
+  ASSERT_EQ(target_inline_entries1[0].values.begin()->second.data_type,
+      target_inline_entries2[0].values.begin()->second.data_type);
+  ASSERT_EQ(target_inline_entries1[0].values.begin()->second.data_value,
+      target_inline_entries2[0].values.begin()->second.data_value);
 
   const auto& overlay_entries1 = data1->GetOverlayEntries();
   const auto& overlay_entries2 = data2->GetOverlayEntries();
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index ee9a424..7b7dc17 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -47,10 +47,11 @@
   ASSERT_EQ((entry).target_id, (target_resid));                 \
   ASSERT_EQ((entry).overlay_id, (overlay_resid))
 
-#define ASSERT_TARGET_INLINE_ENTRY(entry, target_resid, expected_type, expected_value) \
-  ASSERT_EQ((entry).target_id, target_resid);                                          \
-  ASSERT_EQ((entry).value.data_type, (expected_type));                                 \
-  ASSERT_EQ((entry).value.data_value, (expected_value))
+#define ASSERT_TARGET_INLINE_ENTRY(entry, target_resid, ex_config, expected_type, expected_value) \
+  ASSERT_EQ((entry).target_id, target_resid);                                                     \
+  ASSERT_EQ((entry).values.begin()->first.to_string(), (ex_config));                              \
+  ASSERT_EQ((entry).values.begin()->second.data_type, (expected_type));                           \
+  ASSERT_EQ((entry).values.begin()->second.data_value, (expected_value))
 
 #define ASSERT_OVERLAY_ENTRY(entry, overlay_resid, target_resid) \
   ASSERT_EQ((entry).overlay_id, (overlay_resid));                \
@@ -67,7 +68,7 @@
   std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
   ASSERT_THAT(header, NotNull());
   ASSERT_EQ(header->GetMagic(), 0x504d4449U);
-  ASSERT_EQ(header->GetVersion(), 0x08U);
+  ASSERT_EQ(header->GetVersion(), 0x09U);
   ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
   ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
   ASSERT_EQ(header->GetFulfilledPolicies(), 0x11);
@@ -122,8 +123,8 @@
 
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 1U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000, Res_value::TYPE_INT_HEX,
-                             0x12345678);
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000,  "land-xxhdpi-v7",
+                             Res_value::TYPE_INT_HEX, 0x12345678);
 
   const auto& overlay_entries = data->GetOverlayEntries();
   ASSERT_EQ(target_entries.size(), 3U);
@@ -142,7 +143,7 @@
 
   ASSERT_THAT(idmap->GetHeader(), NotNull());
   ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
-  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x08U);
+  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x09U);
   ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
   ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), kIdmapRawDataPolicies);
@@ -165,8 +166,8 @@
 
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 1U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000, Res_value::TYPE_INT_HEX,
-                             0x12345678);
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000,  "land-xxhdpi-v7",
+                             Res_value::TYPE_INT_HEX, 0x12345678);
 
   const auto& overlay_entries = data->GetOverlayEntries();
   ASSERT_EQ(target_entries.size(), 3U);
@@ -203,7 +204,7 @@
 
   ASSERT_THAT(idmap->GetHeader(), NotNull());
   ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
-  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x08U);
+  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x09U);
   ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC);
   ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC);
@@ -261,9 +262,9 @@
 
   auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target")
                   .SetOverlayable("TestResources")
-                  .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "")
-                  .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "")
-                  .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "")
+                  .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "land-xxhdpi-v7")
+                  .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "land")
+                  .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "xxhdpi-v7")
                   .Build();
 
   ASSERT_TRUE(frro);
@@ -295,11 +296,11 @@
 
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 3U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1, "land-xxhdpi-v7",
                              Res_value::TYPE_INT_DEC, 2U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1, "land",
                              Res_value::TYPE_REFERENCE, 0x7f010000);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str2,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str2, "xxhdpi-v7",
                              Res_value::TYPE_STRING,
                              (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1));
 }
@@ -442,9 +443,9 @@
   constexpr size_t overlay_string_pool_size = 10U;
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 2U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1, std::string(),
                              Res_value::TYPE_INT_DEC, 73U);  // -> 73
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1, std::string(),
                              Res_value::TYPE_STRING,
                              overlay_string_pool_size + 0U);  // -> "Hello World"
 
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index a6371cb..7112eeb 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -64,7 +64,7 @@
   (*idmap)->accept(&visitor);
 
   ASSERT_CONTAINS_REGEX(ADDRESS "504d4449  magic\n", stream.str());
-  ASSERT_CONTAINS_REGEX(ADDRESS "00000008  version\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000009  version\n", stream.str());
   ASSERT_CONTAINS_REGEX(
       StringPrintf(ADDRESS "%s  target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING),
       stream.str());
@@ -75,6 +75,8 @@
   ASSERT_CONTAINS_REGEX(ADDRESS "00000001  enforce overlayable\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000004  target entry count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000000  target inline entry count", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000000  target inline entry value count", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000000  config count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000004  overlay entry count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "0000000a  string pool index offset", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f010000  target id: integer/int1", stream.str());
@@ -111,7 +113,7 @@
   (*idmap)->accept(&visitor);
 
   ASSERT_CONTAINS_REGEX(ADDRESS "504d4449  magic\n", stream.str());
-  ASSERT_CONTAINS_REGEX(ADDRESS "00000008  version\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000009  version\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00001234  target crc\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00005678  overlay crc\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000011  fulfilled policies: public|signature\n", stream.str());
@@ -124,17 +126,25 @@
   ASSERT_CONTAINS_REGEX(ADDRESS "........  overlay name: OverlayName\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000003  target entry count\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000001  target inline entry count\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000001  target inline entry value count", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000001  config count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000003  overlay entry count\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000000  string pool index offset\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  target id\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  overlay id\n", stream.str());
-  ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030000  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030000  overlay id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030002  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030001  overlay id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f040000  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "0000000e  config: land-xxhdpi-v7 size\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "........  config: land-xxhdpi-v7\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "      11  type: integer\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "12345678  data\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  overlay id\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f030002  target id\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000004  string pool size\n", stream.str());
-  ASSERT_CONTAINS_REGEX("000000a4: ........  string pool\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "........  string pool\n", stream.str());
 }
 
 }  // namespace android::idmap2
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index ca9a444..016d427 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -111,19 +111,20 @@
     return Error("Failed to find mapping for target resource");
   }
 
-  auto actual_overlay_value = std::get_if<TargetValue>(&entry_map->second);
-  if (actual_overlay_value == nullptr) {
+  auto config_map = std::get_if<ConfigMap>(&entry_map->second);
+  if (config_map == nullptr || config_map->empty()) {
     return Error("Target resource is not mapped to an inline value");
   }
+  auto actual_overlay_value = config_map->begin()->second;
 
-  if (actual_overlay_value->data_type != type) {
+  if (actual_overlay_value.data_type != type) {
     return Error(R"(Expected type: "0x%02x" Actual type: "0x%02x")", type,
-                 actual_overlay_value->data_type);
+                 actual_overlay_value.data_type);
   }
 
-  if (actual_overlay_value->data_value != value) {
+  if (actual_overlay_value.data_value != value) {
     return Error(R"(Expected value: "0x%08x" Actual value: "0x%08x")", type,
-                 actual_overlay_value->data_value);
+                 actual_overlay_value.data_value);
   }
 
   return Result<Unit>({});
diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h
index 6b5f3a8..45740e2 100644
--- a/cmds/idmap2/tests/TestHelpers.h
+++ b/cmds/idmap2/tests/TestHelpers.h
@@ -30,7 +30,7 @@
     0x49, 0x44, 0x4d, 0x50,
 
     // 0x4: version
-    0x08, 0x00, 0x00, 0x00,
+    0x09, 0x00, 0x00, 0x00,
 
     // 0x8: target crc
     0x34, 0x12, 0x00, 0x00,
@@ -76,66 +76,123 @@
     // 0x58: target_inline_entry_count
     0x01, 0x00, 0x00, 0x00,
 
-    // 0x5c: overlay_entry_count
+    // 0x5c: target_inline_entry_value_count
+    0x01, 0x00, 0x00, 0x00,
+
+    // 0x60: config_count
+    0x01, 0x00, 0x00, 0x00,
+
+    // 0x64: overlay_entry_count
     0x03, 0x00, 0x00, 0x00,
 
-    // 0x60: string_pool_offset
+    // 0x68: string_pool_offset
     0x00, 0x00, 0x00, 0x00,
 
     // TARGET ENTRIES
-    // 0x64: target id (0x7f020000)
+    // 0x6c: target id (0x7f020000)
     0x00, 0x00, 0x02, 0x7f,
 
-    // 0x68: overlay_id (0x7f020000)
+    // 0x70: overlay_id (0x7f020000)
     0x00, 0x00, 0x02, 0x7f,
 
-    // 0x6c: target id (0x7f030000)
+    // 0x74: target id (0x7f030000)
     0x00, 0x00, 0x03, 0x7f,
 
-    // 0x70: overlay_id (0x7f030000)
+    // 0x78: overlay_id (0x7f030000)
     0x00, 0x00, 0x03, 0x7f,
 
-    // 0x74: target id (0x7f030002)
+    // 0x7c: target id (0x7f030002)
     0x02, 0x00, 0x03, 0x7f,
 
-    // 0x78: overlay_id (0x7f030001)
+    // 0x80: overlay_id (0x7f030001)
     0x01, 0x00, 0x03, 0x7f,
 
     // INLINE TARGET ENTRIES
 
-    // 0x7c: target_id
+    // 0x84: target_id
     0x00, 0x00, 0x04, 0x7f,
 
-    // 0x80: Res_value::size (value ignored by idmap)
+    // 0x88: start value index
+    0x00, 0x00, 0x00, 0x00,
+
+    // 0x8c: value count
+    0x01, 0x00, 0x00, 0x00,
+
+    // INLINE TARGET ENTRY VALUES
+
+    // 0x90: config index
+    0x00, 0x00, 0x00, 0x00,
+
+    // 0x94: Res_value::size (value ignored by idmap)
     0x08, 0x00,
 
-    // 0x82: Res_value::res0 (value ignored by idmap)
+    // 0x98: Res_value::res0 (value ignored by idmap)
     0x00,
 
-    // 0x83: Res_value::dataType (TYPE_INT_HEX)
+    // 0x9c: Res_value::dataType (TYPE_INT_HEX)
     0x11,
 
-    // 0x84: Res_value::data
+    // 0xa0: Res_value::data
     0x78, 0x56, 0x34, 0x12,
 
+    // CONFIGURATIONS
+
+    // 0xa4: ConfigDescription
+    // size
+    0x40, 0x00, 0x00, 0x00,
+    // 0xa8: imsi
+    0x00, 0x00, 0x00, 0x00,
+    // 0xac: locale
+    0x00, 0x00, 0x00, 0x00,
+    // 0xb0: screenType
+    0x02, 0x00, 0xe0, 0x01,
+    // 0xb4: input
+    0x00, 0x00, 0x00, 0x00,
+    // 0xb8: screenSize
+    0x00, 0x00, 0x00, 0x00,
+    // 0xbc: version
+    0x07, 0x00, 0x00, 0x00,
+    // 0xc0: screenConfig
+    0x00, 0x00, 0x00, 0x00,
+    // 0xc4: screenSizeDp
+    0x00, 0x00, 0x00, 0x00,
+    // 0xc8: localeScript
+    0x00, 0x00, 0x00, 0x00,
+    // 0xcc: localVariant(1)
+    0x00, 0x00, 0x00, 0x00,
+    // 0xd0: localVariant(2)
+    0x00, 0x00, 0x00, 0x00,
+    // 0xd4: screenConfig2
+    0x00, 0x00, 0x00, 0x00,
+    // 0xd8: localeScriptWasComputed
+    0x00,
+    // 0xd9: localeNumberingSystem(1)
+    0x00, 0x00, 0x00, 0x00,
+    // 0xdd: localeNumberingSystem(2)
+    0x00, 0x00, 0x00, 0x00,
+
+    // 0xe1: padding
+    0x00, 0x00, 0x00,
+
+
     // OVERLAY ENTRIES
-    // 0x88: 0x7f020000 -> 0x7f020000
+    // 0xe4: 0x7f020000 -> 0x7f020000
     0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f,
 
-    // 0x90: 0x7f030000 -> 0x7f030000
+    // 0xec: 0x7f030000 -> 0x7f030000
     0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f,
 
-    // 0x98: 0x7f030001 -> 0x7f030002
+    // 0xf4: 0x7f030001 -> 0x7f030002
     0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f,
 
-    // 0xa0: string pool
+    // 0xfc: string pool
     // string length,
     0x04, 0x00, 0x00, 0x00,
 
-    // 0xa4 string contents "test"
+    // 0x100 string contents "test"
     0x74, 0x65, 0x73, 0x74};
 
-const unsigned int kIdmapRawDataLen = 0xa8;
+const unsigned int kIdmapRawDataLen = 0x104;
 const unsigned int kIdmapRawDataOffset = 0x54;
 const unsigned int kIdmapRawDataTargetCrc = 0x1234;
 const unsigned int kIdmapRawOverlayCrc = 0x5678;