19d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski/*
27ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * Copyright (C) 2016 The Android Open Source Project
39d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski *
49d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
59d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * you may not use this file except in compliance with the License.
69d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * You may obtain a copy of the License at
79d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski *
89d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
99d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski *
109d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * Unless required by applicable law or agreed to in writing, software
119d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
129d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * See the License for the specific language governing permissions and
149d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski * limitations under the License.
159d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski */
169d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski
177ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "androidfw/AssetManager2.h"
184c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski
197ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "android-base/logging.h"
209d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski
219d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski#include "TestHelpers.h"
22929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski#include "androidfw/ResourceUtils.h"
23da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski#include "data/lib_one/R.h"
24da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski#include "data/libclient/R.h"
257ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "data/styles/R.h"
2603ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski#include "data/system/R.h"
279d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski
284c67a475a334e4f65238d439a3339195e03c03beAdam Lesinskinamespace app = com::android::app;
29da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskinamespace lib_one = com::android::lib_one;
30da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskinamespace libclient = com::android::libclient;
319d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski
324c67a475a334e4f65238d439a3339195e03c03beAdam Lesinskinamespace android {
339d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski
347ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinskiclass ThemeTest : public ::testing::Test {
357ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski public:
367ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  void SetUp() override {
3703ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski    system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/);
3803ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski    ASSERT_NE(nullptr, system_assets_);
3903ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski
407ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski    style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
417ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski    ASSERT_NE(nullptr, style_assets_);
42da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
43da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski    libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk");
44da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski    ASSERT_NE(nullptr, libclient_assets_);
45da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
46da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski    lib_one_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_one/lib_one.apk");
47da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski    ASSERT_NE(nullptr, lib_one_assets_);
48da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
49da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski    lib_two_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_two/lib_two.apk");
50da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski    ASSERT_NE(nullptr, lib_two_assets_);
517ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  }
527ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
537ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski protected:
5403ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  std::unique_ptr<const ApkAssets> system_assets_;
550c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski  std::unique_ptr<const ApkAssets> style_assets_;
560c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski  std::unique_ptr<const ApkAssets> libclient_assets_;
570c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski  std::unique_ptr<const ApkAssets> lib_one_assets_;
580c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski  std::unique_ptr<const ApkAssets> lib_two_assets_;
597ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski};
607ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
617ad1110ecd6a840fcd2895c62668828a1ca029c6Adam LesinskiTEST_F(ThemeTest, EmptyTheme) {
627ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager;
637ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
647ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
657ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
667ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(0u, theme->GetChangingConfigurations());
677ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(&assetmanager, theme->GetAssetManager());
687ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
697ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  Res_value value;
707ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  uint32_t flags;
717ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(kInvalidCookie, theme->GetAttribute(app::R::attr::attr_one, &value, &flags));
727ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}
737ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
747ad1110ecd6a840fcd2895c62668828a1ca029c6Adam LesinskiTEST_F(ThemeTest, SingleThemeNoParent) {
757ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager;
767ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
777ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
787ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
797ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleOne));
807ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
817ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  Res_value value;
827ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  uint32_t flags;
837ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ApkAssetsCookie cookie;
847ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
857ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags);
867ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
877ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
887ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(1u, value.data);
897ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
907ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
917ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_two, &value, &flags);
927ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
937ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
947ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(2u, value.data);
957ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
967ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}
977ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
987ad1110ecd6a840fcd2895c62668828a1ca029c6Adam LesinskiTEST_F(ThemeTest, SingleThemeWithParent) {
997ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager;
1007ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
1017ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1027ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
1037ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo));
1047ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1057ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  Res_value value;
1067ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  uint32_t flags;
1077ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ApkAssetsCookie cookie;
1087ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1097ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags);
1107ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1117ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
1127ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(1u, value.data);
1137ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1147ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1157ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_two, &value, &flags);
1167ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1177ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_STRING, value.dataType);
1187ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(0, cookie);
1197ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(std::string("string"),
1207ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski            GetStringFromPool(assetmanager.GetStringPoolForCookie(0), value.data));
1217ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1227ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1237ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // This attribute should point to an attr_indirect, so the result should be 3.
1247ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_three, &value, &flags);
1257ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1267ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
1277ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(3u, value.data);
1287ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1297ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}
1307ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
13130080e2f282f40222bd9cc617e0c11d63c82f829Adam LesinskiTEST_F(ThemeTest, TryToUseBadResourceId) {
13230080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  AssetManager2 assetmanager;
13330080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
13430080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski
13530080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
13630080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo));
13730080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski
13830080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  Res_value value;
13930080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  uint32_t flags;
14030080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski  ASSERT_EQ(kInvalidCookie, theme->GetAttribute(0x7f000001, &value, &flags));
14130080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski}
14230080e2f282f40222bd9cc617e0c11d63c82f829Adam Lesinski
1437ad1110ecd6a840fcd2895c62668828a1ca029c6Adam LesinskiTEST_F(ThemeTest, MultipleThemesOverlaidNotForce) {
1447ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager;
1457ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
1467ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1477ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
1487ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo));
1497ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree));
1507ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1517ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  Res_value value;
1527ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  uint32_t flags;
1537ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ApkAssetsCookie cookie;
1547ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1557ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // attr_one is still here from the base.
1567ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags);
1577ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1587ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
1597ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(1u, value.data);
1607ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1617ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1627ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // check for the new attr_six
1637ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_six, &value, &flags);
1647ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1657ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
1667ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(6u, value.data);
1677ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1687ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1697ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // check for the old attr_five (force=true was not used).
1707ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_five, &value, &flags);
1717ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1727ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
1737ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(app::R::string::string_one, value.data);
1747ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1757ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}
1767ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1777ad1110ecd6a840fcd2895c62668828a1ca029c6Adam LesinskiTEST_F(ThemeTest, MultipleThemesOverlaidForced) {
1787ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager;
1797ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
1807ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1817ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
1827ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo));
1837ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree, true /* force */));
1847ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1857ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  Res_value value;
1867ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  uint32_t flags;
1877ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ApkAssetsCookie cookie;
1887ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1897ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // attr_one is still here from the base.
1907ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags);
1917ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1927ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
1937ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(1u, value.data);
1947ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
1957ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
1967ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // check for the new attr_six
1977ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_six, &value, &flags);
1987ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
1997ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
2007ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(6u, value.data);
2017ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
2027ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2037ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // check for the new attr_five (force=true was used).
2047ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme->GetAttribute(app::R::attr::attr_five, &value, &flags);
2057ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
2067ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
2077ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(5u, value.data);
2087ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
209da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski}
210da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
211da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam LesinskiTEST_F(ThemeTest, ResolveDynamicAttributesAndReferencesToSharedLibrary) {
212da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  AssetManager2 assetmanager;
213da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  assetmanager.SetApkAssets(
214da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski      {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
215da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
216da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  std::unique_ptr<Theme> theme = assetmanager.NewTheme();
217da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  ASSERT_TRUE(theme->ApplyStyle(libclient::R::style::Theme, false /*force*/));
218da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
219da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  Res_value value;
220da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  uint32_t flags;
221da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  ApkAssetsCookie cookie;
222da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
223da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  // The attribute should be resolved to the final value.
224da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  cookie = theme->GetAttribute(libclient::R::attr::foo, &value, &flags);
225da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
226da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
227da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  EXPECT_EQ(700u, value.data);
228da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
229da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
230da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  // The reference should be resolved to a TYPE_REFERENCE.
231da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  cookie = theme->GetAttribute(libclient::R::attr::bar, &value, &flags);
232da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
233da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
234da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski
235da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski  // lib_one is assigned package ID 0x03.
236929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski  EXPECT_EQ(3u, get_package_id(value.data));
237929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski  EXPECT_EQ(get_type_id(lib_one::R::string::foo), get_type_id(value.data));
238929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski  EXPECT_EQ(get_entry_id(lib_one::R::string::foo), get_entry_id(value.data));
2397ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}
2407ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2417ad1110ecd6a840fcd2895c62668828a1ca029c6Adam LesinskiTEST_F(ThemeTest, CopyThemeSameAssetManager) {
2427ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager;
2437ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  assetmanager.SetApkAssets({style_assets_.get()});
2447ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2457ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme_one = assetmanager.NewTheme();
2467ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne));
2477ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2487ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  Res_value value;
2497ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  uint32_t flags;
2507ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ApkAssetsCookie cookie;
2517ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2527ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // attr_one is still here from the base.
2537ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags);
2547ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
2557ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
2567ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(1u, value.data);
2577ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
2587ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2597ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // attr_six is not here.
2607ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_six, &value, &flags));
2617ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2627ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  std::unique_ptr<Theme> theme_two = assetmanager.NewTheme();
2637ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleThree));
2647ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2657ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // Copy the theme to theme_one.
2667ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme_one->SetTo(*theme_two));
2677ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2687ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // Clear theme_two to make sure we test that there WAS a copy.
2697ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  theme_two->Clear();
2707ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2717ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // attr_one is now not here.
2727ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags));
2737ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2747ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  // attr_six is now here because it was copied.
2757ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  cookie = theme_one->GetAttribute(app::R::attr::attr_six, &value, &flags);
2767ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_NE(kInvalidCookie, cookie);
2777ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
2787ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(6u, value.data);
2797ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
2807ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}
2817ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
28203ebac8c68f9925592a172fcfd11d56f48cadaebAdam LesinskiTEST_F(ThemeTest, OnlyCopySystemThemeWhenAssetManagersDiffer) {
2837ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager_one;
28403ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  assetmanager_one.SetApkAssets({system_assets_.get(), style_assets_.get()});
2857ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2867ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  AssetManager2 assetmanager_two;
28703ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  assetmanager_two.SetApkAssets({system_assets_.get(), style_assets_.get()});
2887ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2897ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  auto theme_one = assetmanager_one.NewTheme();
2907ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne));
2917ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
2927ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  auto theme_two = assetmanager_two.NewTheme();
29303ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  ASSERT_TRUE(theme_two->ApplyStyle(R::style::Theme_One));
2947ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski  ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo));
2957ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski
29603ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  EXPECT_TRUE(theme_one->SetTo(*theme_two));
29703ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski
29803ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  Res_value value;
29903ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  uint32_t flags;
30003ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski
30103ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  // No app resources.
30203ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags));
30303ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski
30403ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  // Only system.
30503ebac8c68f9925592a172fcfd11d56f48cadaebAdam Lesinski  EXPECT_NE(kInvalidCookie, theme_one->GetAttribute(R::attr::foreground, &value, &flags));
3069d9cc6233c7035c32d3b8622aa5dc7d413193dc7Adam Lesinski}
3074c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski
3084c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski}  // namespace android
309