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