1 /*
2 * Copyright (C) 2014 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/ResourceTypes.h>
18
19 #include <utils/String8.h>
20 #include <utils/String16.h>
21 #include "TestHelpers.h"
22 #include "data/basic/R.h"
23 #include "data/lib/R.h"
24
25 #include <gtest/gtest.h>
26
27 using namespace android;
28
29 namespace {
30
31 /**
32 * Include a binary resource table.
33 *
34 * Package: com.android.test.basic
35 */
36 #include "data/basic/basic_arsc.h"
37
38 #include "data/lib/lib_arsc.h"
39
40 enum { MAY_NOT_BE_BAG = false };
41
TEST(ResTableTest,shouldLoadSuccessfully)42 TEST(ResTableTest, shouldLoadSuccessfully) {
43 ResTable table;
44 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
45 }
46
TEST(ResTableTest,simpleTypeIsRetrievedCorrectly)47 TEST(ResTableTest, simpleTypeIsRetrievedCorrectly) {
48 ResTable table;
49 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
50
51 Res_value val;
52 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG);
53
54 ASSERT_GE(block, 0);
55 ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
56
57 const ResStringPool* pool = table.getTableStringBlock(block);
58 ASSERT_TRUE(NULL != pool);
59 ASSERT_EQ(String8("test1"), pool->string8ObjectAt(val.data));
60 }
61
TEST(ResTableTest,resourceNameIsResolved)62 TEST(ResTableTest, resourceNameIsResolved) {
63 ResTable table;
64 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
65
66 String16 defPackage("com.android.test.basic");
67 String16 testName("@string/test1");
68 uint32_t resID = table.identifierForName(testName.string(), testName.size(),
69 0, 0,
70 defPackage.string(), defPackage.size());
71 ASSERT_NE(uint32_t(0x00000000), resID);
72 ASSERT_EQ(base::R::string::test1, resID);
73 }
74
TEST(ResTableTest,noParentThemeIsAppliedCorrectly)75 TEST(ResTableTest, noParentThemeIsAppliedCorrectly) {
76 ResTable table;
77 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
78
79 ResTable::Theme theme(table);
80 ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme1));
81
82 Res_value val;
83 uint32_t specFlags = 0;
84 ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);
85 ASSERT_GE(index, 0);
86 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
87 ASSERT_EQ(uint32_t(100), val.data);
88
89 index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);
90 ASSERT_GE(index, 0);
91 ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
92 ASSERT_EQ(base::R::integer::number1, val.data);
93 }
94
TEST(ResTableTest,parentThemeIsAppliedCorrectly)95 TEST(ResTableTest, parentThemeIsAppliedCorrectly) {
96 ResTable table;
97 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
98
99 ResTable::Theme theme(table);
100 ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme2));
101
102 Res_value val;
103 uint32_t specFlags = 0;
104 ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);
105 ASSERT_GE(index, 0);
106 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
107 ASSERT_EQ(uint32_t(300), val.data);
108
109 index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);
110 ASSERT_GE(index, 0);
111 ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
112 ASSERT_EQ(base::R::integer::number1, val.data);
113 }
114
TEST(ResTableTest,libraryThemeIsAppliedCorrectly)115 TEST(ResTableTest, libraryThemeIsAppliedCorrectly) {
116 ResTable table;
117 ASSERT_EQ(NO_ERROR, table.add(lib_arsc, lib_arsc_len));
118
119 ResTable::Theme theme(table);
120 ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme));
121
122 Res_value val;
123 uint32_t specFlags = 0;
124 ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags);
125 ASSERT_GE(index, 0);
126 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
127 ASSERT_EQ(uint32_t(700), val.data);
128 }
129
TEST(ResTableTest,referenceToBagIsNotResolved)130 TEST(ResTableTest, referenceToBagIsNotResolved) {
131 ResTable table;
132 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
133
134 Res_value val;
135 ssize_t block = table.getResource(base::R::integer::number2, &val, MAY_NOT_BE_BAG);
136 ASSERT_GE(block, 0);
137 ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
138 ASSERT_EQ(base::R::array::integerArray1, val.data);
139
140 ssize_t newBlock = table.resolveReference(&val, block);
141 EXPECT_EQ(block, newBlock);
142 EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
143 EXPECT_EQ(base::R::array::integerArray1, val.data);
144 }
145
TEST(ResTableTest,resourcesStillAccessibleAfterParameterChange)146 TEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {
147 ResTable table;
148 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
149
150 Res_value val;
151 ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
152 ASSERT_GE(block, 0);
153 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
154
155 const ResTable::bag_entry* entry;
156 ssize_t count = table.lockBag(base::R::array::integerArray1, &entry);
157 ASSERT_GE(count, 0);
158 table.unlockBag(entry);
159
160 ResTable_config param;
161 memset(¶m, 0, sizeof(param));
162 param.density = 320;
163 table.setParameters(¶m);
164
165 block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
166 ASSERT_GE(block, 0);
167 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
168
169 count = table.lockBag(base::R::array::integerArray1, &entry);
170 ASSERT_GE(count, 0);
171 table.unlockBag(entry);
172 }
173
TEST(ResTableTest,resourceIsOverridenWithBetterConfig)174 TEST(ResTableTest, resourceIsOverridenWithBetterConfig) {
175 ResTable table;
176 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
177
178 Res_value val;
179 ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
180 ASSERT_GE(block, 0);
181 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
182 ASSERT_EQ(uint32_t(200), val.data);
183
184 ResTable_config param;
185 memset(¶m, 0, sizeof(param));
186 param.language[0] = 's';
187 param.language[1] = 'v';
188 param.country[0] = 'S';
189 param.country[1] = 'E';
190 table.setParameters(¶m);
191
192 block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
193 ASSERT_GE(block, 0);
194 ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
195 ASSERT_EQ(uint32_t(400), val.data);
196 }
197
TEST(ResTableTest,emptyTableHasSensibleDefaults)198 TEST(ResTableTest, emptyTableHasSensibleDefaults) {
199 const int32_t assetCookie = 1;
200
201 ResTable table;
202 ASSERT_EQ(NO_ERROR, table.addEmpty(assetCookie));
203
204 // Adding an empty table gives us one table!
205 ASSERT_EQ(uint32_t(1), table.getTableCount());
206
207 // Adding an empty table doesn't mean we get packages.
208 ASSERT_EQ(uint32_t(0), table.getBasePackageCount());
209
210 Res_value val;
211 ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0);
212 }
213
214 }
215