17a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski/*
27a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * Copyright (C) 2016 The Android Open Source Project
37a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski *
47a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
57a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * you may not use this file except in compliance with the License.
67a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * You may obtain a copy of the License at
77a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski *
87a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
97a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski *
107a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * Unless required by applicable law or agreed to in writing, software
117a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
127a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * See the License for the specific language governing permissions and
147a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski * limitations under the License.
157a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski */
167a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
177a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski#include "androidfw/AttributeResolution.h"
18ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski
1906d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski#include <array>
2006d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski
21ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski#include "android-base/file.h"
22ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski#include "android-base/logging.h"
23ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski#include "android-base/macros.h"
24bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski#include "androidfw/AssetManager2.h"
25bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski#include "androidfw/ResourceUtils.h"
26ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski
277a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski#include "TestHelpers.h"
287a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski#include "data/styles/R.h"
297a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
307a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinskiusing com::android::app::R;
317a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
32ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinskinamespace android {
33ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski
347a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinskiclass AttributeResolutionTest : public ::testing::Test {
357a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski public:
367a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  virtual void SetUp() override {
37bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    styles_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
38bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    ASSERT_NE(nullptr, styles_assets_);
39bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    assetmanager_.SetApkAssets({styles_assets_.get()});
407a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  }
417a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
427a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski protected:
43bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::unique_ptr<const ApkAssets> styles_assets_;
44bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  AssetManager2 assetmanager_;
457a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski};
467a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
477a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinskiclass AttributeResolutionXmlTest : public AttributeResolutionTest {
487a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski public:
497a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  virtual void SetUp() override {
507a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski    AttributeResolutionTest::SetUp();
514c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski
52bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    std::unique_ptr<Asset> asset =
53bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski        assetmanager_.OpenNonAsset("res/layout/layout.xml", Asset::ACCESS_BUFFER);
54bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    ASSERT_NE(nullptr, asset);
554c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski
56bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    ASSERT_EQ(NO_ERROR,
57bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski              xml_parser_.setTo(asset->getBuffer(true), asset->getLength(), true /*copyData*/));
587a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
597a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski    // Skip to the first tag.
607a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski    while (xml_parser_.next() != ResXMLParser::START_TAG) {
617a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski    }
627a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  }
637a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
647a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski protected:
657a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  ResXMLTree xml_parser_;
667a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski};
677a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
68bebfcc46a249a70af04bc18490a897888a142fb8Adam LesinskiTEST(AttributeResolutionLibraryTest, ApplyStyleWithDefaultStyleResId) {
69bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  AssetManager2 assetmanager;
70bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  auto apk_assets = ApkAssets::LoadAsSharedLibrary(GetTestDataPath() + "/styles/styles.apk");
71bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ASSERT_NE(nullptr, apk_assets);
72bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  assetmanager.SetApkAssets({apk_assets.get()});
73bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski
74bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
75bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski
76bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::array<uint32_t, 2> attrs{
77bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski      {fix_package_id(R::attr::attr_one, 0x02), fix_package_id(R::attr::attr_two, 0x02)}};
78bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
79bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::array<uint32_t, attrs.size() + 1> indices;
80bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ApplyStyle(theme.get(), nullptr /*xml_parser*/, 0u /*def_style_attr*/,
81bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski             fix_package_id(R::style::StyleOne, 0x02), attrs.data(), attrs.size(), values.data(),
82bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski             indices.data());
83bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski
84bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
85bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski
86bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  const uint32_t* values_cursor = values.data();
87bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
88bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
89bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
90bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
91bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
92bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
93bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski
94bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
95bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
96bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(2u, values_cursor[STYLE_DATA]);
97bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
98bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
99bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
100bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
101bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski}
102bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski
1037a37b74d37ff79e805c9e97d977e07bfec753c5aAdam LesinskiTEST_F(AttributeResolutionTest, Theme) {
104bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
105bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
1067a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
10732e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
10832e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski                                 R::attr::attr_four, R::attr::attr_empty}};
10906d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski  std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
1107a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
111bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ASSERT_TRUE(ResolveAttrs(theme.get(), 0u /*def_style_attr*/, 0u /*def_style_res*/,
11206d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski                           nullptr /*src_values*/, 0 /*src_values_length*/, attrs.data(),
11306d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski                           attrs.size(), values.data(), nullptr /*out_indices*/));
1147a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1157a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
1167a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1177a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  const uint32_t* values_cursor = values.data();
1187a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
1197a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
1207a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1217a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
1227a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1237a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1247a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1257a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
1267a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
1277a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1287a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
1297a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1307a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1317a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1327a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
1337a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
1347a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
1357a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1367a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
1377a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1387a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1397a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1407a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
1417a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
1427a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
1437a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1447a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
1457a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1467a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
14732e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski
14832e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  // @empty comes from the theme, so it has the same asset cookie and changing configurations flags
14932e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  // as the theme.
15032e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
15132e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
15232e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
15332e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
15432e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
15532e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
15632e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1577a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski}
1587a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1597a37b74d37ff79e805c9e97d977e07bfec753c5aAdam LesinskiTEST_F(AttributeResolutionXmlTest, XmlParser) {
16032e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
16132e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski                                 R::attr::attr_four, R::attr::attr_empty}};
16206d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski  std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
1637a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
164bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ASSERT_TRUE(RetrieveAttributes(&assetmanager_, &xml_parser_, attrs.data(), attrs.size(),
165bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski                                 values.data(), nullptr /*out_indices*/));
1667a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1677a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  uint32_t* values_cursor = values.data();
1687a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
16932e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
1707a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1717a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
1727a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1737a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1747a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1757a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
1767a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
1777a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DATA]);
1787a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1797a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
1807a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1817a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1827a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1837a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
1847a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
1857a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
1867a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1877a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
1887a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1897a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
1907a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
1917a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
1927a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, values_cursor[STYLE_TYPE]);
1937a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(R::attr::attr_indirect, values_cursor[STYLE_DATA]);
1947a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
1957a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
1967a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
1977a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
19832e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski
19932e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
20032e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
20132e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
20232e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
20332e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
20432e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
20532e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
2067a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski}
2077a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2087a37b74d37ff79e805c9e97d977e07bfec753c5aAdam LesinskiTEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
209bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
210bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
2117a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
21232e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  std::array<uint32_t, 6> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
21332e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski                                 R::attr::attr_four, R::attr::attr_five, R::attr::attr_empty}};
21406d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski  std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
21532e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  std::array<uint32_t, attrs.size() + 1> indices;
2167a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
217bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski  ApplyStyle(theme.get(), &xml_parser_, 0u /*def_style_attr*/, 0u /*def_style_res*/, attrs.data(),
21806d3e8fec7e2b29f99d755bee849023d88957953Adam Lesinski             attrs.size(), values.data(), indices.data());
2197a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2207a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
2217a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2227a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  uint32_t* values_cursor = values.data();
22332e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
22432e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
2257a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
22632e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
2277a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
22832e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
2297a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2307a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
2317a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
2327a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
2337a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
2347a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
2357a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
2367a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2377a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
2387a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
2397a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
2407a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
2417a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
2427a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
2437a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
2447a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2457a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
2467a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
2477a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
2487a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
2497a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
2507a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
2517a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
2527a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski
2537a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
2547a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
2557a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(R::string::string_one, values_cursor[STYLE_RESOURCE_ID]);
2567a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
2577a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
2587a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
25932e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski
26032e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  // @empty comes from the theme, so it has the same asset cookie and changing configurations flags
26132e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  // as the theme.
26232e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  values_cursor += STYLE_NUM_ENTRIES;
26332e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
26432e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]);
26532e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
26632e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
26732e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
26832e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
26932e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski
27032e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  // The first element of indices contains the number of indices.
27132e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  std::array<uint32_t, 7> expected_indices = {{6u, 0u, 1u, 2u, 3u, 4u, 5u}};
27232e7501a27f0f19bccdf9e91f9b87869c093f695Adam Lesinski  EXPECT_EQ(expected_indices, indices);
2737a37b74d37ff79e805c9e97d977e07bfec753c5aAdam Lesinski}
274ea7897954f6339dcc2e5af1584f72c6b2ecd7a67Adam Lesinski
2757ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski} // namespace android
2767ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
277