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 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 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 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 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 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 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 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