• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "link/ReferenceLinker.h"
18 
19 #include "test/Test.h"
20 
21 using android::ResTable_map;
22 using ::testing::NotNull;
23 
24 namespace aapt {
25 
TEST(ReferenceLinkerTest,LinkSimpleReferences)26 TEST(ReferenceLinkerTest, LinkSimpleReferences) {
27   std::unique_ptr<ResourceTable> table =
28       test::ResourceTableBuilder()
29           .SetPackageId("com.app.test", 0x7f)
30           .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
31                         "com.app.test:string/bar")
32 
33           // Test use of local reference (w/o package name).
34           .AddReference("com.app.test:string/bar", ResourceId(0x7f020001),
35                         "string/baz")
36 
37           .AddReference("com.app.test:string/baz", ResourceId(0x7f020002),
38                         "android:string/ok")
39           .Build();
40 
41   std::unique_ptr<IAaptContext> context =
42       test::ContextBuilder()
43           .SetCompilationPackage("com.app.test")
44           .SetPackageId(0x7f)
45           .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
46           .AddSymbolSource(
47               util::make_unique<ResourceTableSymbolSource>(table.get()))
48           .AddSymbolSource(
49               test::StaticSymbolSourceBuilder()
50                   .AddPublicSymbol("android:string/ok", ResourceId(0x01040034))
51                   .Build())
52           .Build();
53 
54   ReferenceLinker linker;
55   ASSERT_TRUE(linker.Consume(context.get(), table.get()));
56 
57   Reference* ref = test::GetValue<Reference>(table.get(), "com.app.test:string/foo");
58   ASSERT_THAT(ref, NotNull());
59   ASSERT_TRUE(ref->id);
60   EXPECT_EQ(ResourceId(0x7f020001), ref->id.value());
61 
62   ref = test::GetValue<Reference>(table.get(), "com.app.test:string/bar");
63   ASSERT_THAT(ref, NotNull());
64   ASSERT_TRUE(ref->id);
65   EXPECT_EQ(ResourceId(0x7f020002), ref->id.value());
66 
67   ref = test::GetValue<Reference>(table.get(), "com.app.test:string/baz");
68   ASSERT_THAT(ref, NotNull());
69   ASSERT_TRUE(ref->id);
70   EXPECT_EQ(ResourceId(0x01040034), ref->id.value());
71 }
72 
TEST(ReferenceLinkerTest,LinkStyleAttributes)73 TEST(ReferenceLinkerTest, LinkStyleAttributes) {
74   std::unique_ptr<ResourceTable> table =
75       test::ResourceTableBuilder()
76           .SetPackageId("com.app.test", 0x7f)
77           .AddValue("com.app.test:style/Theme",
78                     test::StyleBuilder()
79                         .SetParent("android:style/Theme.Material")
80                         .AddItem("android:attr/foo",
81                                  ResourceUtils::TryParseColor("#ff00ff"))
82                         .AddItem("android:attr/bar", {} /* placeholder */)
83                         .Build())
84           .Build();
85 
86   {
87     // We need to fill in the value for the attribute android:attr/bar after we
88     // build the table, because we need access to the string pool.
89     Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme");
90     ASSERT_THAT(style, NotNull());
91     style->entries.back().value =
92         util::make_unique<RawString>(table->string_pool.MakeRef("one|two"));
93   }
94 
95   std::unique_ptr<IAaptContext> context =
96       test::ContextBuilder()
97           .SetCompilationPackage("com.app.test")
98           .SetPackageId(0x7f)
99           .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
100           .AddSymbolSource(
101               test::StaticSymbolSourceBuilder()
102                   .AddPublicSymbol("android:style/Theme.Material",
103                                    ResourceId(0x01060000))
104                   .AddPublicSymbol("android:attr/foo", ResourceId(0x01010001),
105                                    test::AttributeBuilder()
106                                        .SetTypeMask(ResTable_map::TYPE_COLOR)
107                                        .Build())
108                   .AddPublicSymbol("android:attr/bar", ResourceId(0x01010002),
109                                    test::AttributeBuilder()
110                                        .SetTypeMask(ResTable_map::TYPE_FLAGS)
111                                        .AddItem("one", 0x01)
112                                        .AddItem("two", 0x02)
113                                        .Build())
114                   .Build())
115           .Build();
116 
117   ReferenceLinker linker;
118   ASSERT_TRUE(linker.Consume(context.get(), table.get()));
119 
120   Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme");
121   ASSERT_THAT(style, NotNull());
122   ASSERT_TRUE(style->parent);
123   ASSERT_TRUE(style->parent.value().id);
124   EXPECT_EQ(ResourceId(0x01060000), style->parent.value().id.value());
125 
126   ASSERT_EQ(2u, style->entries.size());
127 
128   ASSERT_TRUE(style->entries[0].key.id);
129   EXPECT_EQ(ResourceId(0x01010001), style->entries[0].key.id.value());
130   ASSERT_THAT(ValueCast<BinaryPrimitive>(style->entries[0].value.get()), NotNull());
131 
132   ASSERT_TRUE(style->entries[1].key.id);
133   EXPECT_EQ(ResourceId(0x01010002), style->entries[1].key.id.value());
134   ASSERT_THAT(ValueCast<BinaryPrimitive>(style->entries[1].value.get()), NotNull());
135 }
136 
TEST(ReferenceLinkerTest,LinkMangledReferencesAndAttributes)137 TEST(ReferenceLinkerTest, LinkMangledReferencesAndAttributes) {
138   std::unique_ptr<IAaptContext> context =
139       test::ContextBuilder()
140           .SetCompilationPackage("com.app.test")
141           .SetPackageId(0x7f)
142           .SetNameManglerPolicy(
143               NameManglerPolicy{"com.app.test", {"com.android.support"}})
144           .AddSymbolSource(
145               test::StaticSymbolSourceBuilder()
146                   .AddPublicSymbol("com.app.test:attr/com.android.support$foo",
147                                    ResourceId(0x7f010000),
148                                    test::AttributeBuilder()
149                                        .SetTypeMask(ResTable_map::TYPE_COLOR)
150                                        .Build())
151                   .Build())
152           .Build();
153 
154   std::unique_ptr<ResourceTable> table =
155       test::ResourceTableBuilder()
156           .SetPackageId("com.app.test", 0x7f)
157           .AddValue("com.app.test:style/Theme", ResourceId(0x7f020000),
158                     test::StyleBuilder()
159                         .AddItem("com.android.support:attr/foo",
160                                  ResourceUtils::TryParseColor("#ff0000"))
161                         .Build())
162           .Build();
163 
164   ReferenceLinker linker;
165   ASSERT_TRUE(linker.Consume(context.get(), table.get()));
166 
167   Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme");
168   ASSERT_THAT(style, NotNull());
169   ASSERT_EQ(1u, style->entries.size());
170   ASSERT_TRUE(style->entries.front().key.id);
171   EXPECT_EQ(ResourceId(0x7f010000), style->entries.front().key.id.value());
172 }
173 
TEST(ReferenceLinkerTest,FailToLinkPrivateSymbols)174 TEST(ReferenceLinkerTest, FailToLinkPrivateSymbols) {
175   std::unique_ptr<ResourceTable> table =
176       test::ResourceTableBuilder()
177           .SetPackageId("com.app.test", 0x7f)
178           .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
179                         "android:string/hidden")
180           .Build();
181 
182   std::unique_ptr<IAaptContext> context =
183       test::ContextBuilder()
184           .SetCompilationPackage("com.app.test")
185           .SetPackageId(0x7f)
186           .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
187           .AddSymbolSource(
188               util::make_unique<ResourceTableSymbolSource>(table.get()))
189           .AddSymbolSource(
190               test::StaticSymbolSourceBuilder()
191                   .AddSymbol("android:string/hidden", ResourceId(0x01040034))
192                   .Build())
193           .Build();
194 
195   ReferenceLinker linker;
196   ASSERT_FALSE(linker.Consume(context.get(), table.get()));
197 }
198 
TEST(ReferenceLinkerTest,FailToLinkPrivateMangledSymbols)199 TEST(ReferenceLinkerTest, FailToLinkPrivateMangledSymbols) {
200   std::unique_ptr<ResourceTable> table =
201       test::ResourceTableBuilder()
202           .SetPackageId("com.app.test", 0x7f)
203           .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
204                         "com.app.lib:string/hidden")
205           .Build();
206 
207   std::unique_ptr<IAaptContext> context =
208       test::ContextBuilder()
209           .SetCompilationPackage("com.app.test")
210           .SetPackageId(0x7f)
211           .SetNameManglerPolicy(
212               NameManglerPolicy{"com.app.test", {"com.app.lib"}})
213           .AddSymbolSource(
214               util::make_unique<ResourceTableSymbolSource>(table.get()))
215           .AddSymbolSource(
216               test::StaticSymbolSourceBuilder()
217                   .AddSymbol("com.app.test:string/com.app.lib$hidden",
218                              ResourceId(0x7f040034))
219                   .Build())
220 
221           .Build();
222 
223   ReferenceLinker linker;
224   ASSERT_FALSE(linker.Consume(context.get(), table.get()));
225 }
226 
TEST(ReferenceLinkerTest,FailToLinkPrivateStyleAttributes)227 TEST(ReferenceLinkerTest, FailToLinkPrivateStyleAttributes) {
228   std::unique_ptr<ResourceTable> table =
229       test::ResourceTableBuilder()
230           .SetPackageId("com.app.test", 0x7f)
231           .AddValue("com.app.test:style/Theme",
232                     test::StyleBuilder()
233                         .AddItem("android:attr/hidden",
234                                  ResourceUtils::TryParseColor("#ff00ff"))
235                         .Build())
236           .Build();
237 
238   std::unique_ptr<IAaptContext> context =
239       test::ContextBuilder()
240           .SetCompilationPackage("com.app.test")
241           .SetPackageId(0x7f)
242           .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
243           .AddSymbolSource(
244               util::make_unique<ResourceTableSymbolSource>(table.get()))
245           .AddSymbolSource(
246               test::StaticSymbolSourceBuilder()
247                   .AddSymbol("android:attr/hidden", ResourceId(0x01010001),
248                              test::AttributeBuilder()
249                                  .SetTypeMask(android::ResTable_map::TYPE_COLOR)
250                                  .Build())
251                   .Build())
252           .Build();
253 
254   ReferenceLinker linker;
255   ASSERT_FALSE(linker.Consume(context.get(), table.get()));
256 }
257 
TEST(ReferenceLinkerTest,AppsWithSamePackageButDifferentIdAreVisibleNonPublic)258 TEST(ReferenceLinkerTest, AppsWithSamePackageButDifferentIdAreVisibleNonPublic) {
259   NameMangler mangler(NameManglerPolicy{"com.app.test"});
260   SymbolTable table(&mangler);
261   table.AppendSource(test::StaticSymbolSourceBuilder()
262                          .AddSymbol("com.app.test:string/foo", ResourceId(0x7f010000))
263                          .Build());
264 
265   std::string error;
266   const CallSite call_site{ResourceNameRef("com.app.test", ResourceType::kString, "foo")};
267   const SymbolTable::Symbol* symbol = ReferenceLinker::ResolveSymbolCheckVisibility(
268       *test::BuildReference("com.app.test:string/foo"), call_site, &table, &error);
269   ASSERT_THAT(symbol, NotNull());
270   EXPECT_TRUE(error.empty());
271 }
272 
TEST(ReferenceLinkerTest,AppsWithDifferentPackageCanNotUseEachOthersAttribute)273 TEST(ReferenceLinkerTest, AppsWithDifferentPackageCanNotUseEachOthersAttribute) {
274   NameMangler mangler(NameManglerPolicy{"com.app.ext"});
275   SymbolTable table(&mangler);
276   table.AppendSource(test::StaticSymbolSourceBuilder()
277                          .AddSymbol("com.app.test:attr/foo", ResourceId(0x7f010000),
278                                     test::AttributeBuilder().Build())
279                          .AddPublicSymbol("com.app.test:attr/public_foo", ResourceId(0x7f010001),
280                                           test::AttributeBuilder().Build())
281                          .Build());
282 
283   std::string error;
284   const CallSite call_site{ResourceNameRef("com.app.ext", ResourceType::kLayout, "foo")};
285 
286   EXPECT_FALSE(ReferenceLinker::CompileXmlAttribute(
287       *test::BuildReference("com.app.test:attr/foo"), call_site, &table, &error));
288   EXPECT_FALSE(error.empty());
289 
290   error = "";
291   ASSERT_TRUE(ReferenceLinker::CompileXmlAttribute(
292       *test::BuildReference("com.app.test:attr/public_foo"), call_site, &table, &error));
293   EXPECT_TRUE(error.empty());
294 }
295 
296 }  // namespace aapt
297