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/Log.h"
20 #include "utils/String8.h"
21 #include "utils/Vector.h"
22
23 #include "TestHelpers.h"
24 #include "gtest/gtest.h"
25
26 namespace android {
27
selectBest(const ResTable_config & target,const Vector<ResTable_config> & configs)28 static ResTable_config selectBest(const ResTable_config& target,
29 const Vector<ResTable_config>& configs) {
30 ResTable_config bestConfig;
31 memset(&bestConfig, 0, sizeof(bestConfig));
32 const size_t configCount = configs.size();
33 for (size_t i = 0; i < configCount; i++) {
34 const ResTable_config& thisConfig = configs[i];
35 if (!thisConfig.match(target)) {
36 continue;
37 }
38
39 if (thisConfig.isBetterThan(bestConfig, &target)) {
40 bestConfig = thisConfig;
41 }
42 }
43 return bestConfig;
44 }
45
buildDensityConfig(int density)46 static ResTable_config buildDensityConfig(int density) {
47 ResTable_config config;
48 memset(&config, 0, sizeof(config));
49 config.density = uint16_t(density);
50 config.sdkVersion = 4;
51 return config;
52 }
53
TEST(ConfigTest,shouldSelectBestDensity)54 TEST(ConfigTest, shouldSelectBestDensity) {
55 ResTable_config deviceConfig;
56 memset(&deviceConfig, 0, sizeof(deviceConfig));
57 deviceConfig.density = ResTable_config::DENSITY_XHIGH;
58 deviceConfig.sdkVersion = 21;
59
60 Vector<ResTable_config> configs;
61
62 ResTable_config expectedBest =
63 buildDensityConfig(ResTable_config::DENSITY_HIGH);
64 configs.add(expectedBest);
65 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
66
67 expectedBest = buildDensityConfig(ResTable_config::DENSITY_XXHIGH);
68 configs.add(expectedBest);
69 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
70
71 expectedBest = buildDensityConfig(int(ResTable_config::DENSITY_XXHIGH) - 20);
72 configs.add(expectedBest);
73 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
74
75 configs.add(buildDensityConfig(int(ResTable_config::DENSITY_HIGH) + 20));
76 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
77
78 configs.add(buildDensityConfig(int(ResTable_config::DENSITY_XHIGH) - 1));
79 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
80
81 expectedBest = buildDensityConfig(ResTable_config::DENSITY_XHIGH);
82 configs.add(expectedBest);
83 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
84
85 expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);
86 expectedBest.sdkVersion = 21;
87 configs.add(expectedBest);
88 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
89 }
90
TEST(ConfigTest,shouldSelectBestDensityWhenNoneSpecified)91 TEST(ConfigTest, shouldSelectBestDensityWhenNoneSpecified) {
92 ResTable_config deviceConfig;
93 memset(&deviceConfig, 0, sizeof(deviceConfig));
94 deviceConfig.sdkVersion = 21;
95
96 Vector<ResTable_config> configs;
97 configs.add(buildDensityConfig(ResTable_config::DENSITY_HIGH));
98
99 ResTable_config expectedBest =
100 buildDensityConfig(ResTable_config::DENSITY_MEDIUM);
101 configs.add(expectedBest);
102 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
103
104 expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);
105 configs.add(expectedBest);
106 ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
107 }
108
TEST(ConfigTest,shouldMatchRoundQualifier)109 TEST(ConfigTest, shouldMatchRoundQualifier) {
110 ResTable_config deviceConfig;
111 memset(&deviceConfig, 0, sizeof(deviceConfig));
112
113 ResTable_config roundConfig;
114 memset(&roundConfig, 0, sizeof(roundConfig));
115 roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
116
117 EXPECT_FALSE(roundConfig.match(deviceConfig));
118
119 deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
120
121 EXPECT_TRUE(roundConfig.match(deviceConfig));
122
123 deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;
124
125 EXPECT_FALSE(roundConfig.match(deviceConfig));
126
127 ResTable_config notRoundConfig;
128 memset(¬RoundConfig, 0, sizeof(notRoundConfig));
129 notRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;
130
131 EXPECT_TRUE(notRoundConfig.match(deviceConfig));
132 }
133
TEST(ConfigTest,RoundQualifierShouldHaveStableSortOrder)134 TEST(ConfigTest, RoundQualifierShouldHaveStableSortOrder) {
135 ResTable_config defaultConfig;
136 memset(&defaultConfig, 0, sizeof(defaultConfig));
137
138 ResTable_config longConfig = defaultConfig;
139 longConfig.screenLayout = ResTable_config::SCREENLONG_YES;
140
141 ResTable_config longRoundConfig = longConfig;
142 longRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
143
144 ResTable_config longRoundPortConfig = longConfig;
145 longRoundPortConfig.orientation = ResTable_config::ORIENTATION_PORT;
146
147 EXPECT_TRUE(longConfig.compare(longRoundConfig) < 0);
148 EXPECT_TRUE(longConfig.compareLogical(longRoundConfig) < 0);
149 EXPECT_TRUE(longRoundConfig.compare(longConfig) > 0);
150 EXPECT_TRUE(longRoundConfig.compareLogical(longConfig) > 0);
151
152 EXPECT_TRUE(longRoundConfig.compare(longRoundPortConfig) < 0);
153 EXPECT_TRUE(longRoundConfig.compareLogical(longRoundPortConfig) < 0);
154 EXPECT_TRUE(longRoundPortConfig.compare(longRoundConfig) > 0);
155 EXPECT_TRUE(longRoundPortConfig.compareLogical(longRoundConfig) > 0);
156 }
157
TEST(ConfigTest,ScreenShapeHasCorrectDiff)158 TEST(ConfigTest, ScreenShapeHasCorrectDiff) {
159 ResTable_config defaultConfig;
160 memset(&defaultConfig, 0, sizeof(defaultConfig));
161
162 ResTable_config roundConfig = defaultConfig;
163 roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
164
165 EXPECT_EQ(defaultConfig.diff(roundConfig),
166 ResTable_config::CONFIG_SCREEN_ROUND);
167 }
168
TEST(ConfigTest,RoundIsMoreSpecific)169 TEST(ConfigTest, RoundIsMoreSpecific) {
170 ResTable_config deviceConfig;
171 memset(&deviceConfig, 0, sizeof(deviceConfig));
172 deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
173 deviceConfig.screenLayout = ResTable_config::SCREENLONG_YES;
174
175 ResTable_config targetConfigA;
176 memset(&targetConfigA, 0, sizeof(targetConfigA));
177
178 ResTable_config targetConfigB = targetConfigA;
179 targetConfigB.screenLayout = ResTable_config::SCREENLONG_YES;
180
181 ResTable_config targetConfigC = targetConfigB;
182 targetConfigC.screenLayout2 = ResTable_config::SCREENROUND_YES;
183
184 EXPECT_TRUE(targetConfigB.isBetterThan(targetConfigA, &deviceConfig));
185 EXPECT_TRUE(targetConfigC.isBetterThan(targetConfigB, &deviceConfig));
186 }
187
TEST(ConfigTest,ScreenIsWideGamut)188 TEST(ConfigTest, ScreenIsWideGamut) {
189 ResTable_config defaultConfig;
190 memset(&defaultConfig, 0, sizeof(defaultConfig));
191
192 ResTable_config wideGamutConfig = defaultConfig;
193 wideGamutConfig.colorMode = ResTable_config::WIDE_COLOR_GAMUT_YES;
194
195 EXPECT_EQ(defaultConfig.diff(wideGamutConfig), ResTable_config::CONFIG_COLOR_MODE);
196 }
197
TEST(ConfigTest,ScreenIsHdr)198 TEST(ConfigTest, ScreenIsHdr) {
199 ResTable_config defaultConfig;
200 memset(&defaultConfig, 0, sizeof(defaultConfig));
201
202 ResTable_config hdrConfig = defaultConfig;
203 hdrConfig.colorMode = ResTable_config::HDR_YES;
204
205 EXPECT_EQ(defaultConfig.diff(hdrConfig), ResTable_config::CONFIG_COLOR_MODE);
206 }
207
TEST(ConfigTest,GrammaticalGender)208 TEST(ConfigTest, GrammaticalGender) {
209 ResTable_config defaultConfig = {};
210 ResTable_config masculine = {};
211 masculine.grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_MASCULINE;
212
213 EXPECT_EQ(defaultConfig.diff(masculine), ResTable_config::CONFIG_GRAMMATICAL_GENDER);
214
215 ResTable_config feminine = {};
216 feminine.grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_FEMININE;
217
218 EXPECT_EQ(defaultConfig.diff(feminine), ResTable_config::CONFIG_GRAMMATICAL_GENDER);
219 EXPECT_EQ(masculine.diff(feminine), ResTable_config::CONFIG_GRAMMATICAL_GENDER);
220 }
221
222 } // namespace android.
223