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 "TestHelpers.h"
21 #include "android-base/file.h"
22 #include "android-base/logging.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 using ::testing::Eq;
40 using ::testing::NotNull;
41 using ::testing::StrEq;
42 
43 namespace android {
44 
45 class AssetManager2Test : public ::testing::Test {
46  public:
SetUp()47   void SetUp() override {
48     // Move to the test data directory so the idmap can locate the overlay APK.
49     std::string original_path = base::GetExecutableDirectory();
50     chdir(GetTestDataPath().c_str());
51 
52     basic_assets_ = ApkAssets::Load("basic/basic.apk");
53     ASSERT_NE(nullptr, basic_assets_);
54 
55     basic_de_fr_assets_ = ApkAssets::Load("basic/basic_de_fr.apk");
56     ASSERT_NE(nullptr, basic_de_fr_assets_);
57 
58     basic_xhdpi_assets_ = ApkAssets::Load("basic/basic_xhdpi-v4.apk");
59     ASSERT_NE(nullptr, basic_de_fr_assets_);
60 
61     basic_xxhdpi_assets_ = ApkAssets::Load("basic/basic_xxhdpi-v4.apk");
62     ASSERT_NE(nullptr, basic_de_fr_assets_);
63 
64     style_assets_ = ApkAssets::Load("styles/styles.apk");
65     ASSERT_NE(nullptr, style_assets_);
66 
67     lib_one_assets_ = ApkAssets::Load("lib_one/lib_one.apk");
68     ASSERT_NE(nullptr, lib_one_assets_);
69 
70     lib_two_assets_ = ApkAssets::Load("lib_two/lib_two.apk");
71     ASSERT_NE(nullptr, lib_two_assets_);
72 
73     libclient_assets_ = ApkAssets::Load("libclient/libclient.apk");
74     ASSERT_NE(nullptr, libclient_assets_);
75 
76     appaslib_assets_ = ApkAssets::Load("appaslib/appaslib.apk", PROPERTY_DYNAMIC);
77     ASSERT_NE(nullptr, appaslib_assets_);
78 
79     system_assets_ = ApkAssets::Load("system/system.apk", PROPERTY_SYSTEM);
80     ASSERT_NE(nullptr, system_assets_);
81 
82     app_assets_ = ApkAssets::Load("app/app.apk");
83     ASSERT_THAT(app_assets_, NotNull());
84 
85     overlay_assets_ = ApkAssets::LoadOverlay("overlay/overlay.idmap");
86     ASSERT_NE(nullptr, overlay_assets_);
87 
88     overlayable_assets_ = ApkAssets::Load("overlayable/overlayable.apk");
89     ASSERT_THAT(overlayable_assets_, NotNull());
90     chdir(original_path.c_str());
91   }
92 
93  protected:
94   AssetManager2::ApkAssetsPtr basic_assets_;
95   AssetManager2::ApkAssetsPtr basic_de_fr_assets_;
96   AssetManager2::ApkAssetsPtr basic_xhdpi_assets_;
97   AssetManager2::ApkAssetsPtr basic_xxhdpi_assets_;
98   AssetManager2::ApkAssetsPtr style_assets_;
99   AssetManager2::ApkAssetsPtr lib_one_assets_;
100   AssetManager2::ApkAssetsPtr lib_two_assets_;
101   AssetManager2::ApkAssetsPtr libclient_assets_;
102   AssetManager2::ApkAssetsPtr appaslib_assets_;
103   AssetManager2::ApkAssetsPtr system_assets_;
104   AssetManager2::ApkAssetsPtr app_assets_;
105   AssetManager2::ApkAssetsPtr overlay_assets_;
106   AssetManager2::ApkAssetsPtr overlayable_assets_;
107 };
108 
TEST_F(AssetManager2Test,FindsResourceFromSingleApkAssets)109 TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
110   ResTable_config desired_config;
111   memset(&desired_config, 0, sizeof(desired_config));
112   desired_config.language[0] = 'd';
113   desired_config.language[1] = 'e';
114 
115   AssetManager2 assetmanager;
116   assetmanager.SetConfigurations({desired_config});
117   assetmanager.SetApkAssets({basic_assets_});
118 
119   auto value = assetmanager.GetResource(basic::R::string::test1);
120   ASSERT_TRUE(value.has_value());
121 
122   // Came from our ApkAssets.
123   EXPECT_EQ(0, value->cookie);
124 
125   // It is the default config.
126   EXPECT_EQ(0, value->config.language[0]);
127   EXPECT_EQ(0, value->config.language[1]);
128 
129   // It is a string.
130   EXPECT_EQ(Res_value::TYPE_STRING, value->type);
131 }
132 
TEST_F(AssetManager2Test,FindsResourceFromMultipleApkAssets)133 TEST_F(AssetManager2Test, FindsResourceFromMultipleApkAssets) {
134   ResTable_config desired_config;
135   memset(&desired_config, 0, sizeof(desired_config));
136   desired_config.language[0] = 'd';
137   desired_config.language[1] = 'e';
138 
139   AssetManager2 assetmanager;
140   assetmanager.SetConfigurations({desired_config});
141   assetmanager.SetApkAssets({basic_assets_, basic_de_fr_assets_});
142 
143   auto value = assetmanager.GetResource(basic::R::string::test1);
144   ASSERT_TRUE(value.has_value());
145 
146   // Came from our de_fr ApkAssets.
147   EXPECT_EQ(1, value->cookie);
148 
149   // The configuration is German.
150   EXPECT_EQ('d', value->config.language[0]);
151   EXPECT_EQ('e', value->config.language[1]);
152 
153   // It is a string.
154   EXPECT_EQ(Res_value::TYPE_STRING, value->type);
155 }
156 
TEST_F(AssetManager2Test,FindsResourceFromSharedLibrary)157 TEST_F(AssetManager2Test, FindsResourceFromSharedLibrary) {
158   AssetManager2 assetmanager;
159 
160   // libclient is built with lib_one and then lib_two in order.
161   // Reverse the order to test that proper package ID re-assignment is happening.
162   assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_});
163 
164   auto value = assetmanager.GetResource(libclient::R::string::foo_one);
165   ASSERT_TRUE(value.has_value());
166 
167   // Reference comes from libclient.
168   EXPECT_EQ(2, value->cookie);
169   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
170 
171   // Lookup the reference.
172   value = assetmanager.GetResource(value->data);
173   ASSERT_TRUE(value.has_value());
174   EXPECT_EQ(1, value->cookie);
175   EXPECT_EQ(Res_value::TYPE_STRING, value->type);
176   EXPECT_EQ(std::string("Foo from lib_one"),
177             GetStringFromPool(assetmanager.GetStringPoolForCookie(value->cookie), value->data));
178 
179   value = assetmanager.GetResource(libclient::R::string::foo_two);
180   ASSERT_TRUE(value.has_value());
181 
182   // Reference comes from libclient.
183   EXPECT_EQ(2, value->cookie);
184   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
185 
186   // Lookup the reference.
187   value = assetmanager.GetResource(value->data);
188   ASSERT_TRUE(value.has_value());
189   EXPECT_EQ(0, value->cookie);
190   EXPECT_EQ(Res_value::TYPE_STRING, value->type);
191   EXPECT_EQ(std::string("Foo from lib_two"),
192             GetStringFromPool(assetmanager.GetStringPoolForCookie(value->cookie), value->data));
193 }
194 
TEST_F(AssetManager2Test,FindsResourceFromAppLoadedAsSharedLibrary)195 TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) {
196   AssetManager2 assetmanager;
197   assetmanager.SetApkAssets({appaslib_assets_});
198 
199   // The appaslib package will have been assigned the package ID 0x02.
200   auto value = assetmanager.GetResource(fix_package_id(appaslib::R::integer::number1, 0x02));
201   ASSERT_TRUE(value.has_value());
202   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
203   EXPECT_EQ(fix_package_id(appaslib::R::array::integerArray1, 0x02), value->data);
204 }
205 
TEST_F(AssetManager2Test,AssignsOverlayPackageIdLast)206 TEST_F(AssetManager2Test, AssignsOverlayPackageIdLast) {
207   AssetManager2 assetmanager;
208   assetmanager.SetApkAssets({overlayable_assets_, overlay_assets_, lib_one_assets_});
209 
210   ASSERT_EQ(3, assetmanager.GetApkAssetsCount());
211   auto op = assetmanager.StartOperation();
212   ASSERT_EQ(overlayable_assets_, assetmanager.GetApkAssets(0));
213   ASSERT_EQ(overlay_assets_, assetmanager.GetApkAssets(1));
214   ASSERT_EQ(lib_one_assets_, assetmanager.GetApkAssets(2));
215 
216   auto get_first_package_id = [&assetmanager](auto apkAssets) -> uint8_t {
217     return assetmanager.GetAssignedPackageId(apkAssets->GetLoadedArsc()->GetPackages()[0].get());
218   };
219 
220   ASSERT_EQ(0x7f, get_first_package_id(overlayable_assets_));
221   ASSERT_EQ(0x03, get_first_package_id(overlay_assets_));
222   ASSERT_EQ(0x02, get_first_package_id(lib_one_assets_));
223 }
224 
TEST_F(AssetManager2Test,GetSharedLibraryResourceName)225 TEST_F(AssetManager2Test, GetSharedLibraryResourceName) {
226   AssetManager2 assetmanager;
227   assetmanager.SetApkAssets({lib_one_assets_});
228 
229   auto name = assetmanager.GetResourceName(lib_one::R::string::foo);
230   ASSERT_TRUE(name.has_value());
231   ASSERT_EQ("com.android.lib_one:string/foo", ToFormattedResourceString(*name));
232 }
233 
TEST_F(AssetManager2Test,GetResourceNameNonMatchingConfig)234 TEST_F(AssetManager2Test, GetResourceNameNonMatchingConfig) {
235   AssetManager2 assetmanager;
236   assetmanager.SetApkAssets({basic_de_fr_assets_});
237 
238   auto value = assetmanager.GetResourceName(basic::R::string::test1);
239   ASSERT_TRUE(value.has_value());
240   EXPECT_EQ("com.android.basic:string/test1", ToFormattedResourceString(*value));
241 }
242 
TEST_F(AssetManager2Test,GetResourceTypeSpecFlags)243 TEST_F(AssetManager2Test, GetResourceTypeSpecFlags) {
244   AssetManager2 assetmanager;
245   assetmanager.SetApkAssets({basic_de_fr_assets_});
246 
247   auto value = assetmanager.GetResourceTypeSpecFlags(basic::R::string::test1);
248   ASSERT_TRUE(value.has_value());
249   EXPECT_EQ(ResTable_typeSpec::SPEC_PUBLIC | ResTable_config::CONFIG_LOCALE, *value);
250 }
251 
TEST_F(AssetManager2Test,FindsBagResourceFromSingleApkAssets)252 TEST_F(AssetManager2Test, FindsBagResourceFromSingleApkAssets) {
253   AssetManager2 assetmanager;
254   assetmanager.SetApkAssets({basic_assets_});
255 
256   auto bag = assetmanager.GetBag(basic::R::array::integerArray1);
257   ASSERT_TRUE(bag.has_value());
258 
259   ASSERT_EQ(3u, (*bag)->entry_count);
260 
261   EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), (*bag)->entries[0].value.dataType);
262   EXPECT_EQ(1u, (*bag)->entries[0].value.data);
263   EXPECT_EQ(0, (*bag)->entries[0].cookie);
264 
265   EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), (*bag)->entries[1].value.dataType);
266   EXPECT_EQ(2u, (*bag)->entries[1].value.data);
267   EXPECT_EQ(0, (*bag)->entries[1].cookie);
268 
269   EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), (*bag)->entries[2].value.dataType);
270   EXPECT_EQ(3u, (*bag)->entries[2].value.data);
271   EXPECT_EQ(0, (*bag)->entries[2].cookie);
272 }
273 
TEST_F(AssetManager2Test,FindsBagResourceFromMultipleApkAssets)274 TEST_F(AssetManager2Test, FindsBagResourceFromMultipleApkAssets) {}
275 
TEST_F(AssetManager2Test,FindsBagResourceFromSharedLibrary)276 TEST_F(AssetManager2Test, FindsBagResourceFromSharedLibrary) {
277   AssetManager2 assetmanager;
278 
279   // libclient is built with lib_one and then lib_two in order.
280   // Reverse the order to test that proper package ID re-assignment is happening.
281   assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_});
282 
283   auto bag = assetmanager.GetBag(fix_package_id(lib_one::R::style::Theme, 0x03));
284   ASSERT_TRUE(bag.has_value());
285 
286   ASSERT_GE((*bag)->entry_count, 2u);
287 
288   // First two attributes come from lib_one.
289   EXPECT_EQ(1, (*bag)->entries[0].cookie);
290   EXPECT_EQ(0x03, get_package_id((*bag)->entries[0].key));
291   EXPECT_EQ(1, (*bag)->entries[1].cookie);
292   EXPECT_EQ(0x03, get_package_id((*bag)->entries[1].key));
293 }
294 
TEST_F(AssetManager2Test,FindsBagResourceFromMultipleSharedLibraries)295 TEST_F(AssetManager2Test, FindsBagResourceFromMultipleSharedLibraries) {
296   AssetManager2 assetmanager;
297 
298   // libclient is built with lib_one and then lib_two in order.
299   // Reverse the order to test that proper package ID re-assignment is happening.
300   assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_});
301 
302   auto bag = assetmanager.GetBag(libclient::R::style::ThemeMultiLib);
303   ASSERT_TRUE(bag.has_value());
304   ASSERT_EQ((*bag)->entry_count, 2u);
305 
306   // First attribute comes from lib_two.
307   EXPECT_EQ(2, (*bag)->entries[0].cookie);
308   EXPECT_EQ(0x02, get_package_id((*bag)->entries[0].key));
309 
310   // The next two attributes come from lib_one.
311   EXPECT_EQ(2, (*bag)->entries[1].cookie);
312   EXPECT_EQ(0x03, get_package_id((*bag)->entries[1].key));
313 }
314 
TEST_F(AssetManager2Test,FindsStyleResourceWithParentFromSharedLibrary)315 TEST_F(AssetManager2Test, FindsStyleResourceWithParentFromSharedLibrary) {
316   AssetManager2 assetmanager;
317 
318   // libclient is built with lib_one and then lib_two in order.
319   // Reverse the order to test that proper package ID re-assignment is happening.
320   assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_});
321 
322   auto bag = assetmanager.GetBag(libclient::R::style::Theme);
323   ASSERT_TRUE(bag.has_value());
324   ASSERT_GE((*bag)->entry_count, 2u);
325 
326   // First two attributes come from lib_one.
327   EXPECT_EQ(1, (*bag)->entries[0].cookie);
328   EXPECT_EQ(0x03, get_package_id((*bag)->entries[0].key));
329   EXPECT_EQ(1, (*bag)->entries[1].cookie);
330   EXPECT_EQ(0x03, get_package_id((*bag)->entries[1].key));
331 }
332 
TEST_F(AssetManager2Test,MergesStylesWithParentFromSingleApkAssets)333 TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) {
334   AssetManager2 assetmanager;
335   assetmanager.SetApkAssets({style_assets_});
336 
337   auto bag_one = assetmanager.GetBag(app::R::style::StyleOne);
338   ASSERT_TRUE(bag_one.has_value());
339   ASSERT_EQ(2u, (*bag_one)->entry_count);
340 
341   EXPECT_EQ(app::R::attr::attr_one, (*bag_one)->entries[0].key);
342   EXPECT_EQ(Res_value::TYPE_INT_DEC, (*bag_one)->entries[0].value.dataType);
343   EXPECT_EQ(1u, (*bag_one)->entries[0].value.data);
344   EXPECT_EQ(0, (*bag_one)->entries[0].cookie);
345 
346   EXPECT_EQ(app::R::attr::attr_two, (*bag_one)->entries[1].key);
347   EXPECT_EQ(Res_value::TYPE_INT_DEC, (*bag_one)->entries[1].value.dataType);
348   EXPECT_EQ(2u, (*bag_one)->entries[1].value.data);
349   EXPECT_EQ(0, (*bag_one)->entries[1].cookie);
350 
351   auto bag_two = assetmanager.GetBag(app::R::style::StyleTwo);
352   ASSERT_TRUE(bag_two.has_value());
353   ASSERT_EQ(6u, (*bag_two)->entry_count);
354 
355   // attr_one is inherited from StyleOne.
356   EXPECT_EQ(app::R::attr::attr_one, (*bag_two)->entries[0].key);
357   EXPECT_EQ(Res_value::TYPE_INT_DEC, (*bag_two)->entries[0].value.dataType);
358   EXPECT_EQ(1u, (*bag_two)->entries[0].value.data);
359   EXPECT_EQ(0, (*bag_two)->entries[0].cookie);
360   EXPECT_EQ(app::R::style::StyleOne, (*bag_two)->entries[0].style);
361 
362   // attr_two should be overridden from StyleOne by StyleTwo.
363   EXPECT_EQ(app::R::attr::attr_two, (*bag_two)->entries[1].key);
364   EXPECT_EQ(Res_value::TYPE_STRING, (*bag_two)->entries[1].value.dataType);
365   EXPECT_EQ(0, (*bag_two)->entries[1].cookie);
366   EXPECT_EQ(app::R::style::StyleTwo, (*bag_two)->entries[1].style);
367   EXPECT_EQ(std::string("string"), GetStringFromPool(assetmanager.GetStringPoolForCookie(0),
368                                                      (*bag_two)->entries[1].value.data));
369 
370   // The rest are new attributes.
371 
372   EXPECT_EQ(app::R::attr::attr_three, (*bag_two)->entries[2].key);
373   EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, (*bag_two)->entries[2].value.dataType);
374   EXPECT_EQ(app::R::attr::attr_indirect, (*bag_two)->entries[2].value.data);
375   EXPECT_EQ(0, (*bag_two)->entries[2].cookie);
376   EXPECT_EQ(app::R::style::StyleTwo, (*bag_two)->entries[2].style);
377 
378   EXPECT_EQ(app::R::attr::attr_five, (*bag_two)->entries[3].key);
379   EXPECT_EQ(Res_value::TYPE_REFERENCE, (*bag_two)->entries[3].value.dataType);
380   EXPECT_EQ(app::R::string::string_one, (*bag_two)->entries[3].value.data);
381   EXPECT_EQ(0, (*bag_two)->entries[3].cookie);
382   EXPECT_EQ(app::R::style::StyleTwo, (*bag_two)->entries[3].style);
383 
384   EXPECT_EQ(app::R::attr::attr_indirect, (*bag_two)->entries[4].key);
385   EXPECT_EQ(Res_value::TYPE_INT_DEC, (*bag_two)->entries[4].value.dataType);
386   EXPECT_EQ(3u, (*bag_two)->entries[4].value.data);
387   EXPECT_EQ(0, (*bag_two)->entries[4].cookie);
388   EXPECT_EQ(app::R::style::StyleTwo, (*bag_two)->entries[4].style);
389 
390   EXPECT_EQ(app::R::attr::attr_empty, (*bag_two)->entries[5].key);
391   EXPECT_EQ(Res_value::TYPE_NULL, (*bag_two)->entries[5].value.dataType);
392   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, (*bag_two)->entries[5].value.data);
393   EXPECT_EQ(0, (*bag_two)->entries[5].cookie);
394   EXPECT_EQ(app::R::style::StyleTwo, (*bag_two)->entries[5].style);
395 }
396 
TEST_F(AssetManager2Test,MergeStylesCircularDependency)397 TEST_F(AssetManager2Test, MergeStylesCircularDependency) {
398   AssetManager2 assetmanager;
399   assetmanager.SetApkAssets({style_assets_});
400 
401   // GetBag should stop traversing the parents of styles when a circular
402   // dependency is detected
403   auto bag = assetmanager.GetBag(app::R::style::StyleFour);
404   ASSERT_TRUE(bag.has_value());
405   ASSERT_EQ(3u, (*bag)->entry_count);
406 }
407 
TEST_F(AssetManager2Test,ResolveReferenceToResource)408 TEST_F(AssetManager2Test, ResolveReferenceToResource) {
409   AssetManager2 assetmanager;
410   assetmanager.SetApkAssets({basic_assets_});
411 
412   auto value = assetmanager.GetResource(basic::R::integer::ref1);
413   ASSERT_TRUE(value.has_value());
414   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
415   EXPECT_EQ(basic::R::integer::ref2, value->data);
416 
417   auto result = assetmanager.ResolveReference(*value);
418   ASSERT_TRUE(result.has_value());
419   EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type);
420   EXPECT_EQ(12000u, value->data);
421   EXPECT_EQ(basic::R::integer::ref2, value->resid);
422 }
423 
TEST_F(AssetManager2Test,ResolveReferenceToBag)424 TEST_F(AssetManager2Test, ResolveReferenceToBag) {
425   AssetManager2 assetmanager;
426   assetmanager.SetApkAssets({basic_assets_});
427 
428   auto value = assetmanager.GetResource(basic::R::integer::number2, true /*may_be_bag*/);
429   ASSERT_TRUE(value.has_value());
430   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
431   EXPECT_EQ(basic::R::array::integerArray1, value->data);
432 
433   auto result = assetmanager.ResolveReference(*value);
434   ASSERT_TRUE(result.has_value());
435   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
436   EXPECT_EQ(basic::R::array::integerArray1, value->data);
437   EXPECT_EQ(basic::R::array::integerArray1, value->resid);
438 }
439 
TEST_F(AssetManager2Test,ResolveDeepIdReference)440 TEST_F(AssetManager2Test, ResolveDeepIdReference) {
441   AssetManager2 assetmanager;
442   assetmanager.SetApkAssets({basic_assets_});
443 
444   // Set up the resource ids
445   auto high_ref = assetmanager.GetResourceId("@id/high_ref", "values", "com.android.basic");
446   ASSERT_TRUE(high_ref.has_value());
447 
448   auto middle_ref = assetmanager.GetResourceId("@id/middle_ref", "values", "com.android.basic");
449   ASSERT_TRUE(middle_ref.has_value());
450 
451   auto low_ref = assetmanager.GetResourceId("@id/low_ref", "values", "com.android.basic");
452   ASSERT_TRUE(low_ref.has_value());
453 
454   // Retrieve the most shallow resource
455   auto value = assetmanager.GetResource(*high_ref);
456   ASSERT_TRUE(value.has_value());
457   EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type);
458   EXPECT_EQ(*middle_ref, value->data);;
459 
460   // Check that resolving the reference resolves to the deepest id
461   auto result = assetmanager.ResolveReference(*value);
462   ASSERT_TRUE(result.has_value());
463   EXPECT_EQ(*low_ref, value->resid);
464 }
465 
TEST_F(AssetManager2Test,DensityOverride)466 TEST_F(AssetManager2Test, DensityOverride) {
467   AssetManager2 assetmanager;
468   assetmanager.SetApkAssets({basic_assets_, basic_xhdpi_assets_, basic_xxhdpi_assets_});
469   assetmanager.SetConfigurations({{
470     .density = ResTable_config::DENSITY_XHIGH,
471     .sdkVersion = 21,
472   }});
473 
474   auto value = assetmanager.GetResource(basic::R::string::density, false /*may_be_bag*/);
475   ASSERT_TRUE(value.has_value());
476   EXPECT_EQ(Res_value::TYPE_STRING, value->type);
477   EXPECT_EQ("xhdpi", GetStringFromPool(assetmanager.GetStringPoolForCookie(value->cookie),
478                                        value->data));
479 
480   value = assetmanager.GetResource(basic::R::string::density, false /*may_be_bag*/,
481                                    ResTable_config::DENSITY_XXHIGH);
482   ASSERT_TRUE(value.has_value());
483   EXPECT_EQ(Res_value::TYPE_STRING, value->type);
484   EXPECT_EQ("xxhdpi", GetStringFromPool(assetmanager.GetStringPoolForCookie(value->cookie),
485                                         value->data));
486 }
487 
TEST_F(AssetManager2Test,KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved)488 TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved) {
489   AssetManager2 assetmanager;
490   assetmanager.SetApkAssets({basic_assets_});
491 
492   // Create some kind of value that is NOT a reference.
493   AssetManager2::SelectedValue value{};
494   value.cookie = 1;
495   value.type = Res_value::TYPE_STRING;
496   value.resid = basic::R::string::test1;
497 
498   auto result = assetmanager.ResolveReference(value);
499   ASSERT_TRUE(result.has_value());
500   EXPECT_EQ(1, value.cookie);
501   EXPECT_EQ(basic::R::string::test1, value.resid);
502 }
503 
TEST_F(AssetManager2Test,ResolveReferenceMissingResourceDoNotCacheFlags)504 TEST_F(AssetManager2Test, ResolveReferenceMissingResourceDoNotCacheFlags) {
505   AssetManager2 assetmanager;
506   assetmanager.SetApkAssets({basic_assets_});
507   {
508     AssetManager2::SelectedValue value{};
509     value.data = basic::R::string::test1;
510     value.type = Res_value::TYPE_REFERENCE;
511     value.flags = ResTable_config::CONFIG_KEYBOARD;
512 
513     auto result = assetmanager.ResolveReference(value);
514     ASSERT_TRUE(result.has_value());
515     EXPECT_EQ(Res_value::TYPE_STRING, value.type);
516     EXPECT_EQ(0, value.cookie);
517     EXPECT_EQ(basic::R::string::test1, value.resid);
518     EXPECT_EQ(ResTable_typeSpec::SPEC_PUBLIC | ResTable_config::CONFIG_KEYBOARD, value.flags);
519   }
520   {
521     AssetManager2::SelectedValue value{};
522     value.data = basic::R::string::test1;
523     value.type = Res_value::TYPE_REFERENCE;
524     value.flags = ResTable_config::CONFIG_COLOR_MODE;
525 
526     auto result = assetmanager.ResolveReference(value);
527     ASSERT_TRUE(result.has_value());
528     EXPECT_EQ(Res_value::TYPE_STRING, value.type);
529     EXPECT_EQ(0, value.cookie);
530     EXPECT_EQ(basic::R::string::test1, value.resid);
531     EXPECT_EQ(ResTable_typeSpec::SPEC_PUBLIC | ResTable_config::CONFIG_COLOR_MODE, value.flags);
532   }
533 }
534 
TEST_F(AssetManager2Test,ResolveReferenceMissingResource)535 TEST_F(AssetManager2Test, ResolveReferenceMissingResource) {
536   AssetManager2 assetmanager;
537   assetmanager.SetApkAssets({basic_assets_});
538 
539   const uint32_t kMissingResId = 0x8001ffff;
540   AssetManager2::SelectedValue value{};
541   value.type = Res_value::TYPE_REFERENCE;
542   value.data = kMissingResId;
543 
544   auto result = assetmanager.ResolveReference(value);
545   ASSERT_FALSE(result.has_value());
546   EXPECT_EQ(Res_value::TYPE_REFERENCE, value.type);
547   EXPECT_EQ(kMissingResId, value.data);
548   EXPECT_EQ(kMissingResId, value.resid);
549   EXPECT_EQ(-1, value.cookie);
550   EXPECT_EQ(0, value.flags);
551 }
552 
TEST_F(AssetManager2Test,ResolveReferenceMissingResourceLib)553 TEST_F(AssetManager2Test, ResolveReferenceMissingResourceLib) {
554   AssetManager2 assetmanager;
555   assetmanager.SetApkAssets({libclient_assets_});
556 
557   AssetManager2::SelectedValue value{};
558   value.type = Res_value::TYPE_REFERENCE;
559   value.data = libclient::R::string::foo_one;
560 
561   auto result = assetmanager.ResolveReference(value);
562   ASSERT_TRUE(result.has_value());
563   EXPECT_EQ(Res_value::TYPE_DYNAMIC_REFERENCE, value.type);
564   EXPECT_EQ(lib_one::R::string::foo, value.data);
565   EXPECT_EQ(libclient::R::string::foo_one, value.resid);
566   EXPECT_EQ(0, value.cookie);
567   EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value.flags);
568 }
569 
IsConfigurationPresent(const std::set<ResTable_config> & configurations,const ResTable_config & configuration)570 static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
571                                    const ResTable_config& configuration) {
572   return configurations.count(configuration) > 0;
573 }
574 
TEST_F(AssetManager2Test,GetResourceConfigurations)575 TEST_F(AssetManager2Test, GetResourceConfigurations) {
576   AssetManager2 assetmanager;
577   assetmanager.SetApkAssets({system_assets_, basic_de_fr_assets_});
578 
579   auto configurations = assetmanager.GetResourceConfigurations();
580   ASSERT_TRUE(configurations.has_value());
581 
582   // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
583   // And one extra for the default configuration.
584   EXPECT_EQ(4u, configurations->size());
585 
586   ResTable_config expected_config;
587   memset(&expected_config, 0, sizeof(expected_config));
588   expected_config.language[0] = 's';
589   expected_config.language[1] = 'v';
590   EXPECT_TRUE(IsConfigurationPresent(*configurations, expected_config));
591 
592   expected_config.language[0] = 'd';
593   expected_config.language[1] = 'e';
594   EXPECT_TRUE(IsConfigurationPresent(*configurations, expected_config));
595 
596   expected_config.language[0] = 'f';
597   expected_config.language[1] = 'r';
598   EXPECT_TRUE(IsConfigurationPresent(*configurations, expected_config));
599 
600   // Take out the system assets.
601   configurations = assetmanager.GetResourceConfigurations(true /* exclude_system */);
602   ASSERT_TRUE(configurations.has_value());
603 
604   // We expect de and fr from basic_de_fr assets.
605   EXPECT_EQ(2u, configurations->size());
606 
607   expected_config.language[0] = 's';
608   expected_config.language[1] = 'v';
609   EXPECT_FALSE(IsConfigurationPresent(*configurations, expected_config));
610 
611   expected_config.language[0] = 'd';
612   expected_config.language[1] = 'e';
613   EXPECT_TRUE(IsConfigurationPresent(*configurations, expected_config));
614 
615   expected_config.language[0] = 'f';
616   expected_config.language[1] = 'r';
617   EXPECT_TRUE(IsConfigurationPresent(*configurations, expected_config));
618 }
619 
TEST_F(AssetManager2Test,GetResourceLocales)620 TEST_F(AssetManager2Test, GetResourceLocales) {
621   AssetManager2 assetmanager;
622   assetmanager.SetApkAssets({system_assets_, basic_de_fr_assets_});
623 
624   std::set<std::string> locales = assetmanager.GetResourceLocales();
625 
626   // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
627   EXPECT_EQ(3u, locales.size());
628   EXPECT_GT(locales.count("sv"), 0u);
629   EXPECT_GT(locales.count("de"), 0u);
630   EXPECT_GT(locales.count("fr"), 0u);
631 
632   locales = assetmanager.GetResourceLocales(true /*exclude_system*/);
633   // We expect the de and fr locales from basic_de_fr assets.
634   EXPECT_EQ(2u, locales.size());
635   EXPECT_GT(locales.count("de"), 0u);
636   EXPECT_GT(locales.count("fr"), 0u);
637 }
638 
TEST_F(AssetManager2Test,GetResourceId)639 TEST_F(AssetManager2Test, GetResourceId) {
640   AssetManager2 assetmanager;
641   assetmanager.SetApkAssets({basic_assets_});
642 
643   auto resid = assetmanager.GetResourceId("com.android.basic:layout/main", "", "");
644   ASSERT_TRUE(resid.has_value());
645   EXPECT_EQ(basic::R::layout::main, *resid);
646 
647   resid = assetmanager.GetResourceId("layout/main", "", "com.android.basic");
648   ASSERT_TRUE(resid.has_value());
649   EXPECT_EQ(basic::R::layout::main, *resid);
650 
651   resid = assetmanager.GetResourceId("main", "layout", "com.android.basic");
652   ASSERT_TRUE(resid.has_value());
653   EXPECT_EQ(basic::R::layout::main, *resid);
654 }
655 
TEST_F(AssetManager2Test,OpensFileFromSingleApkAssets)656 TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) {
657   AssetManager2 assetmanager;
658   assetmanager.SetApkAssets({system_assets_});
659 
660   std::unique_ptr<Asset> asset = assetmanager.Open("file.txt", Asset::ACCESS_BUFFER);
661   ASSERT_THAT(asset, NotNull());
662 
663   const char* data = reinterpret_cast<const char*>(asset->getBuffer(false /*wordAligned*/));
664   ASSERT_THAT(data, NotNull());
665   EXPECT_THAT(std::string(data, asset->getLength()), StrEq("file\n"));
666 }
667 
TEST_F(AssetManager2Test,OpensFileFromMultipleApkAssets)668 TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) {
669   AssetManager2 assetmanager;
670   assetmanager.SetApkAssets({system_assets_, app_assets_});
671 
672   std::unique_ptr<Asset> asset = assetmanager.Open("file.txt", Asset::ACCESS_BUFFER);
673   ASSERT_THAT(asset, NotNull());
674 
675   const char* data = reinterpret_cast<const char*>(asset->getBuffer(false /*wordAligned*/));
676   ASSERT_THAT(data, NotNull());
677   EXPECT_THAT(std::string(data, asset->getLength()), StrEq("app override file\n"));
678 }
679 
TEST_F(AssetManager2Test,OpenDir)680 TEST_F(AssetManager2Test, OpenDir) {
681   AssetManager2 assetmanager;
682   assetmanager.SetApkAssets({system_assets_});
683 
684   std::unique_ptr<AssetDir> asset_dir = assetmanager.OpenDir("");
685   ASSERT_THAT(asset_dir, NotNull());
686   ASSERT_THAT(asset_dir->getFileCount(), Eq(2u));
687 
688   EXPECT_THAT(asset_dir->getFileName(0), Eq(String8("file.txt")));
689   EXPECT_THAT(asset_dir->getFileType(0), Eq(FileType::kFileTypeRegular));
690 
691   EXPECT_THAT(asset_dir->getFileName(1), Eq(String8("subdir")));
692   EXPECT_THAT(asset_dir->getFileType(1), Eq(FileType::kFileTypeDirectory));
693 
694   asset_dir = assetmanager.OpenDir("subdir");
695   ASSERT_THAT(asset_dir, NotNull());
696   ASSERT_THAT(asset_dir->getFileCount(), Eq(1u));
697 
698   EXPECT_THAT(asset_dir->getFileName(0), Eq(String8("subdir_file.txt")));
699   EXPECT_THAT(asset_dir->getFileType(0), Eq(FileType::kFileTypeRegular));
700 }
701 
TEST_F(AssetManager2Test,OpenDirFromManyApks)702 TEST_F(AssetManager2Test, OpenDirFromManyApks) {
703   AssetManager2 assetmanager;
704   assetmanager.SetApkAssets({system_assets_, app_assets_});
705 
706   std::unique_ptr<AssetDir> asset_dir = assetmanager.OpenDir("");
707   ASSERT_THAT(asset_dir, NotNull());
708   ASSERT_THAT(asset_dir->getFileCount(), Eq(3u));
709 
710   EXPECT_THAT(asset_dir->getFileName(0), Eq(String8("app_file.txt")));
711   EXPECT_THAT(asset_dir->getFileType(0), Eq(FileType::kFileTypeRegular));
712 
713   EXPECT_THAT(asset_dir->getFileName(1), Eq(String8("file.txt")));
714   EXPECT_THAT(asset_dir->getFileType(1), Eq(FileType::kFileTypeRegular));
715 
716   EXPECT_THAT(asset_dir->getFileName(2), Eq(String8("subdir")));
717   EXPECT_THAT(asset_dir->getFileType(2), Eq(FileType::kFileTypeDirectory));
718 }
719 
TEST_F(AssetManager2Test,GetLastPathWithoutEnablingReturnsEmpty)720 TEST_F(AssetManager2Test, GetLastPathWithoutEnablingReturnsEmpty) {
721   ResTable_config desired_config;
722 
723   AssetManager2 assetmanager;
724   assetmanager.SetConfigurations({desired_config});
725   assetmanager.SetApkAssets({basic_assets_});
726   assetmanager.SetResourceResolutionLoggingEnabled(false);
727 
728   auto value = assetmanager.GetResource(basic::R::string::test1);
729   ASSERT_TRUE(value.has_value());
730 
731   auto result = assetmanager.GetLastResourceResolution();
732   EXPECT_EQ("", result);
733 }
734 
TEST_F(AssetManager2Test,GetLastPathWithoutResolutionReturnsEmpty)735 TEST_F(AssetManager2Test, GetLastPathWithoutResolutionReturnsEmpty) {
736   ResTable_config desired_config;
737 
738   AssetManager2 assetmanager;
739   assetmanager.SetConfigurations({desired_config});
740   assetmanager.SetApkAssets({basic_assets_});
741 
742   auto result = assetmanager.GetLastResourceResolution();
743   EXPECT_EQ("", result);
744 }
745 
TEST_F(AssetManager2Test,GetLastPathWithSingleApkAssets)746 TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) {
747   ResTable_config desired_config;
748   memset(&desired_config, 0, sizeof(desired_config));
749   desired_config.language[0] = 'd';
750   desired_config.language[1] = 'e';
751 
752   AssetManager2 assetmanager;
753   assetmanager.SetResourceResolutionLoggingEnabled(true);
754   assetmanager.SetConfigurations({desired_config});
755   assetmanager.SetApkAssets({basic_assets_});
756 
757   auto value = assetmanager.GetResource(basic::R::string::test1);
758   ASSERT_TRUE(value.has_value());
759 
760   auto result = assetmanager.GetLastResourceResolution();
761   EXPECT_EQ(
762       "Resolution for 0x7f030000 com.android.basic:string/test1\n"
763       "\tFor config - de\n"
764       "\tFound initial: basic/basic.apk #0\n"
765       "Best matching is from default configuration of com.android.basic",
766       result);
767 }
768 
TEST_F(AssetManager2Test,GetLastPathWithMultipleApkAssets)769 TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) {
770   ResTable_config desired_config;
771   memset(&desired_config, 0, sizeof(desired_config));
772   desired_config.language[0] = 'd';
773   desired_config.language[1] = 'e';
774 
775   AssetManager2 assetmanager;
776   assetmanager.SetResourceResolutionLoggingEnabled(true);
777   assetmanager.SetConfigurations({desired_config});
778   assetmanager.SetApkAssets({basic_assets_, basic_de_fr_assets_});
779 
780   auto value = assetmanager.GetResource(basic::R::string::test1);
781   ASSERT_TRUE(value.has_value());
782 
783   auto result = assetmanager.GetLastResourceResolution();
784   EXPECT_EQ(
785       "Resolution for 0x7f030000 com.android.basic:string/test1\n"
786       "\tFor config - de\n"
787       "\tFound initial: basic/basic.apk #0\n"
788       "\tFound better: basic/basic_de_fr.apk #1 - de\n"
789       "Best matching is from de configuration of com.android.basic",
790       result);
791 }
792 
TEST_F(AssetManager2Test,GetLastPathAfterDisablingReturnsEmpty)793 TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) {
794   ResTable_config desired_config;
795   memset(&desired_config, 0, sizeof(desired_config));
796 
797   AssetManager2 assetmanager;
798   assetmanager.SetResourceResolutionLoggingEnabled(true);
799   assetmanager.SetConfigurations({desired_config});
800   assetmanager.SetApkAssets({basic_assets_});
801 
802   auto value = assetmanager.GetResource(basic::R::string::test1);
803   ASSERT_TRUE(value.has_value());
804 
805   auto resultEnabled = assetmanager.GetLastResourceResolution();
806   ASSERT_NE("", resultEnabled);
807 
808   assetmanager.SetResourceResolutionLoggingEnabled(false);
809 
810   auto resultDisabled = assetmanager.GetLastResourceResolution();
811   EXPECT_EQ("", resultDisabled);
812 }
813 
TEST_F(AssetManager2Test,GetOverlayablesToString)814 TEST_F(AssetManager2Test, GetOverlayablesToString) {
815   ResTable_config desired_config;
816   memset(&desired_config, 0, sizeof(desired_config));
817 
818   AssetManager2 assetmanager;
819   assetmanager.SetResourceResolutionLoggingEnabled(true);
820   assetmanager.SetConfigurations({desired_config});
821   assetmanager.SetApkAssets({overlayable_assets_});
822 
823   const auto map = assetmanager.GetOverlayableMapForPackage(0x7f);
824   ASSERT_NE(nullptr, map);
825   ASSERT_EQ(3, map->size());
826   ASSERT_EQ(map->at("OverlayableResources1"), "overlay://theme");
827   ASSERT_EQ(map->at("OverlayableResources2"), "overlay://com.android.overlayable");
828   ASSERT_EQ(map->at("OverlayableResources3"), "");
829 
830   std::string api;
831   ASSERT_TRUE(assetmanager.GetOverlayablesToString("com.android.overlayable", &api));
832   ASSERT_EQ(api.find("not_overlayable"), std::string::npos);
833   ASSERT_NE(api.find("resource='com.android.overlayable:string/overlayable2' overlayable='OverlayableResources1' actor='overlay://theme' policy='0x0000000a'\n"),
834             std::string::npos);
835 }
836 
TEST_F(AssetManager2Test,GetApkAssets)837 TEST_F(AssetManager2Test, GetApkAssets) {
838   AssetManager2 assetmanager;
839   assetmanager.SetApkAssets({overlayable_assets_, overlay_assets_, lib_one_assets_});
840 
841   ASSERT_EQ(3, assetmanager.GetApkAssetsCount());
842   EXPECT_EQ(1, overlayable_assets_->getStrongCount());
843   EXPECT_EQ(1, overlay_assets_->getStrongCount());
844   EXPECT_EQ(1, lib_one_assets_->getStrongCount());
845 
846   {
847     auto op = assetmanager.StartOperation();
848     ASSERT_EQ(overlayable_assets_, assetmanager.GetApkAssets(0));
849     ASSERT_EQ(overlay_assets_, assetmanager.GetApkAssets(1));
850     EXPECT_EQ(2, overlayable_assets_->getStrongCount());
851     EXPECT_EQ(2, overlay_assets_->getStrongCount());
852     EXPECT_EQ(1, lib_one_assets_->getStrongCount());
853   }
854   EXPECT_EQ(1, overlayable_assets_->getStrongCount());
855   EXPECT_EQ(1, overlay_assets_->getStrongCount());
856   EXPECT_EQ(1, lib_one_assets_->getStrongCount());
857 }
858 
859 }  // namespace android
860