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 24 using ::testing::Eq; 25 using ::testing::IsNull; 26 using ::testing::Ne; 27 using ::testing::NotNull; 28 29 namespace aapt { 30 31 TEST(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 50 TEST(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 64 TEST(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 79 using SymbolTableTestFixture = CommandTestFixture; 80 TEST_F(SymbolTableTestFixture, FindByNameWhenSymbolIsMangledInResTable) { 81 using namespace android; 82 StdErrDiagnostics diag; 83 84 // Create a static library. 85 const std::string static_lib_compiled_files_dir = GetTestPath("static-lib-compiled"); 86 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), 87 R"(<?xml version="1.0" encoding="utf-8"?> 88 <resources> 89 <item type="id" name="foo"/> 90 </resources>)", 91 static_lib_compiled_files_dir, &diag)); 92 93 const std::string static_lib_apk = GetTestPath("static_lib.apk"); 94 std::vector<std::string> link_args = { 95 "--manifest", GetDefaultManifest("com.android.lib"), 96 "--min-sdk-version", "22", 97 "--static-lib", 98 "-o", static_lib_apk, 99 }; 100 ASSERT_TRUE(Link(link_args, static_lib_compiled_files_dir, &diag)); 101 102 // Merge the static library into the main application package. The static library resources will 103 // be mangled with the library package name. 104 const std::string app_compiled_files_dir = GetTestPath("app-compiled"); 105 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), 106 R"(<?xml version="1.0" encoding="utf-8"?> 107 <resources> 108 <item type="id" name="bar"/> 109 </resources>)", 110 app_compiled_files_dir, &diag)); 111 112 const std::string out_apk = GetTestPath("out.apk"); 113 link_args = { 114 "--manifest", GetDefaultManifest("com.android.app"), 115 "--min-sdk-version", "22", 116 "-o", out_apk, 117 static_lib_apk 118 }; 119 ASSERT_TRUE(Link(link_args, app_compiled_files_dir, &diag)); 120 121 // Construct the test AssetManager. 122 auto asset_manager_source = util::make_unique<AssetManagerSymbolSource>(); 123 asset_manager_source->AddAssetPath(out_apk); 124 125 NameMangler name_mangler(NameManglerPolicy{"com.android.app"}); 126 SymbolTable symbol_table(&name_mangler); 127 symbol_table.AppendSource(std::move(asset_manager_source)); 128 129 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.lib:id/foo")), NotNull()); 130 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.app:id/bar")), NotNull()); 131 132 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.app:id/foo")), IsNull()); 133 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.lib:id/bar")), IsNull()); 134 EXPECT_THAT(symbol_table.FindByName(test::ParseNameOrDie("com.android.other:id/foo")), IsNull()); 135 } 136 137 } // namespace aapt 138