blob: 69cf5ee7002b692cf5fb0cffc63beb7431ccc1bf [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
2 * Copyright (C) 2015 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
Adam Lesinskicacb28f2016-10-19 12:18:14 -070017#include "link/TableMerger.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070018
Adam Lesinski6a008172016-02-02 17:02:58 -080019#include "filter/ConfigFilter.h"
Adam Lesinskia6fe3452015-12-09 15:20:52 -080020#include "io/FileSystem.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070021#include "test/Test.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070022
Adam Lesinski5924d8c2017-05-30 15:15:58 -070023using ::aapt::test::ValueEq;
24using ::testing::Contains;
Adam Lesinski5924d8c2017-05-30 15:15:58 -070025using ::testing::Eq;
Adam Lesinski8780eb62017-10-31 17:44:39 -070026using ::testing::Field;
27using ::testing::NotNull;
28using ::testing::Pointee;
29using ::testing::StrEq;
30using ::testing::UnorderedElementsAreArray;
Adam Lesinski5924d8c2017-05-30 15:15:58 -070031
Winson62ac8b52019-12-04 08:36:48 -080032using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
33
Adam Lesinski1ab598f2015-08-14 14:26:04 -070034namespace aapt {
35
36struct TableMergerTest : public ::testing::Test {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070037 std::unique_ptr<IAaptContext> context_;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070038
Adam Lesinskicacb28f2016-10-19 12:18:14 -070039 void SetUp() override {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070040 context_ =
Adam Lesinskicacb28f2016-10-19 12:18:14 -070041 test::ContextBuilder()
42 // We are compiling this package.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070043 .SetCompilationPackage("com.app.a")
Adam Lesinski1ab598f2015-08-14 14:26:04 -070044
Adam Lesinskicacb28f2016-10-19 12:18:14 -070045 // Merge all packages that have this package ID.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070046 .SetPackageId(0x7f)
Adam Lesinski1ab598f2015-08-14 14:26:04 -070047
Adam Lesinskicacb28f2016-10-19 12:18:14 -070048 // Mangle all packages that do not have this package name.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070049 .SetNameManglerPolicy(NameManglerPolicy{"com.app.a", {"com.app.b"}})
Adam Lesinski1ab598f2015-08-14 14:26:04 -070050
Adam Lesinskice5e56e2016-10-21 17:56:45 -070051 .Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -070052 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -070053};
54
55TEST_F(TableMergerTest, SimpleMerge) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070056 std::unique_ptr<ResourceTable> table_a =
Adam Lesinskicacb28f2016-10-19 12:18:14 -070057 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -070058 .SetPackageId("com.app.a", 0x7f)
59 .AddReference("com.app.a:id/foo", "com.app.a:id/bar")
60 .AddReference("com.app.a:id/bar", "com.app.b:id/foo")
61 .AddValue(
Adam Lesinskicacb28f2016-10-19 12:18:14 -070062 "com.app.a:styleable/view",
Adam Lesinskice5e56e2016-10-21 17:56:45 -070063 test::StyleableBuilder().AddItem("com.app.b:id/foo").Build())
64 .Build();
Adam Lesinski1ab598f2015-08-14 14:26:04 -070065
Adam Lesinskice5e56e2016-10-21 17:56:45 -070066 std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder()
67 .SetPackageId("com.app.b", 0x7f)
68 .AddSimple("com.app.b:id/foo")
69 .Build();
Adam Lesinski1ab598f2015-08-14 14:26:04 -070070
Adam Lesinskice5e56e2016-10-21 17:56:45 -070071 ResourceTable final_table;
72 TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
Adam Lesinski1ab598f2015-08-14 14:26:04 -070073
Adam Lesinski00451162017-10-03 07:44:08 -070074 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
Adam Lesinski8780eb62017-10-31 17:44:39 -070075 ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070076
Adam Lesinskice5e56e2016-10-21 17:56:45 -070077 EXPECT_TRUE(merger.merged_packages().count("com.app.b") != 0);
Adam Lesinski1ab598f2015-08-14 14:26:04 -070078
Adam Lesinskicacb28f2016-10-19 12:18:14 -070079 // Entries from com.app.a should not be mangled.
Adam Lesinski5924d8c2017-05-30 15:15:58 -070080 EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo")));
81 EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar")));
82 EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:styleable/view")));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070083
Adam Lesinskicacb28f2016-10-19 12:18:14 -070084 // The unmangled name should not be present.
Adam Lesinski5924d8c2017-05-30 15:15:58 -070085 EXPECT_FALSE(final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo")));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070086
Adam Lesinskicacb28f2016-10-19 12:18:14 -070087 // Look for the mangled name.
Adam Lesinski5924d8c2017-05-30 15:15:58 -070088 EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/com.app.b$foo")));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070089}
90
Adam Lesinskia6fe3452015-12-09 15:20:52 -080091TEST_F(TableMergerTest, MergeFile) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070092 ResourceTable final_table;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070093 TableMergerOptions options;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070094 options.auto_add_overlay = false;
95 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinskia6fe3452015-12-09 15:20:52 -080096
Adam Lesinskice5e56e2016-10-21 17:56:45 -070097 ResourceFile file_desc;
98 file_desc.config = test::ParseConfigOrDie("hdpi-v4");
99 file_desc.name = test::ParseNameOrDie("layout/main");
100 file_desc.source = Source("res/layout-hdpi/main.xml");
101 test::TestFile test_file("path/to/res/layout-hdpi/main.xml.flat");
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800102
Adam Lesinski00451162017-10-03 07:44:08 -0700103 ASSERT_TRUE(merger.MergeFile(file_desc, false /*overlay*/, &test_file));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800104
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700105 FileReference* file = test::GetValueForConfig<FileReference>(
106 &final_table, "com.app.a:layout/main", test::ParseConfigOrDie("hdpi-v4"));
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700107 ASSERT_THAT(file, NotNull());
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700108 EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), *file->path);
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800109}
110
111TEST_F(TableMergerTest, MergeFileOverlay) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700112 ResourceTable final_table;
113 TableMergerOptions options;
114 options.auto_add_overlay = false;
115 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800116
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700117 ResourceFile file_desc;
118 file_desc.name = test::ParseNameOrDie("xml/foo");
119 test::TestFile file_a("path/to/fileA.xml.flat");
120 test::TestFile file_b("path/to/fileB.xml.flat");
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800121
Adam Lesinski00451162017-10-03 07:44:08 -0700122 ASSERT_TRUE(merger.MergeFile(file_desc, false /*overlay*/, &file_a));
123 ASSERT_TRUE(merger.MergeFile(file_desc, true /*overlay*/, &file_b));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800124}
125
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700126TEST_F(TableMergerTest, MergeFileReferences) {
Adam Lesinski8780eb62017-10-31 17:44:39 -0700127 test::TestFile file_a("res/xml/file.xml");
128 test::TestFile file_b("res/xml/file.xml");
129
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700130 std::unique_ptr<ResourceTable> table_a =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700131 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700132 .SetPackageId("com.app.a", 0x7f)
Adam Lesinski8780eb62017-10-31 17:44:39 -0700133 .AddFileReference("com.app.a:xml/file", "res/xml/file.xml", &file_a)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700134 .Build();
135 std::unique_ptr<ResourceTable> table_b =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700136 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700137 .SetPackageId("com.app.b", 0x7f)
Adam Lesinski8780eb62017-10-31 17:44:39 -0700138 .AddFileReference("com.app.b:xml/file", "res/xml/file.xml", &file_b)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700139 .Build();
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700140
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700141 ResourceTable final_table;
142 TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700143
Adam Lesinski00451162017-10-03 07:44:08 -0700144 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
Adam Lesinski8780eb62017-10-31 17:44:39 -0700145 ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700146
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700147 FileReference* f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/file");
148 ASSERT_THAT(f, NotNull());
Adam Lesinski8780eb62017-10-31 17:44:39 -0700149 EXPECT_THAT(*f->path, StrEq("res/xml/file.xml"));
150 EXPECT_THAT(f->file, Eq(&file_a));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700151
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700152 f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/com.app.b$file");
153 ASSERT_THAT(f, NotNull());
Adam Lesinski8780eb62017-10-31 17:44:39 -0700154 EXPECT_THAT(*f->path, StrEq("res/xml/com.app.b$file.xml"));
155 EXPECT_THAT(f->file, Eq(&file_b));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800156}
157
158TEST_F(TableMergerTest, OverrideResourceWithOverlay) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700159 std::unique_ptr<ResourceTable> base =
160 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700161 .SetPackageId("", 0x00)
162 .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
163 .Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700164 std::unique_ptr<ResourceTable> overlay =
165 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700166 .SetPackageId("", 0x00)
167 .AddValue("bool/foo", ResourceUtils::TryParseBool("false"))
168 .Build();
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800169
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700170 ResourceTable final_table;
171 TableMergerOptions options;
172 options.auto_add_overlay = false;
173 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800174
Adam Lesinski00451162017-10-03 07:44:08 -0700175 ASSERT_TRUE(merger.Merge({}, base.get(), false /*overlay*/));
176 ASSERT_TRUE(merger.Merge({}, overlay.get(), true /*overlay*/));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800177
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700178 BinaryPrimitive* foo = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
179 ASSERT_THAT(foo,
180 Pointee(Field(&BinaryPrimitive::value, Field(&android::Res_value::data, Eq(0u)))));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800181}
182
Ryan Mitchella9e31602018-06-28 16:41:38 -0700183TEST_F(TableMergerTest, DoNotOverrideResourceComment) {
184 std::unique_ptr<Value> foo_original = ResourceUtils::TryParseBool("true");
185 foo_original->SetComment(android::StringPiece("Original foo comment"));
186 std::unique_ptr<Value> bar_original = ResourceUtils::TryParseBool("true");
187
188 std::unique_ptr<Value> foo_overlay = ResourceUtils::TryParseBool("false");
189 foo_overlay->SetComment(android::StringPiece("Overlay foo comment"));
190 std::unique_ptr<Value> bar_overlay = ResourceUtils::TryParseBool("false");
191 bar_overlay->SetComment(android::StringPiece("Overlay bar comment"));
192 std::unique_ptr<Value> baz_overlay = ResourceUtils::TryParseBool("false");
193 baz_overlay->SetComment(android::StringPiece("Overlay baz comment"));
194
195 std::unique_ptr<ResourceTable> base =
196 test::ResourceTableBuilder()
197 .SetPackageId("", 0x00)
198 .AddValue("bool/foo", std::move(foo_original))
199 .AddValue("bool/bar", std::move(bar_original))
200 .Build();
201
202 std::unique_ptr<ResourceTable> overlay =
203 test::ResourceTableBuilder()
204 .SetPackageId("", 0x00)
205 .AddValue("bool/foo", std::move(foo_overlay))
206 .AddValue("bool/bar", std::move(bar_overlay))
207 .AddValue("bool/baz", std::move(baz_overlay))
208 .Build();
209
210 ResourceTable final_table;
211 TableMergerOptions options;
212 options.auto_add_overlay = true;
213 TableMerger merger(context_.get(), &final_table, options);
214
215 ASSERT_TRUE(merger.Merge({}, base.get(), false /*overlay*/));
216 ASSERT_TRUE(merger.Merge({}, overlay.get(), true /*overlay*/));
217
218 BinaryPrimitive* foo = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
219 EXPECT_THAT(foo, Pointee(Property(&BinaryPrimitive::GetComment, StrEq("Original foo comment"))));
220 BinaryPrimitive* bar = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/bar");
221 EXPECT_THAT(bar, Pointee(Property(&BinaryPrimitive::GetComment, StrEq(""))));
222 BinaryPrimitive* baz = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/baz");
223 EXPECT_THAT(baz, Pointee(Property(&BinaryPrimitive::GetComment, StrEq("Overlay baz comment"))));
224}
225
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700226TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700227 std::unique_ptr<ResourceTable> base =
228 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700229 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800230 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700231 .Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700232 std::unique_ptr<ResourceTable> overlay =
233 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700234 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800235 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700236 .Build();
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700237
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700238 ResourceTable final_table;
239 TableMergerOptions options;
240 options.auto_add_overlay = false;
241 TableMerger merger(context_.get(), &final_table, options);
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700242
Adam Lesinski00451162017-10-03 07:44:08 -0700243 ASSERT_TRUE(merger.Merge({}, base.get(), false /*overlay*/));
244 ASSERT_TRUE(merger.Merge({}, overlay.get(), true /*overlay*/));
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700245}
246
247TEST_F(TableMergerTest, FailToOverrideConflictingTypeIdsWithOverlay) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700248 std::unique_ptr<ResourceTable> base =
249 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700250 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800251 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700252 .Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700253 std::unique_ptr<ResourceTable> overlay =
254 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700255 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800256 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001), Visibility::Level::kPublic)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700257 .Build();
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700258
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700259 ResourceTable final_table;
260 TableMergerOptions options;
261 options.auto_add_overlay = false;
262 TableMerger merger(context_.get(), &final_table, options);
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700263
Adam Lesinski00451162017-10-03 07:44:08 -0700264 ASSERT_TRUE(merger.Merge({}, base.get(), false /*overlay*/));
265 ASSERT_FALSE(merger.Merge({}, overlay.get(), true /*overlay*/));
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700266}
267
268TEST_F(TableMergerTest, FailToOverrideConflictingEntryIdsWithOverlay) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700269 std::unique_ptr<ResourceTable> base =
270 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700271 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800272 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700273 .Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700274 std::unique_ptr<ResourceTable> overlay =
275 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700276 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800277 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002), Visibility::Level::kPublic)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700278 .Build();
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700279
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700280 ResourceTable final_table;
281 TableMergerOptions options;
282 options.auto_add_overlay = false;
283 TableMerger merger(context_.get(), &final_table, options);
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700284
Adam Lesinski00451162017-10-03 07:44:08 -0700285 ASSERT_TRUE(merger.Merge({}, base.get(), false /*overlay*/));
286 ASSERT_FALSE(merger.Merge({}, overlay.get(), true /*overlay*/));
Alexandria Cornwall6a1f8db2016-08-11 13:49:44 -0700287}
288
Izabela Orlowskad51efe82018-04-24 18:18:29 +0100289TEST_F(TableMergerTest, FailConflictingVisibility) {
290 std::unique_ptr<ResourceTable> base =
291 test::ResourceTableBuilder()
292 .SetPackageId("", 0x7f)
293 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPublic)
294 .Build();
295 std::unique_ptr<ResourceTable> overlay =
296 test::ResourceTableBuilder()
297 .SetPackageId("", 0x7f)
298 .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), Visibility::Level::kPrivate)
299 .Build();
300
301 // It should fail if the "--strict-visibility" flag is set.
302 ResourceTable final_table;
303 TableMergerOptions options;
304 options.auto_add_overlay = false;
305 options.strict_visibility = true;
306 TableMerger merger(context_.get(), &final_table, options);
307
308 ASSERT_TRUE(merger.Merge({}, base.get(), false /*overlay*/));
309 ASSERT_FALSE(merger.Merge({}, overlay.get(), true /*overlay*/));
310
311 // But it should still pass if the flag is not set.
312 ResourceTable final_table2;
313 options.strict_visibility = false;
314 TableMerger merger2(context_.get(), &final_table2, options);
315
316 ASSERT_TRUE(merger2.Merge({}, base.get(), false /*overlay*/));
317 ASSERT_TRUE(merger2.Merge({}, overlay.get(), true /*overlay*/));
318}
319
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800320TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700321 std::unique_ptr<ResourceTable> table_a =
Adam Lesinski4488f1c2017-05-26 17:33:38 -0700322 test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700323 std::unique_ptr<ResourceTable> table_b =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700324 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700325 .SetPackageId("", 0x7f)
Adam Lesinski71be7052017-12-12 16:48:07 -0800326 .SetSymbolState("bool/foo", {}, Visibility::Level::kUndefined, true /*allow new overlay*/)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700327 .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
328 .Build();
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800329
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700330 ResourceTable final_table;
Adam Lesinski4488f1c2017-05-26 17:33:38 -0700331 TableMergerOptions options;
332 options.auto_add_overlay = false;
333 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800334
Adam Lesinski00451162017-10-03 07:44:08 -0700335 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
336 ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800337}
338
339TEST_F(TableMergerTest, MergeAddResourceFromOverlayWithAutoAddOverlay) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700340 std::unique_ptr<ResourceTable> table_a =
341 test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
342 std::unique_ptr<ResourceTable> table_b =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700343 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700344 .SetPackageId("", 0x7f)
345 .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
346 .Build();
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800347
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700348 ResourceTable final_table;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700349 TableMergerOptions options;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700350 options.auto_add_overlay = true;
351 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800352
Adam Lesinski00451162017-10-03 07:44:08 -0700353 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
354 ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800355}
356
357TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700358 std::unique_ptr<ResourceTable> table_a =
359 test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
360 std::unique_ptr<ResourceTable> table_b =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700361 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700362 .SetPackageId("", 0x7f)
363 .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
364 .Build();
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800365
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700366 ResourceTable final_table;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700367 TableMergerOptions options;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700368 options.auto_add_overlay = false;
369 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800370
Adam Lesinski00451162017-10-03 07:44:08 -0700371 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
372 ASSERT_FALSE(merger.Merge({}, table_b.get(), true /*overlay*/));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700373}
374
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700375TEST_F(TableMergerTest, OverlaidStyleablesAndStylesShouldBeMerged) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700376 std::unique_ptr<ResourceTable> table_a =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700377 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700378 .SetPackageId("com.app.a", 0x7f)
379 .AddValue("com.app.a:styleable/Foo",
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700380 test::StyleableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700381 .AddItem("com.app.a:attr/bar")
382 .AddItem("com.app.a:attr/foo", ResourceId(0x01010000))
383 .Build())
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700384 .AddValue("com.app.a:style/Theme",
385 test::StyleBuilder()
386 .SetParent("com.app.a:style/Parent")
387 .AddItem("com.app.a:attr/bar", util::make_unique<Id>())
388 .AddItem("com.app.a:attr/foo", ResourceUtils::MakeBool(false))
389 .Build())
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700390 .Build();
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700391
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700392 std::unique_ptr<ResourceTable> table_b =
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700393 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700394 .SetPackageId("com.app.a", 0x7f)
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700395 .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder()
396 .AddItem("com.app.a:attr/bat")
397 .AddItem("com.app.a:attr/foo")
398 .Build())
399 .AddValue("com.app.a:style/Theme",
400 test::StyleBuilder()
401 .SetParent("com.app.a:style/OverlayParent")
402 .AddItem("com.app.a:attr/bat", util::make_unique<Id>())
403 .AddItem("com.app.a:attr/foo", ResourceId(0x01010000),
404 ResourceUtils::MakeBool(true))
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700405 .Build())
406 .Build();
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700407
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700408 ResourceTable final_table;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700409 TableMergerOptions options;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700410 options.auto_add_overlay = true;
411 TableMerger merger(context_.get(), &final_table, options);
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700412
Adam Lesinski00451162017-10-03 07:44:08 -0700413 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
414 ASSERT_TRUE(merger.Merge({}, table_b.get(), true /*overlay*/));
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700415
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700416 Styleable* styleable = test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo");
417 ASSERT_THAT(styleable, NotNull());
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700418
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700419 std::vector<Reference> expected_refs = {
420 Reference(test::ParseNameOrDie("com.app.a:attr/bar")),
421 Reference(test::ParseNameOrDie("com.app.a:attr/bat")),
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700422 Reference(test::ParseNameOrDie("com.app.a:attr/foo"), ResourceId(0x01010000)),
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700423 };
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700424 EXPECT_THAT(styleable->entries, UnorderedElementsAreArray(expected_refs));
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700425
Adam Lesinski5924d8c2017-05-30 15:15:58 -0700426 Style* style = test::GetValue<Style>(&final_table, "com.app.a:style/Theme");
427 ASSERT_THAT(style, NotNull());
428
429 std::vector<Reference> extracted_refs;
430 for (const auto& entry : style->entries) {
431 extracted_refs.push_back(entry.key);
432 }
433 EXPECT_THAT(extracted_refs, UnorderedElementsAreArray(expected_refs));
434
435 const auto expected = ResourceUtils::MakeBool(true);
436 EXPECT_THAT(style->entries, Contains(Field(&Style::Entry::value, Pointee(ValueEq(*expected)))));
437 EXPECT_THAT(style->parent,
438 Eq(make_value(Reference(test::ParseNameOrDie("com.app.a:style/OverlayParent")))));
Adam Lesinski5c3464c2016-08-24 16:03:48 -0700439}
440
Donald Chai121c6e82019-06-12 12:51:57 -0700441TEST_F(TableMergerTest, OverrideStyleInsteadOfOverlaying) {
442 std::unique_ptr<ResourceTable> table_a =
443 test::ResourceTableBuilder()
444 .SetPackageId("com.app.a", 0x7f)
445 .AddValue(
446 "com.app.a:styleable/MyWidget",
447 test::StyleableBuilder().AddItem("com.app.a:attr/foo", ResourceId(0x1234)).Build())
448 .AddValue("com.app.a:style/Theme",
449 test::StyleBuilder()
450 .AddItem("com.app.a:attr/foo", ResourceUtils::MakeBool(false))
451 .Build())
452 .Build();
453 std::unique_ptr<ResourceTable> table_b =
454 test::ResourceTableBuilder()
455 .SetPackageId("com.app.a", 0x7f)
456 .AddValue(
457 "com.app.a:styleable/MyWidget",
458 test::StyleableBuilder().AddItem("com.app.a:attr/bar", ResourceId(0x5678)).Build())
459 .AddValue(
460 "com.app.a:style/Theme",
461 test::StyleBuilder().AddItem("com.app.a:attr/bat", util::make_unique<Id>()).Build())
462 .Build();
463
464 ResourceTable final_table;
465 TableMergerOptions options;
466 options.auto_add_overlay = true;
467 options.override_styles_instead_of_overlaying = true;
468 TableMerger merger(context_.get(), &final_table, options);
469 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
470 ASSERT_TRUE(merger.Merge({}, table_b.get(), true /*overlay*/));
471
472 // Styleables are always overlaid
473 std::unique_ptr<Styleable> expected_styleable = test::StyleableBuilder()
474 // The merged Styleable has its entries ordered by name.
475 .AddItem("com.app.a:attr/bar", ResourceId(0x5678))
476 .AddItem("com.app.a:attr/foo", ResourceId(0x1234))
477 .Build();
478 const Styleable* actual_styleable =
479 test::GetValue<Styleable>(&final_table, "com.app.a:styleable/MyWidget");
480 ASSERT_NE(actual_styleable, nullptr);
481 EXPECT_TRUE(actual_styleable->Equals(expected_styleable.get()));
482 // Style should be overridden
483 const Style* actual_style = test::GetValue<Style>(&final_table, "com.app.a:style/Theme");
484 ASSERT_NE(actual_style, nullptr);
485 EXPECT_TRUE(actual_style->Equals(test::GetValue<Style>(table_b.get(), "com.app.a:style/Theme")));
486}
487
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800488TEST_F(TableMergerTest, SetOverlayable) {
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800489 auto overlayable = std::make_shared<Overlayable>("CustomizableResources",
490 "overlay://customization");
491 OverlayableItem overlayable_item(overlayable);
Winson62ac8b52019-12-04 08:36:48 -0800492 overlayable_item.policies |= PolicyFlags::PRODUCT_PARTITION;
493 overlayable_item.policies |= PolicyFlags::VENDOR_PARTITION;
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800494
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700495 std::unique_ptr<ResourceTable> table_a =
496 test::ResourceTableBuilder()
497 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800498 .SetOverlayable("bool/foo", overlayable_item)
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700499 .Build();
500
501 std::unique_ptr<ResourceTable> table_b =
502 test::ResourceTableBuilder()
503 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800504 .AddSimple("bool/foo")
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700505 .Build();
506
507 ResourceTable final_table;
508 TableMergerOptions options;
509 options.auto_add_overlay = true;
510 TableMerger merger(context_.get(), &final_table, options);
511 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
512 ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
513
514 const ResourceName name = test::ParseNameOrDie("com.app.a:bool/foo");
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800515 Maybe<ResourceTable::SearchResult> search_result = final_table.FindResource(name);
516 ASSERT_TRUE(search_result);
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800517 ASSERT_TRUE(search_result.value().entry->overlayable_item);
518 OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value();
519 EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("CustomizableResources"));
520 EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://customization"));
Winson62ac8b52019-12-04 08:36:48 -0800521 EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PRODUCT_PARTITION
522 | PolicyFlags::VENDOR_PARTITION));
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700523}
524
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800525TEST_F(TableMergerTest, SetOverlayableLater) {
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800526 auto overlayable = std::make_shared<Overlayable>("CustomizableResources",
527 "overlay://customization");
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700528 std::unique_ptr<ResourceTable> table_a =
529 test::ResourceTableBuilder()
530 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800531 .AddSimple("bool/foo")
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700532 .Build();
533
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800534 OverlayableItem overlayable_item(overlayable);
Winson62ac8b52019-12-04 08:36:48 -0800535 overlayable_item.policies |= PolicyFlags::PUBLIC;
536 overlayable_item.policies |= PolicyFlags::SYSTEM_PARTITION;
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700537 std::unique_ptr<ResourceTable> table_b =
538 test::ResourceTableBuilder()
539 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800540 .SetOverlayable("bool/foo", overlayable_item)
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800541 .Build();
542
543 ResourceTable final_table;
544 TableMergerOptions options;
545 options.auto_add_overlay = true;
546 TableMerger merger(context_.get(), &final_table, options);
547 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
548 ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
549
550 const ResourceName name = test::ParseNameOrDie("com.app.a:bool/foo");
551 Maybe<ResourceTable::SearchResult> search_result = final_table.FindResource(name);
552 ASSERT_TRUE(search_result);
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800553 ASSERT_TRUE(search_result.value().entry->overlayable_item);
554 OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value();
555 EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("CustomizableResources"));
556 EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://customization"));
Winson62ac8b52019-12-04 08:36:48 -0800557 EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::PUBLIC
558 | PolicyFlags::SYSTEM_PARTITION));
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800559}
560
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800561TEST_F(TableMergerTest, SameResourceDifferentNameFail) {
562 auto overlayable_first = std::make_shared<Overlayable>("CustomizableResources",
563 "overlay://customization");
564 OverlayableItem overlayable_item_first(overlayable_first);
Winson62ac8b52019-12-04 08:36:48 -0800565 overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800566 std::unique_ptr<ResourceTable> table_a =
567 test::ResourceTableBuilder()
568 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800569 .SetOverlayable("bool/foo", overlayable_item_first)
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800570 .Build();
571
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800572 auto overlayable_second = std::make_shared<Overlayable>("ThemeResources",
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700573 "overlay://customization");
574 OverlayableItem overlayable_item_second(overlayable_second);
Winson62ac8b52019-12-04 08:36:48 -0800575 overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700576 std::unique_ptr<ResourceTable> table_b =
577 test::ResourceTableBuilder()
578 .SetPackageId("com.app.a", 0x7f)
579 .SetOverlayable("bool/foo", overlayable_item_second)
580 .Build();
581
582 ResourceTable final_table;
583 TableMergerOptions options;
584 options.auto_add_overlay = true;
585 TableMerger merger(context_.get(), &final_table, options);
586 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
587 ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
588}
589
590TEST_F(TableMergerTest, SameResourceDifferentActorFail) {
591 auto overlayable_first = std::make_shared<Overlayable>("CustomizableResources",
592 "overlay://customization");
593 OverlayableItem overlayable_item_first(overlayable_first);
Winson62ac8b52019-12-04 08:36:48 -0800594 overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700595 std::unique_ptr<ResourceTable> table_a =
596 test::ResourceTableBuilder()
597 .SetPackageId("com.app.a", 0x7f)
598 .SetOverlayable("bool/foo", overlayable_item_first)
599 .Build();
600
601 auto overlayable_second = std::make_shared<Overlayable>("CustomizableResources",
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800602 "overlay://theme");
603 OverlayableItem overlayable_item_second(overlayable_second);
Winson62ac8b52019-12-04 08:36:48 -0800604 overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800605 std::unique_ptr<ResourceTable> table_b =
606 test::ResourceTableBuilder()
607 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800608 .SetOverlayable("bool/foo", overlayable_item_second)
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700609 .Build();
610
611 ResourceTable final_table;
612 TableMergerOptions options;
613 options.auto_add_overlay = true;
614 TableMerger merger(context_.get(), &final_table, options);
615 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
616 ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
617}
618
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700619TEST_F(TableMergerTest, SameResourceDifferentPoliciesFail) {
620 auto overlayable_first = std::make_shared<Overlayable>("CustomizableResources",
621 "overlay://customization");
622 OverlayableItem overlayable_item_first(overlayable_first);
Winson62ac8b52019-12-04 08:36:48 -0800623 overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700624 std::unique_ptr<ResourceTable> table_a =
625 test::ResourceTableBuilder()
626 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800627 .SetOverlayable("bool/foo", overlayable_item_first)
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700628 .Build();
629
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700630 auto overlayable_second = std::make_shared<Overlayable>("CustomizableResources",
631 "overlay://customization");
632 OverlayableItem overlayable_item_second(overlayable_second);
Winson62ac8b52019-12-04 08:36:48 -0800633 overlayable_item_second.policies |= PolicyFlags::SIGNATURE;
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700634 std::unique_ptr<ResourceTable> table_b =
635 test::ResourceTableBuilder()
636 .SetPackageId("com.app.a", 0x7f)
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800637 .SetOverlayable("bool/foo", overlayable_item_second)
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700638 .Build();
639
640 ResourceTable final_table;
641 TableMergerOptions options;
642 options.auto_add_overlay = true;
643 TableMerger merger(context_.get(), &final_table, options);
644 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
645 ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
646}
647
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700648TEST_F(TableMergerTest, SameResourceSameOverlayable) {
649 auto overlayable = std::make_shared<Overlayable>("CustomizableResources",
650 "overlay://customization");
651
652 OverlayableItem overlayable_item_first(overlayable);
Winson62ac8b52019-12-04 08:36:48 -0800653 overlayable_item_first.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700654 std::unique_ptr<ResourceTable> table_a =
655 test::ResourceTableBuilder()
656 .SetPackageId("com.app.a", 0x7f)
657 .SetOverlayable("bool/foo", overlayable_item_first)
658 .Build();
659
660 OverlayableItem overlayable_item_second(overlayable);
Winson62ac8b52019-12-04 08:36:48 -0800661 overlayable_item_second.policies |= PolicyFlags::PRODUCT_PARTITION;
Ryan Mitchellced9a5c2019-04-05 10:44:16 -0700662 std::unique_ptr<ResourceTable> table_b =
663 test::ResourceTableBuilder()
664 .SetPackageId("com.app.a", 0x7f)
665 .SetOverlayable("bool/foo", overlayable_item_second)
666 .Build();
667
668 ResourceTable final_table;
669 TableMergerOptions options;
670 options.auto_add_overlay = true;
671 TableMerger merger(context_.get(), &final_table, options);
672 ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
673 ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
674}
675
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700676} // namespace aapt