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
24 #include <gtest/gtest.h>
25
26 using namespace android;
27
28 namespace {
29
30 /**
31 * Include a binary resource table. This table
32 * is a base table for an APK split.
33 *
34 * Package: com.android.test.basic
35 */
36 #include "data/basic/basic_arsc.h"
37
38 /**
39 * Include a binary resource table. This table
40 * is a configuration split table for an APK split.
41 *
42 * Package: com.android.test.basic
43 */
44 #include "data/basic/split_de_fr_arsc.h"
45 #include "data/basic/split_hdpi_v4_arsc.h"
46 #include "data/basic/split_xhdpi_v4_arsc.h"
47 #include "data/basic/split_xxhdpi_v4_arsc.h"
48
49 /**
50 * Include a binary resource table. This table
51 * is a feature split table for an APK split.
52 *
53 * Package: com.android.test.basic
54 */
55 #include "data/feature/feature_arsc.h"
56
57 enum { MAY_NOT_BE_BAG = false };
58
makeConfigFrench(ResTable_config * config)59 void makeConfigFrench(ResTable_config* config) {
60 memset(config, 0, sizeof(*config));
61 config->language[0] = 'f';
62 config->language[1] = 'r';
63 }
64
TEST(SplitTest,TestLoadBase)65 TEST(SplitTest, TestLoadBase) {
66 ResTable table;
67 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
68 }
69
TEST(SplitTest,TestGetResourceFromBase)70 TEST(SplitTest, TestGetResourceFromBase) {
71 ResTable_config frenchConfig;
72 makeConfigFrench(&frenchConfig);
73
74 ResTable table;
75 table.setParameters(&frenchConfig);
76
77 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
78
79 ResTable_config expectedConfig;
80 memset(&expectedConfig, 0, sizeof(expectedConfig));
81
82 Res_value val;
83 ResTable_config config;
84 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);
85
86 // The returned block should tell us which string pool to get the value, if it is a string.
87 EXPECT_GE(block, 0);
88
89 // We expect the default resource to be selected since it is the only resource configuration.
90 EXPECT_EQ(0, expectedConfig.compare(config));
91
92 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);
93 }
94
TEST(SplitTest,TestGetResourceFromSplit)95 TEST(SplitTest, TestGetResourceFromSplit) {
96 ResTable_config expectedConfig;
97 makeConfigFrench(&expectedConfig);
98
99 ResTable table;
100 table.setParameters(&expectedConfig);
101
102 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
103 ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));
104
105 Res_value val;
106 ResTable_config config;
107 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);
108
109 EXPECT_GE(block, 0);
110
111 EXPECT_EQ(0, expectedConfig.compare(config));
112
113 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);
114 }
115
TEST(SplitTest,ResourcesFromBaseAndSplitHaveSameNames)116 TEST(SplitTest, ResourcesFromBaseAndSplitHaveSameNames) {
117 ResTable_config expectedConfig;
118 makeConfigFrench(&expectedConfig);
119
120 ResTable table;
121 table.setParameters(&expectedConfig);
122
123 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
124
125 ResTable::resource_name baseName;
126 EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &baseName));
127
128 ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));
129
130 ResTable::resource_name frName;
131 EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &frName));
132
133 EXPECT_EQ(
134 String16(baseName.package, baseName.packageLen),
135 String16(frName.package, frName.packageLen));
136
137 EXPECT_EQ(
138 String16(baseName.type, baseName.typeLen),
139 String16(frName.type, frName.typeLen));
140
141 EXPECT_EQ(
142 String16(baseName.name, baseName.nameLen),
143 String16(frName.name, frName.nameLen));
144 }
145
TEST(SplitTest,TypeEntrySpecFlagsAreUpdated)146 TEST(SplitTest, TypeEntrySpecFlagsAreUpdated) {
147 ResTable_config defaultConfig;
148 memset(&defaultConfig, 0, sizeof(defaultConfig));
149
150 ResTable table;
151 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
152
153 Res_value val;
154 uint32_t specFlags = 0;
155 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &specFlags, NULL);
156 EXPECT_GE(block, 0);
157
158 EXPECT_EQ(static_cast<uint32_t>(0), specFlags);
159
160 ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));
161
162 uint32_t frSpecFlags = 0;
163 block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &frSpecFlags, NULL);
164 EXPECT_GE(block, 0);
165
166 EXPECT_EQ(ResTable_config::CONFIG_LOCALE, frSpecFlags);
167 }
168
TEST(SplitTest,SelectBestDensity)169 TEST(SplitTest, SelectBestDensity) {
170 ResTable_config baseConfig;
171 memset(&baseConfig, 0, sizeof(baseConfig));
172 baseConfig.density = ResTable_config::DENSITY_XHIGH;
173 baseConfig.sdkVersion = 21;
174
175 ResTable table;
176 table.setParameters(&baseConfig);
177 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
178 ASSERT_EQ(NO_ERROR, table.add(split_hdpi_v4_arsc, split_hdpi_v4_arsc_len));
179
180 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "hdpi"));
181
182 ASSERT_EQ(NO_ERROR, table.add(split_xhdpi_v4_arsc, split_xhdpi_v4_arsc_len));
183
184 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xhdpi"));
185
186 ASSERT_EQ(NO_ERROR, table.add(split_xxhdpi_v4_arsc, split_xxhdpi_v4_arsc_len));
187
188 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xhdpi"));
189
190 baseConfig.density = ResTable_config::DENSITY_XXHIGH;
191 table.setParameters(&baseConfig);
192
193 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xxhdpi"));
194 }
195
TEST(SplitFeatureTest,TestNewResourceIsAccessible)196 TEST(SplitFeatureTest, TestNewResourceIsAccessible) {
197 ResTable table;
198 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
199
200 Res_value val;
201 ssize_t block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);
202 EXPECT_LT(block, 0);
203
204 ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));
205
206 block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);
207 EXPECT_GE(block, 0);
208
209 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);
210 }
211
TEST(SplitFeatureTest,TestNewResourceNameHasCorrectName)212 TEST(SplitFeatureTest, TestNewResourceNameHasCorrectName) {
213 ResTable table;
214 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
215
216 ResTable::resource_name name;
217 EXPECT_FALSE(table.getResourceName(base::R::string::test3, false, &name));
218
219 ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));
220
221 ASSERT_TRUE(table.getResourceName(base::R::string::test3, false, &name));
222
223 EXPECT_EQ(String16("com.android.test.basic"),
224 String16(name.package, name.packageLen));
225
226 EXPECT_EQ(String16("string"),
227 String16(name.type, name.typeLen));
228
229 EXPECT_EQ(String16("test3"),
230 String16(name.name, name.nameLen));
231 }
232
TEST(SplitFeatureTest,TestNewResourceIsAccessibleByName)233 TEST(SplitFeatureTest, TestNewResourceIsAccessibleByName) {
234 ResTable table;
235 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
236 ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));
237
238 const String16 name("test3");
239 const String16 type("string");
240 const String16 package("com.android.test.basic");
241 ASSERT_EQ(base::R::string::test3, table.identifierForName(name.string(), name.size(),
242 type.string(), type.size(),
243 package.string(), package.size()));
244 }
245
246 } // namespace
247