blob: 6054fa3338bd7a996527d5b9d21ba4c18d1ceb90 [file] [log] [blame]
Adam Lesinski7ad11102016-10-28 16:39:15 -07001/*
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"
Adam Lesinski929d6512017-01-16 19:11:19 -080023#include "androidfw/ResourceUtils.h"
Adam Lesinskida431a22016-12-29 16:08:16 -050024#include "data/appaslib/R.h"
Adam Lesinski7ad11102016-10-28 16:39:15 -070025#include "data/basic/R.h"
Adam Lesinskida431a22016-12-29 16:08:16 -050026#include "data/lib_one/R.h"
27#include "data/lib_two/R.h"
28#include "data/libclient/R.h"
Adam Lesinski7ad11102016-10-28 16:39:15 -070029#include "data/styles/R.h"
Adam Lesinski0c405242017-01-13 20:47:26 -080030#include "data/system/R.h"
Adam Lesinski7ad11102016-10-28 16:39:15 -070031
Adam Lesinski7ad11102016-10-28 16:39:15 -070032namespace app = com::android::app;
Adam Lesinskida431a22016-12-29 16:08:16 -050033namespace appaslib = com::android::appaslib::app;
34namespace basic = com::android::basic;
35namespace lib_one = com::android::lib_one;
36namespace lib_two = com::android::lib_two;
37namespace libclient = com::android::libclient;
Adam Lesinski7ad11102016-10-28 16:39:15 -070038
Adam Lesinskibebfcc42018-02-12 14:27:46 -080039using ::testing::Eq;
40using ::testing::NotNull;
41using ::testing::StrEq;
42
Adam Lesinski7ad11102016-10-28 16:39:15 -070043namespace android {
44
45class AssetManager2Test : public ::testing::Test {
46 public:
47 void SetUp() override {
48 basic_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
49 ASSERT_NE(nullptr, basic_assets_);
50
51 basic_de_fr_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic_de_fr.apk");
52 ASSERT_NE(nullptr, basic_de_fr_assets_);
53
54 style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
55 ASSERT_NE(nullptr, style_assets_);
Adam Lesinskida431a22016-12-29 16:08:16 -050056
57 lib_one_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_one/lib_one.apk");
58 ASSERT_NE(nullptr, lib_one_assets_);
59
60 lib_two_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_two/lib_two.apk");
61 ASSERT_NE(nullptr, lib_two_assets_);
62
63 libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk");
64 ASSERT_NE(nullptr, libclient_assets_);
65
Ryan Mitchellef40d2e2020-03-11 10:26:08 -070066 appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk",
67 PROPERTY_DYNAMIC);
Adam Lesinskida431a22016-12-29 16:08:16 -050068 ASSERT_NE(nullptr, appaslib_assets_);
Adam Lesinski0c405242017-01-13 20:47:26 -080069
Ryan Mitchellef40d2e2020-03-11 10:26:08 -070070 system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk",
71 PROPERTY_SYSTEM);
Adam Lesinski0c405242017-01-13 20:47:26 -080072 ASSERT_NE(nullptr, system_assets_);
Adam Lesinskibebfcc42018-02-12 14:27:46 -080073
74 app_assets_ = ApkAssets::Load(GetTestDataPath() + "/app/app.apk");
75 ASSERT_THAT(app_assets_, NotNull());
Mårten Kongstadc92c4dd2019-02-05 01:29:59 +010076
77 overlayable_assets_ = ApkAssets::Load(GetTestDataPath() + "/overlayable/overlayable.apk");
78 ASSERT_THAT(overlayable_assets_, NotNull());
Adam Lesinski7ad11102016-10-28 16:39:15 -070079 }
80
81 protected:
Adam Lesinski0c405242017-01-13 20:47:26 -080082 std::unique_ptr<const ApkAssets> basic_assets_;
83 std::unique_ptr<const ApkAssets> basic_de_fr_assets_;
84 std::unique_ptr<const ApkAssets> style_assets_;
85 std::unique_ptr<const ApkAssets> lib_one_assets_;
86 std::unique_ptr<const ApkAssets> lib_two_assets_;
87 std::unique_ptr<const ApkAssets> libclient_assets_;
88 std::unique_ptr<const ApkAssets> appaslib_assets_;
89 std::unique_ptr<const ApkAssets> system_assets_;
Adam Lesinskibebfcc42018-02-12 14:27:46 -080090 std::unique_ptr<const ApkAssets> app_assets_;
Mårten Kongstadc92c4dd2019-02-05 01:29:59 +010091 std::unique_ptr<const ApkAssets> overlayable_assets_;
Adam Lesinski7ad11102016-10-28 16:39:15 -070092};
93
Adam Lesinskida431a22016-12-29 16:08:16 -050094TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
Adam Lesinski7ad11102016-10-28 16:39:15 -070095 ResTable_config desired_config;
96 memset(&desired_config, 0, sizeof(desired_config));
97 desired_config.language[0] = 'd';
98 desired_config.language[1] = 'e';
99
100 AssetManager2 assetmanager;
101 assetmanager.SetConfiguration(desired_config);
102 assetmanager.SetApkAssets({basic_assets_.get()});
103
104 Res_value value;
105 ResTable_config selected_config;
106 uint32_t flags;
107
108 ApkAssetsCookie cookie =
109 assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
110 0 /*density_override*/, &value, &selected_config, &flags);
111 ASSERT_NE(kInvalidCookie, cookie);
112
113 // Came from our ApkAssets.
114 EXPECT_EQ(0, cookie);
115
116 // It is the default config.
117 EXPECT_EQ(0, selected_config.language[0]);
118 EXPECT_EQ(0, selected_config.language[1]);
119
120 // It is a string.
121 EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
122}
123
Adam Lesinskida431a22016-12-29 16:08:16 -0500124TEST_F(AssetManager2Test, FindsResourceFromMultipleApkAssets) {
Adam Lesinski7ad11102016-10-28 16:39:15 -0700125 ResTable_config desired_config;
126 memset(&desired_config, 0, sizeof(desired_config));
127 desired_config.language[0] = 'd';
128 desired_config.language[1] = 'e';
129
130 AssetManager2 assetmanager;
131 assetmanager.SetConfiguration(desired_config);
132 assetmanager.SetApkAssets({basic_assets_.get(), basic_de_fr_assets_.get()});
133
134 Res_value value;
135 ResTable_config selected_config;
136 uint32_t flags;
137
138 ApkAssetsCookie cookie =
139 assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
140 0 /*density_override*/, &value, &selected_config, &flags);
141 ASSERT_NE(kInvalidCookie, cookie);
142
143 // Came from our de_fr ApkAssets.
144 EXPECT_EQ(1, cookie);
145
Adam Lesinskida431a22016-12-29 16:08:16 -0500146 // The configuration is German.
Adam Lesinski7ad11102016-10-28 16:39:15 -0700147 EXPECT_EQ('d', selected_config.language[0]);
148 EXPECT_EQ('e', selected_config.language[1]);
149
150 // It is a string.
151 EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
152}
153
Adam Lesinskida431a22016-12-29 16:08:16 -0500154TEST_F(AssetManager2Test, FindsResourceFromSharedLibrary) {
155 AssetManager2 assetmanager;
156
157 // libclient is built with lib_one and then lib_two in order.
158 // Reverse the order to test that proper package ID re-assignment is happening.
159 assetmanager.SetApkAssets(
160 {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
161
162 Res_value value;
163 ResTable_config selected_config;
164 uint32_t flags;
165
166 ApkAssetsCookie cookie =
167 assetmanager.GetResource(libclient::R::string::foo_one, false /*may_be_bag*/,
168 0 /*density_override*/, &value, &selected_config, &flags);
169 ASSERT_NE(kInvalidCookie, cookie);
170
171 // Reference comes from libclient.
172 EXPECT_EQ(2, cookie);
173 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
174
175 // Lookup the reference.
176 cookie = assetmanager.GetResource(value.data, false /* may_be_bag */, 0 /* density_override*/,
177 &value, &selected_config, &flags);
178 ASSERT_NE(kInvalidCookie, cookie);
179 EXPECT_EQ(1, cookie);
180 EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
181 EXPECT_EQ(std::string("Foo from lib_one"),
182 GetStringFromPool(assetmanager.GetStringPoolForCookie(cookie), value.data));
183
184 cookie = assetmanager.GetResource(libclient::R::string::foo_two, false /*may_be_bag*/,
185 0 /*density_override*/, &value, &selected_config, &flags);
186 ASSERT_NE(kInvalidCookie, cookie);
187
188 // Reference comes from libclient.
189 EXPECT_EQ(2, cookie);
190 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
191
192 // Lookup the reference.
193 cookie = assetmanager.GetResource(value.data, false /* may_be_bag */, 0 /* density_override*/,
194 &value, &selected_config, &flags);
195 ASSERT_NE(kInvalidCookie, cookie);
196 EXPECT_EQ(0, cookie);
197 EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
198 EXPECT_EQ(std::string("Foo from lib_two"),
199 GetStringFromPool(assetmanager.GetStringPoolForCookie(cookie), value.data));
200}
201
202TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) {
203 AssetManager2 assetmanager;
204 assetmanager.SetApkAssets({appaslib_assets_.get()});
205
206 // The appaslib package will have been assigned the package ID 0x02.
207
208 Res_value value;
209 ResTable_config selected_config;
210 uint32_t flags;
211 ApkAssetsCookie cookie = assetmanager.GetResource(
Adam Lesinski929d6512017-01-16 19:11:19 -0800212 fix_package_id(appaslib::R::integer::number1, 0x02), false /*may_be_bag*/,
Adam Lesinskida431a22016-12-29 16:08:16 -0500213 0u /*density_override*/, &value, &selected_config, &flags);
214 ASSERT_NE(kInvalidCookie, cookie);
215 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
Adam Lesinski929d6512017-01-16 19:11:19 -0800216 EXPECT_EQ(fix_package_id(appaslib::R::array::integerArray1, 0x02), value.data);
Adam Lesinskida431a22016-12-29 16:08:16 -0500217}
218
Ryan Mitchell741e96f2019-01-23 16:56:51 -0800219TEST_F(AssetManager2Test, GetSharedLibraryResourceName) {
220 AssetManager2 assetmanager;
221 assetmanager.SetApkAssets({lib_one_assets_.get()});
222
223 AssetManager2::ResourceName name;
224 ASSERT_TRUE(assetmanager.GetResourceName(lib_one::R::string::foo, &name));
225 std::string formatted_name = ToFormattedResourceString(&name);
226 ASSERT_EQ(formatted_name, "com.android.lib_one:string/foo");
227}
228
Adam Lesinskida431a22016-12-29 16:08:16 -0500229TEST_F(AssetManager2Test, FindsBagResourceFromSingleApkAssets) {
Adam Lesinski7ad11102016-10-28 16:39:15 -0700230 AssetManager2 assetmanager;
231 assetmanager.SetApkAssets({basic_assets_.get()});
232
233 const ResolvedBag* bag = assetmanager.GetBag(basic::R::array::integerArray1);
234 ASSERT_NE(nullptr, bag);
235 ASSERT_EQ(3u, bag->entry_count);
236
237 EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), bag->entries[0].value.dataType);
238 EXPECT_EQ(1u, bag->entries[0].value.data);
239 EXPECT_EQ(0, bag->entries[0].cookie);
240
241 EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), bag->entries[1].value.dataType);
242 EXPECT_EQ(2u, bag->entries[1].value.data);
243 EXPECT_EQ(0, bag->entries[1].cookie);
244
245 EXPECT_EQ(static_cast<uint8_t>(Res_value::TYPE_INT_DEC), bag->entries[2].value.dataType);
246 EXPECT_EQ(3u, bag->entries[2].value.data);
247 EXPECT_EQ(0, bag->entries[2].cookie);
248}
249
Adam Lesinskida431a22016-12-29 16:08:16 -0500250TEST_F(AssetManager2Test, FindsBagResourceFromMultipleApkAssets) {}
251
252TEST_F(AssetManager2Test, FindsBagResourceFromSharedLibrary) {
253 AssetManager2 assetmanager;
254
255 // libclient is built with lib_one and then lib_two in order.
256 // Reverse the order to test that proper package ID re-assignment is happening.
257 assetmanager.SetApkAssets(
258 {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
259
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800260 const ResolvedBag* bag = assetmanager.GetBag(fix_package_id(lib_one::R::style::Theme, 0x03));
261 ASSERT_NE(nullptr, bag);
262 ASSERT_GE(bag->entry_count, 2u);
263
264 // First two attributes come from lib_one.
265 EXPECT_EQ(1, bag->entries[0].cookie);
266 EXPECT_EQ(0x03, get_package_id(bag->entries[0].key));
267 EXPECT_EQ(1, bag->entries[1].cookie);
268 EXPECT_EQ(0x03, get_package_id(bag->entries[1].key));
269}
270
Ryan Mitchell155d5392020-02-10 13:35:24 -0800271TEST_F(AssetManager2Test, FindsBagResourceFromMultipleSharedLibraries) {
272 AssetManager2 assetmanager;
273
274 // libclient is built with lib_one and then lib_two in order.
275 // Reverse the order to test that proper package ID re-assignment is happening.
276 assetmanager.SetApkAssets(
277 {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
278
279 const ResolvedBag* bag = assetmanager.GetBag(libclient::R::style::ThemeMultiLib);
280 ASSERT_NE(nullptr, bag);
281 ASSERT_EQ(bag->entry_count, 2u);
282
283 // First attribute comes from lib_two.
284 EXPECT_EQ(2, bag->entries[0].cookie);
285 EXPECT_EQ(0x02, get_package_id(bag->entries[0].key));
286
287 // The next two attributes come from lib_one.
288 EXPECT_EQ(2, bag->entries[1].cookie);
289 EXPECT_EQ(0x03, get_package_id(bag->entries[1].key));
290}
291
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800292TEST_F(AssetManager2Test, FindsStyleResourceWithParentFromSharedLibrary) {
293 AssetManager2 assetmanager;
294
295 // libclient is built with lib_one and then lib_two in order.
296 // Reverse the order to test that proper package ID re-assignment is happening.
297 assetmanager.SetApkAssets(
298 {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
299
Adam Lesinskida431a22016-12-29 16:08:16 -0500300 const ResolvedBag* bag = assetmanager.GetBag(libclient::R::style::Theme);
301 ASSERT_NE(nullptr, bag);
302 ASSERT_GE(bag->entry_count, 2u);
303
304 // First two attributes come from lib_one.
305 EXPECT_EQ(1, bag->entries[0].cookie);
Adam Lesinski929d6512017-01-16 19:11:19 -0800306 EXPECT_EQ(0x03, get_package_id(bag->entries[0].key));
Adam Lesinskida431a22016-12-29 16:08:16 -0500307 EXPECT_EQ(1, bag->entries[1].cookie);
Adam Lesinski929d6512017-01-16 19:11:19 -0800308 EXPECT_EQ(0x03, get_package_id(bag->entries[1].key));
Adam Lesinskida431a22016-12-29 16:08:16 -0500309}
310
Adam Lesinski7ad11102016-10-28 16:39:15 -0700311TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) {
312 AssetManager2 assetmanager;
313 assetmanager.SetApkAssets({style_assets_.get()});
314
315 const ResolvedBag* bag_one = assetmanager.GetBag(app::R::style::StyleOne);
316 ASSERT_NE(nullptr, bag_one);
317 ASSERT_EQ(2u, bag_one->entry_count);
318
319 EXPECT_EQ(app::R::attr::attr_one, bag_one->entries[0].key);
320 EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_one->entries[0].value.dataType);
321 EXPECT_EQ(1u, bag_one->entries[0].value.data);
322 EXPECT_EQ(0, bag_one->entries[0].cookie);
323
324 EXPECT_EQ(app::R::attr::attr_two, bag_one->entries[1].key);
325 EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_one->entries[1].value.dataType);
326 EXPECT_EQ(2u, bag_one->entries[1].value.data);
327 EXPECT_EQ(0, bag_one->entries[1].cookie);
328
329 const ResolvedBag* bag_two = assetmanager.GetBag(app::R::style::StyleTwo);
330 ASSERT_NE(nullptr, bag_two);
Adam Lesinski32e75012017-05-09 15:25:37 -0700331 ASSERT_EQ(6u, bag_two->entry_count);
Adam Lesinski7ad11102016-10-28 16:39:15 -0700332
333 // attr_one is inherited from StyleOne.
334 EXPECT_EQ(app::R::attr::attr_one, bag_two->entries[0].key);
335 EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_two->entries[0].value.dataType);
336 EXPECT_EQ(1u, bag_two->entries[0].value.data);
337 EXPECT_EQ(0, bag_two->entries[0].cookie);
Aurimas Liutikasd42a6702018-11-15 15:48:28 -0800338 EXPECT_EQ(app::R::style::StyleOne, bag_two->entries[0].style);
Adam Lesinski7ad11102016-10-28 16:39:15 -0700339
340 // attr_two should be overridden from StyleOne by StyleTwo.
341 EXPECT_EQ(app::R::attr::attr_two, bag_two->entries[1].key);
342 EXPECT_EQ(Res_value::TYPE_STRING, bag_two->entries[1].value.dataType);
343 EXPECT_EQ(0, bag_two->entries[1].cookie);
Aurimas Liutikasd42a6702018-11-15 15:48:28 -0800344 EXPECT_EQ(app::R::style::StyleTwo, bag_two->entries[1].style);
Adam Lesinski7ad11102016-10-28 16:39:15 -0700345 EXPECT_EQ(std::string("string"), GetStringFromPool(assetmanager.GetStringPoolForCookie(0),
346 bag_two->entries[1].value.data));
347
348 // The rest are new attributes.
349
350 EXPECT_EQ(app::R::attr::attr_three, bag_two->entries[2].key);
351 EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, bag_two->entries[2].value.dataType);
352 EXPECT_EQ(app::R::attr::attr_indirect, bag_two->entries[2].value.data);
353 EXPECT_EQ(0, bag_two->entries[2].cookie);
Aurimas Liutikasd42a6702018-11-15 15:48:28 -0800354 EXPECT_EQ(app::R::style::StyleTwo, bag_two->entries[2].style);
Adam Lesinski7ad11102016-10-28 16:39:15 -0700355
356 EXPECT_EQ(app::R::attr::attr_five, bag_two->entries[3].key);
357 EXPECT_EQ(Res_value::TYPE_REFERENCE, bag_two->entries[3].value.dataType);
358 EXPECT_EQ(app::R::string::string_one, bag_two->entries[3].value.data);
359 EXPECT_EQ(0, bag_two->entries[3].cookie);
Aurimas Liutikasd42a6702018-11-15 15:48:28 -0800360 EXPECT_EQ(app::R::style::StyleTwo, bag_two->entries[3].style);
Adam Lesinski7ad11102016-10-28 16:39:15 -0700361
362 EXPECT_EQ(app::R::attr::attr_indirect, bag_two->entries[4].key);
363 EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_two->entries[4].value.dataType);
364 EXPECT_EQ(3u, bag_two->entries[4].value.data);
365 EXPECT_EQ(0, bag_two->entries[4].cookie);
Aurimas Liutikasd42a6702018-11-15 15:48:28 -0800366 EXPECT_EQ(app::R::style::StyleTwo, bag_two->entries[4].style);
Adam Lesinski32e75012017-05-09 15:25:37 -0700367
368 EXPECT_EQ(app::R::attr::attr_empty, bag_two->entries[5].key);
369 EXPECT_EQ(Res_value::TYPE_NULL, bag_two->entries[5].value.dataType);
370 EXPECT_EQ(Res_value::DATA_NULL_EMPTY, bag_two->entries[5].value.data);
371 EXPECT_EQ(0, bag_two->entries[5].cookie);
Aurimas Liutikasd42a6702018-11-15 15:48:28 -0800372 EXPECT_EQ(app::R::style::StyleTwo, bag_two->entries[5].style);
Adam Lesinski7ad11102016-10-28 16:39:15 -0700373}
374
y57cd1952018-04-12 14:26:23 -0700375TEST_F(AssetManager2Test, MergeStylesCircularDependency) {
376 AssetManager2 assetmanager;
377 assetmanager.SetApkAssets({style_assets_.get()});
378
379 // GetBag should stop traversing the parents of styles when a circular
380 // dependency is detected
381 const ResolvedBag* bag_one = assetmanager.GetBag(app::R::style::StyleFour);
382 ASSERT_NE(nullptr, bag_one);
383 ASSERT_EQ(3u, bag_one->entry_count);
384}
385
Adam Lesinski0c405242017-01-13 20:47:26 -0800386TEST_F(AssetManager2Test, ResolveReferenceToResource) {
387 AssetManager2 assetmanager;
388 assetmanager.SetApkAssets({basic_assets_.get()});
389
390 Res_value value;
391 ResTable_config selected_config;
392 uint32_t flags;
393 ApkAssetsCookie cookie =
394 assetmanager.GetResource(basic::R::integer::ref1, false /*may_be_bag*/,
395 0u /*density_override*/, &value, &selected_config, &flags);
396 ASSERT_NE(kInvalidCookie, cookie);
397
398 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
399 EXPECT_EQ(basic::R::integer::ref2, value.data);
400
Adam Lesinski1c855a02017-11-29 09:59:37 -0800401 uint32_t last_ref = 0u;
Adam Lesinski0c405242017-01-13 20:47:26 -0800402 cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
403 ASSERT_NE(kInvalidCookie, cookie);
404 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
405 EXPECT_EQ(12000u, value.data);
Adam Lesinskid1ecd7a2017-01-23 12:58:11 -0800406 EXPECT_EQ(basic::R::integer::ref2, last_ref);
Adam Lesinski0c405242017-01-13 20:47:26 -0800407}
408
409TEST_F(AssetManager2Test, ResolveReferenceToBag) {
410 AssetManager2 assetmanager;
411 assetmanager.SetApkAssets({basic_assets_.get()});
412
413 Res_value value;
414 ResTable_config selected_config;
415 uint32_t flags;
416 ApkAssetsCookie cookie =
417 assetmanager.GetResource(basic::R::integer::number2, true /*may_be_bag*/,
418 0u /*density_override*/, &value, &selected_config, &flags);
419 ASSERT_NE(kInvalidCookie, cookie);
420
421 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
422 EXPECT_EQ(basic::R::array::integerArray1, value.data);
423
Adam Lesinski1c855a02017-11-29 09:59:37 -0800424 uint32_t last_ref = 0u;
Adam Lesinski0c405242017-01-13 20:47:26 -0800425 cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
426 ASSERT_NE(kInvalidCookie, cookie);
427 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
428 EXPECT_EQ(basic::R::array::integerArray1, value.data);
Adam Lesinskid1ecd7a2017-01-23 12:58:11 -0800429 EXPECT_EQ(basic::R::array::integerArray1, last_ref);
Adam Lesinski0c405242017-01-13 20:47:26 -0800430}
431
y9efbbef2018-04-18 11:29:09 -0700432TEST_F(AssetManager2Test, ResolveDeepIdReference) {
433 AssetManager2 assetmanager;
434 assetmanager.SetApkAssets({basic_assets_.get()});
435
436 // Set up the resource ids
437 const uint32_t high_ref = assetmanager
438 .GetResourceId("@id/high_ref", "values", "com.android.basic");
439 ASSERT_NE(high_ref, 0u);
440 const uint32_t middle_ref = assetmanager
441 .GetResourceId("@id/middle_ref", "values", "com.android.basic");
442 ASSERT_NE(middle_ref, 0u);
443 const uint32_t low_ref = assetmanager
444 .GetResourceId("@id/low_ref", "values", "com.android.basic");
445 ASSERT_NE(low_ref, 0u);
446
447 // Retrieve the most shallow resource
448 Res_value value;
449 ResTable_config config;
450 uint32_t flags;
451 ApkAssetsCookie cookie = assetmanager.GetResource(high_ref, false /*may_be_bag*/,
452 0 /*density_override*/,
453 &value, &config, &flags);
454 ASSERT_NE(kInvalidCookie, cookie);
455 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
456 EXPECT_EQ(middle_ref, value.data);
457
458 // Check that resolving the reference resolves to the deepest id
459 uint32_t last_ref = high_ref;
460 assetmanager.ResolveReference(cookie, &value, &config, &flags, &last_ref);
461 EXPECT_EQ(last_ref, low_ref);
462}
463
Adam Lesinski1c855a02017-11-29 09:59:37 -0800464TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved) {
465 AssetManager2 assetmanager;
466 assetmanager.SetApkAssets({basic_assets_.get()});
467
468 ResTable_config selected_config;
469 memset(&selected_config, 0, sizeof(selected_config));
470
471 uint32_t flags = 0u;
472
473 // Create some kind of Res_value that is NOT a reference.
474 Res_value value;
475 value.dataType = Res_value::TYPE_STRING;
476 value.data = 0;
477
478 uint32_t last_ref = basic::R::string::test1;
479 EXPECT_EQ(1, assetmanager.ResolveReference(1, &value, &selected_config, &flags, &last_ref));
480 EXPECT_EQ(basic::R::string::test1, last_ref);
481}
482
Adam Lesinski0c405242017-01-13 20:47:26 -0800483static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
484 const ResTable_config& configuration) {
485 return configurations.count(configuration) > 0;
486}
487
488TEST_F(AssetManager2Test, GetResourceConfigurations) {
489 AssetManager2 assetmanager;
490 assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
491
492 std::set<ResTable_config> configurations = assetmanager.GetResourceConfigurations();
493
494 // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
495 // And one extra for the default configuration.
496 EXPECT_EQ(4u, configurations.size());
497
498 ResTable_config expected_config;
499 memset(&expected_config, 0, sizeof(expected_config));
500 expected_config.language[0] = 's';
501 expected_config.language[1] = 'v';
502 EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
503
504 expected_config.language[0] = 'd';
505 expected_config.language[1] = 'e';
506 EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
507
508 expected_config.language[0] = 'f';
509 expected_config.language[1] = 'r';
510 EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
511
512 // Take out the system assets.
513 configurations = assetmanager.GetResourceConfigurations(true /* exclude_system */);
514
515 // We expect de and fr from basic_de_fr assets.
516 EXPECT_EQ(2u, configurations.size());
517
518 expected_config.language[0] = 's';
519 expected_config.language[1] = 'v';
520 EXPECT_FALSE(IsConfigurationPresent(configurations, expected_config));
521
522 expected_config.language[0] = 'd';
523 expected_config.language[1] = 'e';
524 EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
525
526 expected_config.language[0] = 'f';
527 expected_config.language[1] = 'r';
528 EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
529}
530
531TEST_F(AssetManager2Test, GetResourceLocales) {
532 AssetManager2 assetmanager;
533 assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
534
535 std::set<std::string> locales = assetmanager.GetResourceLocales();
536
537 // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
538 EXPECT_EQ(3u, locales.size());
539 EXPECT_GT(locales.count("sv"), 0u);
540 EXPECT_GT(locales.count("de"), 0u);
541 EXPECT_GT(locales.count("fr"), 0u);
542
543 locales = assetmanager.GetResourceLocales(true /*exclude_system*/);
544 // We expect the de and fr locales from basic_de_fr assets.
545 EXPECT_EQ(2u, locales.size());
546 EXPECT_GT(locales.count("de"), 0u);
547 EXPECT_GT(locales.count("fr"), 0u);
548}
549
550TEST_F(AssetManager2Test, GetResourceId) {
551 AssetManager2 assetmanager;
552 assetmanager.SetApkAssets({basic_assets_.get()});
553
554 EXPECT_EQ(basic::R::layout::main,
555 assetmanager.GetResourceId("com.android.basic:layout/main", "", ""));
556 EXPECT_EQ(basic::R::layout::main,
557 assetmanager.GetResourceId("layout/main", "", "com.android.basic"));
558 EXPECT_EQ(basic::R::layout::main,
559 assetmanager.GetResourceId("main", "layout", "com.android.basic"));
560}
561
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800562TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) {
563 AssetManager2 assetmanager;
564 assetmanager.SetApkAssets({system_assets_.get()});
Adam Lesinski7ad11102016-10-28 16:39:15 -0700565
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800566 std::unique_ptr<Asset> asset = assetmanager.Open("file.txt", Asset::ACCESS_BUFFER);
567 ASSERT_THAT(asset, NotNull());
568
569 const char* data = reinterpret_cast<const char*>(asset->getBuffer(false /*wordAligned*/));
570 ASSERT_THAT(data, NotNull());
571 EXPECT_THAT(std::string(data, asset->getLength()), StrEq("file\n"));
572}
573
574TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) {
575 AssetManager2 assetmanager;
576 assetmanager.SetApkAssets({system_assets_.get(), app_assets_.get()});
577
578 std::unique_ptr<Asset> asset = assetmanager.Open("file.txt", Asset::ACCESS_BUFFER);
579 ASSERT_THAT(asset, NotNull());
580
581 const char* data = reinterpret_cast<const char*>(asset->getBuffer(false /*wordAligned*/));
582 ASSERT_THAT(data, NotNull());
583 EXPECT_THAT(std::string(data, asset->getLength()), StrEq("app override file\n"));
584}
585
586TEST_F(AssetManager2Test, OpenDir) {
587 AssetManager2 assetmanager;
588 assetmanager.SetApkAssets({system_assets_.get()});
589
590 std::unique_ptr<AssetDir> asset_dir = assetmanager.OpenDir("");
591 ASSERT_THAT(asset_dir, NotNull());
592 ASSERT_THAT(asset_dir->getFileCount(), Eq(2u));
593
594 EXPECT_THAT(asset_dir->getFileName(0), Eq(String8("file.txt")));
595 EXPECT_THAT(asset_dir->getFileType(0), Eq(FileType::kFileTypeRegular));
596
597 EXPECT_THAT(asset_dir->getFileName(1), Eq(String8("subdir")));
598 EXPECT_THAT(asset_dir->getFileType(1), Eq(FileType::kFileTypeDirectory));
599
600 asset_dir = assetmanager.OpenDir("subdir");
601 ASSERT_THAT(asset_dir, NotNull());
602 ASSERT_THAT(asset_dir->getFileCount(), Eq(1u));
603
604 EXPECT_THAT(asset_dir->getFileName(0), Eq(String8("subdir_file.txt")));
605 EXPECT_THAT(asset_dir->getFileType(0), Eq(FileType::kFileTypeRegular));
606}
607
608TEST_F(AssetManager2Test, OpenDirFromManyApks) {
609 AssetManager2 assetmanager;
610 assetmanager.SetApkAssets({system_assets_.get(), app_assets_.get()});
611
612 std::unique_ptr<AssetDir> asset_dir = assetmanager.OpenDir("");
613 ASSERT_THAT(asset_dir, NotNull());
614 ASSERT_THAT(asset_dir->getFileCount(), Eq(3u));
615
616 EXPECT_THAT(asset_dir->getFileName(0), Eq(String8("app_file.txt")));
617 EXPECT_THAT(asset_dir->getFileType(0), Eq(FileType::kFileTypeRegular));
618
619 EXPECT_THAT(asset_dir->getFileName(1), Eq(String8("file.txt")));
620 EXPECT_THAT(asset_dir->getFileType(1), Eq(FileType::kFileTypeRegular));
621
622 EXPECT_THAT(asset_dir->getFileName(2), Eq(String8("subdir")));
623 EXPECT_THAT(asset_dir->getFileType(2), Eq(FileType::kFileTypeDirectory));
624}
Adam Lesinski7ad11102016-10-28 16:39:15 -0700625
Winson2f3669b2019-01-11 11:28:34 -0800626TEST_F(AssetManager2Test, GetLastPathWithoutEnablingReturnsEmpty) {
627 ResTable_config desired_config;
628
629 AssetManager2 assetmanager;
630 assetmanager.SetConfiguration(desired_config);
631 assetmanager.SetApkAssets({basic_assets_.get()});
632 assetmanager.SetResourceResolutionLoggingEnabled(false);
633
634 Res_value value;
635 ResTable_config selected_config;
636 uint32_t flags;
637
638 ApkAssetsCookie cookie =
639 assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
640 0 /*density_override*/, &value, &selected_config, &flags);
641 ASSERT_NE(kInvalidCookie, cookie);
642
643 auto result = assetmanager.GetLastResourceResolution();
644 EXPECT_EQ("", result);
645}
646
647TEST_F(AssetManager2Test, GetLastPathWithoutResolutionReturnsEmpty) {
648 ResTable_config desired_config;
649
650 AssetManager2 assetmanager;
651 assetmanager.SetConfiguration(desired_config);
652 assetmanager.SetApkAssets({basic_assets_.get()});
653
654 auto result = assetmanager.GetLastResourceResolution();
655 EXPECT_EQ("", result);
656}
657
658TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) {
659 ResTable_config desired_config;
660 memset(&desired_config, 0, sizeof(desired_config));
661 desired_config.language[0] = 'd';
662 desired_config.language[1] = 'e';
663
664 AssetManager2 assetmanager;
665 assetmanager.SetResourceResolutionLoggingEnabled(true);
666 assetmanager.SetConfiguration(desired_config);
667 assetmanager.SetApkAssets({basic_assets_.get()});
668
669 Res_value value;
670 ResTable_config selected_config;
671 uint32_t flags;
672
673 ApkAssetsCookie cookie =
674 assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
675 0 /*density_override*/, &value, &selected_config, &flags);
676 ASSERT_NE(kInvalidCookie, cookie);
677
678 auto result = assetmanager.GetLastResourceResolution();
679 EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n\tFor config -de\n\tFound initial: com.android.basic", result);
680}
681
682TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) {
683 ResTable_config desired_config;
684 memset(&desired_config, 0, sizeof(desired_config));
685 desired_config.language[0] = 'd';
686 desired_config.language[1] = 'e';
687
688 AssetManager2 assetmanager;
689 assetmanager.SetResourceResolutionLoggingEnabled(true);
690 assetmanager.SetConfiguration(desired_config);
691 assetmanager.SetApkAssets({basic_assets_.get(), basic_de_fr_assets_.get()});
692
693 Res_value value = Res_value();
694 ResTable_config selected_config;
695 uint32_t flags;
696
697 ApkAssetsCookie cookie =
698 assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
699 0 /*density_override*/, &value, &selected_config, &flags);
700 ASSERT_NE(kInvalidCookie, cookie);
701
702 auto result = assetmanager.GetLastResourceResolution();
703 EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n\tFor config -de\n\tFound initial: com.android.basic\n\tFound better: com.android.basic -de", result);
704}
705
706TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) {
707 ResTable_config desired_config;
708 memset(&desired_config, 0, sizeof(desired_config));
709
710 AssetManager2 assetmanager;
711 assetmanager.SetResourceResolutionLoggingEnabled(true);
712 assetmanager.SetConfiguration(desired_config);
713 assetmanager.SetApkAssets({basic_assets_.get()});
714
715 Res_value value = Res_value();
716 ResTable_config selected_config;
717 uint32_t flags;
718
719 ApkAssetsCookie cookie =
720 assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
721 0 /*density_override*/, &value, &selected_config, &flags);
722 ASSERT_NE(kInvalidCookie, cookie);
723
724 auto resultEnabled = assetmanager.GetLastResourceResolution();
725 ASSERT_NE("", resultEnabled);
726
727 assetmanager.SetResourceResolutionLoggingEnabled(false);
728
729 auto resultDisabled = assetmanager.GetLastResourceResolution();
730 EXPECT_EQ("", resultDisabled);
731}
732
Ryan Mitchell2e394222019-08-28 12:10:51 -0700733TEST_F(AssetManager2Test, GetOverlayablesToString) {
Mårten Kongstadc92c4dd2019-02-05 01:29:59 +0100734 ResTable_config desired_config;
735 memset(&desired_config, 0, sizeof(desired_config));
736
737 AssetManager2 assetmanager;
738 assetmanager.SetResourceResolutionLoggingEnabled(true);
739 assetmanager.SetConfiguration(desired_config);
740 assetmanager.SetApkAssets({overlayable_assets_.get()});
741
742 const auto map = assetmanager.GetOverlayableMapForPackage(0x7f);
743 ASSERT_NE(nullptr, map);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700744 ASSERT_EQ(3, map->size());
Mårten Kongstadc92c4dd2019-02-05 01:29:59 +0100745 ASSERT_EQ(map->at("OverlayableResources1"), "overlay://theme");
746 ASSERT_EQ(map->at("OverlayableResources2"), "overlay://com.android.overlayable");
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700747 ASSERT_EQ(map->at("OverlayableResources3"), "");
Ryan Mitchell2e394222019-08-28 12:10:51 -0700748
749 std::string api;
750 ASSERT_TRUE(assetmanager.GetOverlayablesToString("com.android.overlayable", &api));
751 ASSERT_EQ(api.find("not_overlayable"), std::string::npos);
752 ASSERT_NE(api.find("resource='com.android.overlayable:string/overlayable2' overlayable='OverlayableResources1' actor='overlay://theme' policy='0x0000000a'\n"),
753 std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700754
Mårten Kongstadc92c4dd2019-02-05 01:29:59 +0100755}
756
Adam Lesinski7ad11102016-10-28 16:39:15 -0700757} // namespace android