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   expectedBest = buildDensityConfig(ResTable_config::DENSITY_XHIGH);
79   configs.add(expectedBest);
80   ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
81 
82   expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);
83   expectedBest.sdkVersion = 21;
84   configs.add(expectedBest);
85   ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
86 }
87 
TEST(ConfigTest,shouldSelectBestDensityWhenNoneSpecified)88 TEST(ConfigTest, shouldSelectBestDensityWhenNoneSpecified) {
89   ResTable_config deviceConfig;
90   memset(&deviceConfig, 0, sizeof(deviceConfig));
91   deviceConfig.sdkVersion = 21;
92 
93   Vector<ResTable_config> configs;
94   configs.add(buildDensityConfig(ResTable_config::DENSITY_HIGH));
95 
96   ResTable_config expectedBest =
97       buildDensityConfig(ResTable_config::DENSITY_MEDIUM);
98   configs.add(expectedBest);
99   ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
100 
101   expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);
102   configs.add(expectedBest);
103   ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));
104 }
105 
TEST(ConfigTest,shouldMatchRoundQualifier)106 TEST(ConfigTest, shouldMatchRoundQualifier) {
107   ResTable_config deviceConfig;
108   memset(&deviceConfig, 0, sizeof(deviceConfig));
109 
110   ResTable_config roundConfig;
111   memset(&roundConfig, 0, sizeof(roundConfig));
112   roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
113 
114   EXPECT_FALSE(roundConfig.match(deviceConfig));
115 
116   deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
117 
118   EXPECT_TRUE(roundConfig.match(deviceConfig));
119 
120   deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;
121 
122   EXPECT_FALSE(roundConfig.match(deviceConfig));
123 
124   ResTable_config notRoundConfig;
125   memset(&notRoundConfig, 0, sizeof(notRoundConfig));
126   notRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;
127 
128   EXPECT_TRUE(notRoundConfig.match(deviceConfig));
129 }
130 
TEST(ConfigTest,RoundQualifierShouldHaveStableSortOrder)131 TEST(ConfigTest, RoundQualifierShouldHaveStableSortOrder) {
132   ResTable_config defaultConfig;
133   memset(&defaultConfig, 0, sizeof(defaultConfig));
134 
135   ResTable_config longConfig = defaultConfig;
136   longConfig.screenLayout = ResTable_config::SCREENLONG_YES;
137 
138   ResTable_config longRoundConfig = longConfig;
139   longRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
140 
141   ResTable_config longRoundPortConfig = longConfig;
142   longRoundPortConfig.orientation = ResTable_config::ORIENTATION_PORT;
143 
144   EXPECT_TRUE(longConfig.compare(longRoundConfig) < 0);
145   EXPECT_TRUE(longConfig.compareLogical(longRoundConfig) < 0);
146   EXPECT_TRUE(longRoundConfig.compare(longConfig) > 0);
147   EXPECT_TRUE(longRoundConfig.compareLogical(longConfig) > 0);
148 
149   EXPECT_TRUE(longRoundConfig.compare(longRoundPortConfig) < 0);
150   EXPECT_TRUE(longRoundConfig.compareLogical(longRoundPortConfig) < 0);
151   EXPECT_TRUE(longRoundPortConfig.compare(longRoundConfig) > 0);
152   EXPECT_TRUE(longRoundPortConfig.compareLogical(longRoundConfig) > 0);
153 }
154 
TEST(ConfigTest,ScreenShapeHasCorrectDiff)155 TEST(ConfigTest, ScreenShapeHasCorrectDiff) {
156   ResTable_config defaultConfig;
157   memset(&defaultConfig, 0, sizeof(defaultConfig));
158 
159   ResTable_config roundConfig = defaultConfig;
160   roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
161 
162   EXPECT_EQ(defaultConfig.diff(roundConfig),
163             ResTable_config::CONFIG_SCREEN_ROUND);
164 }
165 
TEST(ConfigTest,RoundIsMoreSpecific)166 TEST(ConfigTest, RoundIsMoreSpecific) {
167   ResTable_config deviceConfig;
168   memset(&deviceConfig, 0, sizeof(deviceConfig));
169   deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;
170   deviceConfig.screenLayout = ResTable_config::SCREENLONG_YES;
171 
172   ResTable_config targetConfigA;
173   memset(&targetConfigA, 0, sizeof(targetConfigA));
174 
175   ResTable_config targetConfigB = targetConfigA;
176   targetConfigB.screenLayout = ResTable_config::SCREENLONG_YES;
177 
178   ResTable_config targetConfigC = targetConfigB;
179   targetConfigC.screenLayout2 = ResTable_config::SCREENROUND_YES;
180 
181   EXPECT_TRUE(targetConfigB.isBetterThan(targetConfigA, &deviceConfig));
182   EXPECT_TRUE(targetConfigC.isBetterThan(targetConfigB, &deviceConfig));
183 }
184 
TEST(ConfigTest,ScreenIsWideGamut)185 TEST(ConfigTest, ScreenIsWideGamut) {
186   ResTable_config defaultConfig;
187   memset(&defaultConfig, 0, sizeof(defaultConfig));
188 
189   ResTable_config wideGamutConfig = defaultConfig;
190   wideGamutConfig.colorMode = ResTable_config::WIDE_COLOR_GAMUT_YES;
191 
192   EXPECT_EQ(defaultConfig.diff(wideGamutConfig), ResTable_config::CONFIG_COLOR_MODE);
193 }
194 
TEST(ConfigTest,ScreenIsHdr)195 TEST(ConfigTest, ScreenIsHdr) {
196   ResTable_config defaultConfig;
197   memset(&defaultConfig, 0, sizeof(defaultConfig));
198 
199   ResTable_config hdrConfig = defaultConfig;
200   hdrConfig.colorMode = ResTable_config::HDR_YES;
201 
202   EXPECT_EQ(defaultConfig.diff(hdrConfig), ResTable_config::CONFIG_COLOR_MODE);
203 }
204 
205 }  // namespace android.
206