blob: 15109d99a6fd752c8b09a283e8f40125ec8e8672 [file] [log] [blame]
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -08001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android-base/file.h>
18#include <gtest/gtest.h>
19#include <idmap2/FabricatedOverlay.h>
Jeremy Meyera761f332022-10-21 17:42:14 +000020#include "TestHelpers.h"
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080021
22#include <fstream>
Mårten Kongstad1195a6b2021-05-11 12:57:01 +000023#include <utility>
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080024
25namespace android::idmap2 {
26
27TEST(FabricatedOverlayTests, OverlayInfo) {
28 auto overlay =
29 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
30 .SetOverlayable("TestResources")
31 .Build();
32
33 ASSERT_TRUE(overlay);
34 auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
35 auto info = container->FindOverlayInfo("SandTheme");
36 ASSERT_TRUE(info);
37 EXPECT_EQ("SandTheme", (*info).name);
38 EXPECT_EQ("TestResources", (*info).target_name);
39
40 info = container->FindOverlayInfo("OceanTheme");
41 ASSERT_FALSE(info);
42}
43
44TEST(FabricatedOverlayTests, SetResourceValue) {
Jeremy Meyera761f332022-10-21 17:42:14 +000045 auto path = GetTestDataPath() + "/overlay/res/drawable/android.png";
46 auto fd = android::base::unique_fd(::open(path.c_str(), O_RDONLY | O_CLOEXEC));
47 ASSERT_TRUE(fd > 0) << "errno " << errno << " for path " << path;
48
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080049 auto overlay =
50 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
Jeremy Meyer77c8a932022-08-18 22:06:55 +000051 .SetResourceValue(
52 "com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "port")
53 .SetResourceValue(
54 "com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U, "land")
55 .SetResourceValue(
56 "string/int3", Res_value::TYPE_REFERENCE, 0x7f010000, "xxhdpi-v7")
57 .SetResourceValue(
58 "com.example.target:string/string1",
59 Res_value::TYPE_STRING,
60 "foobar",
61 "en-rUS-normal-xxhdpi-v21")
Jeremy Meyerdeb46f312023-11-08 12:20:24 -080062 .SetResourceValue("com.example.target:drawable/dr1", fd, 0, 8341, "port-xxhdpi-v7", false)
Jeremy Meyera761f332022-10-21 17:42:14 +000063 .setFrroPath("/foo/bar/biz.frro")
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080064 .Build();
65 ASSERT_TRUE(overlay);
66 auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
67 auto info = container->FindOverlayInfo("SandTheme");
68 ASSERT_TRUE(info);
69 ASSERT_TRUE((*info).target_name.empty());
70
71 auto crc = (*container).GetCrc();
72 ASSERT_TRUE(crc) << crc.GetErrorMessage();
73 EXPECT_NE(0U, *crc);
74
75 auto pairs = container->GetOverlayData(*info);
76 ASSERT_TRUE(pairs);
Jeremy Meyera761f332022-10-21 17:42:14 +000077 ASSERT_EQ(5U, pairs->pairs.size());
Jeremy Meyer65871022022-07-12 22:45:08 +000078 auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
79 pairs->string_pool_data->data_length, false);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080080
81 auto& it = pairs->pairs[0];
Jeremy Meyera761f332022-10-21 17:42:14 +000082 ASSERT_EQ("com.example.target:drawable/dr1", it.resource_name);
Jeremy Meyer77c8a932022-08-18 22:06:55 +000083 auto entry = std::get_if<TargetValueWithConfig>(&it.value);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080084 ASSERT_NE(nullptr, entry);
Jeremy Meyera761f332022-10-21 17:42:14 +000085 ASSERT_EQ(std::string("frro://foo/bar/biz.frro?offset=16&size=8341"),
86 string_pool.string8At(entry->value.data_value).value_or(""));
87 ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
88 ASSERT_EQ("port-xxhdpi-v7", entry->config);
89
90 it = pairs->pairs[1];
91 ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
92 entry = std::get_if<TargetValueWithConfig>(&it.value);
93 ASSERT_NE(nullptr, entry);
Jeremy Meyer77c8a932022-08-18 22:06:55 +000094 ASSERT_EQ(1U, entry->value.data_value);
95 ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
96 ASSERT_EQ("port", entry->config);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080097
Jeremy Meyera761f332022-10-21 17:42:14 +000098 it = pairs->pairs[2];
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -080099 ASSERT_EQ("com.example.target:string/int3", it.resource_name);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000100 entry = std::get_if<TargetValueWithConfig>(&it.value);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800101 ASSERT_NE(nullptr, entry);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000102 ASSERT_EQ(0x7f010000, entry->value.data_value);
103 ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->value.data_type);
104 ASSERT_EQ("xxhdpi-v7", entry->config);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800105
Jeremy Meyera761f332022-10-21 17:42:14 +0000106 it = pairs->pairs[3];
Jeremy Meyer65871022022-07-12 22:45:08 +0000107 ASSERT_EQ("com.example.target:string/string1", it.resource_name);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000108 entry = std::get_if<TargetValueWithConfig>(&it.value);
Jeremy Meyer65871022022-07-12 22:45:08 +0000109 ASSERT_NE(nullptr, entry);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000110 ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
111 ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
112 ASSERT_EQ("en-rUS-normal-xxhdpi-v21", entry->config);
Jeremy Meyer65871022022-07-12 22:45:08 +0000113
Jeremy Meyera761f332022-10-21 17:42:14 +0000114 it = pairs->pairs[4];
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800115 ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000116 entry = std::get_if<TargetValueWithConfig>(&it.value);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800117 ASSERT_NE(nullptr, entry);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000118 ASSERT_EQ(2U, entry->value.data_value);
119 ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
120 ASSERT_EQ("land", entry->config);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800121}
122
123TEST(FabricatedOverlayTests, SetResourceValueBadArgs) {
124 {
125 auto builder =
126 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000127 .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U, "");
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800128 ASSERT_FALSE(builder.Build());
129 }
130 {
131 auto builder =
132 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000133 .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U, "");
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800134 ASSERT_FALSE(builder.Build());
135 }
136}
137
138TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
139 auto overlay =
140 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
141 .SetOverlayable("TestResources")
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000142 .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "")
143 .SetResourceValue(
144 "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "")
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800145 .Build();
146 ASSERT_TRUE(overlay);
Yurii Zubrytskyie7c1f002024-01-30 13:50:57 -0800147 TempFrroFile tf;
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800148 std::ofstream out(tf.path);
149 ASSERT_TRUE((*overlay).ToBinaryStream(out));
150 out.close();
151
152 auto container = OverlayResourceContainer::FromPath(tf.path);
153 ASSERT_TRUE(container) << container.GetErrorMessage();
154 EXPECT_EQ(tf.path, (*container)->GetPath());
155
156 auto crc = (*container)->GetCrc();
157 ASSERT_TRUE(crc) << crc.GetErrorMessage();
158 EXPECT_NE(0U, *crc);
159
160 auto info = (*container)->FindOverlayInfo("SandTheme");
161 ASSERT_TRUE(info) << info.GetErrorMessage();
162 EXPECT_EQ("SandTheme", (*info).name);
163 EXPECT_EQ("TestResources", (*info).target_name);
164
165 auto pairs = (*container)->GetOverlayData(*info);
166 ASSERT_TRUE(pairs) << pairs.GetErrorMessage();
Jeremy Meyer65871022022-07-12 22:45:08 +0000167 EXPECT_EQ(2U, pairs->pairs.size());
168 auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
169 pairs->string_pool_data->data_length, false);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800170
171 auto& it = pairs->pairs[0];
172 ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000173 auto entry = std::get_if<TargetValueWithConfig>(&it.value);
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800174 ASSERT_NE(nullptr, entry);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000175 EXPECT_EQ(1U, entry->value.data_value);
176 EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
Jeremy Meyer65871022022-07-12 22:45:08 +0000177
178 it = pairs->pairs[1];
179 ASSERT_EQ("com.example.target:string/string1", it.resource_name);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000180 entry = std::get_if<TargetValueWithConfig>(&it.value);
Jeremy Meyer65871022022-07-12 22:45:08 +0000181 ASSERT_NE(nullptr, entry);
Jeremy Meyer77c8a932022-08-18 22:06:55 +0000182 ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
183 ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
Ryan Mitchell2ed8bfa2021-01-08 13:34:28 -0800184}
185
Mårten Kongstad1195a6b2021-05-11 12:57:01 +0000186} // namespace android::idmap2