1fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski/*
2fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * Copyright (C) 2014 The Android Open Source Project
3fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *
4fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * you may not use this file except in compliance with the License.
6fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * You may obtain a copy of the License at
7fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *
8fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *
10fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * See the License for the specific language governing permissions and
14fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * limitations under the License.
15fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski */
16fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
17fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <androidfw/ResourceTypes.h>
18fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <ctype.h>
19fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
20fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "AaptConfig.h"
21fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "AaptAssets.h"
22fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "AaptUtil.h"
23fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "ResourceFilter.h"
24dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski#include "SdkConstants.h"
25fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
26fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiusing android::String8;
27fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiusing android::Vector;
28fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiusing android::ResTable_config;
29fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
30fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskinamespace AaptConfig {
31fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
32fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatic const char* kWildcardName = "any";
33fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
34fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parse(const String8& str, ConfigDescription* out) {
35fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '-');
36fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
37fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ConfigDescription config;
38fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    AaptLocaleValue locale;
39fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ssize_t index = 0;
40fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ssize_t localeIndex = 0;
41fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const ssize_t N = parts.size();
42fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* part = parts[index].string();
43fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
44fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (str.length() == 0) {
45fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        goto success;
46fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
47fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
48fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseMcc(part, &config)) {
49fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
50fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
51fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
52fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
53fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
54fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
55fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
56fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseMnc(part, &config)) {
57fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
58fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
59fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
60fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
61fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
62fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
63fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
64fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // Locale spans a few '-' separators, so we let it
65fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // control the index.
66fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    localeIndex = locale.initFromDirName(parts, index);
67fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (localeIndex < 0) {
68fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
69fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (localeIndex > index) {
70fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        locale.writeTo(&config);
71fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index = localeIndex;
72fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index >= N) {
73fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
74fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
75fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
76fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
77fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
78fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseLayoutDirection(part, &config)) {
79fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
80fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
81fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
82fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
83fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
84fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
85fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
86fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseSmallestScreenWidthDp(part, &config)) {
87fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
88fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
89fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
90fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
91fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
92fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
93fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
94fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenWidthDp(part, &config)) {
95fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
96fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
97fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
98fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
99fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
100fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
101fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
102fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenHeightDp(part, &config)) {
103fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
104fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
105fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
106fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
107fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
108fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
109fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
110fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenLayoutSize(part, &config)) {
111fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
112fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
113fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
114fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
115fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
116fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
117fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
118fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenLayoutLong(part, &config)) {
119fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
120fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
121fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
122fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
123fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
124fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
125fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1262738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    if (parseScreenRound(part, &config)) {
1272738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        index++;
1282738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (index == N) {
1292738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski            goto success;
1302738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        }
1312738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        part = parts[index].string();
1322738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    }
1332738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski
134c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (parseWideColorGamut(part, &config)) {
135c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        index++;
136c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        if (index == N) {
137c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy            goto success;
138c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        }
139c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        part = parts[index].string();
140c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    }
141c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
142c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (parseHdr(part, &config)) {
143c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        index++;
144c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        if (index == N) {
145c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy            goto success;
146c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        }
147c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        part = parts[index].string();
148c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    }
149c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
150fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseOrientation(part, &config)) {
151fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
152fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
153fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
154fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
155fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
156fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
157fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
158fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseUiModeType(part, &config)) {
159fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
160fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
161fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
162fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
163fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
164fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
165fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
166fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseUiModeNight(part, &config)) {
167fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
168fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
169fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
170fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
171fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
172fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
173fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
174fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseDensity(part, &config)) {
175fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
176fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
177fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
178fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
179fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
180fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
181fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
182fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseTouchscreen(part, &config)) {
183fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
184fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
185fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
186fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
187fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
188fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
189fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
190fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseKeysHidden(part, &config)) {
191fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
192fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
193fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
194fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
195fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
196fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
197fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
198fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseKeyboard(part, &config)) {
199fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
200fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
201fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
202fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
203fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
204fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
205fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
206fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseNavHidden(part, &config)) {
207fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
208fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
209fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
210fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
211fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
212fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
213fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
214fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseNavigation(part, &config)) {
215fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
216fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
217fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
218fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
219fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
220fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
221fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
222fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenSize(part, &config)) {
223fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
224fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
225fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
226fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
227fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
228fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
229fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
230fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseVersion(part, &config)) {
231fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
232fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
233fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
234fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
238fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // Unrecognized.
239fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
240fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
241fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskisuccess:
242fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out != NULL) {
243fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        applyVersionForCompatibility(&config);
244fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        *out = config;
245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
247fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
248fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
249fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseCommaSeparatedList(const String8& str, std::set<ConfigDescription>* outSet) {
250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, ',');
251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const size_t N = parts.size();
252fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    for (size_t i = 0; i < N; i++) {
253fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        ConfigDescription config;
254fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (!parse(parts[i], &config)) {
255fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            return false;
256fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
257fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        outSet->insert(config);
258fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
259fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
260fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
261fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
262fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid applyVersionForCompatibility(ConfigDescription* config) {
263fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (config == NULL) {
264fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return;
265fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
266fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
267fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t minSdk = 0;
2681a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen    if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
269c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                == ResTable_config::UI_MODE_TYPE_VR_HEADSET
2704832745b84d6a358582f2264d22acacf25e01b07Romain Guy            || config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT
2714832745b84d6a358582f2264d22acacf25e01b07Romain Guy            || config->colorMode & ResTable_config::MASK_HDR) {
2721a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen        minSdk = SDK_O;
2731a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen    } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
2742738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        minSdk = SDK_MNC;
2752738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    } else if (config->density == ResTable_config::DENSITY_ANY) {
276dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski        minSdk = SDK_LOLLIPOP;
2779086562a6a524cc0c96231411863cd65d8785bfeAdam Lesinski    } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY
279fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
280fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_HONEYCOMB_MR2;
281fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::UI_MODE_TYPE_ANY
283fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)
284fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::UI_MODE_NIGHT_ANY) {
285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_FROYO;
286fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)
287fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::SCREENSIZE_ANY
288fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)
289fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::SCREENLONG_ANY
290fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->density != ResTable_config::DENSITY_DEFAULT) {
291fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_DONUT;
292fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
293fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
294fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (minSdk > config->sdkVersion) {
295fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        config->sdkVersion = minSdk;
296fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
297fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
298fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
299fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseMcc(const char* name, ResTable_config* out) {
300fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
301fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = 0;
302fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
303fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* c = name;
305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'm') return false;
306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
311fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
312fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* val = c;
313fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
315fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
316fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
317fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*c != 0) return false;
318fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (c-val != 3) return false;
319fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int d = atoi(val);
321fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (d != 0) {
322fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = d;
323fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
324fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
325fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
326fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
327fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
328fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
329fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseMnc(const char* name, ResTable_config* out) {
330fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
331fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = 0;
332fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
334fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* c = name;
335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'm') return false;
336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'n') return false;
338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* val = c;
343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
345fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
346fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*c != 0) return false;
348fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (c-val == 0 || c-val > 3) return false;
349fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
351fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->mnc = atoi(val);
352fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out->mnc == 0) {
353fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->mnc = ACONFIGURATION_MNC_ZERO;
354fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
355fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
356fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
357fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
358fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
359fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
360fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseLayoutDirection(const char* name, ResTable_config* out) {
361fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
362fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
363fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
364fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_ANY;
365fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
366fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "ldltr") == 0) {
367fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
368fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
369fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_LTR;
370fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
371fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "ldrtl") == 0) {
372fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
373fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
374fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_RTL;
375fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
376fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
377fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
378fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
379fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
380fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
381fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenLayoutSize(const char* name, ResTable_config* out) {
382fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
383fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
384fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
385fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_ANY;
386fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
387fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "small") == 0) {
388fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
389fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
390fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_SMALL;
391fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
392fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "normal") == 0) {
393fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
394fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
395fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_NORMAL;
396fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "large") == 0) {
398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
400fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_LARGE;
401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
402fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "xlarge") == 0) {
403fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_XLARGE;
406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
407fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
408fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
411fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
412fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenLayoutLong(const char* name, ResTable_config* out) {
413fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
414fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
415fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
416fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_ANY;
417fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
418fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "long") == 0) {
419fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
420fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
421fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_YES;
422fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
423fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notlong") == 0) {
424fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
426fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_NO;
427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
4292738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    return false;
4302738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski}
431fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
4322738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinskibool parseScreenRound(const char* name, ResTable_config* out) {
4332738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
4342738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (out) out->screenLayout2 =
4352738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
4362738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                | ResTable_config::SCREENROUND_ANY;
4372738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        return true;
4382738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    } else if (strcmp(name, "round") == 0) {
4392738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (out) out->screenLayout2 =
4402738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
4412738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                | ResTable_config::SCREENROUND_YES;
4422738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        return true;
4432738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    } else if (strcmp(name, "notround") == 0) {
4442738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (out) out->screenLayout2 =
4452738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
4462738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                | ResTable_config::SCREENROUND_NO;
4472738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        return true;
4482738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    }
449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
450fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
451fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
452c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guybool parseWideColorGamut(const char* name, ResTable_config* out) {
453c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (strcmp(name, kWildcardName) == 0) {
4544832745b84d6a358582f2264d22acacf25e01b07Romain Guy        if (out) out->colorMode =
4554832745b84d6a358582f2264d22acacf25e01b07Romain Guy                (out->colorMode&~ResTable_config::MASK_WIDE_COLOR_GAMUT)
456c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                | ResTable_config::WIDE_COLOR_GAMUT_ANY;
457c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        return true;
458c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    } else if (strcmp(name, "widecg") == 0) {
4594832745b84d6a358582f2264d22acacf25e01b07Romain Guy        if (out) out->colorMode =
4604832745b84d6a358582f2264d22acacf25e01b07Romain Guy                (out->colorMode&~ResTable_config::MASK_WIDE_COLOR_GAMUT)
461c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                | ResTable_config::WIDE_COLOR_GAMUT_YES;
462c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        return true;
463c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    } else if (strcmp(name, "nowidecg") == 0) {
4644832745b84d6a358582f2264d22acacf25e01b07Romain Guy        if (out) out->colorMode =
4654832745b84d6a358582f2264d22acacf25e01b07Romain Guy                (out->colorMode&~ResTable_config::MASK_WIDE_COLOR_GAMUT)
466c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                | ResTable_config::WIDE_COLOR_GAMUT_NO;
467c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        return true;
468c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    }
469c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return false;
470c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy}
471c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
472c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guybool parseHdr(const char* name, ResTable_config* out) {
473c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (strcmp(name, kWildcardName) == 0) {
4744832745b84d6a358582f2264d22acacf25e01b07Romain Guy        if (out) out->colorMode =
4754832745b84d6a358582f2264d22acacf25e01b07Romain Guy                (out->colorMode&~ResTable_config::MASK_HDR)
476c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                | ResTable_config::HDR_ANY;
477c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        return true;
478c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    } else if (strcmp(name, "highdr") == 0) {
4794832745b84d6a358582f2264d22acacf25e01b07Romain Guy        if (out) out->colorMode =
4804832745b84d6a358582f2264d22acacf25e01b07Romain Guy                (out->colorMode&~ResTable_config::MASK_HDR)
481c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                | ResTable_config::HDR_YES;
482c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        return true;
483c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    } else if (strcmp(name, "lowdr") == 0) {
4844832745b84d6a358582f2264d22acacf25e01b07Romain Guy        if (out) out->colorMode =
4854832745b84d6a358582f2264d22acacf25e01b07Romain Guy                (out->colorMode&~ResTable_config::MASK_HDR)
486c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                | ResTable_config::HDR_NO;
487c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy        return true;
488c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    }
489c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return false;
490c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy}
491c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
492fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseOrientation(const char* name, ResTable_config* out) {
493fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
494fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_ANY;
495fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
496fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "port") == 0) {
497fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_PORT;
498fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
499fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "land") == 0) {
500fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_LAND;
501fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
502fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "square") == 0) {
503fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_SQUARE;
504fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
505fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
506fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
507fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
508fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
509fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
510fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseUiModeType(const char* name, ResTable_config* out) {
511fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
512fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
513fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
514fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_TYPE_ANY;
515fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
516fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "desk") == 0) {
517fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
518fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
519fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_DESK;
520fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
521fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "car") == 0) {
522fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
523fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
524fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_CAR;
525fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
526fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "television") == 0) {
527fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
528fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
529fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_TELEVISION;
530fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
531fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "appliance") == 0) {
532fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
533fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
534fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_APPLIANCE;
535fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
536fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "watch") == 0) {
537fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
538fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
539fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_WATCH;
540fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
5411a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen    } else if (strcmp(name, "vrheadset") == 0) {
5421a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen      if (out) out->uiMode =
5431a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
5441a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen              | ResTable_config::UI_MODE_TYPE_VR_HEADSET;
5451a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen        return true;
546fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
547fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
548fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
549fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
550fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
551fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseUiModeNight(const char* name, ResTable_config* out) {
552fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
553fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
554fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
555fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_NIGHT_ANY;
556fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
557fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "night") == 0) {
558fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
559fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
560fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_NIGHT_YES;
561fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
562fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notnight") == 0) {
563fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
564fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
565fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_NIGHT_NO;
566fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
567fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
568fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
569fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
570fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
571fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
572fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseDensity(const char* name, ResTable_config* out) {
573fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
574fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
575fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
576fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
577fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
57831245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    if (strcmp(name, "anydpi") == 0) {
57931245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_ANY;
58031245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        return true;
58131245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    }
58231245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski
583fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "nodpi") == 0) {
584fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_NONE;
585fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
586fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
587fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
588fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "ldpi") == 0) {
589fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_LOW;
590fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
591fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
592fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
593fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "mdpi") == 0) {
594fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
595fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
596fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
597fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
598fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "tvdpi") == 0) {
599fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_TV;
600fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
601fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
602fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
603fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "hdpi") == 0) {
604fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_HIGH;
605fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
606fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
607fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
608fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xhdpi") == 0) {
609fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XHIGH;
610fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
611fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
612fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
613fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xxhdpi") == 0) {
614fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
615fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
616fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
617fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
618fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xxxhdpi") == 0) {
619fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
620fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
621fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
622fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
623fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    char* c = (char*)name;
624fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
625fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
626fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
627fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
628fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // check that we have 'dpi' after the last digit.
629fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (toupper(c[0]) != 'D' ||
630fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            toupper(c[1]) != 'P' ||
631fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            toupper(c[2]) != 'I' ||
632fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            c[3] != 0) {
633fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
634fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
635fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
636fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // temporarily replace the first letter with \0 to
637fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // use atoi.
638fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    char tmp = c[0];
639fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c[0] = '\0';
640fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
641fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int d = atoi(name);
642fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c[0] = tmp;
643fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
644fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (d != 0) {
645fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = d;
646fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
647fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
648fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
649fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
650fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
651fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
652fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseTouchscreen(const char* name, ResTable_config* out) {
653fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
654fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
655fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
656fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notouch") == 0) {
657fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
658fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
659fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "stylus") == 0) {
660fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
661fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
662fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "finger") == 0) {
663fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
664fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
665fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
666fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
667fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
668fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
669fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
670fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseKeysHidden(const char* name, ResTable_config* out) {
671fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t mask = 0;
672fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t value = 0;
673fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
674fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
675fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_ANY;
676fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keysexposed") == 0) {
677fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
678fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_NO;
679fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keyshidden") == 0) {
680fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
681fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_YES;
682fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keyssoft") == 0) {
683fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
684fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_SOFT;
685fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
686fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
687fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mask != 0) {
688fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
689fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
690fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
691fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
692fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
693fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
694fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
695fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseKeyboard(const char* name, ResTable_config* out) {
696fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
697fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_ANY;
698fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
699fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "nokeys") == 0) {
700fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_NOKEYS;
701fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
702fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "qwerty") == 0) {
703fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_QWERTY;
704fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
705fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "12key") == 0) {
706fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_12KEY;
707fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
708fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
709fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
710fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
711fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
712fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
713fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseNavHidden(const char* name, ResTable_config* out) {
714fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t mask = 0;
715fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t value = 0;
716fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
717fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
718fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_ANY;
719fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "navexposed") == 0) {
720fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
721fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_NO;
722fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "navhidden") == 0) {
723fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
724fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_YES;
725fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
726fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
727fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mask != 0) {
728fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
729fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
730fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
731fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
732fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
733fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
734fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
735fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseNavigation(const char* name, ResTable_config* out) {
736fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
737fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_ANY;
738fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
739fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "nonav") == 0) {
740fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_NONAV;
741fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
742fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "dpad") == 0) {
743fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_DPAD;
744fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
745fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "trackball") == 0) {
746fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_TRACKBALL;
747fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
748fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "wheel") == 0) {
749fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_WHEEL;
750fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
751fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
752fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
753fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
754fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
755fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
756fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenSize(const char* name, ResTable_config* out) {
757fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
758fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
759fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenWidth = out->SCREENWIDTH_ANY;
760fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenHeight = out->SCREENHEIGHT_ANY;
761fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
762fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
763fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
764fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
765fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
766fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
767fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || *x != 'x') return false;
768fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
769fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    x++;
770fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
771fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* y = x;
772fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*y >= '0' && *y <= '9') y++;
773fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (y == name || *y != 0) return false;
774fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 yName(x, y-x);
775fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
776fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t w = (uint16_t)atoi(xName.string());
777fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t h = (uint16_t)atoi(yName.string());
778fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (w < h) {
779fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
780fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
781fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
782fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
783fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenWidth = w;
784fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenHeight = h;
785fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
786fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
787fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
788fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
789fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
790fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
791fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
792fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
793fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
794fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
795fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
796fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
797fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
798fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 's') return false;
799fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
800fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'w') return false;
801fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
802fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
803fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
804fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
805fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
806fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
807fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
808fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());
809fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
810fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
811fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
812fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
813fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
814fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenWidthDp(const char* name, ResTable_config* out) {
815fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
816fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
817fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenWidthDp = out->SCREENWIDTH_ANY;
818fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
819fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
820fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
821fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
822fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'w') return false;
823fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
824fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
825fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
826fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
827fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
828fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
829fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
830fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenWidthDp = (uint16_t)atoi(xName.string());
831fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
832fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
833fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
834fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
835fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
836fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenHeightDp(const char* name, ResTable_config* out) {
837fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
838fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
839fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenHeightDp = out->SCREENWIDTH_ANY;
840fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
841fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
842fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
843fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
844fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'h') return false;
845fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
846fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
847fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
848fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
849fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
850fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
851fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
852fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenHeightDp = (uint16_t)atoi(xName.string());
853fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
854fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
855fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
856fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
857fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
858fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseVersion(const char* name, ResTable_config* out) {
859fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
860fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
861fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->sdkVersion = out->SDKVERSION_ANY;
862fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->minorVersion = out->MINORVERSION_ANY;
863fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
864fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
865fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
866fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
867fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'v') {
868fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
869fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
870fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
871fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
872fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* s = name;
873fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*s >= '0' && *s <= '9') s++;
874fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (s == name || *s != 0) return false;
875fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 sdkName(name, s-name);
876fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
877fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
878fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->sdkVersion = (uint16_t)atoi(sdkName.string());
879fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->minorVersion = 0;
880fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
881fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
882fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
883fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
884fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
885fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiString8 getVersion(const ResTable_config& config) {
886fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return String8::format("v%u", config.sdkVersion);
887fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
888fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
889fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMask) {
890fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return a.diff(b) == axisMask;
891fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
892fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
893de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinskibool isDensityOnly(const ResTable_config& config) {
894ed643e81827797bd22069bf4283348d49fded891Adam Lesinski    if (config.density == ResTable_config::DENSITY_DEFAULT) {
895de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        return false;
896de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    }
897de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
898de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    if (config.density == ResTable_config::DENSITY_ANY) {
899dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski        if (config.sdkVersion != SDK_LOLLIPOP) {
900de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            // Someone modified the sdkVersion from the default, this is not safe to assume.
901de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            return false;
902de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        }
903de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    } else if (config.sdkVersion != SDK_DONUT) {
904de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        return false;
905de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    }
906de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
907de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION;
908de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    const ConfigDescription nullConfig;
909de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    return (nullConfig.diff(config) & ~mask) == 0;
910de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski}
911de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
912fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} // namespace AaptConfig
913