1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include "androidfw/ConfigDescription.h"
18*d57664e9SAndroid Build Coastguard Worker #include "androidfw/Locale.h"
19*d57664e9SAndroid Build Coastguard Worker #include "androidfw/ResourceTypes.h"
20*d57664e9SAndroid Build Coastguard Worker #include "androidfw/StringPiece.h"
21*d57664e9SAndroid Build Coastguard Worker #include "androidfw/Util.h"
22*d57664e9SAndroid Build Coastguard Worker
23*d57664e9SAndroid Build Coastguard Worker #include <string>
24*d57664e9SAndroid Build Coastguard Worker #include <string_view>
25*d57664e9SAndroid Build Coastguard Worker #include <vector>
26*d57664e9SAndroid Build Coastguard Worker
27*d57664e9SAndroid Build Coastguard Worker namespace android {
28*d57664e9SAndroid Build Coastguard Worker
29*d57664e9SAndroid Build Coastguard Worker static const char* kWildcardName = "any";
30*d57664e9SAndroid Build Coastguard Worker
DefaultConfig()31*d57664e9SAndroid Build Coastguard Worker const ConfigDescription& ConfigDescription::DefaultConfig() {
32*d57664e9SAndroid Build Coastguard Worker static ConfigDescription config = {};
33*d57664e9SAndroid Build Coastguard Worker return config;
34*d57664e9SAndroid Build Coastguard Worker }
35*d57664e9SAndroid Build Coastguard Worker
parseMcc(const char * name,ResTable_config * out)36*d57664e9SAndroid Build Coastguard Worker static bool parseMcc(const char* name, ResTable_config* out) {
37*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
38*d57664e9SAndroid Build Coastguard Worker if (out) out->mcc = 0;
39*d57664e9SAndroid Build Coastguard Worker return true;
40*d57664e9SAndroid Build Coastguard Worker }
41*d57664e9SAndroid Build Coastguard Worker const char* c = name;
42*d57664e9SAndroid Build Coastguard Worker if (*c != 'm') return false;
43*d57664e9SAndroid Build Coastguard Worker c++;
44*d57664e9SAndroid Build Coastguard Worker if (*c != 'c') return false;
45*d57664e9SAndroid Build Coastguard Worker c++;
46*d57664e9SAndroid Build Coastguard Worker if (*c != 'c') return false;
47*d57664e9SAndroid Build Coastguard Worker c++;
48*d57664e9SAndroid Build Coastguard Worker
49*d57664e9SAndroid Build Coastguard Worker const char* val = c;
50*d57664e9SAndroid Build Coastguard Worker
51*d57664e9SAndroid Build Coastguard Worker while (*c >= '0' && *c <= '9') {
52*d57664e9SAndroid Build Coastguard Worker c++;
53*d57664e9SAndroid Build Coastguard Worker }
54*d57664e9SAndroid Build Coastguard Worker if (*c != 0) return false;
55*d57664e9SAndroid Build Coastguard Worker if (c - val != 3) return false;
56*d57664e9SAndroid Build Coastguard Worker
57*d57664e9SAndroid Build Coastguard Worker int d = atoi(val);
58*d57664e9SAndroid Build Coastguard Worker if (d != 0) {
59*d57664e9SAndroid Build Coastguard Worker if (out) out->mcc = d;
60*d57664e9SAndroid Build Coastguard Worker return true;
61*d57664e9SAndroid Build Coastguard Worker }
62*d57664e9SAndroid Build Coastguard Worker
63*d57664e9SAndroid Build Coastguard Worker return false;
64*d57664e9SAndroid Build Coastguard Worker }
65*d57664e9SAndroid Build Coastguard Worker
parseMnc(const char * name,ResTable_config * out)66*d57664e9SAndroid Build Coastguard Worker static bool parseMnc(const char* name, ResTable_config* out) {
67*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
68*d57664e9SAndroid Build Coastguard Worker if (out) out->mnc = 0;
69*d57664e9SAndroid Build Coastguard Worker return true;
70*d57664e9SAndroid Build Coastguard Worker }
71*d57664e9SAndroid Build Coastguard Worker const char* c = name;
72*d57664e9SAndroid Build Coastguard Worker if (*c != 'm') return false;
73*d57664e9SAndroid Build Coastguard Worker c++;
74*d57664e9SAndroid Build Coastguard Worker if (*c != 'n') return false;
75*d57664e9SAndroid Build Coastguard Worker c++;
76*d57664e9SAndroid Build Coastguard Worker if (*c != 'c') return false;
77*d57664e9SAndroid Build Coastguard Worker c++;
78*d57664e9SAndroid Build Coastguard Worker
79*d57664e9SAndroid Build Coastguard Worker const char* val = c;
80*d57664e9SAndroid Build Coastguard Worker
81*d57664e9SAndroid Build Coastguard Worker while (*c >= '0' && *c <= '9') {
82*d57664e9SAndroid Build Coastguard Worker c++;
83*d57664e9SAndroid Build Coastguard Worker }
84*d57664e9SAndroid Build Coastguard Worker if (*c != 0) return false;
85*d57664e9SAndroid Build Coastguard Worker if (c - val == 0 || c - val > 3) return false;
86*d57664e9SAndroid Build Coastguard Worker
87*d57664e9SAndroid Build Coastguard Worker if (out) {
88*d57664e9SAndroid Build Coastguard Worker out->mnc = atoi(val);
89*d57664e9SAndroid Build Coastguard Worker if (out->mnc == 0) {
90*d57664e9SAndroid Build Coastguard Worker out->mnc = ACONFIGURATION_MNC_ZERO;
91*d57664e9SAndroid Build Coastguard Worker }
92*d57664e9SAndroid Build Coastguard Worker }
93*d57664e9SAndroid Build Coastguard Worker
94*d57664e9SAndroid Build Coastguard Worker return true;
95*d57664e9SAndroid Build Coastguard Worker }
96*d57664e9SAndroid Build Coastguard Worker
parseGrammaticalInflection(const std::string & name,ResTable_config * out)97*d57664e9SAndroid Build Coastguard Worker static bool parseGrammaticalInflection(const std::string& name, ResTable_config* out) {
98*d57664e9SAndroid Build Coastguard Worker using namespace std::literals;
99*d57664e9SAndroid Build Coastguard Worker if (name == "feminine"sv) {
100*d57664e9SAndroid Build Coastguard Worker if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_FEMININE;
101*d57664e9SAndroid Build Coastguard Worker return true;
102*d57664e9SAndroid Build Coastguard Worker }
103*d57664e9SAndroid Build Coastguard Worker if (name == "masculine"sv) {
104*d57664e9SAndroid Build Coastguard Worker if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_MASCULINE;
105*d57664e9SAndroid Build Coastguard Worker return true;
106*d57664e9SAndroid Build Coastguard Worker }
107*d57664e9SAndroid Build Coastguard Worker if (name == "neuter"sv) {
108*d57664e9SAndroid Build Coastguard Worker if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_NEUTER;
109*d57664e9SAndroid Build Coastguard Worker return true;
110*d57664e9SAndroid Build Coastguard Worker }
111*d57664e9SAndroid Build Coastguard Worker return false;
112*d57664e9SAndroid Build Coastguard Worker }
113*d57664e9SAndroid Build Coastguard Worker
parseLayoutDirection(const char * name,ResTable_config * out)114*d57664e9SAndroid Build Coastguard Worker static bool parseLayoutDirection(const char* name, ResTable_config* out) {
115*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
116*d57664e9SAndroid Build Coastguard Worker if (out)
117*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
118*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
119*d57664e9SAndroid Build Coastguard Worker ResTable_config::LAYOUTDIR_ANY;
120*d57664e9SAndroid Build Coastguard Worker return true;
121*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "ldltr") == 0) {
122*d57664e9SAndroid Build Coastguard Worker if (out)
123*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
124*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
125*d57664e9SAndroid Build Coastguard Worker ResTable_config::LAYOUTDIR_LTR;
126*d57664e9SAndroid Build Coastguard Worker return true;
127*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "ldrtl") == 0) {
128*d57664e9SAndroid Build Coastguard Worker if (out)
129*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
130*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
131*d57664e9SAndroid Build Coastguard Worker ResTable_config::LAYOUTDIR_RTL;
132*d57664e9SAndroid Build Coastguard Worker return true;
133*d57664e9SAndroid Build Coastguard Worker }
134*d57664e9SAndroid Build Coastguard Worker
135*d57664e9SAndroid Build Coastguard Worker return false;
136*d57664e9SAndroid Build Coastguard Worker }
137*d57664e9SAndroid Build Coastguard Worker
parseScreenLayoutSize(const char * name,ResTable_config * out)138*d57664e9SAndroid Build Coastguard Worker static bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
139*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
140*d57664e9SAndroid Build Coastguard Worker if (out)
141*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
142*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
143*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENSIZE_ANY;
144*d57664e9SAndroid Build Coastguard Worker return true;
145*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "small") == 0) {
146*d57664e9SAndroid Build Coastguard Worker if (out)
147*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
148*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
149*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENSIZE_SMALL;
150*d57664e9SAndroid Build Coastguard Worker return true;
151*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "normal") == 0) {
152*d57664e9SAndroid Build Coastguard Worker if (out)
153*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
154*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
155*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENSIZE_NORMAL;
156*d57664e9SAndroid Build Coastguard Worker return true;
157*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "large") == 0) {
158*d57664e9SAndroid Build Coastguard Worker if (out)
159*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
160*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
161*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENSIZE_LARGE;
162*d57664e9SAndroid Build Coastguard Worker return true;
163*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "xlarge") == 0) {
164*d57664e9SAndroid Build Coastguard Worker if (out)
165*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
166*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
167*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENSIZE_XLARGE;
168*d57664e9SAndroid Build Coastguard Worker return true;
169*d57664e9SAndroid Build Coastguard Worker }
170*d57664e9SAndroid Build Coastguard Worker
171*d57664e9SAndroid Build Coastguard Worker return false;
172*d57664e9SAndroid Build Coastguard Worker }
173*d57664e9SAndroid Build Coastguard Worker
parseScreenLayoutLong(const char * name,ResTable_config * out)174*d57664e9SAndroid Build Coastguard Worker static bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
175*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
176*d57664e9SAndroid Build Coastguard Worker if (out)
177*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
178*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
179*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENLONG_ANY;
180*d57664e9SAndroid Build Coastguard Worker return true;
181*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "long") == 0) {
182*d57664e9SAndroid Build Coastguard Worker if (out)
183*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
184*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
185*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENLONG_YES;
186*d57664e9SAndroid Build Coastguard Worker return true;
187*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "notlong") == 0) {
188*d57664e9SAndroid Build Coastguard Worker if (out)
189*d57664e9SAndroid Build Coastguard Worker out->screenLayout =
190*d57664e9SAndroid Build Coastguard Worker (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
191*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENLONG_NO;
192*d57664e9SAndroid Build Coastguard Worker return true;
193*d57664e9SAndroid Build Coastguard Worker }
194*d57664e9SAndroid Build Coastguard Worker
195*d57664e9SAndroid Build Coastguard Worker return false;
196*d57664e9SAndroid Build Coastguard Worker }
197*d57664e9SAndroid Build Coastguard Worker
parseScreenRound(const char * name,ResTable_config * out)198*d57664e9SAndroid Build Coastguard Worker static bool parseScreenRound(const char* name, ResTable_config* out) {
199*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
200*d57664e9SAndroid Build Coastguard Worker if (out)
201*d57664e9SAndroid Build Coastguard Worker out->screenLayout2 =
202*d57664e9SAndroid Build Coastguard Worker (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
203*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENROUND_ANY;
204*d57664e9SAndroid Build Coastguard Worker return true;
205*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "round") == 0) {
206*d57664e9SAndroid Build Coastguard Worker if (out)
207*d57664e9SAndroid Build Coastguard Worker out->screenLayout2 =
208*d57664e9SAndroid Build Coastguard Worker (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
209*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENROUND_YES;
210*d57664e9SAndroid Build Coastguard Worker return true;
211*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "notround") == 0) {
212*d57664e9SAndroid Build Coastguard Worker if (out)
213*d57664e9SAndroid Build Coastguard Worker out->screenLayout2 =
214*d57664e9SAndroid Build Coastguard Worker (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
215*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENROUND_NO;
216*d57664e9SAndroid Build Coastguard Worker return true;
217*d57664e9SAndroid Build Coastguard Worker }
218*d57664e9SAndroid Build Coastguard Worker return false;
219*d57664e9SAndroid Build Coastguard Worker }
220*d57664e9SAndroid Build Coastguard Worker
parseWideColorGamut(const char * name,ResTable_config * out)221*d57664e9SAndroid Build Coastguard Worker static bool parseWideColorGamut(const char* name, ResTable_config* out) {
222*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
223*d57664e9SAndroid Build Coastguard Worker if (out)
224*d57664e9SAndroid Build Coastguard Worker out->colorMode =
225*d57664e9SAndroid Build Coastguard Worker (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
226*d57664e9SAndroid Build Coastguard Worker ResTable_config::WIDE_COLOR_GAMUT_ANY;
227*d57664e9SAndroid Build Coastguard Worker return true;
228*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "widecg") == 0) {
229*d57664e9SAndroid Build Coastguard Worker if (out)
230*d57664e9SAndroid Build Coastguard Worker out->colorMode =
231*d57664e9SAndroid Build Coastguard Worker (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
232*d57664e9SAndroid Build Coastguard Worker ResTable_config::WIDE_COLOR_GAMUT_YES;
233*d57664e9SAndroid Build Coastguard Worker return true;
234*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "nowidecg") == 0) {
235*d57664e9SAndroid Build Coastguard Worker if (out)
236*d57664e9SAndroid Build Coastguard Worker out->colorMode =
237*d57664e9SAndroid Build Coastguard Worker (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
238*d57664e9SAndroid Build Coastguard Worker ResTable_config::WIDE_COLOR_GAMUT_NO;
239*d57664e9SAndroid Build Coastguard Worker return true;
240*d57664e9SAndroid Build Coastguard Worker }
241*d57664e9SAndroid Build Coastguard Worker return false;
242*d57664e9SAndroid Build Coastguard Worker }
243*d57664e9SAndroid Build Coastguard Worker
parseHdr(const char * name,ResTable_config * out)244*d57664e9SAndroid Build Coastguard Worker static bool parseHdr(const char* name, ResTable_config* out) {
245*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
246*d57664e9SAndroid Build Coastguard Worker if (out)
247*d57664e9SAndroid Build Coastguard Worker out->colorMode =
248*d57664e9SAndroid Build Coastguard Worker (out->colorMode & ~ResTable_config::MASK_HDR) |
249*d57664e9SAndroid Build Coastguard Worker ResTable_config::HDR_ANY;
250*d57664e9SAndroid Build Coastguard Worker return true;
251*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "highdr") == 0) {
252*d57664e9SAndroid Build Coastguard Worker if (out)
253*d57664e9SAndroid Build Coastguard Worker out->colorMode =
254*d57664e9SAndroid Build Coastguard Worker (out->colorMode & ~ResTable_config::MASK_HDR) |
255*d57664e9SAndroid Build Coastguard Worker ResTable_config::HDR_YES;
256*d57664e9SAndroid Build Coastguard Worker return true;
257*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "lowdr") == 0) {
258*d57664e9SAndroid Build Coastguard Worker if (out)
259*d57664e9SAndroid Build Coastguard Worker out->colorMode =
260*d57664e9SAndroid Build Coastguard Worker (out->colorMode & ~ResTable_config::MASK_HDR) |
261*d57664e9SAndroid Build Coastguard Worker ResTable_config::HDR_NO;
262*d57664e9SAndroid Build Coastguard Worker return true;
263*d57664e9SAndroid Build Coastguard Worker }
264*d57664e9SAndroid Build Coastguard Worker return false;
265*d57664e9SAndroid Build Coastguard Worker }
266*d57664e9SAndroid Build Coastguard Worker
parseOrientation(const char * name,ResTable_config * out)267*d57664e9SAndroid Build Coastguard Worker static bool parseOrientation(const char* name, ResTable_config* out) {
268*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
269*d57664e9SAndroid Build Coastguard Worker if (out) out->orientation = out->ORIENTATION_ANY;
270*d57664e9SAndroid Build Coastguard Worker return true;
271*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "port") == 0) {
272*d57664e9SAndroid Build Coastguard Worker if (out) out->orientation = out->ORIENTATION_PORT;
273*d57664e9SAndroid Build Coastguard Worker return true;
274*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "land") == 0) {
275*d57664e9SAndroid Build Coastguard Worker if (out) out->orientation = out->ORIENTATION_LAND;
276*d57664e9SAndroid Build Coastguard Worker return true;
277*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "square") == 0) {
278*d57664e9SAndroid Build Coastguard Worker if (out) out->orientation = out->ORIENTATION_SQUARE;
279*d57664e9SAndroid Build Coastguard Worker return true;
280*d57664e9SAndroid Build Coastguard Worker }
281*d57664e9SAndroid Build Coastguard Worker
282*d57664e9SAndroid Build Coastguard Worker return false;
283*d57664e9SAndroid Build Coastguard Worker }
284*d57664e9SAndroid Build Coastguard Worker
parseUiModeType(const char * name,ResTable_config * out)285*d57664e9SAndroid Build Coastguard Worker static bool parseUiModeType(const char* name, ResTable_config* out) {
286*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
287*d57664e9SAndroid Build Coastguard Worker if (out)
288*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
289*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_ANY;
290*d57664e9SAndroid Build Coastguard Worker return true;
291*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "desk") == 0) {
292*d57664e9SAndroid Build Coastguard Worker if (out)
293*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
294*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_DESK;
295*d57664e9SAndroid Build Coastguard Worker return true;
296*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "car") == 0) {
297*d57664e9SAndroid Build Coastguard Worker if (out)
298*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
299*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_CAR;
300*d57664e9SAndroid Build Coastguard Worker return true;
301*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "television") == 0) {
302*d57664e9SAndroid Build Coastguard Worker if (out)
303*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
304*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_TELEVISION;
305*d57664e9SAndroid Build Coastguard Worker return true;
306*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "appliance") == 0) {
307*d57664e9SAndroid Build Coastguard Worker if (out)
308*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
309*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_APPLIANCE;
310*d57664e9SAndroid Build Coastguard Worker return true;
311*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "watch") == 0) {
312*d57664e9SAndroid Build Coastguard Worker if (out)
313*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
314*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_WATCH;
315*d57664e9SAndroid Build Coastguard Worker return true;
316*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "vrheadset") == 0) {
317*d57664e9SAndroid Build Coastguard Worker if (out)
318*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
319*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_VR_HEADSET;
320*d57664e9SAndroid Build Coastguard Worker return true;
321*d57664e9SAndroid Build Coastguard Worker }
322*d57664e9SAndroid Build Coastguard Worker
323*d57664e9SAndroid Build Coastguard Worker return false;
324*d57664e9SAndroid Build Coastguard Worker }
325*d57664e9SAndroid Build Coastguard Worker
parseUiModeNight(const char * name,ResTable_config * out)326*d57664e9SAndroid Build Coastguard Worker static bool parseUiModeNight(const char* name, ResTable_config* out) {
327*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
328*d57664e9SAndroid Build Coastguard Worker if (out)
329*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
330*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_NIGHT_ANY;
331*d57664e9SAndroid Build Coastguard Worker return true;
332*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "night") == 0) {
333*d57664e9SAndroid Build Coastguard Worker if (out)
334*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
335*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_NIGHT_YES;
336*d57664e9SAndroid Build Coastguard Worker return true;
337*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "notnight") == 0) {
338*d57664e9SAndroid Build Coastguard Worker if (out)
339*d57664e9SAndroid Build Coastguard Worker out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
340*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_NIGHT_NO;
341*d57664e9SAndroid Build Coastguard Worker return true;
342*d57664e9SAndroid Build Coastguard Worker }
343*d57664e9SAndroid Build Coastguard Worker
344*d57664e9SAndroid Build Coastguard Worker return false;
345*d57664e9SAndroid Build Coastguard Worker }
346*d57664e9SAndroid Build Coastguard Worker
parseDensity(const char * name,ResTable_config * out)347*d57664e9SAndroid Build Coastguard Worker static bool parseDensity(const char* name, ResTable_config* out) {
348*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
349*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_DEFAULT;
350*d57664e9SAndroid Build Coastguard Worker return true;
351*d57664e9SAndroid Build Coastguard Worker }
352*d57664e9SAndroid Build Coastguard Worker
353*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "anydpi") == 0) {
354*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_ANY;
355*d57664e9SAndroid Build Coastguard Worker return true;
356*d57664e9SAndroid Build Coastguard Worker }
357*d57664e9SAndroid Build Coastguard Worker
358*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "nodpi") == 0) {
359*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_NONE;
360*d57664e9SAndroid Build Coastguard Worker return true;
361*d57664e9SAndroid Build Coastguard Worker }
362*d57664e9SAndroid Build Coastguard Worker
363*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "ldpi") == 0) {
364*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_LOW;
365*d57664e9SAndroid Build Coastguard Worker return true;
366*d57664e9SAndroid Build Coastguard Worker }
367*d57664e9SAndroid Build Coastguard Worker
368*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "mdpi") == 0) {
369*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_MEDIUM;
370*d57664e9SAndroid Build Coastguard Worker return true;
371*d57664e9SAndroid Build Coastguard Worker }
372*d57664e9SAndroid Build Coastguard Worker
373*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "tvdpi") == 0) {
374*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_TV;
375*d57664e9SAndroid Build Coastguard Worker return true;
376*d57664e9SAndroid Build Coastguard Worker }
377*d57664e9SAndroid Build Coastguard Worker
378*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "hdpi") == 0) {
379*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_HIGH;
380*d57664e9SAndroid Build Coastguard Worker return true;
381*d57664e9SAndroid Build Coastguard Worker }
382*d57664e9SAndroid Build Coastguard Worker
383*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "xhdpi") == 0) {
384*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_XHIGH;
385*d57664e9SAndroid Build Coastguard Worker return true;
386*d57664e9SAndroid Build Coastguard Worker }
387*d57664e9SAndroid Build Coastguard Worker
388*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "xxhdpi") == 0) {
389*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_XXHIGH;
390*d57664e9SAndroid Build Coastguard Worker return true;
391*d57664e9SAndroid Build Coastguard Worker }
392*d57664e9SAndroid Build Coastguard Worker
393*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, "xxxhdpi") == 0) {
394*d57664e9SAndroid Build Coastguard Worker if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
395*d57664e9SAndroid Build Coastguard Worker return true;
396*d57664e9SAndroid Build Coastguard Worker }
397*d57664e9SAndroid Build Coastguard Worker
398*d57664e9SAndroid Build Coastguard Worker char* c = (char*)name;
399*d57664e9SAndroid Build Coastguard Worker while (*c >= '0' && *c <= '9') {
400*d57664e9SAndroid Build Coastguard Worker c++;
401*d57664e9SAndroid Build Coastguard Worker }
402*d57664e9SAndroid Build Coastguard Worker
403*d57664e9SAndroid Build Coastguard Worker // check that we have 'dpi' after the last digit.
404*d57664e9SAndroid Build Coastguard Worker if (toupper(c[0]) != 'D' || toupper(c[1]) != 'P' || toupper(c[2]) != 'I' ||
405*d57664e9SAndroid Build Coastguard Worker c[3] != 0) {
406*d57664e9SAndroid Build Coastguard Worker return false;
407*d57664e9SAndroid Build Coastguard Worker }
408*d57664e9SAndroid Build Coastguard Worker
409*d57664e9SAndroid Build Coastguard Worker // temporarily replace the first letter with \0 to
410*d57664e9SAndroid Build Coastguard Worker // use atoi.
411*d57664e9SAndroid Build Coastguard Worker char tmp = c[0];
412*d57664e9SAndroid Build Coastguard Worker c[0] = '\0';
413*d57664e9SAndroid Build Coastguard Worker
414*d57664e9SAndroid Build Coastguard Worker int d = atoi(name);
415*d57664e9SAndroid Build Coastguard Worker c[0] = tmp;
416*d57664e9SAndroid Build Coastguard Worker
417*d57664e9SAndroid Build Coastguard Worker if (d != 0) {
418*d57664e9SAndroid Build Coastguard Worker if (out) out->density = d;
419*d57664e9SAndroid Build Coastguard Worker return true;
420*d57664e9SAndroid Build Coastguard Worker }
421*d57664e9SAndroid Build Coastguard Worker
422*d57664e9SAndroid Build Coastguard Worker return false;
423*d57664e9SAndroid Build Coastguard Worker }
424*d57664e9SAndroid Build Coastguard Worker
parseTouchscreen(const char * name,ResTable_config * out)425*d57664e9SAndroid Build Coastguard Worker static bool parseTouchscreen(const char* name, ResTable_config* out) {
426*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
427*d57664e9SAndroid Build Coastguard Worker if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
428*d57664e9SAndroid Build Coastguard Worker return true;
429*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "notouch") == 0) {
430*d57664e9SAndroid Build Coastguard Worker if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
431*d57664e9SAndroid Build Coastguard Worker return true;
432*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "stylus") == 0) {
433*d57664e9SAndroid Build Coastguard Worker if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
434*d57664e9SAndroid Build Coastguard Worker return true;
435*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "finger") == 0) {
436*d57664e9SAndroid Build Coastguard Worker if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
437*d57664e9SAndroid Build Coastguard Worker return true;
438*d57664e9SAndroid Build Coastguard Worker }
439*d57664e9SAndroid Build Coastguard Worker
440*d57664e9SAndroid Build Coastguard Worker return false;
441*d57664e9SAndroid Build Coastguard Worker }
442*d57664e9SAndroid Build Coastguard Worker
parseKeysHidden(const char * name,ResTable_config * out)443*d57664e9SAndroid Build Coastguard Worker static bool parseKeysHidden(const char* name, ResTable_config* out) {
444*d57664e9SAndroid Build Coastguard Worker uint8_t mask = 0;
445*d57664e9SAndroid Build Coastguard Worker uint8_t value = 0;
446*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
447*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_KEYSHIDDEN;
448*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::KEYSHIDDEN_ANY;
449*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "keysexposed") == 0) {
450*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_KEYSHIDDEN;
451*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::KEYSHIDDEN_NO;
452*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "keyshidden") == 0) {
453*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_KEYSHIDDEN;
454*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::KEYSHIDDEN_YES;
455*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "keyssoft") == 0) {
456*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_KEYSHIDDEN;
457*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::KEYSHIDDEN_SOFT;
458*d57664e9SAndroid Build Coastguard Worker }
459*d57664e9SAndroid Build Coastguard Worker
460*d57664e9SAndroid Build Coastguard Worker if (mask != 0) {
461*d57664e9SAndroid Build Coastguard Worker if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
462*d57664e9SAndroid Build Coastguard Worker return true;
463*d57664e9SAndroid Build Coastguard Worker }
464*d57664e9SAndroid Build Coastguard Worker
465*d57664e9SAndroid Build Coastguard Worker return false;
466*d57664e9SAndroid Build Coastguard Worker }
467*d57664e9SAndroid Build Coastguard Worker
parseKeyboard(const char * name,ResTable_config * out)468*d57664e9SAndroid Build Coastguard Worker static bool parseKeyboard(const char* name, ResTable_config* out) {
469*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
470*d57664e9SAndroid Build Coastguard Worker if (out) out->keyboard = out->KEYBOARD_ANY;
471*d57664e9SAndroid Build Coastguard Worker return true;
472*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "nokeys") == 0) {
473*d57664e9SAndroid Build Coastguard Worker if (out) out->keyboard = out->KEYBOARD_NOKEYS;
474*d57664e9SAndroid Build Coastguard Worker return true;
475*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "qwerty") == 0) {
476*d57664e9SAndroid Build Coastguard Worker if (out) out->keyboard = out->KEYBOARD_QWERTY;
477*d57664e9SAndroid Build Coastguard Worker return true;
478*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "12key") == 0) {
479*d57664e9SAndroid Build Coastguard Worker if (out) out->keyboard = out->KEYBOARD_12KEY;
480*d57664e9SAndroid Build Coastguard Worker return true;
481*d57664e9SAndroid Build Coastguard Worker }
482*d57664e9SAndroid Build Coastguard Worker
483*d57664e9SAndroid Build Coastguard Worker return false;
484*d57664e9SAndroid Build Coastguard Worker }
485*d57664e9SAndroid Build Coastguard Worker
parseNavHidden(const char * name,ResTable_config * out)486*d57664e9SAndroid Build Coastguard Worker static bool parseNavHidden(const char* name, ResTable_config* out) {
487*d57664e9SAndroid Build Coastguard Worker uint8_t mask = 0;
488*d57664e9SAndroid Build Coastguard Worker uint8_t value = 0;
489*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
490*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_NAVHIDDEN;
491*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::NAVHIDDEN_ANY;
492*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "navexposed") == 0) {
493*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_NAVHIDDEN;
494*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::NAVHIDDEN_NO;
495*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "navhidden") == 0) {
496*d57664e9SAndroid Build Coastguard Worker mask = ResTable_config::MASK_NAVHIDDEN;
497*d57664e9SAndroid Build Coastguard Worker value = ResTable_config::NAVHIDDEN_YES;
498*d57664e9SAndroid Build Coastguard Worker }
499*d57664e9SAndroid Build Coastguard Worker
500*d57664e9SAndroid Build Coastguard Worker if (mask != 0) {
501*d57664e9SAndroid Build Coastguard Worker if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
502*d57664e9SAndroid Build Coastguard Worker return true;
503*d57664e9SAndroid Build Coastguard Worker }
504*d57664e9SAndroid Build Coastguard Worker
505*d57664e9SAndroid Build Coastguard Worker return false;
506*d57664e9SAndroid Build Coastguard Worker }
507*d57664e9SAndroid Build Coastguard Worker
parseNavigation(const char * name,ResTable_config * out)508*d57664e9SAndroid Build Coastguard Worker static bool parseNavigation(const char* name, ResTable_config* out) {
509*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
510*d57664e9SAndroid Build Coastguard Worker if (out) out->navigation = out->NAVIGATION_ANY;
511*d57664e9SAndroid Build Coastguard Worker return true;
512*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "nonav") == 0) {
513*d57664e9SAndroid Build Coastguard Worker if (out) out->navigation = out->NAVIGATION_NONAV;
514*d57664e9SAndroid Build Coastguard Worker return true;
515*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "dpad") == 0) {
516*d57664e9SAndroid Build Coastguard Worker if (out) out->navigation = out->NAVIGATION_DPAD;
517*d57664e9SAndroid Build Coastguard Worker return true;
518*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "trackball") == 0) {
519*d57664e9SAndroid Build Coastguard Worker if (out) out->navigation = out->NAVIGATION_TRACKBALL;
520*d57664e9SAndroid Build Coastguard Worker return true;
521*d57664e9SAndroid Build Coastguard Worker } else if (strcmp(name, "wheel") == 0) {
522*d57664e9SAndroid Build Coastguard Worker if (out) out->navigation = out->NAVIGATION_WHEEL;
523*d57664e9SAndroid Build Coastguard Worker return true;
524*d57664e9SAndroid Build Coastguard Worker }
525*d57664e9SAndroid Build Coastguard Worker
526*d57664e9SAndroid Build Coastguard Worker return false;
527*d57664e9SAndroid Build Coastguard Worker }
528*d57664e9SAndroid Build Coastguard Worker
parseScreenSize(const char * name,ResTable_config * out)529*d57664e9SAndroid Build Coastguard Worker static bool parseScreenSize(const char* name, ResTable_config* out) {
530*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
531*d57664e9SAndroid Build Coastguard Worker if (out) {
532*d57664e9SAndroid Build Coastguard Worker out->screenWidth = out->SCREENWIDTH_ANY;
533*d57664e9SAndroid Build Coastguard Worker out->screenHeight = out->SCREENHEIGHT_ANY;
534*d57664e9SAndroid Build Coastguard Worker }
535*d57664e9SAndroid Build Coastguard Worker return true;
536*d57664e9SAndroid Build Coastguard Worker }
537*d57664e9SAndroid Build Coastguard Worker
538*d57664e9SAndroid Build Coastguard Worker const char* x = name;
539*d57664e9SAndroid Build Coastguard Worker while (*x >= '0' && *x <= '9') x++;
540*d57664e9SAndroid Build Coastguard Worker if (x == name || *x != 'x') return false;
541*d57664e9SAndroid Build Coastguard Worker std::string xName(name, x - name);
542*d57664e9SAndroid Build Coastguard Worker x++;
543*d57664e9SAndroid Build Coastguard Worker
544*d57664e9SAndroid Build Coastguard Worker const char* y = x;
545*d57664e9SAndroid Build Coastguard Worker while (*y >= '0' && *y <= '9') y++;
546*d57664e9SAndroid Build Coastguard Worker if (y == name || *y != 0) return false;
547*d57664e9SAndroid Build Coastguard Worker std::string yName(x, y - x);
548*d57664e9SAndroid Build Coastguard Worker
549*d57664e9SAndroid Build Coastguard Worker uint16_t w = (uint16_t)atoi(xName.c_str());
550*d57664e9SAndroid Build Coastguard Worker uint16_t h = (uint16_t)atoi(yName.c_str());
551*d57664e9SAndroid Build Coastguard Worker if (w < h) {
552*d57664e9SAndroid Build Coastguard Worker return false;
553*d57664e9SAndroid Build Coastguard Worker }
554*d57664e9SAndroid Build Coastguard Worker
555*d57664e9SAndroid Build Coastguard Worker if (out) {
556*d57664e9SAndroid Build Coastguard Worker out->screenWidth = w;
557*d57664e9SAndroid Build Coastguard Worker out->screenHeight = h;
558*d57664e9SAndroid Build Coastguard Worker }
559*d57664e9SAndroid Build Coastguard Worker
560*d57664e9SAndroid Build Coastguard Worker return true;
561*d57664e9SAndroid Build Coastguard Worker }
562*d57664e9SAndroid Build Coastguard Worker
parseSmallestScreenWidthDp(const char * name,ResTable_config * out)563*d57664e9SAndroid Build Coastguard Worker static bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
564*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
565*d57664e9SAndroid Build Coastguard Worker if (out) {
566*d57664e9SAndroid Build Coastguard Worker out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
567*d57664e9SAndroid Build Coastguard Worker }
568*d57664e9SAndroid Build Coastguard Worker return true;
569*d57664e9SAndroid Build Coastguard Worker }
570*d57664e9SAndroid Build Coastguard Worker
571*d57664e9SAndroid Build Coastguard Worker if (*name != 's') return false;
572*d57664e9SAndroid Build Coastguard Worker name++;
573*d57664e9SAndroid Build Coastguard Worker if (*name != 'w') return false;
574*d57664e9SAndroid Build Coastguard Worker name++;
575*d57664e9SAndroid Build Coastguard Worker const char* x = name;
576*d57664e9SAndroid Build Coastguard Worker while (*x >= '0' && *x <= '9') x++;
577*d57664e9SAndroid Build Coastguard Worker if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
578*d57664e9SAndroid Build Coastguard Worker std::string xName(name, x - name);
579*d57664e9SAndroid Build Coastguard Worker
580*d57664e9SAndroid Build Coastguard Worker if (out) {
581*d57664e9SAndroid Build Coastguard Worker out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
582*d57664e9SAndroid Build Coastguard Worker }
583*d57664e9SAndroid Build Coastguard Worker
584*d57664e9SAndroid Build Coastguard Worker return true;
585*d57664e9SAndroid Build Coastguard Worker }
586*d57664e9SAndroid Build Coastguard Worker
parseScreenWidthDp(const char * name,ResTable_config * out)587*d57664e9SAndroid Build Coastguard Worker static bool parseScreenWidthDp(const char* name, ResTable_config* out) {
588*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
589*d57664e9SAndroid Build Coastguard Worker if (out) {
590*d57664e9SAndroid Build Coastguard Worker out->screenWidthDp = out->SCREENWIDTH_ANY;
591*d57664e9SAndroid Build Coastguard Worker }
592*d57664e9SAndroid Build Coastguard Worker return true;
593*d57664e9SAndroid Build Coastguard Worker }
594*d57664e9SAndroid Build Coastguard Worker
595*d57664e9SAndroid Build Coastguard Worker if (*name != 'w') return false;
596*d57664e9SAndroid Build Coastguard Worker name++;
597*d57664e9SAndroid Build Coastguard Worker const char* x = name;
598*d57664e9SAndroid Build Coastguard Worker while (*x >= '0' && *x <= '9') x++;
599*d57664e9SAndroid Build Coastguard Worker if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
600*d57664e9SAndroid Build Coastguard Worker std::string xName(name, x - name);
601*d57664e9SAndroid Build Coastguard Worker
602*d57664e9SAndroid Build Coastguard Worker if (out) {
603*d57664e9SAndroid Build Coastguard Worker out->screenWidthDp = (uint16_t)atoi(xName.c_str());
604*d57664e9SAndroid Build Coastguard Worker }
605*d57664e9SAndroid Build Coastguard Worker
606*d57664e9SAndroid Build Coastguard Worker return true;
607*d57664e9SAndroid Build Coastguard Worker }
608*d57664e9SAndroid Build Coastguard Worker
parseScreenHeightDp(const char * name,ResTable_config * out)609*d57664e9SAndroid Build Coastguard Worker static bool parseScreenHeightDp(const char* name, ResTable_config* out) {
610*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
611*d57664e9SAndroid Build Coastguard Worker if (out) {
612*d57664e9SAndroid Build Coastguard Worker out->screenHeightDp = out->SCREENWIDTH_ANY;
613*d57664e9SAndroid Build Coastguard Worker }
614*d57664e9SAndroid Build Coastguard Worker return true;
615*d57664e9SAndroid Build Coastguard Worker }
616*d57664e9SAndroid Build Coastguard Worker
617*d57664e9SAndroid Build Coastguard Worker if (*name != 'h') return false;
618*d57664e9SAndroid Build Coastguard Worker name++;
619*d57664e9SAndroid Build Coastguard Worker const char* x = name;
620*d57664e9SAndroid Build Coastguard Worker while (*x >= '0' && *x <= '9') x++;
621*d57664e9SAndroid Build Coastguard Worker if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
622*d57664e9SAndroid Build Coastguard Worker std::string xName(name, x - name);
623*d57664e9SAndroid Build Coastguard Worker
624*d57664e9SAndroid Build Coastguard Worker if (out) {
625*d57664e9SAndroid Build Coastguard Worker out->screenHeightDp = (uint16_t)atoi(xName.c_str());
626*d57664e9SAndroid Build Coastguard Worker }
627*d57664e9SAndroid Build Coastguard Worker
628*d57664e9SAndroid Build Coastguard Worker return true;
629*d57664e9SAndroid Build Coastguard Worker }
630*d57664e9SAndroid Build Coastguard Worker
parseVersion(const char * name,ResTable_config * out)631*d57664e9SAndroid Build Coastguard Worker static bool parseVersion(const char* name, ResTable_config* out) {
632*d57664e9SAndroid Build Coastguard Worker if (strcmp(name, kWildcardName) == 0) {
633*d57664e9SAndroid Build Coastguard Worker if (out) {
634*d57664e9SAndroid Build Coastguard Worker out->sdkVersion = out->SDKVERSION_ANY;
635*d57664e9SAndroid Build Coastguard Worker out->minorVersion = out->MINORVERSION_ANY;
636*d57664e9SAndroid Build Coastguard Worker }
637*d57664e9SAndroid Build Coastguard Worker return true;
638*d57664e9SAndroid Build Coastguard Worker }
639*d57664e9SAndroid Build Coastguard Worker
640*d57664e9SAndroid Build Coastguard Worker if (*name != 'v') {
641*d57664e9SAndroid Build Coastguard Worker return false;
642*d57664e9SAndroid Build Coastguard Worker }
643*d57664e9SAndroid Build Coastguard Worker
644*d57664e9SAndroid Build Coastguard Worker name++;
645*d57664e9SAndroid Build Coastguard Worker const char* s = name;
646*d57664e9SAndroid Build Coastguard Worker while (*s >= '0' && *s <= '9') s++;
647*d57664e9SAndroid Build Coastguard Worker if (s == name || *s != 0) return false;
648*d57664e9SAndroid Build Coastguard Worker std::string sdkName(name, s - name);
649*d57664e9SAndroid Build Coastguard Worker
650*d57664e9SAndroid Build Coastguard Worker if (out) {
651*d57664e9SAndroid Build Coastguard Worker out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
652*d57664e9SAndroid Build Coastguard Worker out->minorVersion = 0;
653*d57664e9SAndroid Build Coastguard Worker }
654*d57664e9SAndroid Build Coastguard Worker
655*d57664e9SAndroid Build Coastguard Worker return true;
656*d57664e9SAndroid Build Coastguard Worker }
657*d57664e9SAndroid Build Coastguard Worker
Parse(StringPiece str,ConfigDescription * out)658*d57664e9SAndroid Build Coastguard Worker bool ConfigDescription::Parse(StringPiece str, ConfigDescription* out) {
659*d57664e9SAndroid Build Coastguard Worker std::vector<std::string> parts = util::SplitAndLowercase(str, '-');
660*d57664e9SAndroid Build Coastguard Worker
661*d57664e9SAndroid Build Coastguard Worker ConfigDescription config;
662*d57664e9SAndroid Build Coastguard Worker ssize_t parts_consumed = 0;
663*d57664e9SAndroid Build Coastguard Worker LocaleValue locale;
664*d57664e9SAndroid Build Coastguard Worker
665*d57664e9SAndroid Build Coastguard Worker const auto parts_end = parts.end();
666*d57664e9SAndroid Build Coastguard Worker auto part_iter = parts.begin();
667*d57664e9SAndroid Build Coastguard Worker
668*d57664e9SAndroid Build Coastguard Worker if (str.size() == 0) {
669*d57664e9SAndroid Build Coastguard Worker goto success;
670*d57664e9SAndroid Build Coastguard Worker }
671*d57664e9SAndroid Build Coastguard Worker
672*d57664e9SAndroid Build Coastguard Worker if (parseMcc(part_iter->c_str(), &config)) {
673*d57664e9SAndroid Build Coastguard Worker ++part_iter;
674*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
675*d57664e9SAndroid Build Coastguard Worker goto success;
676*d57664e9SAndroid Build Coastguard Worker }
677*d57664e9SAndroid Build Coastguard Worker }
678*d57664e9SAndroid Build Coastguard Worker
679*d57664e9SAndroid Build Coastguard Worker if (parseMnc(part_iter->c_str(), &config)) {
680*d57664e9SAndroid Build Coastguard Worker ++part_iter;
681*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
682*d57664e9SAndroid Build Coastguard Worker goto success;
683*d57664e9SAndroid Build Coastguard Worker }
684*d57664e9SAndroid Build Coastguard Worker }
685*d57664e9SAndroid Build Coastguard Worker
686*d57664e9SAndroid Build Coastguard Worker // Locale spans a few '-' separators, so we let it
687*d57664e9SAndroid Build Coastguard Worker // control the index.
688*d57664e9SAndroid Build Coastguard Worker parts_consumed = locale.InitFromParts(part_iter, parts_end);
689*d57664e9SAndroid Build Coastguard Worker if (parts_consumed < 0) {
690*d57664e9SAndroid Build Coastguard Worker return false;
691*d57664e9SAndroid Build Coastguard Worker } else {
692*d57664e9SAndroid Build Coastguard Worker locale.WriteTo(&config);
693*d57664e9SAndroid Build Coastguard Worker part_iter += parts_consumed;
694*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
695*d57664e9SAndroid Build Coastguard Worker goto success;
696*d57664e9SAndroid Build Coastguard Worker }
697*d57664e9SAndroid Build Coastguard Worker }
698*d57664e9SAndroid Build Coastguard Worker
699*d57664e9SAndroid Build Coastguard Worker if (parseGrammaticalInflection(*part_iter, &config)) {
700*d57664e9SAndroid Build Coastguard Worker ++part_iter;
701*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
702*d57664e9SAndroid Build Coastguard Worker goto success;
703*d57664e9SAndroid Build Coastguard Worker }
704*d57664e9SAndroid Build Coastguard Worker }
705*d57664e9SAndroid Build Coastguard Worker
706*d57664e9SAndroid Build Coastguard Worker if (parseLayoutDirection(part_iter->c_str(), &config)) {
707*d57664e9SAndroid Build Coastguard Worker ++part_iter;
708*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
709*d57664e9SAndroid Build Coastguard Worker goto success;
710*d57664e9SAndroid Build Coastguard Worker }
711*d57664e9SAndroid Build Coastguard Worker }
712*d57664e9SAndroid Build Coastguard Worker
713*d57664e9SAndroid Build Coastguard Worker if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) {
714*d57664e9SAndroid Build Coastguard Worker ++part_iter;
715*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
716*d57664e9SAndroid Build Coastguard Worker goto success;
717*d57664e9SAndroid Build Coastguard Worker }
718*d57664e9SAndroid Build Coastguard Worker }
719*d57664e9SAndroid Build Coastguard Worker
720*d57664e9SAndroid Build Coastguard Worker if (parseScreenWidthDp(part_iter->c_str(), &config)) {
721*d57664e9SAndroid Build Coastguard Worker ++part_iter;
722*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
723*d57664e9SAndroid Build Coastguard Worker goto success;
724*d57664e9SAndroid Build Coastguard Worker }
725*d57664e9SAndroid Build Coastguard Worker }
726*d57664e9SAndroid Build Coastguard Worker
727*d57664e9SAndroid Build Coastguard Worker if (parseScreenHeightDp(part_iter->c_str(), &config)) {
728*d57664e9SAndroid Build Coastguard Worker ++part_iter;
729*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
730*d57664e9SAndroid Build Coastguard Worker goto success;
731*d57664e9SAndroid Build Coastguard Worker }
732*d57664e9SAndroid Build Coastguard Worker }
733*d57664e9SAndroid Build Coastguard Worker
734*d57664e9SAndroid Build Coastguard Worker if (parseScreenLayoutSize(part_iter->c_str(), &config)) {
735*d57664e9SAndroid Build Coastguard Worker ++part_iter;
736*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
737*d57664e9SAndroid Build Coastguard Worker goto success;
738*d57664e9SAndroid Build Coastguard Worker }
739*d57664e9SAndroid Build Coastguard Worker }
740*d57664e9SAndroid Build Coastguard Worker
741*d57664e9SAndroid Build Coastguard Worker if (parseScreenLayoutLong(part_iter->c_str(), &config)) {
742*d57664e9SAndroid Build Coastguard Worker ++part_iter;
743*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
744*d57664e9SAndroid Build Coastguard Worker goto success;
745*d57664e9SAndroid Build Coastguard Worker }
746*d57664e9SAndroid Build Coastguard Worker }
747*d57664e9SAndroid Build Coastguard Worker
748*d57664e9SAndroid Build Coastguard Worker if (parseScreenRound(part_iter->c_str(), &config)) {
749*d57664e9SAndroid Build Coastguard Worker ++part_iter;
750*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
751*d57664e9SAndroid Build Coastguard Worker goto success;
752*d57664e9SAndroid Build Coastguard Worker }
753*d57664e9SAndroid Build Coastguard Worker }
754*d57664e9SAndroid Build Coastguard Worker
755*d57664e9SAndroid Build Coastguard Worker if (parseWideColorGamut(part_iter->c_str(), &config)) {
756*d57664e9SAndroid Build Coastguard Worker ++part_iter;
757*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
758*d57664e9SAndroid Build Coastguard Worker goto success;
759*d57664e9SAndroid Build Coastguard Worker }
760*d57664e9SAndroid Build Coastguard Worker }
761*d57664e9SAndroid Build Coastguard Worker
762*d57664e9SAndroid Build Coastguard Worker if (parseHdr(part_iter->c_str(), &config)) {
763*d57664e9SAndroid Build Coastguard Worker ++part_iter;
764*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
765*d57664e9SAndroid Build Coastguard Worker goto success;
766*d57664e9SAndroid Build Coastguard Worker }
767*d57664e9SAndroid Build Coastguard Worker }
768*d57664e9SAndroid Build Coastguard Worker
769*d57664e9SAndroid Build Coastguard Worker if (parseOrientation(part_iter->c_str(), &config)) {
770*d57664e9SAndroid Build Coastguard Worker ++part_iter;
771*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
772*d57664e9SAndroid Build Coastguard Worker goto success;
773*d57664e9SAndroid Build Coastguard Worker }
774*d57664e9SAndroid Build Coastguard Worker }
775*d57664e9SAndroid Build Coastguard Worker
776*d57664e9SAndroid Build Coastguard Worker if (parseUiModeType(part_iter->c_str(), &config)) {
777*d57664e9SAndroid Build Coastguard Worker ++part_iter;
778*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
779*d57664e9SAndroid Build Coastguard Worker goto success;
780*d57664e9SAndroid Build Coastguard Worker }
781*d57664e9SAndroid Build Coastguard Worker }
782*d57664e9SAndroid Build Coastguard Worker
783*d57664e9SAndroid Build Coastguard Worker if (parseUiModeNight(part_iter->c_str(), &config)) {
784*d57664e9SAndroid Build Coastguard Worker ++part_iter;
785*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
786*d57664e9SAndroid Build Coastguard Worker goto success;
787*d57664e9SAndroid Build Coastguard Worker }
788*d57664e9SAndroid Build Coastguard Worker }
789*d57664e9SAndroid Build Coastguard Worker
790*d57664e9SAndroid Build Coastguard Worker if (parseDensity(part_iter->c_str(), &config)) {
791*d57664e9SAndroid Build Coastguard Worker ++part_iter;
792*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
793*d57664e9SAndroid Build Coastguard Worker goto success;
794*d57664e9SAndroid Build Coastguard Worker }
795*d57664e9SAndroid Build Coastguard Worker }
796*d57664e9SAndroid Build Coastguard Worker
797*d57664e9SAndroid Build Coastguard Worker if (parseTouchscreen(part_iter->c_str(), &config)) {
798*d57664e9SAndroid Build Coastguard Worker ++part_iter;
799*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
800*d57664e9SAndroid Build Coastguard Worker goto success;
801*d57664e9SAndroid Build Coastguard Worker }
802*d57664e9SAndroid Build Coastguard Worker }
803*d57664e9SAndroid Build Coastguard Worker
804*d57664e9SAndroid Build Coastguard Worker if (parseKeysHidden(part_iter->c_str(), &config)) {
805*d57664e9SAndroid Build Coastguard Worker ++part_iter;
806*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
807*d57664e9SAndroid Build Coastguard Worker goto success;
808*d57664e9SAndroid Build Coastguard Worker }
809*d57664e9SAndroid Build Coastguard Worker }
810*d57664e9SAndroid Build Coastguard Worker
811*d57664e9SAndroid Build Coastguard Worker if (parseKeyboard(part_iter->c_str(), &config)) {
812*d57664e9SAndroid Build Coastguard Worker ++part_iter;
813*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
814*d57664e9SAndroid Build Coastguard Worker goto success;
815*d57664e9SAndroid Build Coastguard Worker }
816*d57664e9SAndroid Build Coastguard Worker }
817*d57664e9SAndroid Build Coastguard Worker
818*d57664e9SAndroid Build Coastguard Worker if (parseNavHidden(part_iter->c_str(), &config)) {
819*d57664e9SAndroid Build Coastguard Worker ++part_iter;
820*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
821*d57664e9SAndroid Build Coastguard Worker goto success;
822*d57664e9SAndroid Build Coastguard Worker }
823*d57664e9SAndroid Build Coastguard Worker }
824*d57664e9SAndroid Build Coastguard Worker
825*d57664e9SAndroid Build Coastguard Worker if (parseNavigation(part_iter->c_str(), &config)) {
826*d57664e9SAndroid Build Coastguard Worker ++part_iter;
827*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
828*d57664e9SAndroid Build Coastguard Worker goto success;
829*d57664e9SAndroid Build Coastguard Worker }
830*d57664e9SAndroid Build Coastguard Worker }
831*d57664e9SAndroid Build Coastguard Worker
832*d57664e9SAndroid Build Coastguard Worker if (parseScreenSize(part_iter->c_str(), &config)) {
833*d57664e9SAndroid Build Coastguard Worker ++part_iter;
834*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
835*d57664e9SAndroid Build Coastguard Worker goto success;
836*d57664e9SAndroid Build Coastguard Worker }
837*d57664e9SAndroid Build Coastguard Worker }
838*d57664e9SAndroid Build Coastguard Worker
839*d57664e9SAndroid Build Coastguard Worker if (parseVersion(part_iter->c_str(), &config)) {
840*d57664e9SAndroid Build Coastguard Worker ++part_iter;
841*d57664e9SAndroid Build Coastguard Worker if (part_iter == parts_end) {
842*d57664e9SAndroid Build Coastguard Worker goto success;
843*d57664e9SAndroid Build Coastguard Worker }
844*d57664e9SAndroid Build Coastguard Worker }
845*d57664e9SAndroid Build Coastguard Worker
846*d57664e9SAndroid Build Coastguard Worker // Unrecognized.
847*d57664e9SAndroid Build Coastguard Worker return false;
848*d57664e9SAndroid Build Coastguard Worker
849*d57664e9SAndroid Build Coastguard Worker success:
850*d57664e9SAndroid Build Coastguard Worker if (out != NULL) {
851*d57664e9SAndroid Build Coastguard Worker ApplyVersionForCompatibility(&config);
852*d57664e9SAndroid Build Coastguard Worker *out = config;
853*d57664e9SAndroid Build Coastguard Worker }
854*d57664e9SAndroid Build Coastguard Worker return true;
855*d57664e9SAndroid Build Coastguard Worker }
856*d57664e9SAndroid Build Coastguard Worker
ApplyVersionForCompatibility(ConfigDescription * config)857*d57664e9SAndroid Build Coastguard Worker void ConfigDescription::ApplyVersionForCompatibility(
858*d57664e9SAndroid Build Coastguard Worker ConfigDescription* config) {
859*d57664e9SAndroid Build Coastguard Worker uint16_t min_sdk = 0;
860*d57664e9SAndroid Build Coastguard Worker if (config->grammaticalInflection != 0) {
861*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_U;
862*d57664e9SAndroid Build Coastguard Worker } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
863*d57664e9SAndroid Build Coastguard Worker == ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
864*d57664e9SAndroid Build Coastguard Worker config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT ||
865*d57664e9SAndroid Build Coastguard Worker config->colorMode & ResTable_config::MASK_HDR) {
866*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_O;
867*d57664e9SAndroid Build Coastguard Worker } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
868*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_MARSHMALLOW;
869*d57664e9SAndroid Build Coastguard Worker } else if (config->density == ResTable_config::DENSITY_ANY) {
870*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_LOLLIPOP;
871*d57664e9SAndroid Build Coastguard Worker } else if (config->smallestScreenWidthDp !=
872*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENWIDTH_ANY ||
873*d57664e9SAndroid Build Coastguard Worker config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
874*d57664e9SAndroid Build Coastguard Worker config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
875*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_HONEYCOMB_MR2;
876*d57664e9SAndroid Build Coastguard Worker } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) !=
877*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_TYPE_ANY ||
878*d57664e9SAndroid Build Coastguard Worker (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) !=
879*d57664e9SAndroid Build Coastguard Worker ResTable_config::UI_MODE_NIGHT_ANY) {
880*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_FROYO;
881*d57664e9SAndroid Build Coastguard Worker } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) !=
882*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENSIZE_ANY ||
883*d57664e9SAndroid Build Coastguard Worker (config->screenLayout & ResTable_config::MASK_SCREENLONG) !=
884*d57664e9SAndroid Build Coastguard Worker ResTable_config::SCREENLONG_ANY ||
885*d57664e9SAndroid Build Coastguard Worker config->density != ResTable_config::DENSITY_DEFAULT) {
886*d57664e9SAndroid Build Coastguard Worker min_sdk = SDK_DONUT;
887*d57664e9SAndroid Build Coastguard Worker }
888*d57664e9SAndroid Build Coastguard Worker
889*d57664e9SAndroid Build Coastguard Worker if (min_sdk > config->sdkVersion) {
890*d57664e9SAndroid Build Coastguard Worker config->sdkVersion = min_sdk;
891*d57664e9SAndroid Build Coastguard Worker }
892*d57664e9SAndroid Build Coastguard Worker }
893*d57664e9SAndroid Build Coastguard Worker
CopyWithoutSdkVersion() const894*d57664e9SAndroid Build Coastguard Worker ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
895*d57664e9SAndroid Build Coastguard Worker ConfigDescription copy = *this;
896*d57664e9SAndroid Build Coastguard Worker copy.sdkVersion = 0;
897*d57664e9SAndroid Build Coastguard Worker return copy;
898*d57664e9SAndroid Build Coastguard Worker }
899*d57664e9SAndroid Build Coastguard Worker
GetBcp47LanguageTag(bool canonicalize) const900*d57664e9SAndroid Build Coastguard Worker std::string ConfigDescription::GetBcp47LanguageTag(bool canonicalize) const {
901*d57664e9SAndroid Build Coastguard Worker char locale[RESTABLE_MAX_LOCALE_LEN];
902*d57664e9SAndroid Build Coastguard Worker getBcp47Locale(locale, canonicalize);
903*d57664e9SAndroid Build Coastguard Worker return std::string(locale);
904*d57664e9SAndroid Build Coastguard Worker }
905*d57664e9SAndroid Build Coastguard Worker
to_string() const906*d57664e9SAndroid Build Coastguard Worker std::string ConfigDescription::to_string() const {
907*d57664e9SAndroid Build Coastguard Worker const String8 str = toString();
908*d57664e9SAndroid Build Coastguard Worker return std::string(str.c_str(), str.size());
909*d57664e9SAndroid Build Coastguard Worker }
910*d57664e9SAndroid Build Coastguard Worker
Dominates(const ConfigDescription & o) const911*d57664e9SAndroid Build Coastguard Worker bool ConfigDescription::Dominates(const ConfigDescription& o) const {
912*d57664e9SAndroid Build Coastguard Worker if (*this == o) {
913*d57664e9SAndroid Build Coastguard Worker return true;
914*d57664e9SAndroid Build Coastguard Worker }
915*d57664e9SAndroid Build Coastguard Worker
916*d57664e9SAndroid Build Coastguard Worker // Locale de-duping is not-trivial, disable for now (b/62409213).
917*d57664e9SAndroid Build Coastguard Worker // We must also disable de-duping for all configuration qualifiers with precedence higher than
918*d57664e9SAndroid Build Coastguard Worker // locale (b/171892595)
919*d57664e9SAndroid Build Coastguard Worker if (diff(o) & (CONFIG_LOCALE | CONFIG_MCC | CONFIG_MNC)) {
920*d57664e9SAndroid Build Coastguard Worker return false;
921*d57664e9SAndroid Build Coastguard Worker }
922*d57664e9SAndroid Build Coastguard Worker
923*d57664e9SAndroid Build Coastguard Worker if (*this == DefaultConfig()) {
924*d57664e9SAndroid Build Coastguard Worker return true;
925*d57664e9SAndroid Build Coastguard Worker }
926*d57664e9SAndroid Build Coastguard Worker
927*d57664e9SAndroid Build Coastguard Worker return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
928*d57664e9SAndroid Build Coastguard Worker !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this);
929*d57664e9SAndroid Build Coastguard Worker }
930*d57664e9SAndroid Build Coastguard Worker
HasHigherPrecedenceThan(const ConfigDescription & o) const931*d57664e9SAndroid Build Coastguard Worker bool ConfigDescription::HasHigherPrecedenceThan(
932*d57664e9SAndroid Build Coastguard Worker const ConfigDescription& o) const {
933*d57664e9SAndroid Build Coastguard Worker // The order of the following tests defines the importance of one
934*d57664e9SAndroid Build Coastguard Worker // configuration parameter over another. Those tests first are more
935*d57664e9SAndroid Build Coastguard Worker // important, trumping any values in those following them.
936*d57664e9SAndroid Build Coastguard Worker // The ordering should be the same as ResTable_config#isBetterThan.
937*d57664e9SAndroid Build Coastguard Worker if (mcc || o.mcc) return (!o.mcc);
938*d57664e9SAndroid Build Coastguard Worker if (mnc || o.mnc) return (!o.mnc);
939*d57664e9SAndroid Build Coastguard Worker if (language[0] || o.language[0]) return (!o.language[0]);
940*d57664e9SAndroid Build Coastguard Worker if (country[0] || o.country[0]) return (!o.country[0]);
941*d57664e9SAndroid Build Coastguard Worker // Script and variant require either a language or country, both of which
942*d57664e9SAndroid Build Coastguard Worker // have higher precedence.
943*d57664e9SAndroid Build Coastguard Worker if (grammaticalInflection || o.grammaticalInflection) return !o.grammaticalInflection;
944*d57664e9SAndroid Build Coastguard Worker if ((screenLayout | o.screenLayout) & MASK_LAYOUTDIR) {
945*d57664e9SAndroid Build Coastguard Worker return !(o.screenLayout & MASK_LAYOUTDIR);
946*d57664e9SAndroid Build Coastguard Worker }
947*d57664e9SAndroid Build Coastguard Worker if (smallestScreenWidthDp || o.smallestScreenWidthDp)
948*d57664e9SAndroid Build Coastguard Worker return (!o.smallestScreenWidthDp);
949*d57664e9SAndroid Build Coastguard Worker if (screenWidthDp || o.screenWidthDp) return (!o.screenWidthDp);
950*d57664e9SAndroid Build Coastguard Worker if (screenHeightDp || o.screenHeightDp) return (!o.screenHeightDp);
951*d57664e9SAndroid Build Coastguard Worker if ((screenLayout | o.screenLayout) & MASK_SCREENSIZE) {
952*d57664e9SAndroid Build Coastguard Worker return !(o.screenLayout & MASK_SCREENSIZE);
953*d57664e9SAndroid Build Coastguard Worker }
954*d57664e9SAndroid Build Coastguard Worker if ((screenLayout | o.screenLayout) & MASK_SCREENLONG) {
955*d57664e9SAndroid Build Coastguard Worker return !(o.screenLayout & MASK_SCREENLONG);
956*d57664e9SAndroid Build Coastguard Worker }
957*d57664e9SAndroid Build Coastguard Worker if ((screenLayout2 | o.screenLayout2) & MASK_SCREENROUND) {
958*d57664e9SAndroid Build Coastguard Worker return !(o.screenLayout2 & MASK_SCREENROUND);
959*d57664e9SAndroid Build Coastguard Worker }
960*d57664e9SAndroid Build Coastguard Worker if ((colorMode | o.colorMode) & MASK_HDR) {
961*d57664e9SAndroid Build Coastguard Worker return !(o.colorMode & MASK_HDR);
962*d57664e9SAndroid Build Coastguard Worker }
963*d57664e9SAndroid Build Coastguard Worker if ((colorMode | o.colorMode) & MASK_WIDE_COLOR_GAMUT) {
964*d57664e9SAndroid Build Coastguard Worker return !(o.colorMode & MASK_WIDE_COLOR_GAMUT);
965*d57664e9SAndroid Build Coastguard Worker }
966*d57664e9SAndroid Build Coastguard Worker if (orientation || o.orientation) return (!o.orientation);
967*d57664e9SAndroid Build Coastguard Worker if ((uiMode | o.uiMode) & MASK_UI_MODE_TYPE) {
968*d57664e9SAndroid Build Coastguard Worker return !(o.uiMode & MASK_UI_MODE_TYPE);
969*d57664e9SAndroid Build Coastguard Worker }
970*d57664e9SAndroid Build Coastguard Worker if ((uiMode | o.uiMode) & MASK_UI_MODE_NIGHT) {
971*d57664e9SAndroid Build Coastguard Worker return !(o.uiMode & MASK_UI_MODE_NIGHT);
972*d57664e9SAndroid Build Coastguard Worker }
973*d57664e9SAndroid Build Coastguard Worker if (density || o.density) return (!o.density);
974*d57664e9SAndroid Build Coastguard Worker if (touchscreen || o.touchscreen) return (!o.touchscreen);
975*d57664e9SAndroid Build Coastguard Worker if ((inputFlags | o.inputFlags) & MASK_KEYSHIDDEN) {
976*d57664e9SAndroid Build Coastguard Worker return !(o.inputFlags & MASK_KEYSHIDDEN);
977*d57664e9SAndroid Build Coastguard Worker }
978*d57664e9SAndroid Build Coastguard Worker if ((inputFlags | o.inputFlags) & MASK_NAVHIDDEN) {
979*d57664e9SAndroid Build Coastguard Worker return !(o.inputFlags & MASK_NAVHIDDEN);
980*d57664e9SAndroid Build Coastguard Worker }
981*d57664e9SAndroid Build Coastguard Worker if (keyboard || o.keyboard) return (!o.keyboard);
982*d57664e9SAndroid Build Coastguard Worker if (navigation || o.navigation) return (!o.navigation);
983*d57664e9SAndroid Build Coastguard Worker if (screenWidth || o.screenWidth) return (!o.screenWidth);
984*d57664e9SAndroid Build Coastguard Worker if (screenHeight || o.screenHeight) return (!o.screenHeight);
985*d57664e9SAndroid Build Coastguard Worker if (sdkVersion || o.sdkVersion) return (!o.sdkVersion);
986*d57664e9SAndroid Build Coastguard Worker if (minorVersion || o.minorVersion) return (!o.minorVersion);
987*d57664e9SAndroid Build Coastguard Worker // Both configurations have nothing defined except some possible future
988*d57664e9SAndroid Build Coastguard Worker // value. Returning the comparison of the two configurations is a
989*d57664e9SAndroid Build Coastguard Worker // "best effort" at this point to protect against incorrect dominations.
990*d57664e9SAndroid Build Coastguard Worker return *this != o;
991*d57664e9SAndroid Build Coastguard Worker }
992*d57664e9SAndroid Build Coastguard Worker
ConflictsWith(const ConfigDescription & o) const993*d57664e9SAndroid Build Coastguard Worker bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const {
994*d57664e9SAndroid Build Coastguard Worker // This method should be updated as new configuration parameters are
995*d57664e9SAndroid Build Coastguard Worker // introduced (e.g. screenConfig2).
996*d57664e9SAndroid Build Coastguard Worker auto pred = [](const uint32_t a, const uint32_t b) -> bool {
997*d57664e9SAndroid Build Coastguard Worker return a == 0 || b == 0 || a == b;
998*d57664e9SAndroid Build Coastguard Worker };
999*d57664e9SAndroid Build Coastguard Worker // The values here can be found in ResTable_config#match. Density and range
1000*d57664e9SAndroid Build Coastguard Worker // values can't lead to conflicts, and are ignored.
1001*d57664e9SAndroid Build Coastguard Worker return !pred(mcc, o.mcc) || !pred(mnc, o.mnc) || !pred(locale, o.locale) ||
1002*d57664e9SAndroid Build Coastguard Worker !pred(grammaticalInflection, o.grammaticalInflection) ||
1003*d57664e9SAndroid Build Coastguard Worker !pred(screenLayout & MASK_LAYOUTDIR,
1004*d57664e9SAndroid Build Coastguard Worker o.screenLayout & MASK_LAYOUTDIR) ||
1005*d57664e9SAndroid Build Coastguard Worker !pred(screenLayout & MASK_SCREENLONG,
1006*d57664e9SAndroid Build Coastguard Worker o.screenLayout & MASK_SCREENLONG) ||
1007*d57664e9SAndroid Build Coastguard Worker !pred(uiMode & MASK_UI_MODE_TYPE, o.uiMode & MASK_UI_MODE_TYPE) ||
1008*d57664e9SAndroid Build Coastguard Worker !pred(uiMode & MASK_UI_MODE_NIGHT, o.uiMode & MASK_UI_MODE_NIGHT) ||
1009*d57664e9SAndroid Build Coastguard Worker !pred(screenLayout2 & MASK_SCREENROUND,
1010*d57664e9SAndroid Build Coastguard Worker o.screenLayout2 & MASK_SCREENROUND) ||
1011*d57664e9SAndroid Build Coastguard Worker !pred(colorMode & MASK_HDR, o.colorMode & MASK_HDR) ||
1012*d57664e9SAndroid Build Coastguard Worker !pred(colorMode & MASK_WIDE_COLOR_GAMUT,
1013*d57664e9SAndroid Build Coastguard Worker o.colorMode & MASK_WIDE_COLOR_GAMUT) ||
1014*d57664e9SAndroid Build Coastguard Worker !pred(orientation, o.orientation) ||
1015*d57664e9SAndroid Build Coastguard Worker !pred(touchscreen, o.touchscreen) ||
1016*d57664e9SAndroid Build Coastguard Worker !pred(inputFlags & MASK_KEYSHIDDEN, o.inputFlags & MASK_KEYSHIDDEN) ||
1017*d57664e9SAndroid Build Coastguard Worker !pred(inputFlags & MASK_NAVHIDDEN, o.inputFlags & MASK_NAVHIDDEN) ||
1018*d57664e9SAndroid Build Coastguard Worker !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation);
1019*d57664e9SAndroid Build Coastguard Worker }
1020*d57664e9SAndroid Build Coastguard Worker
IsCompatibleWith(const ConfigDescription & o) const1021*d57664e9SAndroid Build Coastguard Worker bool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const {
1022*d57664e9SAndroid Build Coastguard Worker return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
1023*d57664e9SAndroid Build Coastguard Worker }
1024*d57664e9SAndroid Build Coastguard Worker
1025*d57664e9SAndroid Build Coastguard Worker } // namespace android
1026