Store string frros in a string pool and copy that pool to the idmap

Bug: 232940948
Test: manual with test app and added automated tests
Change-Id: I30f5efefff7cf4fb0869188be78cc08e8efe7f04
diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
index 468ea0c..91331ca 100644
--- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp
+++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
@@ -46,6 +46,7 @@
           .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U)
           .SetResourceValue("com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U)
           .SetResourceValue("string/int3", Res_value::TYPE_REFERENCE, 0x7f010000)
+          .SetResourceValue("com.example.target:string/string1", Res_value::TYPE_STRING, "foobar")
           .Build();
   ASSERT_TRUE(overlay);
   auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
@@ -59,8 +60,9 @@
 
   auto pairs = container->GetOverlayData(*info);
   ASSERT_TRUE(pairs);
-  EXPECT_FALSE(pairs->string_pool_data.has_value());
-  ASSERT_EQ(3U, pairs->pairs.size());
+  ASSERT_EQ(4U, pairs->pairs.size());
+  auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
+                                        pairs->string_pool_data->data_length, false);
 
   auto& it = pairs->pairs[0];
   ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
@@ -77,6 +79,13 @@
   ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->data_type);
 
   it = pairs->pairs[2];
+  ASSERT_EQ("com.example.target:string/string1", it.resource_name);
+  entry = std::get_if<TargetValue>(&it.value);
+  ASSERT_NE(nullptr, entry);
+  ASSERT_EQ(Res_value::TYPE_STRING, entry->data_type);
+  ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->data_value).value_or(""));
+
+  it = pairs->pairs[3];
   ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name);
   entry = std::get_if<TargetValue>(&it.value);
   ASSERT_NE(nullptr, entry);
@@ -104,6 +113,7 @@
       FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
           .SetOverlayable("TestResources")
           .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U)
+          .SetResourceValue("com.example.target:string/string1", Res_value::TYPE_STRING, "foobar")
           .Build();
   ASSERT_TRUE(overlay);
   TemporaryFile tf;
@@ -126,7 +136,9 @@
 
   auto pairs = (*container)->GetOverlayData(*info);
   ASSERT_TRUE(pairs) << pairs.GetErrorMessage();
-  EXPECT_EQ(1U, pairs->pairs.size());
+  EXPECT_EQ(2U, pairs->pairs.size());
+  auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
+                                        pairs->string_pool_data->data_length, false);
 
   auto& it = pairs->pairs[0];
   ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
@@ -134,6 +146,13 @@
   ASSERT_NE(nullptr, entry);
   EXPECT_EQ(1U, entry->data_value);
   EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
+
+  it = pairs->pairs[1];
+  ASSERT_EQ("com.example.target:string/string1", it.resource_name);
+  entry = std::get_if<TargetValue>(&it.value);
+  ASSERT_NE(nullptr, entry);
+  ASSERT_EQ(Res_value::TYPE_STRING, entry->data_type);
+  ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->data_value).value_or(""));
 }
 
 }  // namespace android::idmap2
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 738b9cf..a3799f9 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -263,6 +263,7 @@
                   .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")
                   .Build();
 
   ASSERT_TRUE(frro);
@@ -288,12 +289,19 @@
   ASSERT_EQ(data->GetTargetEntries().size(), 0U);
   ASSERT_EQ(data->GetOverlayEntries().size(), 0U);
 
+  auto string_pool_data = data->GetStringPoolData();
+  auto string_pool = ResStringPool(string_pool_data.data(), string_pool_data.size(), false);
+
+
   const auto& target_inline_entries = data->GetTargetInlineEntries();
-  ASSERT_EQ(target_inline_entries.size(), 2U);
+  ASSERT_EQ(target_inline_entries.size(), 3U);
   ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
                              Res_value::TYPE_INT_DEC, 2U);
   ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
                              Res_value::TYPE_REFERENCE, 0x7f010000);
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str2,
+                             Res_value::TYPE_STRING,
+                             (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1));
 }
 
 TEST(IdmapTests, FailCreateIdmapInvalidName) {
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index 89219c9..ad998b9 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -41,6 +41,7 @@
     constexpr ResourceId policy_system = 0x7f02000c;
     constexpr ResourceId policy_system_vendor = 0x7f02000d;
     constexpr ResourceId str1 = 0x7f02000e;
+    constexpr ResourceId str2 = 0x7f02000f;
     constexpr ResourceId str3 = 0x7f020010;
     constexpr ResourceId str4 = 0x7f020011;
   }  // namespace string
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 32b3d13..c05abcf 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -196,6 +196,7 @@
                   .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")
                   .Build();
 
   ASSERT_TRUE(frro);
@@ -209,9 +210,14 @@
 
   ASSERT_TRUE(resources) << resources.GetErrorMessage();
   auto& res = *resources;
-  ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U);
+  auto string_pool_data = res.GetStringPoolData();
+  auto string_pool = ResStringPool(string_pool_data.data(), string_pool_data.size(), false);
+
+  ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
   ASSERT_EQ(res.GetOverlayToTargetMap().size(), 0U);
   ASSERT_RESULT(MappingExists(res, R::target::string::str1, Res_value::TYPE_REFERENCE, 0x7f010000));
+  ASSERT_RESULT(MappingExists(res, R::target::string::str2, Res_value::TYPE_STRING,
+                              (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1)));
   ASSERT_RESULT(MappingExists(res, R::target::integer::int1, Res_value::TYPE_INT_DEC, 2U));
 }