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 
     25 #include "TestHelpers.h"
     26 #include "data/styles/R.h"
     27 
     28 using com::android::app::R;
     29 
     30 namespace android {
     31 
     32 class AttributeResolutionTest : public ::testing::Test {
     33  public:
     34   virtual void SetUp() override {
     35     std::string contents;
     36     ASSERT_TRUE(ReadFileFromZipToString(
     37         GetTestDataPath() + "/styles/styles.apk", "resources.arsc", &contents));
     38     ASSERT_EQ(NO_ERROR, table_.add(contents.data(), contents.size(),
     39                                    1 /*cookie*/, true /*copyData*/));
     40   }
     41 
     42  protected:
     43   ResTable table_;
     44 };
     45 
     46 class AttributeResolutionXmlTest : public AttributeResolutionTest {
     47  public:
     48   virtual void SetUp() override {
     49     AttributeResolutionTest::SetUp();
     50 
     51     std::string contents;
     52     ASSERT_TRUE(
     53         ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk",
     54                                 "res/layout/layout.xml", &contents));
     55 
     56     ASSERT_EQ(NO_ERROR, xml_parser_.setTo(contents.data(), contents.size(),
     57                                           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_F(AttributeResolutionTest, Theme) {
     69   ResTable::Theme theme(table_);
     70   ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
     71 
     72   std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
     73                                  R::attr::attr_four, R::attr::attr_empty}};
     74   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
     75 
     76   ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/,
     77                            nullptr /*src_values*/, 0 /*src_values_length*/, attrs.data(),
     78                            attrs.size(), values.data(), nullptr /*out_indices*/));
     79 
     80   const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
     81 
     82   const uint32_t* values_cursor = values.data();
     83   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
     84   EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
     85   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
     86   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
     87   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
     88   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
     89 
     90   values_cursor += STYLE_NUM_ENTRIES;
     91   EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
     92   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
     93   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
     94   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
     95   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
     96 
     97   values_cursor += STYLE_NUM_ENTRIES;
     98   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
     99   EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
    100   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    101   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    102   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    103   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    104 
    105   values_cursor += STYLE_NUM_ENTRIES;
    106   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    107   EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
    108   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    109   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    110   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    111   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    112 
    113   // @empty comes from the theme, so it has the same asset cookie and changing configurations flags
    114   // as the theme.
    115   values_cursor += STYLE_NUM_ENTRIES;
    116   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    117   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    118   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    119   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    120   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    121   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    122 }
    123 
    124 TEST_F(AttributeResolutionXmlTest, XmlParser) {
    125   std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
    126                                  R::attr::attr_four, R::attr::attr_empty}};
    127   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
    128 
    129   ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs.data(), attrs.size(), values.data(),
    130                                  nullptr /*out_indices*/));
    131 
    132   uint32_t* values_cursor = values.data();
    133   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    134   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    135   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    136   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    137   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    138   EXPECT_EQ(0u, 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(0u, 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   values_cursor += STYLE_NUM_ENTRIES;
    149   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    150   EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
    151   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    152   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    153   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    154   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    155 
    156   values_cursor += STYLE_NUM_ENTRIES;
    157   EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, values_cursor[STYLE_TYPE]);
    158   EXPECT_EQ(R::attr::attr_indirect, values_cursor[STYLE_DATA]);
    159   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    160   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    161   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    162   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    163 
    164   values_cursor += STYLE_NUM_ENTRIES;
    165   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    166   EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
    167   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    168   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    169   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    170   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    171 }
    172 
    173 TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
    174   ResTable::Theme theme(table_);
    175   ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
    176 
    177   std::array<uint32_t, 6> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
    178                                  R::attr::attr_four, R::attr::attr_five, R::attr::attr_empty}};
    179   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
    180   std::array<uint32_t, attrs.size() + 1> indices;
    181 
    182   ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*def_style_res*/, attrs.data(),
    183              attrs.size(), values.data(), indices.data());
    184 
    185   const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
    186 
    187   uint32_t* values_cursor = values.data();
    188   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    189   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    190   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    191   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    192   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    193   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    194 
    195   values_cursor += STYLE_NUM_ENTRIES;
    196   EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
    197   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    198   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    199   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    200   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    201 
    202   values_cursor += STYLE_NUM_ENTRIES;
    203   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    204   EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
    205   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    206   EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
    207   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    208   EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    209 
    210   values_cursor += STYLE_NUM_ENTRIES;
    211   EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
    212   EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
    213   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    214   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    215   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    216   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    217 
    218   values_cursor += STYLE_NUM_ENTRIES;
    219   EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
    220   EXPECT_EQ(R::string::string_one, values_cursor[STYLE_RESOURCE_ID]);
    221   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    222   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    223   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    224 
    225   // @empty comes from the theme, so it has the same asset cookie and changing configurations flags
    226   // as the theme.
    227   values_cursor += STYLE_NUM_ENTRIES;
    228   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
    229   EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
    230   EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
    231   EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
    232   EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
    233   EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
    234 
    235   // The first element of indices contains the number of indices.
    236   std::array<uint32_t, 7> expected_indices = {{6u, 0u, 1u, 2u, 3u, 4u, 5u}};
    237   EXPECT_EQ(expected_indices, indices);
    238 }
    239 
    240 } // namespace android
    241 
    242