1 /*
2 * Copyright (C) 2016 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 "format/proto/ProtoSerialize.h"
18
19 #include "ResourceUtils.h"
20 #include "format/proto/ProtoDeserialize.h"
21 #include "test/Test.h"
22
23 using ::android::ConfigDescription;
24 using ::android::StringPiece;
25 using ::testing::Eq;
26 using ::testing::IsEmpty;
27 using ::testing::NotNull;
28 using ::testing::SizeIs;
29 using ::testing::StrEq;
30
31 namespace aapt {
32
33 class MockFileCollection : public io::IFileCollection {
34 public:
35 MOCK_METHOD1(FindFile, io::IFile*(const StringPiece& path));
36 MOCK_METHOD0(Iterator, std::unique_ptr<io::IFileCollectionIterator>());
37 MOCK_METHOD0(GetDirSeparator, char());
38 };
39
TEST(ProtoSerializeTest,SerializeSinglePackage)40 TEST(ProtoSerializeTest, SerializeSinglePackage) {
41 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
42 std::unique_ptr<ResourceTable> table =
43 test::ResourceTableBuilder()
44 .SetPackageId("com.app.a", 0x7f)
45 .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000), "res/layout/main.xml")
46 .AddReference("com.app.a:layout/other", ResourceId(0x7f020001), "com.app.a:layout/main")
47 .AddString("com.app.a:string/text", {}, "hi")
48 .AddValue("com.app.a:id/foo", {}, util::make_unique<Id>())
49 .SetSymbolState("com.app.a:bool/foo", {}, Visibility::Level::kUndefined,
50 true /*allow_new*/)
51 .Build();
52
53 Visibility public_symbol;
54 public_symbol.level = Visibility::Level::kPublic;
55 ASSERT_TRUE(table->SetVisibilityWithId(test::ParseNameOrDie("com.app.a:layout/main"),
56 public_symbol, ResourceId(0x7f020000),
57 context->GetDiagnostics()));
58
59 Id* id = test::GetValue<Id>(table.get(), "com.app.a:id/foo");
60 ASSERT_THAT(id, NotNull());
61
62 // Make a plural.
63 std::unique_ptr<Plural> plural = util::make_unique<Plural>();
64 plural->values[Plural::One] = util::make_unique<String>(table->string_pool.MakeRef("one"));
65 ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.app.a:plurals/hey"), ConfigDescription{},
66 {}, std::move(plural), context->GetDiagnostics()));
67
68 // Make a styled string.
69 StyleString style_string;
70 style_string.str = "hello";
71 style_string.spans.push_back(Span{"b", 0u, 4u});
72 ASSERT_TRUE(
73 table->AddResource(test::ParseNameOrDie("com.app.a:string/styled"), ConfigDescription{}, {},
74 util::make_unique<StyledString>(table->string_pool.MakeRef(style_string)),
75 context->GetDiagnostics()));
76
77 // Make a resource with different products.
78 ASSERT_TRUE(table->AddResource(
79 test::ParseNameOrDie("com.app.a:integer/one"), test::ParseConfigOrDie("land"), {},
80 test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u), context->GetDiagnostics()));
81 ASSERT_TRUE(table->AddResource(
82 test::ParseNameOrDie("com.app.a:integer/one"), test::ParseConfigOrDie("land"), "tablet",
83 test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 321u), context->GetDiagnostics()));
84
85 // Make a reference with both resource name and resource ID.
86 // The reference should point to a resource outside of this table to test that both name and id
87 // get serialized.
88 Reference expected_ref;
89 expected_ref.name = test::ParseNameOrDie("android:layout/main");
90 expected_ref.id = ResourceId(0x01020000);
91 ASSERT_TRUE(table->AddResource(
92 test::ParseNameOrDie("com.app.a:layout/abc"), ConfigDescription::DefaultConfig(), {},
93 util::make_unique<Reference>(expected_ref), context->GetDiagnostics()));
94
95 // Make an overlayable resource.
96 OverlayableItem overlayable_item(std::make_shared<Overlayable>(
97 "OverlayableName", "overlay://theme", Source("res/values/overlayable.xml", 40)));
98 overlayable_item.source = Source("res/values/overlayable.xml", 42);
99 ASSERT_TRUE(table->SetOverlayable(test::ParseNameOrDie("com.app.a:integer/overlayable"),
100 overlayable_item, test::GetDiagnostics()));
101
102 pb::ResourceTable pb_table;
103 SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
104
105 test::TestFile file_a("res/layout/main.xml");
106 MockFileCollection files;
107 EXPECT_CALL(files, FindFile(Eq("res/layout/main.xml")))
108 .WillRepeatedly(::testing::Return(&file_a));
109
110 ResourceTable new_table;
111 std::string error;
112 ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error)) << error;
113 EXPECT_THAT(error, IsEmpty());
114
115 Id* new_id = test::GetValue<Id>(&new_table, "com.app.a:id/foo");
116 ASSERT_THAT(new_id, NotNull());
117 EXPECT_THAT(new_id->IsWeak(), Eq(id->IsWeak()));
118
119 Maybe<ResourceTable::SearchResult> result =
120 new_table.FindResource(test::ParseNameOrDie("com.app.a:layout/main"));
121 ASSERT_TRUE(result);
122
123 EXPECT_THAT(result.value().type->visibility_level, Eq(Visibility::Level::kPublic));
124 EXPECT_THAT(result.value().entry->visibility.level, Eq(Visibility::Level::kPublic));
125
126 result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/foo"));
127 ASSERT_TRUE(result);
128 EXPECT_THAT(result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
129 EXPECT_TRUE(result.value().entry->allow_new);
130
131 // Find the product-dependent values
132 BinaryPrimitive* prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
133 &new_table, "com.app.a:integer/one", test::ParseConfigOrDie("land"), "");
134 ASSERT_THAT(prim, NotNull());
135 EXPECT_THAT(prim->value.data, Eq(123u));
136
137 prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
138 &new_table, "com.app.a:integer/one", test::ParseConfigOrDie("land"), "tablet");
139 ASSERT_THAT(prim, NotNull());
140 EXPECT_THAT(prim->value.data, Eq(321u));
141
142 Reference* actual_ref = test::GetValue<Reference>(&new_table, "com.app.a:layout/abc");
143 ASSERT_THAT(actual_ref, NotNull());
144 ASSERT_TRUE(actual_ref->name);
145 ASSERT_TRUE(actual_ref->id);
146 EXPECT_THAT(*actual_ref, Eq(expected_ref));
147
148 FileReference* actual_file_ref =
149 test::GetValue<FileReference>(&new_table, "com.app.a:layout/main");
150 ASSERT_THAT(actual_file_ref, NotNull());
151 EXPECT_THAT(actual_file_ref->file, Eq(&file_a));
152
153 StyledString* actual_styled_str =
154 test::GetValue<StyledString>(&new_table, "com.app.a:string/styled");
155 ASSERT_THAT(actual_styled_str, NotNull());
156 EXPECT_THAT(actual_styled_str->value->value, Eq("hello"));
157 ASSERT_THAT(actual_styled_str->value->spans, SizeIs(1u));
158 EXPECT_THAT(*actual_styled_str->value->spans[0].name, Eq("b"));
159 EXPECT_THAT(actual_styled_str->value->spans[0].first_char, Eq(0u));
160 EXPECT_THAT(actual_styled_str->value->spans[0].last_char, Eq(4u));
161
162 Maybe<ResourceTable::SearchResult> search_result =
163 new_table.FindResource(test::ParseNameOrDie("com.app.a:integer/overlayable"));
164 ASSERT_TRUE(search_result);
165 ASSERT_THAT(search_result.value().entry, NotNull());
166 ASSERT_TRUE(search_result.value().entry->overlayable_item);
167 OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value();
168 EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("OverlayableName"));
169 EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme"));
170 EXPECT_THAT(result_overlayable_item.overlayable->source.path, Eq("res/values/overlayable.xml"));
171 EXPECT_THAT(result_overlayable_item.overlayable->source.line, Eq(40));
172 EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone));
173 EXPECT_THAT(result_overlayable_item.source.path, Eq("res/values/overlayable.xml"));
174 EXPECT_THAT(result_overlayable_item.source.line, Eq(42));
175 }
176
TEST(ProtoSerializeTest,SerializeAndDeserializeXml)177 TEST(ProtoSerializeTest, SerializeAndDeserializeXml) {
178 xml::Element element;
179 element.line_number = 22;
180 element.column_number = 23;
181 element.name = "element";
182 element.namespace_uri = "uri://";
183
184 xml::NamespaceDecl decl;
185 decl.prefix = "android";
186 decl.uri = xml::kSchemaAndroid;
187 decl.line_number = 21;
188 decl.column_number = 24;
189
190 element.namespace_decls.push_back(decl);
191
192 xml::Attribute attr;
193 attr.name = "name";
194 attr.namespace_uri = xml::kSchemaAndroid;
195 attr.value = "23dp";
196 attr.compiled_attribute = xml::AaptAttribute(Attribute{}, ResourceId(0x01010000));
197 attr.compiled_value =
198 ResourceUtils::TryParseItemForAttribute(attr.value, android::ResTable_map::TYPE_DIMENSION);
199 attr.compiled_value->SetSource(Source().WithLine(25));
200 element.attributes.push_back(std::move(attr));
201
202 std::unique_ptr<xml::Text> text = util::make_unique<xml::Text>();
203 text->line_number = 25;
204 text->column_number = 3;
205 text->text = "hey there";
206 element.AppendChild(std::move(text));
207
208 std::unique_ptr<xml::Element> child = util::make_unique<xml::Element>();
209 child->name = "child";
210
211 text = util::make_unique<xml::Text>();
212 text->text = "woah there";
213 child->AppendChild(std::move(text));
214
215 element.AppendChild(std::move(child));
216
217 pb::XmlNode pb_xml;
218 SerializeXmlToPb(element, &pb_xml);
219
220 StringPool pool;
221 xml::Element actual_el;
222 std::string error;
223 ASSERT_TRUE(DeserializeXmlFromPb(pb_xml, &actual_el, &pool, &error));
224 ASSERT_THAT(error, IsEmpty());
225
226 EXPECT_THAT(actual_el.name, StrEq("element"));
227 EXPECT_THAT(actual_el.namespace_uri, StrEq("uri://"));
228 EXPECT_THAT(actual_el.line_number, Eq(22u));
229 EXPECT_THAT(actual_el.column_number, Eq(23u));
230
231 ASSERT_THAT(actual_el.namespace_decls, SizeIs(1u));
232 const xml::NamespaceDecl& actual_decl = actual_el.namespace_decls[0];
233 EXPECT_THAT(actual_decl.prefix, StrEq("android"));
234 EXPECT_THAT(actual_decl.uri, StrEq(xml::kSchemaAndroid));
235 EXPECT_THAT(actual_decl.line_number, Eq(21u));
236 EXPECT_THAT(actual_decl.column_number, Eq(24u));
237
238 ASSERT_THAT(actual_el.attributes, SizeIs(1u));
239 const xml::Attribute& actual_attr = actual_el.attributes[0];
240 EXPECT_THAT(actual_attr.name, StrEq("name"));
241 EXPECT_THAT(actual_attr.namespace_uri, StrEq(xml::kSchemaAndroid));
242 EXPECT_THAT(actual_attr.value, StrEq("23dp"));
243
244 ASSERT_THAT(actual_attr.compiled_value, NotNull());
245 const BinaryPrimitive* prim = ValueCast<BinaryPrimitive>(actual_attr.compiled_value.get());
246 ASSERT_THAT(prim, NotNull());
247 EXPECT_THAT(prim->value.dataType, Eq(android::Res_value::TYPE_DIMENSION));
248
249 ASSERT_TRUE(actual_attr.compiled_attribute);
250 ASSERT_TRUE(actual_attr.compiled_attribute.value().id);
251
252 ASSERT_THAT(actual_el.children, SizeIs(2u));
253 const xml::Text* child_text = xml::NodeCast<xml::Text>(actual_el.children[0].get());
254 ASSERT_THAT(child_text, NotNull());
255 const xml::Element* child_el = xml::NodeCast<xml::Element>(actual_el.children[1].get());
256 ASSERT_THAT(child_el, NotNull());
257
258 EXPECT_THAT(child_text->line_number, Eq(25u));
259 EXPECT_THAT(child_text->column_number, Eq(3u));
260 EXPECT_THAT(child_text->text, StrEq("hey there"));
261
262 EXPECT_THAT(child_el->name, StrEq("child"));
263 ASSERT_THAT(child_el->children, SizeIs(1u));
264
265 child_text = xml::NodeCast<xml::Text>(child_el->children[0].get());
266 ASSERT_THAT(child_text, NotNull());
267 EXPECT_THAT(child_text->text, StrEq("woah there"));
268 }
269
TEST(ProtoSerializeTest,SerializeAndDeserializeXmlTrimEmptyWhitepsace)270 TEST(ProtoSerializeTest, SerializeAndDeserializeXmlTrimEmptyWhitepsace) {
271 xml::Element element;
272 element.line_number = 22;
273 element.column_number = 23;
274 element.name = "element";
275
276 std::unique_ptr<xml::Text> trim_text = util::make_unique<xml::Text>();
277 trim_text->line_number = 25;
278 trim_text->column_number = 3;
279 trim_text->text = " \n ";
280 element.AppendChild(std::move(trim_text));
281
282 std::unique_ptr<xml::Text> keep_text = util::make_unique<xml::Text>();
283 keep_text->line_number = 26;
284 keep_text->column_number = 3;
285 keep_text->text = " hello ";
286 element.AppendChild(std::move(keep_text));
287
288 pb::XmlNode pb_xml;
289 SerializeXmlOptions options;
290 options.remove_empty_text_nodes = true;
291 SerializeXmlToPb(element, &pb_xml, options);
292
293 StringPool pool;
294 xml::Element actual_el;
295 std::string error;
296 ASSERT_TRUE(DeserializeXmlFromPb(pb_xml, &actual_el, &pool, &error));
297 ASSERT_THAT(error, IsEmpty());
298
299 // Only the child that does not consist of only whitespace should remain
300 ASSERT_THAT(actual_el.children, SizeIs(1u));
301 const xml::Text* child_text_keep = xml::NodeCast<xml::Text>(actual_el.children[0].get());
302 ASSERT_THAT(child_text_keep, NotNull());
303 EXPECT_THAT(child_text_keep->text, StrEq( " hello "));
304 }
305
TEST(ProtoSerializeTest,SerializeAndDeserializePrimitives)306 TEST(ProtoSerializeTest, SerializeAndDeserializePrimitives) {
307 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
308 std::unique_ptr<ResourceTable> table =
309 test::ResourceTableBuilder()
310 .AddValue("android:bool/boolean_true",
311 test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, true))
312 .AddValue("android:bool/boolean_false",
313 test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, false))
314 .AddValue("android:color/color_rgb8", ResourceUtils::TryParseColor("#AABBCC"))
315 .AddValue("android:color/color_argb8", ResourceUtils::TryParseColor("#11223344"))
316 .AddValue("android:color/color_rgb4", ResourceUtils::TryParseColor("#DEF"))
317 .AddValue("android:color/color_argb4", ResourceUtils::TryParseColor("#5678"))
318 .AddValue("android:integer/integer_444", ResourceUtils::TryParseInt("444"))
319 .AddValue("android:integer/integer_neg_333", ResourceUtils::TryParseInt("-333"))
320 .AddValue("android:integer/hex_int_abcd", ResourceUtils::TryParseInt("0xABCD"))
321 .AddValue("android:dimen/dimen_1.39mm", ResourceUtils::TryParseFloat("1.39mm"))
322 .AddValue("android:fraction/fraction_27", ResourceUtils::TryParseFloat("27%"))
323 .AddValue("android:dimen/neg_2.3in", ResourceUtils::TryParseFloat("-2.3in"))
324 .AddValue("android:integer/null", ResourceUtils::MakeEmpty())
325 .Build();
326
327 pb::ResourceTable pb_table;
328 SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
329
330 test::TestFile file_a("res/layout/main.xml");
331 MockFileCollection files;
332 EXPECT_CALL(files, FindFile(Eq("res/layout/main.xml")))
333 .WillRepeatedly(::testing::Return(&file_a));
334
335 ResourceTable new_table;
336 std::string error;
337 ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error));
338 EXPECT_THAT(error, IsEmpty());
339
340 BinaryPrimitive* bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(
341 &new_table, "android:bool/boolean_true", ConfigDescription::DefaultConfig(), "");
342 ASSERT_THAT(bp, NotNull());
343 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_BOOLEAN));
344 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseBool("true")->value.data));
345
346 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:bool/boolean_false",
347 ConfigDescription::DefaultConfig(), "");
348 ASSERT_THAT(bp, NotNull());
349 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_BOOLEAN));
350 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseBool("false")->value.data));
351
352 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_rgb8",
353 ConfigDescription::DefaultConfig(), "");
354 ASSERT_THAT(bp, NotNull());
355 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_RGB8));
356 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#AABBCC")->value.data));
357
358 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_argb8",
359 ConfigDescription::DefaultConfig(), "");
360 ASSERT_THAT(bp, NotNull());
361 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_ARGB8));
362 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#11223344")->value.data));
363
364 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_rgb4",
365 ConfigDescription::DefaultConfig(), "");
366 ASSERT_THAT(bp, NotNull());
367 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_RGB4));
368 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#DEF")->value.data));
369
370 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_argb4",
371 ConfigDescription::DefaultConfig(), "");
372 ASSERT_THAT(bp, NotNull());
373 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_ARGB4));
374 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#5678")->value.data));
375
376 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:integer/integer_444",
377 ConfigDescription::DefaultConfig(), "");
378 ASSERT_THAT(bp, NotNull());
379 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
380 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("444")->value.data));
381
382 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(
383 &new_table, "android:integer/integer_neg_333", ConfigDescription::DefaultConfig(), "");
384 ASSERT_THAT(bp, NotNull());
385 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
386 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("-333")->value.data));
387
388 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(
389 &new_table, "android:integer/hex_int_abcd", ConfigDescription::DefaultConfig(), "");
390 ASSERT_THAT(bp, NotNull());
391 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_HEX));
392 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("0xABCD")->value.data));
393
394 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:dimen/dimen_1.39mm",
395 ConfigDescription::DefaultConfig(), "");
396 ASSERT_THAT(bp, NotNull());
397 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_DIMENSION));
398 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("1.39mm")->value.data));
399
400 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(
401 &new_table, "android:fraction/fraction_27", ConfigDescription::DefaultConfig(), "");
402 ASSERT_THAT(bp, NotNull());
403 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_FRACTION));
404 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("27%")->value.data));
405
406 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:dimen/neg_2.3in",
407 ConfigDescription::DefaultConfig(), "");
408 ASSERT_THAT(bp, NotNull());
409 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_DIMENSION));
410 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("-2.3in")->value.data));
411
412 bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:integer/null",
413 ConfigDescription::DefaultConfig(), "");
414 ASSERT_THAT(bp, NotNull());
415 EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_NULL));
416 EXPECT_THAT(bp->value.data, Eq(ResourceUtils::MakeEmpty()->value.data));
417 }
418
ExpectConfigSerializes(const StringPiece & config_str)419 static void ExpectConfigSerializes(const StringPiece& config_str) {
420 const ConfigDescription expected_config = test::ParseConfigOrDie(config_str);
421 pb::Configuration pb_config;
422 SerializeConfig(expected_config, &pb_config);
423
424 ConfigDescription actual_config;
425 std::string error;
426 ASSERT_TRUE(DeserializeConfigFromPb(pb_config, &actual_config, &error));
427 ASSERT_THAT(error, IsEmpty());
428 EXPECT_EQ(expected_config, actual_config);
429 }
430
TEST(ProtoSerializeTest,SerializeDeserializeConfiguration)431 TEST(ProtoSerializeTest, SerializeDeserializeConfiguration) {
432 ExpectConfigSerializes("");
433
434 ExpectConfigSerializes("mcc123");
435
436 ExpectConfigSerializes("mnc123");
437
438 ExpectConfigSerializes("en");
439 ExpectConfigSerializes("en-rGB");
440 ExpectConfigSerializes("b+en+GB");
441
442 ExpectConfigSerializes("ldltr");
443 ExpectConfigSerializes("ldrtl");
444
445 ExpectConfigSerializes("sw3600dp");
446
447 ExpectConfigSerializes("w300dp");
448
449 ExpectConfigSerializes("h400dp");
450
451 ExpectConfigSerializes("small");
452 ExpectConfigSerializes("normal");
453 ExpectConfigSerializes("large");
454 ExpectConfigSerializes("xlarge");
455
456 ExpectConfigSerializes("long");
457 ExpectConfigSerializes("notlong");
458
459 ExpectConfigSerializes("round");
460 ExpectConfigSerializes("notround");
461
462 ExpectConfigSerializes("widecg");
463 ExpectConfigSerializes("nowidecg");
464
465 ExpectConfigSerializes("highdr");
466 ExpectConfigSerializes("lowdr");
467
468 ExpectConfigSerializes("port");
469 ExpectConfigSerializes("land");
470 ExpectConfigSerializes("square");
471
472 ExpectConfigSerializes("desk");
473 ExpectConfigSerializes("car");
474 ExpectConfigSerializes("television");
475 ExpectConfigSerializes("appliance");
476 ExpectConfigSerializes("watch");
477 ExpectConfigSerializes("vrheadset");
478
479 ExpectConfigSerializes("night");
480 ExpectConfigSerializes("notnight");
481
482 ExpectConfigSerializes("300dpi");
483 ExpectConfigSerializes("hdpi");
484
485 ExpectConfigSerializes("notouch");
486 ExpectConfigSerializes("stylus");
487 ExpectConfigSerializes("finger");
488
489 ExpectConfigSerializes("keysexposed");
490 ExpectConfigSerializes("keyshidden");
491 ExpectConfigSerializes("keyssoft");
492
493 ExpectConfigSerializes("nokeys");
494 ExpectConfigSerializes("qwerty");
495 ExpectConfigSerializes("12key");
496
497 ExpectConfigSerializes("navhidden");
498 ExpectConfigSerializes("navexposed");
499
500 ExpectConfigSerializes("nonav");
501 ExpectConfigSerializes("dpad");
502 ExpectConfigSerializes("trackball");
503 ExpectConfigSerializes("wheel");
504
505 ExpectConfigSerializes("300x200");
506
507 ExpectConfigSerializes("v8");
508
509 ExpectConfigSerializes(
510 "mcc123-mnc456-b+en+GB-ldltr-sw300dp-w300dp-h400dp-large-long-round-widecg-highdr-land-car-"
511 "night-xhdpi-stylus-keysexposed-qwerty-navhidden-dpad-300x200-v23");
512 }
513
TEST(ProtoSerializeTest,SerializeAndDeserializeOverlayable)514 TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) {
515 OverlayableItem overlayable_item_foo(std::make_shared<Overlayable>(
516 "CustomizableResources", "overlay://customization"));
517 overlayable_item_foo.policies |= OverlayableItem::Policy::kSystem;
518 overlayable_item_foo.policies |= OverlayableItem::Policy::kProduct;
519
520 OverlayableItem overlayable_item_bar(std::make_shared<Overlayable>(
521 "TaskBar", "overlay://theme"));
522 overlayable_item_bar.policies |= OverlayableItem::Policy::kPublic;
523 overlayable_item_bar.policies |= OverlayableItem::Policy::kVendor;
524
525 OverlayableItem overlayable_item_baz(std::make_shared<Overlayable>(
526 "FontPack", "overlay://theme"));
527 overlayable_item_baz.policies |= OverlayableItem::Policy::kPublic;
528
529 OverlayableItem overlayable_item_boz(std::make_shared<Overlayable>(
530 "IconPack", "overlay://theme"));
531 overlayable_item_boz.policies |= OverlayableItem::Policy::kSignature;
532 overlayable_item_boz.policies |= OverlayableItem::Policy::kOdm;
533 overlayable_item_boz.policies |= OverlayableItem::Policy::kOem;
534
535 OverlayableItem overlayable_item_biz(std::make_shared<Overlayable>(
536 "Other", "overlay://customization"));
537 overlayable_item_biz.comment ="comment";
538
539 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
540 std::unique_ptr<ResourceTable> table =
541 test::ResourceTableBuilder()
542 .SetOverlayable("com.app.a:bool/foo", overlayable_item_foo)
543 .SetOverlayable("com.app.a:bool/bar", overlayable_item_bar)
544 .SetOverlayable("com.app.a:bool/baz", overlayable_item_baz)
545 .SetOverlayable("com.app.a:bool/boz", overlayable_item_boz)
546 .SetOverlayable("com.app.a:bool/biz", overlayable_item_biz)
547 .AddValue("com.app.a:bool/fiz", ResourceUtils::TryParseBool("true"))
548 .Build();
549
550 pb::ResourceTable pb_table;
551 SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
552
553 MockFileCollection files;
554 ResourceTable new_table;
555 std::string error;
556 ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error));
557 EXPECT_THAT(error, IsEmpty());
558
559 Maybe<ResourceTable::SearchResult> search_result =
560 new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/foo"));
561 ASSERT_TRUE(search_result);
562 ASSERT_TRUE(search_result.value().entry->overlayable_item);
563 OverlayableItem& overlayable_item = search_result.value().entry->overlayable_item.value();
564 EXPECT_THAT(overlayable_item.overlayable->name, Eq("CustomizableResources"));
565 EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://customization"));
566 EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kSystem
567 | OverlayableItem::Policy::kProduct));
568
569 search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/bar"));
570 ASSERT_TRUE(search_result);
571 ASSERT_TRUE(search_result.value().entry->overlayable_item);
572 overlayable_item = search_result.value().entry->overlayable_item.value();
573 EXPECT_THAT(overlayable_item.overlayable->name, Eq("TaskBar"));
574 EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme"));
575 EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic
576 | OverlayableItem::Policy::kVendor));
577
578 search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/baz"));
579 ASSERT_TRUE(search_result);
580 ASSERT_TRUE(search_result.value().entry->overlayable_item);
581 overlayable_item = search_result.value().entry->overlayable_item.value();
582 EXPECT_THAT(overlayable_item.overlayable->name, Eq("FontPack"));
583 EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme"));
584 EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic));
585
586 search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/boz"));
587 ASSERT_TRUE(search_result);
588 ASSERT_TRUE(search_result.value().entry->overlayable_item);
589 overlayable_item = search_result.value().entry->overlayable_item.value();
590 EXPECT_THAT(overlayable_item.overlayable->name, Eq("IconPack"));
591 EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme"));
592 EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature
593 | OverlayableItem::Policy::kOdm
594 | OverlayableItem::Policy::kOem));
595
596 search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/biz"));
597 ASSERT_TRUE(search_result);
598 ASSERT_TRUE(search_result.value().entry->overlayable_item);
599 overlayable_item = search_result.value().entry->overlayable_item.value();
600 EXPECT_THAT(overlayable_item.overlayable->name, Eq("Other"));
601 EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kNone));
602 EXPECT_THAT(overlayable_item.comment, Eq("comment"));
603
604 search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/fiz"));
605 ASSERT_TRUE(search_result);
606 ASSERT_FALSE(search_result.value().entry->overlayable_item);
607 }
608
609 } // namespace aapt
610