Theme_test.cpp revision 0c40524953f3d36a880f91183302a2ea5c722930
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/AssetManager2.h" 18 19#include "android-base/logging.h" 20 21#include "TestHelpers.h" 22#include "data/lib_one/R.h" 23#include "data/libclient/R.h" 24#include "data/styles/R.h" 25 26namespace app = com::android::app; 27namespace lib_one = com::android::lib_one; 28namespace libclient = com::android::libclient; 29 30namespace android { 31 32class ThemeTest : public ::testing::Test { 33 public: 34 void SetUp() override { 35 style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); 36 ASSERT_NE(nullptr, style_assets_); 37 38 libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk"); 39 ASSERT_NE(nullptr, libclient_assets_); 40 41 lib_one_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_one/lib_one.apk"); 42 ASSERT_NE(nullptr, lib_one_assets_); 43 44 lib_two_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_two/lib_two.apk"); 45 ASSERT_NE(nullptr, lib_two_assets_); 46 } 47 48 protected: 49 std::unique_ptr<const ApkAssets> style_assets_; 50 std::unique_ptr<const ApkAssets> libclient_assets_; 51 std::unique_ptr<const ApkAssets> lib_one_assets_; 52 std::unique_ptr<const ApkAssets> lib_two_assets_; 53}; 54 55TEST_F(ThemeTest, EmptyTheme) { 56 AssetManager2 assetmanager; 57 assetmanager.SetApkAssets({style_assets_.get()}); 58 59 std::unique_ptr<Theme> theme = assetmanager.NewTheme(); 60 EXPECT_EQ(0u, theme->GetChangingConfigurations()); 61 EXPECT_EQ(&assetmanager, theme->GetAssetManager()); 62 63 Res_value value; 64 uint32_t flags; 65 EXPECT_EQ(kInvalidCookie, theme->GetAttribute(app::R::attr::attr_one, &value, &flags)); 66} 67 68TEST_F(ThemeTest, SingleThemeNoParent) { 69 AssetManager2 assetmanager; 70 assetmanager.SetApkAssets({style_assets_.get()}); 71 72 std::unique_ptr<Theme> theme = assetmanager.NewTheme(); 73 ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleOne)); 74 75 Res_value value; 76 uint32_t flags; 77 ApkAssetsCookie cookie; 78 79 cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); 80 ASSERT_NE(kInvalidCookie, cookie); 81 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 82 EXPECT_EQ(1u, value.data); 83 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 84 85 cookie = theme->GetAttribute(app::R::attr::attr_two, &value, &flags); 86 ASSERT_NE(kInvalidCookie, cookie); 87 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 88 EXPECT_EQ(2u, value.data); 89 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 90} 91 92TEST_F(ThemeTest, SingleThemeWithParent) { 93 AssetManager2 assetmanager; 94 assetmanager.SetApkAssets({style_assets_.get()}); 95 96 std::unique_ptr<Theme> theme = assetmanager.NewTheme(); 97 ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); 98 99 Res_value value; 100 uint32_t flags; 101 ApkAssetsCookie cookie; 102 103 cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); 104 ASSERT_NE(kInvalidCookie, cookie); 105 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 106 EXPECT_EQ(1u, value.data); 107 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 108 109 cookie = theme->GetAttribute(app::R::attr::attr_two, &value, &flags); 110 ASSERT_NE(kInvalidCookie, cookie); 111 EXPECT_EQ(Res_value::TYPE_STRING, value.dataType); 112 EXPECT_EQ(0, cookie); 113 EXPECT_EQ(std::string("string"), 114 GetStringFromPool(assetmanager.GetStringPoolForCookie(0), value.data)); 115 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 116 117 // This attribute should point to an attr_indirect, so the result should be 3. 118 cookie = theme->GetAttribute(app::R::attr::attr_three, &value, &flags); 119 ASSERT_NE(kInvalidCookie, cookie); 120 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 121 EXPECT_EQ(3u, value.data); 122 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 123} 124 125TEST_F(ThemeTest, MultipleThemesOverlaidNotForce) { 126 AssetManager2 assetmanager; 127 assetmanager.SetApkAssets({style_assets_.get()}); 128 129 std::unique_ptr<Theme> theme = assetmanager.NewTheme(); 130 ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); 131 ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree)); 132 133 Res_value value; 134 uint32_t flags; 135 ApkAssetsCookie cookie; 136 137 // attr_one is still here from the base. 138 cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); 139 ASSERT_NE(kInvalidCookie, cookie); 140 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 141 EXPECT_EQ(1u, value.data); 142 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 143 144 // check for the new attr_six 145 cookie = theme->GetAttribute(app::R::attr::attr_six, &value, &flags); 146 ASSERT_NE(kInvalidCookie, cookie); 147 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 148 EXPECT_EQ(6u, value.data); 149 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 150 151 // check for the old attr_five (force=true was not used). 152 cookie = theme->GetAttribute(app::R::attr::attr_five, &value, &flags); 153 ASSERT_NE(kInvalidCookie, cookie); 154 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); 155 EXPECT_EQ(app::R::string::string_one, value.data); 156 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 157} 158 159TEST_F(ThemeTest, MultipleThemesOverlaidForced) { 160 AssetManager2 assetmanager; 161 assetmanager.SetApkAssets({style_assets_.get()}); 162 163 std::unique_ptr<Theme> theme = assetmanager.NewTheme(); 164 ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); 165 ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree, true /* force */)); 166 167 Res_value value; 168 uint32_t flags; 169 ApkAssetsCookie cookie; 170 171 // attr_one is still here from the base. 172 cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); 173 ASSERT_NE(kInvalidCookie, cookie); 174 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 175 EXPECT_EQ(1u, value.data); 176 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 177 178 // check for the new attr_six 179 cookie = theme->GetAttribute(app::R::attr::attr_six, &value, &flags); 180 ASSERT_NE(kInvalidCookie, cookie); 181 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 182 EXPECT_EQ(6u, value.data); 183 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 184 185 // check for the new attr_five (force=true was used). 186 cookie = theme->GetAttribute(app::R::attr::attr_five, &value, &flags); 187 ASSERT_NE(kInvalidCookie, cookie); 188 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 189 EXPECT_EQ(5u, value.data); 190 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 191} 192 193TEST_F(ThemeTest, ResolveDynamicAttributesAndReferencesToSharedLibrary) { 194 AssetManager2 assetmanager; 195 assetmanager.SetApkAssets( 196 {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); 197 198 std::unique_ptr<Theme> theme = assetmanager.NewTheme(); 199 ASSERT_TRUE(theme->ApplyStyle(libclient::R::style::Theme, false /*force*/)); 200 201 Res_value value; 202 uint32_t flags; 203 ApkAssetsCookie cookie; 204 205 // The attribute should be resolved to the final value. 206 cookie = theme->GetAttribute(libclient::R::attr::foo, &value, &flags); 207 ASSERT_NE(kInvalidCookie, cookie); 208 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 209 EXPECT_EQ(700u, value.data); 210 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 211 212 // The reference should be resolved to a TYPE_REFERENCE. 213 cookie = theme->GetAttribute(libclient::R::attr::bar, &value, &flags); 214 ASSERT_NE(kInvalidCookie, cookie); 215 EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); 216 217 // lib_one is assigned package ID 0x03. 218 EXPECT_EQ(3u, util::get_package_id(value.data)); 219 EXPECT_EQ(util::get_type_id(lib_one::R::string::foo), util::get_type_id(value.data)); 220 EXPECT_EQ(util::get_entry_id(lib_one::R::string::foo), util::get_entry_id(value.data)); 221} 222 223TEST_F(ThemeTest, CopyThemeSameAssetManager) { 224 AssetManager2 assetmanager; 225 assetmanager.SetApkAssets({style_assets_.get()}); 226 227 std::unique_ptr<Theme> theme_one = assetmanager.NewTheme(); 228 ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne)); 229 230 Res_value value; 231 uint32_t flags; 232 ApkAssetsCookie cookie; 233 234 // attr_one is still here from the base. 235 cookie = theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags); 236 ASSERT_NE(kInvalidCookie, cookie); 237 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 238 EXPECT_EQ(1u, value.data); 239 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 240 241 // attr_six is not here. 242 EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_six, &value, &flags)); 243 244 std::unique_ptr<Theme> theme_two = assetmanager.NewTheme(); 245 ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleThree)); 246 247 // Copy the theme to theme_one. 248 ASSERT_TRUE(theme_one->SetTo(*theme_two)); 249 250 // Clear theme_two to make sure we test that there WAS a copy. 251 theme_two->Clear(); 252 253 // attr_one is now not here. 254 EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags)); 255 256 // attr_six is now here because it was copied. 257 cookie = theme_one->GetAttribute(app::R::attr::attr_six, &value, &flags); 258 ASSERT_NE(kInvalidCookie, cookie); 259 EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); 260 EXPECT_EQ(6u, value.data); 261 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); 262} 263 264TEST_F(ThemeTest, FailToCopyThemeWithDifferentAssetManager) { 265 AssetManager2 assetmanager_one; 266 assetmanager_one.SetApkAssets({style_assets_.get()}); 267 268 AssetManager2 assetmanager_two; 269 assetmanager_two.SetApkAssets({style_assets_.get()}); 270 271 auto theme_one = assetmanager_one.NewTheme(); 272 ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne)); 273 274 auto theme_two = assetmanager_two.NewTheme(); 275 ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo)); 276 277 EXPECT_FALSE(theme_one->SetTo(*theme_two)); 278} 279 280} // namespace android 281