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(&notRoundConfig, 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