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
26namespace android {
27
28static 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
46static 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
54TEST(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
88TEST(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
106TEST(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
131TEST(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
155TEST(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
166TEST(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
185TEST(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
195TEST(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