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