xref: /aosp_15_r20/frameworks/base/cmds/idmap2/tests/FabricatedOverlayTests.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #include <android-base/file.h>
18*d57664e9SAndroid Build Coastguard Worker #include <gtest/gtest.h>
19*d57664e9SAndroid Build Coastguard Worker #include <idmap2/FabricatedOverlay.h>
20*d57664e9SAndroid Build Coastguard Worker #include "TestHelpers.h"
21*d57664e9SAndroid Build Coastguard Worker 
22*d57664e9SAndroid Build Coastguard Worker #include <fstream>
23*d57664e9SAndroid Build Coastguard Worker #include <utility>
24*d57664e9SAndroid Build Coastguard Worker 
25*d57664e9SAndroid Build Coastguard Worker namespace android::idmap2 {
26*d57664e9SAndroid Build Coastguard Worker 
TEST(FabricatedOverlayTests,OverlayInfo)27*d57664e9SAndroid Build Coastguard Worker TEST(FabricatedOverlayTests, OverlayInfo) {
28*d57664e9SAndroid Build Coastguard Worker   auto overlay =
29*d57664e9SAndroid Build Coastguard Worker       FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
30*d57664e9SAndroid Build Coastguard Worker           .SetOverlayable("TestResources")
31*d57664e9SAndroid Build Coastguard Worker           .Build();
32*d57664e9SAndroid Build Coastguard Worker 
33*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(overlay);
34*d57664e9SAndroid Build Coastguard Worker   auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
35*d57664e9SAndroid Build Coastguard Worker   auto info = container->FindOverlayInfo("SandTheme");
36*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(info);
37*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ("SandTheme", (*info).name);
38*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ("TestResources", (*info).target_name);
39*d57664e9SAndroid Build Coastguard Worker 
40*d57664e9SAndroid Build Coastguard Worker   info = container->FindOverlayInfo("OceanTheme");
41*d57664e9SAndroid Build Coastguard Worker   ASSERT_FALSE(info);
42*d57664e9SAndroid Build Coastguard Worker }
43*d57664e9SAndroid Build Coastguard Worker 
TEST(FabricatedOverlayTests,SetResourceValue)44*d57664e9SAndroid Build Coastguard Worker TEST(FabricatedOverlayTests, SetResourceValue) {
45*d57664e9SAndroid Build Coastguard Worker   auto path = GetTestDataPath() + "/overlay/res/drawable/android.png";
46*d57664e9SAndroid Build Coastguard Worker   auto fd = android::base::unique_fd(::open(path.c_str(), O_RDONLY | O_CLOEXEC));
47*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(fd > 0) << "errno " << errno << " for path " << path;
48*d57664e9SAndroid Build Coastguard Worker 
49*d57664e9SAndroid Build Coastguard Worker   auto overlay =
50*d57664e9SAndroid Build Coastguard Worker       FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
51*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue(
52*d57664e9SAndroid Build Coastguard Worker               "com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "port")
53*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue(
54*d57664e9SAndroid Build Coastguard Worker               "com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U, "land")
55*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue(
56*d57664e9SAndroid Build Coastguard Worker               "string/int3", Res_value::TYPE_REFERENCE, 0x7f010000, "xxhdpi-v7")
57*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue(
58*d57664e9SAndroid Build Coastguard Worker               "com.example.target:string/string1",
59*d57664e9SAndroid Build Coastguard Worker               Res_value::TYPE_STRING,
60*d57664e9SAndroid Build Coastguard Worker               "foobar",
61*d57664e9SAndroid Build Coastguard Worker               "en-rUS-normal-xxhdpi-v21")
62*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue("com.example.target:drawable/dr1", fd, 0, 8341, "port-xxhdpi-v7", false)
63*d57664e9SAndroid Build Coastguard Worker           .setFrroPath("/foo/bar/biz.frro")
64*d57664e9SAndroid Build Coastguard Worker           .Build();
65*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(overlay);
66*d57664e9SAndroid Build Coastguard Worker   auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
67*d57664e9SAndroid Build Coastguard Worker   auto info = container->FindOverlayInfo("SandTheme");
68*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(info);
69*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE((*info).target_name.empty());
70*d57664e9SAndroid Build Coastguard Worker 
71*d57664e9SAndroid Build Coastguard Worker   auto crc = (*container).GetCrc();
72*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(crc) << crc.GetErrorMessage();
73*d57664e9SAndroid Build Coastguard Worker   EXPECT_NE(0U, *crc);
74*d57664e9SAndroid Build Coastguard Worker 
75*d57664e9SAndroid Build Coastguard Worker   auto pairs = container->GetOverlayData(*info);
76*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(pairs);
77*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(5U, pairs->pairs.size());
78*d57664e9SAndroid Build Coastguard Worker   auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
79*d57664e9SAndroid Build Coastguard Worker                                         pairs->string_pool_data->data_length, false);
80*d57664e9SAndroid Build Coastguard Worker 
81*d57664e9SAndroid Build Coastguard Worker   auto& it = pairs->pairs[0];
82*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target:drawable/dr1", it.resource_name);
83*d57664e9SAndroid Build Coastguard Worker   auto entry = std::get_if<TargetValueWithConfig>(&it.value);
84*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
85*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(std::string("frro://foo/bar/biz.frro?offset=16&size=8341"),
86*d57664e9SAndroid Build Coastguard Worker       string_pool.string8At(entry->value.data_value).value_or(""));
87*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
88*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("port-xxhdpi-v7", entry->config);
89*d57664e9SAndroid Build Coastguard Worker 
90*d57664e9SAndroid Build Coastguard Worker   it = pairs->pairs[1];
91*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
92*d57664e9SAndroid Build Coastguard Worker   entry = std::get_if<TargetValueWithConfig>(&it.value);
93*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
94*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(1U, entry->value.data_value);
95*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
96*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("port", entry->config);
97*d57664e9SAndroid Build Coastguard Worker 
98*d57664e9SAndroid Build Coastguard Worker   it = pairs->pairs[2];
99*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target:string/int3", it.resource_name);
100*d57664e9SAndroid Build Coastguard Worker   entry = std::get_if<TargetValueWithConfig>(&it.value);
101*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
102*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(0x7f010000, entry->value.data_value);
103*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->value.data_type);
104*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("xxhdpi-v7", entry->config);
105*d57664e9SAndroid Build Coastguard Worker 
106*d57664e9SAndroid Build Coastguard Worker   it = pairs->pairs[3];
107*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target:string/string1", it.resource_name);
108*d57664e9SAndroid Build Coastguard Worker   entry = std::get_if<TargetValueWithConfig>(&it.value);
109*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
110*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
111*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
112*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("en-rUS-normal-xxhdpi-v21", entry->config);
113*d57664e9SAndroid Build Coastguard Worker 
114*d57664e9SAndroid Build Coastguard Worker   it = pairs->pairs[4];
115*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name);
116*d57664e9SAndroid Build Coastguard Worker   entry = std::get_if<TargetValueWithConfig>(&it.value);
117*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
118*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(2U, entry->value.data_value);
119*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
120*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("land", entry->config);
121*d57664e9SAndroid Build Coastguard Worker }
122*d57664e9SAndroid Build Coastguard Worker 
TEST(FabricatedOverlayTests,SetResourceValueBadArgs)123*d57664e9SAndroid Build Coastguard Worker TEST(FabricatedOverlayTests, SetResourceValueBadArgs) {
124*d57664e9SAndroid Build Coastguard Worker   {
125*d57664e9SAndroid Build Coastguard Worker     auto builder =
126*d57664e9SAndroid Build Coastguard Worker         FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
127*d57664e9SAndroid Build Coastguard Worker             .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U, "");
128*d57664e9SAndroid Build Coastguard Worker     ASSERT_FALSE(builder.Build());
129*d57664e9SAndroid Build Coastguard Worker   }
130*d57664e9SAndroid Build Coastguard Worker   {
131*d57664e9SAndroid Build Coastguard Worker     auto builder =
132*d57664e9SAndroid Build Coastguard Worker         FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
133*d57664e9SAndroid Build Coastguard Worker             .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U, "");
134*d57664e9SAndroid Build Coastguard Worker     ASSERT_FALSE(builder.Build());
135*d57664e9SAndroid Build Coastguard Worker   }
136*d57664e9SAndroid Build Coastguard Worker }
137*d57664e9SAndroid Build Coastguard Worker 
TEST(FabricatedOverlayTests,SerializeAndDeserialize)138*d57664e9SAndroid Build Coastguard Worker TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
139*d57664e9SAndroid Build Coastguard Worker   auto overlay =
140*d57664e9SAndroid Build Coastguard Worker       FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
141*d57664e9SAndroid Build Coastguard Worker           .SetOverlayable("TestResources")
142*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "")
143*d57664e9SAndroid Build Coastguard Worker           .SetResourceValue(
144*d57664e9SAndroid Build Coastguard Worker               "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "")
145*d57664e9SAndroid Build Coastguard Worker           .Build();
146*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(overlay);
147*d57664e9SAndroid Build Coastguard Worker   TempFrroFile tf;
148*d57664e9SAndroid Build Coastguard Worker   std::ofstream out(tf.path);
149*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE((*overlay).ToBinaryStream(out));
150*d57664e9SAndroid Build Coastguard Worker   out.close();
151*d57664e9SAndroid Build Coastguard Worker 
152*d57664e9SAndroid Build Coastguard Worker   auto container = OverlayResourceContainer::FromPath(tf.path);
153*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(container) << container.GetErrorMessage();
154*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ(tf.path, (*container)->GetPath());
155*d57664e9SAndroid Build Coastguard Worker 
156*d57664e9SAndroid Build Coastguard Worker   auto crc = (*container)->GetCrc();
157*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(crc) << crc.GetErrorMessage();
158*d57664e9SAndroid Build Coastguard Worker   EXPECT_NE(0U, *crc);
159*d57664e9SAndroid Build Coastguard Worker 
160*d57664e9SAndroid Build Coastguard Worker   auto info = (*container)->FindOverlayInfo("SandTheme");
161*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(info) << info.GetErrorMessage();
162*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ("SandTheme", (*info).name);
163*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ("TestResources", (*info).target_name);
164*d57664e9SAndroid Build Coastguard Worker 
165*d57664e9SAndroid Build Coastguard Worker   auto pairs = (*container)->GetOverlayData(*info);
166*d57664e9SAndroid Build Coastguard Worker   ASSERT_TRUE(pairs) << pairs.GetErrorMessage();
167*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ(2U, pairs->pairs.size());
168*d57664e9SAndroid Build Coastguard Worker   auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
169*d57664e9SAndroid Build Coastguard Worker                                         pairs->string_pool_data->data_length, false);
170*d57664e9SAndroid Build Coastguard Worker 
171*d57664e9SAndroid Build Coastguard Worker   auto& it = pairs->pairs[0];
172*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
173*d57664e9SAndroid Build Coastguard Worker   auto entry = std::get_if<TargetValueWithConfig>(&it.value);
174*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
175*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ(1U, entry->value.data_value);
176*d57664e9SAndroid Build Coastguard Worker   EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
177*d57664e9SAndroid Build Coastguard Worker 
178*d57664e9SAndroid Build Coastguard Worker   it = pairs->pairs[1];
179*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ("com.example.target:string/string1", it.resource_name);
180*d57664e9SAndroid Build Coastguard Worker   entry = std::get_if<TargetValueWithConfig>(&it.value);
181*d57664e9SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
182*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
183*d57664e9SAndroid Build Coastguard Worker   ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
184*d57664e9SAndroid Build Coastguard Worker }
185*d57664e9SAndroid Build Coastguard Worker 
186*d57664e9SAndroid Build Coastguard Worker }  // namespace android::idmap2
187