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