• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "androidfw/AssetManager2.h"
18 #include "androidfw/AssetManager.h"
19 
20 #include "android-base/logging.h"
21 
22 #include "TestHelpers.h"
23 #include "androidfw/ResourceUtils.h"
24 #include "data/appaslib/R.h"
25 #include "data/basic/R.h"
26 #include "data/lib_one/R.h"
27 #include "data/lib_two/R.h"
28 #include "data/libclient/R.h"
29 #include "data/styles/R.h"
30 #include "data/system/R.h"
31 
32 namespace app = com::android::app;
33 namespace appaslib = com::android::appaslib::app;
34 namespace basic = com::android::basic;
35 namespace lib_one = com::android::lib_one;
36 namespace lib_two = com::android::lib_two;
37 namespace libclient = com::android::libclient;
38 
39 namespace android {
40 
41 class AssetManager2Test : public ::testing::Test {
42  public:
SetUp()43   void SetUp() override {
44     basic_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
45     ASSERT_NE(nullptr, basic_assets_);
46 
47     basic_de_fr_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic_de_fr.apk");
48     ASSERT_NE(nullptr, basic_de_fr_assets_);
49 
50     style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
51     ASSERT_NE(nullptr, style_assets_);
52 
53     lib_one_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_one/lib_one.apk");
54     ASSERT_NE(nullptr, lib_one_assets_);
55 
56     lib_two_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_two/lib_two.apk");
57     ASSERT_NE(nullptr, lib_two_assets_);
58 
59     libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk");
60     ASSERT_NE(nullptr, libclient_assets_);
61 
62     appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
63     ASSERT_NE(nullptr, appaslib_assets_);
64 
65     system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/);
66     ASSERT_NE(nullptr, system_assets_);
67   }
68 
69  protected:
70   std::unique_ptr<const ApkAssets> basic_assets_;
71   std::unique_ptr<const ApkAssets> basic_de_fr_assets_;
72   std::unique_ptr<const ApkAssets> style_assets_;
73   std::unique_ptr<const ApkAssets> lib_one_assets_;
74   std::unique_ptr<const ApkAssets> lib_two_assets_;
75   std::unique_ptr<const ApkAssets> libclient_assets_;
76   std::unique_ptr<const ApkAssets> appaslib_assets_;
77   std::unique_ptr<const ApkAssets> system_assets_;
78 };
79 
TEST_F(AssetManager2Test,FindsResourceFromSingleApkAssets)80 TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
81   ResTable_config desired_config;
82   memset(&desired_config, 0, sizeof(desired_config));
83   desired_config.language[0] = 'd';
84   desired_config.language[1] = 'e';
85 
86   AssetManager2 assetmanager;
87   assetmanager.SetConfiguration(desired_config);
88   assetmanager.SetApkAssets({basic_assets_.get()});
89 
90   Res_value value;
91   ResTable_config selected_config;
92   uint32_t flags;
93 
94   ApkAssetsCookie cookie =
95       assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
96                                0 /*density_override*/, &value, &selected_config, &flags);
97   ASSERT_NE(kInvalidCookie, cookie);
98 
99   // Came from our ApkAssets.
100   EXPECT_EQ(0, cookie);
101 
102   // It is the default config.
103   EXPECT_EQ(0, selected_config.language[0]);
104   EXPECT_EQ(0, selected_config.language[1]);
105 
106   // It is a string.
107   EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
108 }
109 
TEST_F(AssetManager2Test,FindsResourceFromMultipleApkAssets)110 TEST_F(AssetManager2Test, FindsResourceFromMultipleApkAssets) {
111   ResTable_config desired_config;
112   memset(&desired_config, 0, sizeof(desired_config));
113   desired_config.language[0] = 'd';
114   desired_config.language[1] = 'e';
115 
116   AssetManager2 assetmanager;
117   assetmanager.SetConfiguration(desired_config);
118   assetmanager.SetApkAssets({basic_assets_.get(), basic_de_fr_assets_.get()});
119 
120   Res_value value;
121   ResTable_config selected_config;
122   uint32_t flags;
123 
124   ApkAssetsCookie cookie =
125       assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
126                                0 /*density_override*/, &value, &selected_config, &flags);
127   ASSERT_NE(kInvalidCookie, cookie);
128 
129   // Came from our de_fr ApkAssets.
130   EXPECT_EQ(1, cookie);
131 
132   // The configuration is German.
133   EXPECT_EQ('d', selected_config.language[0]);
134   EXPECT_EQ('e', selected_config.language[1]);
135 
136   // It is a string.
137   EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
138 }
139 
TEST_F(AssetManager2Test,FindsResourceFromSharedLibrary)140 TEST_F(AssetManager2Test, FindsResourceFromSharedLibrary) {
141   AssetManager2 assetmanager;
142 
143   // libclient is built with lib_one and then lib_two in order.
144   // Reverse the order to test that proper package ID re-assignment is happening.
145   assetmanager.SetApkAssets(
146       {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
147 
148   Res_value value;
149   ResTable_config selected_config;
150   uint32_t flags;
151 
152   ApkAssetsCookie cookie =
153       assetmanager.GetResource(libclient::R::string::foo_one, false /*may_be_bag*/,
154                                0 /*density_override*/, &value, &selected_config, &flags);
155   ASSERT_NE(kInvalidCookie, cookie);
156 
157   // Reference comes from libclient.
158   EXPECT_EQ(2, cookie);
159   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
160 
161   // Lookup the reference.
162   cookie = assetmanager.GetResource(value.data, false /* may_be_bag */, 0 /* density_override*/,
163                                     &value, &selected_config, &flags);
164   ASSERT_NE(kInvalidCookie, cookie);
165   EXPECT_EQ(1, cookie);
166   EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
167   EXPECT_EQ(std::string("Foo from lib_one"),
168             GetStringFromPool(assetmanager.GetStringPoolForCookie(cookie), value.data));
169 
170   cookie = assetmanager.GetResource(libclient::R::string::foo_two, false /*may_be_bag*/,
171                                     0 /*density_override*/, &value, &selected_config, &flags);
172   ASSERT_NE(kInvalidCookie, cookie);
173 
174   // Reference comes from libclient.
175   EXPECT_EQ(2, cookie);
176   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
177 
178   // Lookup the reference.
179   cookie = assetmanager.GetResource(value.data, false /* may_be_bag */, 0 /* density_override*/,
180                                     &value, &selected_config, &flags);
181   ASSERT_NE(kInvalidCookie, cookie);
182   EXPECT_EQ(0, cookie);
183   EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
184   EXPECT_EQ(std::string("Foo from lib_two"),
185             GetStringFromPool(assetmanager.GetStringPoolForCookie(cookie), value.data));
186 }
187 
TEST_F(AssetManager2Test,FindsResourceFromAppLoadedAsSharedLibrary)188 TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) {
189   AssetManager2 assetmanager;
190   assetmanager.SetApkAssets({appaslib_assets_.get()});
191 
192   // The appaslib package will have been assigned the package ID 0x02.
193 
194   Res_value value;
195   ResTable_config selected_config;
196   uint32_t flags;
197   ApkAssetsCookie cookie = assetmanager.GetResource(
198       fix_package_id(appaslib::R::integer::number1, 0x02), false /*may_be_bag*/,
199       0u /*density_override*/, &value, &selected_config, &flags);
200   ASSERT_NE(kInvalidCookie, cookie);
201   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
202   EXPECT_EQ(fix_package_id(appaslib::R::array::integerArray1, 0x02), value.data);
203 }
204 
TEST_F(AssetManager2Test,FindsBagResourceFromSingleApkAssets)205 TEST_F(AssetManager2Test, FindsBagResourceFromSingleApkAssets) {
206   AssetManager2 assetmanager;
207   assetmanager.SetApkAssets({basic_assets_.get()});
208 
209   const ResolvedBag* bag = assetmanager.GetBag(basic::R::array::integerArray1);
210   ASSERT_NE(nullptr, bag);
211   ASSERT_EQ(3u, bag->entry_count);
212 
213   EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), bag->entries[0].value.dataType);
214   EXPECT_EQ(1u, bag->entries[0].value.data);
215   EXPECT_EQ(0, bag->entries[0].cookie);
216 
217   EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), bag->entries[1].value.dataType);
218   EXPECT_EQ(2u, bag->entries[1].value.data);
219   EXPECT_EQ(0, bag->entries[1].cookie);
220 
221   EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), bag->entries[2].value.dataType);
222   EXPECT_EQ(3u, bag->entries[2].value.data);
223   EXPECT_EQ(0, bag->entries[2].cookie);
224 }
225 
TEST_F(AssetManager2Test,FindsBagResourceFromMultipleApkAssets)226 TEST_F(AssetManager2Test, FindsBagResourceFromMultipleApkAssets) {}
227 
TEST_F(AssetManager2Test,FindsBagResourceFromSharedLibrary)228 TEST_F(AssetManager2Test, FindsBagResourceFromSharedLibrary) {
229   AssetManager2 assetmanager;
230 
231   // libclient is built with lib_one and then lib_two in order.
232   // Reverse the order to test that proper package ID re-assignment is happening.
233   assetmanager.SetApkAssets(
234       {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
235 
236   const ResolvedBag* bag = assetmanager.GetBag(libclient::R::style::Theme);
237   ASSERT_NE(nullptr, bag);
238   ASSERT_GE(bag->entry_count, 2u);
239 
240   // First two attributes come from lib_one.
241   EXPECT_EQ(1, bag->entries[0].cookie);
242   EXPECT_EQ(0x03, get_package_id(bag->entries[0].key));
243   EXPECT_EQ(1, bag->entries[1].cookie);
244   EXPECT_EQ(0x03, get_package_id(bag->entries[1].key));
245 }
246 
TEST_F(AssetManager2Test,MergesStylesWithParentFromSingleApkAssets)247 TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) {
248   AssetManager2 assetmanager;
249   assetmanager.SetApkAssets({style_assets_.get()});
250 
251   const ResolvedBag* bag_one = assetmanager.GetBag(app::R::style::StyleOne);
252   ASSERT_NE(nullptr, bag_one);
253   ASSERT_EQ(2u, bag_one->entry_count);
254 
255   EXPECT_EQ(app::R::attr::attr_one, bag_one->entries[0].key);
256   EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_one->entries[0].value.dataType);
257   EXPECT_EQ(1u, bag_one->entries[0].value.data);
258   EXPECT_EQ(0, bag_one->entries[0].cookie);
259 
260   EXPECT_EQ(app::R::attr::attr_two, bag_one->entries[1].key);
261   EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_one->entries[1].value.dataType);
262   EXPECT_EQ(2u, bag_one->entries[1].value.data);
263   EXPECT_EQ(0, bag_one->entries[1].cookie);
264 
265   const ResolvedBag* bag_two = assetmanager.GetBag(app::R::style::StyleTwo);
266   ASSERT_NE(nullptr, bag_two);
267   ASSERT_EQ(6u, bag_two->entry_count);
268 
269   // attr_one is inherited from StyleOne.
270   EXPECT_EQ(app::R::attr::attr_one, bag_two->entries[0].key);
271   EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_two->entries[0].value.dataType);
272   EXPECT_EQ(1u, bag_two->entries[0].value.data);
273   EXPECT_EQ(0, bag_two->entries[0].cookie);
274 
275   // attr_two should be overridden from StyleOne by StyleTwo.
276   EXPECT_EQ(app::R::attr::attr_two, bag_two->entries[1].key);
277   EXPECT_EQ(Res_value::TYPE_STRING, bag_two->entries[1].value.dataType);
278   EXPECT_EQ(0, bag_two->entries[1].cookie);
279   EXPECT_EQ(std::string("string"), GetStringFromPool(assetmanager.GetStringPoolForCookie(0),
280                                                      bag_two->entries[1].value.data));
281 
282   // The rest are new attributes.
283 
284   EXPECT_EQ(app::R::attr::attr_three, bag_two->entries[2].key);
285   EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, bag_two->entries[2].value.dataType);
286   EXPECT_EQ(app::R::attr::attr_indirect, bag_two->entries[2].value.data);
287   EXPECT_EQ(0, bag_two->entries[2].cookie);
288 
289   EXPECT_EQ(app::R::attr::attr_five, bag_two->entries[3].key);
290   EXPECT_EQ(Res_value::TYPE_REFERENCE, bag_two->entries[3].value.dataType);
291   EXPECT_EQ(app::R::string::string_one, bag_two->entries[3].value.data);
292   EXPECT_EQ(0, bag_two->entries[3].cookie);
293 
294   EXPECT_EQ(app::R::attr::attr_indirect, bag_two->entries[4].key);
295   EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_two->entries[4].value.dataType);
296   EXPECT_EQ(3u, bag_two->entries[4].value.data);
297   EXPECT_EQ(0, bag_two->entries[4].cookie);
298 
299   EXPECT_EQ(app::R::attr::attr_empty, bag_two->entries[5].key);
300   EXPECT_EQ(Res_value::TYPE_NULL, bag_two->entries[5].value.dataType);
301   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, bag_two->entries[5].value.data);
302   EXPECT_EQ(0, bag_two->entries[5].cookie);
303 }
304 
TEST_F(AssetManager2Test,ResolveReferenceToResource)305 TEST_F(AssetManager2Test, ResolveReferenceToResource) {
306   AssetManager2 assetmanager;
307   assetmanager.SetApkAssets({basic_assets_.get()});
308 
309   Res_value value;
310   ResTable_config selected_config;
311   uint32_t flags;
312   ApkAssetsCookie cookie =
313       assetmanager.GetResource(basic::R::integer::ref1, false /*may_be_bag*/,
314                                0u /*density_override*/, &value, &selected_config, &flags);
315   ASSERT_NE(kInvalidCookie, cookie);
316 
317   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
318   EXPECT_EQ(basic::R::integer::ref2, value.data);
319 
320   uint32_t last_ref;
321   cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
322   ASSERT_NE(kInvalidCookie, cookie);
323   EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
324   EXPECT_EQ(12000u, value.data);
325   EXPECT_EQ(basic::R::integer::ref2, last_ref);
326 }
327 
TEST_F(AssetManager2Test,ResolveReferenceToBag)328 TEST_F(AssetManager2Test, ResolveReferenceToBag) {
329   AssetManager2 assetmanager;
330   assetmanager.SetApkAssets({basic_assets_.get()});
331 
332   Res_value value;
333   ResTable_config selected_config;
334   uint32_t flags;
335   ApkAssetsCookie cookie =
336       assetmanager.GetResource(basic::R::integer::number2, true /*may_be_bag*/,
337                                0u /*density_override*/, &value, &selected_config, &flags);
338   ASSERT_NE(kInvalidCookie, cookie);
339 
340   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
341   EXPECT_EQ(basic::R::array::integerArray1, value.data);
342 
343   uint32_t last_ref;
344   cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
345   ASSERT_NE(kInvalidCookie, cookie);
346   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
347   EXPECT_EQ(basic::R::array::integerArray1, value.data);
348   EXPECT_EQ(basic::R::array::integerArray1, last_ref);
349 }
350 
IsConfigurationPresent(const std::set<ResTable_config> & configurations,const ResTable_config & configuration)351 static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
352                                    const ResTable_config& configuration) {
353   return configurations.count(configuration) > 0;
354 }
355 
TEST_F(AssetManager2Test,GetResourceConfigurations)356 TEST_F(AssetManager2Test, GetResourceConfigurations) {
357   AssetManager2 assetmanager;
358   assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
359 
360   std::set<ResTable_config> configurations = assetmanager.GetResourceConfigurations();
361 
362   // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
363   // And one extra for the default configuration.
364   EXPECT_EQ(4u, configurations.size());
365 
366   ResTable_config expected_config;
367   memset(&expected_config, 0, sizeof(expected_config));
368   expected_config.language[0] = 's';
369   expected_config.language[1] = 'v';
370   EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
371 
372   expected_config.language[0] = 'd';
373   expected_config.language[1] = 'e';
374   EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
375 
376   expected_config.language[0] = 'f';
377   expected_config.language[1] = 'r';
378   EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
379 
380   // Take out the system assets.
381   configurations = assetmanager.GetResourceConfigurations(true /* exclude_system */);
382 
383   // We expect de and fr from basic_de_fr assets.
384   EXPECT_EQ(2u, configurations.size());
385 
386   expected_config.language[0] = 's';
387   expected_config.language[1] = 'v';
388   EXPECT_FALSE(IsConfigurationPresent(configurations, expected_config));
389 
390   expected_config.language[0] = 'd';
391   expected_config.language[1] = 'e';
392   EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
393 
394   expected_config.language[0] = 'f';
395   expected_config.language[1] = 'r';
396   EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
397 }
398 
TEST_F(AssetManager2Test,GetResourceLocales)399 TEST_F(AssetManager2Test, GetResourceLocales) {
400   AssetManager2 assetmanager;
401   assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
402 
403   std::set<std::string> locales = assetmanager.GetResourceLocales();
404 
405   // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
406   EXPECT_EQ(3u, locales.size());
407   EXPECT_GT(locales.count("sv"), 0u);
408   EXPECT_GT(locales.count("de"), 0u);
409   EXPECT_GT(locales.count("fr"), 0u);
410 
411   locales = assetmanager.GetResourceLocales(true /*exclude_system*/);
412   // We expect the de and fr locales from basic_de_fr assets.
413   EXPECT_EQ(2u, locales.size());
414   EXPECT_GT(locales.count("de"), 0u);
415   EXPECT_GT(locales.count("fr"), 0u);
416 }
417 
TEST_F(AssetManager2Test,GetResourceId)418 TEST_F(AssetManager2Test, GetResourceId) {
419   AssetManager2 assetmanager;
420   assetmanager.SetApkAssets({basic_assets_.get()});
421 
422   EXPECT_EQ(basic::R::layout::main,
423             assetmanager.GetResourceId("com.android.basic:layout/main", "", ""));
424   EXPECT_EQ(basic::R::layout::main,
425             assetmanager.GetResourceId("layout/main", "", "com.android.basic"));
426   EXPECT_EQ(basic::R::layout::main,
427             assetmanager.GetResourceId("main", "layout", "com.android.basic"));
428 }
429 
TEST_F(AssetManager2Test,OpensFileFromSingleApkAssets)430 TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) {}
431 
TEST_F(AssetManager2Test,OpensFileFromMultipleApkAssets)432 TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) {}
433 
434 }  // namespace android
435