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/AttributeResolution.h"
     18 
     19 #include <array>
     20 
     21 #include "android-base/file.h"
     22 #include "android-base/logging.h"
     23 #include "android-base/macros.h"
     24 #include "androidfw/AssetManager2.h"
     25 #include "androidfw/ResourceUtils.h"
     26 
     27 #include "TestHelpers.h"
     28 #include "data/styles/R.h"
     29 
     30 using com::android::app::R;
     31 
     32 namespace android {
     33 
     34 class AttributeResolutionTest : public ::testing::Test {
     35  public:
     36   virtual void SetUp() override {
     37     styles_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
     38     ASSERT_NE(nullptr, styles_assets_);
     39     assetmanager_.SetApkAssets({styles_assets_.get()});
     40   }
     41 
     42  protected:
     43   std::unique_ptr<const ApkAssets> styles_assets_;
     44   AssetManager2 assetmanager_;
     45 };
     46 
     47 class AttributeResolutionXmlTest : public AttributeResolutionTest {
     48  public:
     49   virtual void SetUp() override {
     50     AttributeResolutionTest::SetUp();
     51 
     52     std::unique_ptr<Asset> asset =
     53         assetmanager_.OpenNonAsset("res/layout/layout.xml", Asset::ACCESS_BUFFER);
     54     ASSERT_NE(nullptr, asset);
     55 
     56     ASSERT_EQ(NO_ERROR,
     57               xml_parser_.setTo(asset->getBuffer(true), asset->getLength(), true /*copyData*/));
     58 
     59     // Skip to the first tag.
     60     while (xml_parser_.next() != ResXMLParser::START_TAG) {
     61     }
     62   }
     63 
     64  protected:
     65   ResXMLTree xml_parser_;
     66 };
     67 
     68 TEST(AttributeResolutionLibraryTest, ApplyStyleWithDefaultStyleResId) {
     69   AssetManager2 assetmanager;
     70   auto apk_assets = ApkAssets::LoadAsSharedLibrary(GetTestDataPath() + "/styles/styles.apk");
     71   ASSERT_NE(nullptr, apk_assets);
     72   assetmanager.SetApkAssets({apk_assets.get()});
     73 
     74   std::unique_ptr<Theme> theme = assetmanager.NewTheme();
     75 
     76   std::array<uint32_t, 2> attrs{
     77       {fix_package_id(R::attr::attr_one, 0x02), fix_package_id(R::attr::attr_two, 0x02)}};
     78   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
     79   std::array<uint32_t, attrs.size() + 1> indices;
     80   ApplyStyle(theme.get(), nullptr /*xml_parser*/, 0u /*def_style_attr*/,
     81              fix_package_id(R::style::StyleOne, 0x02), attrs.data(), attrs.size(), values.data(),
     82              indices.data());
     83 
     84   const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
     85 
     86   const uint32_t* values_cursor = values.data();
     87   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
     88   EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
     89   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
     90   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
     91   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
     92   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
     93 
     94   values_cursor += STYLE_NUM_ENTRIES;
     95   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
     96   EXPECT_EQ(2u, values_cursor[STYLE_DATA]);
     97   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
     98   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
     99   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    100   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    101 }
    102 
    103 TEST_F(AttributeResolutionTest, Theme) {
    104   std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
    105   ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
    106 
    107   std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
    108                                  R::attr::attr_four, R::attr::attr_empty}};
    109   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
    110 
    111   ASSERT_TRUE(ResolveAttrs(theme.get(), 0u /*def_style_attr*/, 0u /*def_style_res*/,
    112                            nullptr /*src_values*/, 0 /*src_values_length*/, attrs.data(),
    113                            attrs.size(), values.data(), nullptr /*out_indices*/));
    114 
    115   const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
    116 
    117   const uint32_t* values_cursor = values.data();
    118   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    119   EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
    120   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    121   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    122   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    123   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    124 
    125   values_cursor += STYLE_NUM_ENTRIES;
    126   EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
    127   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    128   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    129   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    130   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    131 
    132   values_cursor += STYLE_NUM_ENTRIES;
    133   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    134   EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
    135   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    136   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    137   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    138   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    139 
    140   values_cursor += STYLE_NUM_ENTRIES;
    141   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    142   EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
    143   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    144   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    145   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    146   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    147 
    148   // @empty comes from the theme, so it has the same asset cookie and changing configurations flags
    149   // as the theme.
    150   values_cursor += STYLE_NUM_ENTRIES;
    151   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    152   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    153   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    154   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    155   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    156   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    157 }
    158 
    159 TEST_F(AttributeResolutionXmlTest, XmlParser) {
    160   std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
    161                                  R::attr::attr_four, R::attr::attr_empty}};
    162   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
    163 
    164   ASSERT_TRUE(RetrieveAttributes(&assetmanager_, &xml_parser_, attrs.data(), attrs.size(),
    165                                  values.data(), nullptr /*out_indices*/));
    166 
    167   uint32_t* values_cursor = values.data();
    168   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    169   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    170   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    171   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    172   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    173   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    174 
    175   values_cursor += STYLE_NUM_ENTRIES;
    176   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    177   EXPECT_EQ(0u, values_cursor[STYLE_DATA]);
    178   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    179   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    180   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    181   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    182 
    183   values_cursor += STYLE_NUM_ENTRIES;
    184   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    185   EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
    186   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    187   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    188   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    189   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    190 
    191   values_cursor += STYLE_NUM_ENTRIES;
    192   EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, values_cursor[STYLE_TYPE]);
    193   EXPECT_EQ(R::attr::attr_indirect, values_cursor[STYLE_DATA]);
    194   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    195   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    196   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    197   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    198 
    199   values_cursor += STYLE_NUM_ENTRIES;
    200   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    201   EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
    202   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    203   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    204   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    205   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    206 }
    207 
    208 TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
    209   std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
    210   ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
    211 
    212   std::array<uint32_t, 6> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
    213                                  R::attr::attr_four, R::attr::attr_five, R::attr::attr_empty}};
    214   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
    215   std::array<uint32_t, attrs.size() + 1> indices;
    216 
    217   ApplyStyle(theme.get(), &xml_parser_, 0u /*def_style_attr*/, 0u /*def_style_res*/, attrs.data(),
    218              attrs.size(), values.data(), indices.data());
    219 
    220   const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
    221 
    222   uint32_t* values_cursor = values.data();
    223   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    224   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    225   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    226   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    227   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    228   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    229 
    230   values_cursor += STYLE_NUM_ENTRIES;
    231   EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
    232   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    233   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    234   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    235   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    236 
    237   values_cursor += STYLE_NUM_ENTRIES;
    238   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    239   EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
    240   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    241   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    242   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    243   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    244 
    245   values_cursor += STYLE_NUM_ENTRIES;
    246   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    247   EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
    248   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    249   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    250   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    251   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    252 
    253   values_cursor += STYLE_NUM_ENTRIES;
    254   EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
    255   EXPECT_EQ(R::string::string_one, values_cursor[STYLE_RESOURCE_ID]);
    256   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    257   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    258   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    259 
    260   // @empty comes from the theme, so it has the same asset cookie and changing configurations flags
    261   // as the theme.
    262   values_cursor += STYLE_NUM_ENTRIES;
    263   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    264   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    265   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    266   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    267   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    268   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    269 
    270   // The first element of indices contains the number of indices.
    271   std::array<uint32_t, 7> expected_indices = {{6u, 0u, 1u, 2u, 3u, 4u, 5u}};
    272   EXPECT_EQ(expected_indices, indices);
    273 }
    274 
    275 } // namespace android
    276 
    277