1/* 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 17#include "process/SymbolTable.h" 18 19#include "SdkConstants.h" 20#include "format/binary/TableFlattener.h" 21#include "test/Test.h" 22#include "util/BigBuffer.h" 23 24using ::testing::Eq; 25using ::testing::IsNull; 26using ::testing::Ne; 27using ::testing::NotNull; 28 29namespace aapt { 30 31TEST(ResourceTableSymbolSourceTest, FindSymbols) { 32 std::unique_ptr<ResourceTable> table = 33 test::ResourceTableBuilder() 34 .AddSimple("android:id/foo", ResourceId(0x01020000)) 35 .AddSimple("android:id/bar") 36 .AddValue("android:attr/foo", ResourceId(0x01010000), 37 test::AttributeBuilder().Build()) 38 .Build(); 39 40 ResourceTableSymbolSource symbol_source(table.get()); 41 EXPECT_THAT(symbol_source.FindByName(test::ParseNameOrDie("android:id/foo")), NotNull()); 42 EXPECT_THAT(symbol_source.FindByName(test::ParseNameOrDie("android:id/bar")), NotNull()); 43 44 std::unique_ptr<SymbolTable::Symbol> s = 45 symbol_source.FindByName(test::ParseNameOrDie("android:attr/foo")); 46 ASSERT_THAT(s, NotNull()); 47 EXPECT_THAT(s->attribute, NotNull()); 48} 49 50TEST(ResourceTableSymbolSourceTest, FindPrivateAttrSymbol) { 51 std::unique_ptr<ResourceTable> table = 52 test::ResourceTableBuilder() 53 .AddValue("android:^attr-private/foo", ResourceId(0x01010000), 54 test::AttributeBuilder().Build()) 55 .Build(); 56 57 ResourceTableSymbolSource symbol_source(table.get()); 58 std::unique_ptr<SymbolTable::Symbol> s = 59 symbol_source.FindByName(test::ParseNameOrDie("android:attr/foo")); 60 ASSERT_THAT(s, NotNull()); 61 EXPECT_THAT(s->attribute, NotNull()); 62} 63 64TEST(SymbolTableTest, FindByName) { 65 std::unique_ptr<ResourceTable> table = 66 test::ResourceTableBuilder() 67 .AddSimple("com.android.app:id/foo") 68 .AddSimple("com.android.app:id/" + NameMangler::MangleEntry("com.android.lib", "foo")) 69 .Build(); 70 71 NameMangler mangler(NameManglerPolicy{"com.android.app", {"com.android.lib"}}); 72 SymbolTable symbol_table(&mangler); 73 symbol_table.AppendSource(util::make_unique<ResourceTableSymbolSource>(table.get())); 74 75 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("id/foo")), NotNull()); 76 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.lib:id/foo")), NotNull()); 77} 78 79TEST(SymbolTableTest, FindByNameWhenSymbolIsMangledInResTable) { 80 using namespace android; 81 82 std::unique_ptr<IAaptContext> context = 83 test::ContextBuilder() 84 .SetCompilationPackage("com.android.app") 85 .SetPackageId(0x7f) 86 .SetPackageType(PackageType::kApp) 87 .SetMinSdkVersion(SDK_LOLLIPOP_MR1) 88 .SetNameManglerPolicy(NameManglerPolicy{"com.android.app"}) 89 .Build(); 90 91 // Create a ResourceTable with a mangled resource, simulating a static library being merged into 92 // the main application package. 93 std::unique_ptr<ResourceTable> table = 94 test::ResourceTableBuilder() 95 .AddSimple("com.android.app:id/" + NameMangler::MangleEntry("com.android.lib", "foo"), 96 ResourceId(0x7f020000)) 97 .AddSimple("com.android.app:id/bar", ResourceId(0x7f020001)) 98 .Build(); 99 100 BigBuffer buffer(1024u); 101 TableFlattener flattener({}, &buffer); 102 ASSERT_TRUE(flattener.Consume(context.get(), table.get())); 103 104 std::unique_ptr<uint8_t[]> data = util::Copy(buffer); 105 106 // Construct the test AssetManager. 107 auto asset_manager_source = util::make_unique<AssetManagerSymbolSource>(); 108 ResTable& res_table = const_cast<ResTable&>( 109 asset_manager_source->GetAssetManager()->getResources(false /*required*/)); 110 ASSERT_THAT(res_table.add(data.get(), buffer.size()), Eq(NO_ERROR)); 111 112 SymbolTable symbol_table(context->GetNameMangler()); 113 symbol_table.AppendSource(std::move(asset_manager_source)); 114 115 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.lib:id/foo")), NotNull()); 116 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.app:id/bar")), NotNull()); 117 118 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.app:id/foo")), IsNull()); 119 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.lib:id/bar")), IsNull()); 120 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.other:id/foo")), IsNull()); 121} 122 123} // namespace aapt 124