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