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